diff options
-rw-r--r-- | src/post/planar/Makefile.am | 2 | ||||
-rw-r--r-- | src/post/planar/fill.c | 165 | ||||
-rw-r--r-- | src/post/planar/planar.c | 6 |
3 files changed, 171 insertions, 2 deletions
diff --git a/src/post/planar/Makefile.am b/src/post/planar/Makefile.am index 4bdf8c80f..5eeae5a58 100644 --- a/src/post/planar/Makefile.am +++ b/src/post/planar/Makefile.am @@ -7,7 +7,7 @@ libdir = $(XINE_PLUGINDIR)/post lib_LTLIBRARIES = xineplug_post_planar.la -xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c boxblur.c \ +xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c boxblur.c \ denoise3d.c eq.c eq2.c unsharp.c pp.c xineplug_post_planar_la_DEPENDENCIES = $(POSTPROC_LIB) xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(POSTPROC_LIB) -lm diff --git a/src/post/planar/fill.c b/src/post/planar/fill.c new file mode 100644 index 000000000..1fdc2ad8b --- /dev/null +++ b/src/post/planar/fill.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2005 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: fill.c,v 1.1 2005/07/18 18:02:51 jstembridge Exp $ + * + * fill video filter by James Stembridge (jstembridge@gmail.com) + * + * based on invert.c + * + */ + +#include "xine_internal.h" +#include "post.h" + +/* plugin class initialization function */ +void *fill_init_plugin(xine_t *xine, void *); + +/* plugin class functions */ +static post_plugin_t *fill_open_plugin(post_class_t *class_gen, int inputs, + xine_audio_port_t **audio_target, + xine_video_port_t **video_target); +static char *fill_get_identifier(post_class_t *class_gen); +static char *fill_get_description(post_class_t *class_gen); +static void fill_class_dispose(post_class_t *class_gen); + +/* plugin instance functions */ +static void fill_dispose(post_plugin_t *this_gen); + +/* replaced video port functions */ +static vo_frame_t *fill_get_frame(xine_video_port_t *port_gen, uint32_t width, + uint32_t height, double ratio, + int format, int flags); +static int fill_draw(vo_frame_t *frame, xine_stream_t *stream); + + +void *fill_init_plugin(xine_t *xine, void *data) +{ + post_class_t *class = (post_class_t *)malloc(sizeof(post_class_t)); + + if (!class) + return NULL; + + class->open_plugin = fill_open_plugin; + class->get_identifier = fill_get_identifier; + class->get_description = fill_get_description; + class->dispose = fill_class_dispose; + + return class; +} + + +static post_plugin_t *fill_open_plugin(post_class_t *class_gen, int inputs, + xine_audio_port_t **audio_target, + xine_video_port_t **video_target) +{ + post_plugin_t *this = (post_plugin_t *)xine_xmalloc(sizeof(post_plugin_t)); + post_in_t *input; + post_out_t *output; + post_video_port_t *port; + + if (!this || !video_target || !video_target[0]) { + free(this); + return NULL; + } + + _x_post_init(this, 0, 1); + + port = _x_post_intercept_video_port(this, video_target[0], &input, &output); + port->new_port.get_frame = fill_get_frame; + port->new_frame->draw = fill_draw; + + input->xine_in.name = "video"; + output->xine_out.name = "cropped video"; + + this->xine_post.video_input[0] = &port->new_port; + + this->dispose = fill_dispose; + + return this; +} + +static char *fill_get_identifier(post_class_t *class_gen) +{ + return "fill"; +} + +static char *fill_get_description(post_class_t *class_gen) +{ + return "crops left and right of video to fill 4:3 aspect ratio"; +} + +static void fill_class_dispose(post_class_t *class_gen) +{ + free(class_gen); +} + +static void fill_dispose(post_plugin_t *this) +{ + if (_x_post_dispose(this)) + free(this); +} + + +static vo_frame_t *fill_get_frame(xine_video_port_t *port_gen, uint32_t width, + uint32_t height, double ratio, + int format, int flags) +{ + post_video_port_t *port = (post_video_port_t *)port_gen; + post_plugin_t *this = port->post; + vo_frame_t *frame; + + _x_post_rewire(this); + + if (ratio <= 0.0) ratio = (double)width / (double)height; + + if ((ratio > 4.0/3.0) && + (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) { + frame = port->original_port->get_frame(port->original_port, + width, height, 4.0/3.0, format, flags); + + _x_post_inc_usage(port); + frame = _x_post_intercept_video_frame(frame, port); + + frame->ratio = ratio; + } else { + frame = port->original_port->get_frame(port->original_port, + width, height, ratio, format, flags); + /* no need to intercept this one, we are not going to do anything with it */ + } + + return frame; +} + + +static int fill_draw(vo_frame_t *frame, xine_stream_t *stream) +{ + int skip, new_width; + + new_width = (4.0*frame->width) / (3.0*frame->ratio); + + frame->crop_left += (frame->width - new_width) / 2; + frame->crop_right += (frame->width + 1 - new_width) / 2; + frame->ratio = 4.0/3.0; + + _x_post_frame_copy_down(frame, frame->next); + skip = frame->next->draw(frame->next, stream); + _x_post_frame_copy_up(frame, frame->next); + return skip; +} diff --git a/src/post/planar/planar.c b/src/post/planar/planar.c index 07db7a4e5..2d2c76767 100644 --- a/src/post/planar/planar.c +++ b/src/post/planar/planar.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: planar.c,v 1.8 2004/04/17 19:54:32 mroi Exp $ + * $Id: planar.c,v 1.9 2005/07/18 18:02:51 jstembridge Exp $ * * catalog for planar post plugins */ @@ -32,6 +32,9 @@ post_info_t invert_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; extern void *expand_init_plugin(xine_t *xine, void *); post_info_t expand_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; +extern void *fill_init_plugin(xine_t *xine, void*); +post_info_t fill_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; + extern void *eq_init_plugin(xine_t *xine, void *); post_info_t eq_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; @@ -53,6 +56,7 @@ post_info_t pp_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 9, "expand", XINE_VERSION_CODE, &expand_special_info, &expand_init_plugin }, + { PLUGIN_POST, 9, "fill", XINE_VERSION_CODE, &fill_special_info, &fill_init_plugin }, { PLUGIN_POST, 9, "invert", XINE_VERSION_CODE, &invert_special_info, &invert_init_plugin }, { PLUGIN_POST, 9, "eq", XINE_VERSION_CODE, &eq_special_info, &eq_init_plugin }, { PLUGIN_POST, 9, "denoise3d", XINE_VERSION_CODE, &denoise3d_special_info, &denoise3d_init_plugin }, |