From: Kees C. <ke...@ou...> - 2008-07-14 06:41:17
|
This post plugin allows zooming a frame to the window width. For example, if viewing a 16:9 movie encoded into a 4:3 stream, at full-screen on a 16:9 monitor, there was no way I could find to eliminate the resulting black border. Enabling this plugin will crop the top and bottom of the frame so the frame width is maximized. This is similar to MythTV's "zoom" feature, so I named it "zoom". Also, while researching other plugins, I found a minor documentation typo that I fixed. Thanks! --- src/post/planar/Makefile.am | 2 src/post/planar/expand.c | 4 - src/post/planar/zoom.c | 163 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 3 deletions(-) --- xine-lib-1.1.11.1.orig/src/post/planar/zoom.c +++ xine-lib-1.1.11.1/src/post/planar/zoom.c @@ -0,0 +1,163 @@ +/* + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * zoom video filter by Kees Cook <ke...@ou...> + * + * based on fill.c + * based on invert.c + */ + +#include "xine_internal.h" +#include "post.h" + +/* plugin class initialization function */ +void *zoom_init_plugin(xine_t *xine, void *); + +/* plugin class functions */ +static post_plugin_t *zoom_open_plugin(post_class_t *class_gen, int inputs, + xine_audio_port_t **audio_target, + xine_video_port_t **video_target); +static char *zoom_get_identifier(post_class_t *class_gen); +static char *zoom_get_description(post_class_t *class_gen); +static void zoom_class_dispose(post_class_t *class_gen); + +/* plugin instance functions */ +static void zoom_dispose(post_plugin_t *this_gen); + +/* replaced video port functions */ +static vo_frame_t *zoom_get_frame(xine_video_port_t *port_gen, uint32_t width, + uint32_t height, double ratio, + int format, int flags); +static int zoom_draw(vo_frame_t *frame, xine_stream_t *stream); + + +void *zoom_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 = zoom_open_plugin; + class->get_identifier = zoom_get_identifier; + class->get_description = zoom_get_description; + class->dispose = zoom_class_dispose; + + return class; +} + + +static post_plugin_t *zoom_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 = zoom_get_frame; + port->new_frame->draw = zoom_draw; + + input->xine_in.name = "video"; + output->xine_out.name = "cropped video"; + + this->xine_post.video_input[0] = &port->new_port; + + this->dispose = zoom_dispose; + + return this; +} + +static char *zoom_get_identifier(post_class_t *class_gen) +{ + return "zoom"; +} + +static char *zoom_get_description(post_class_t *class_gen) +{ + return "crops top and bottom of video to fill 16:9 aspect ratio"; +} + +static void zoom_class_dispose(post_class_t *class_gen) +{ + free(class_gen); +} + +static void zoom_dispose(post_plugin_t *this) +{ + if (_x_post_dispose(this)) + free(this); +} + + +static vo_frame_t *zoom_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 < 16.0/9.0) && + (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) { + frame = port->original_port->get_frame(port->original_port, + width, height, 16.0/9.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 zoom_draw(vo_frame_t *frame, xine_stream_t *stream) +{ + int skip, new_width; + + new_height = (16.0*frame->ratio) / (9.0*frame->height); + + frame->crop_top += (frame->height - new_height) / 2; + frame->crop_bottom += (frame->height + 1 - new_height) / 2; + frame->ratio = 16.0/9.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; +} --- xine-lib-1.1.11.1.orig/src/post/planar/Makefile.am +++ xine-lib-1.1.11.1/src/post/planar/Makefile.am @@ -22,7 +22,7 @@ xinepost_LTLIBRARIES = xineplug_post_planar.la -xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c boxblur.c \ +xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c zoom.c boxblur.c \ denoise3d.c eq.c eq2.c unsharp.c pp.c noise.c xineplug_post_planar_la_DEPENDENCIES = $(postproc_dep) xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(postproc_lib) -lm $(PTHREAD_LIBS) $(LTLIBINTL) --- xine-lib-1.1.11.1.orig/src/post/planar/expand.c +++ xine-lib-1.1.11.1/src/post/planar/expand.c @@ -21,7 +21,7 @@ * * expand video filter by James Stembridge 24/05/2003 * improved by Michael Roitzsch - * centre_crop_out_mode by Reinhard Nissl + * centre_cut_out_mode by Reinhard Nissl * * based on invert.c * @@ -54,7 +54,7 @@ * see the frame area between the black bars and by that modify the * enlarged version directly. No need for later copying. * - * When centre_crop_out_mode is enabled, the plugin will detect the black + * When centre_cut is enabled, the plugin will detect the black * bars to the left and right of the image and will then set up cropping * to efficiently remove the black border around the 4:3 image, which the * plugin would produce otherwise for this case. -- Kees Cook @outflux.net |