/* * 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 * * 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; }