expand.c
来自「linux下的MPEG1」· C语言 代码 · 共 456 行 · 第 1/2 页
C
456 行
/* * Copyright (C) 2003 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: * * expand video filter by James Stembridge 24/05/2003 * improved by Michael Roitzsch * centre_crop_out_mode by Reinhard Nissl * * based on invert.c * */#include "xine_internal.h"#include "post.h"/* The expand trick explained: * * The expand plugin is meant to take frames of arbitrary aspect ratio and * converts them to 4:3 aspect by adding black bars on the top and bottom * of the frame. This allows us to shift overlays down into the black area * so they don't cover the image. * * How do we do that? The naive approach would be to intercept the frame's * draw() function and simply copy the frame's content into a larger one. * This is quite CPU intensive because of the huge memcpy()s involved. * * Therefore the better idea is to trick the decoder into rendering the * image into a frame with pre-attached black borders. This is the way: * - when the decoder asks for a new frame, we allocate an enlarged * frame from the original port and prepare it with black borders * - we modify this frame's base pointers so that the decoder will only see * the area between the black bars * - this frame is given to the decoder, which paints its image inside * - when the decoder draws the frame, the post plugin architecture * will automatically restore the old pointers * This way, the decoder (or any other post plugin up the tree) will only * 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 * 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. */ /* plugin class initialization function */void *expand_init_plugin(xine_t *xine, void *);/* plugin structures */typedef struct expand_parameters_s { int enable_automatic_shift; int overlay_y_offset; double aspect; int centre_cut_out_mode;} expand_parameters_t;START_PARAM_DESCR(expand_parameters_t)PARAM_ITEM(POST_PARAM_TYPE_BOOL, enable_automatic_shift, NULL, 0, 1, 0, "enable automatic overlay shifting")PARAM_ITEM(POST_PARAM_TYPE_INT, overlay_y_offset, NULL, -500, 500, 0, "manually shift the overlay vertically")PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, aspect, NULL, 1.0, 3.5, 0, "target aspect ratio")PARAM_ITEM(POST_PARAM_TYPE_BOOL, centre_cut_out_mode, NULL, 0, 1, 0, "cut out centred 4:3 image contained in 16:9 frame")END_PARAM_DESCR(expand_param_descr)typedef struct post_expand_s { post_plugin_t post; xine_post_in_t parameter_input; int enable_automatic_shift; int overlay_y_offset; double aspect; int top_bar_height; int centre_cut_out_mode; int cropping_active;} post_expand_t;/* plugin class functions */static post_plugin_t *expand_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target);static char *expand_get_identifier(post_class_t *class_gen);static char *expand_get_description(post_class_t *class_gen);static void expand_class_dispose(post_class_t *class_gen);/* plugin instance functions */static void expand_dispose(post_plugin_t *this_gen);/* parameter functions */static xine_post_api_descr_t *expand_get_param_descr(void);static int expand_set_parameters(xine_post_t *this_gen, void *param_gen);static int expand_get_parameters(xine_post_t *this_gen, void *param_gen);static char *expand_get_help (void);/* replaced video port functions */static vo_frame_t *expand_get_frame(xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags);/* replaced vo_frame functions */static int expand_draw(vo_frame_t *frame, xine_stream_t *stream);/* overlay manager intercept check */static int expand_intercept_ovl(post_video_port_t *port);/* replaced overlay manager functions */static int32_t expand_overlay_add_event(video_overlay_manager_t *this_gen, void *event);void *expand_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 = expand_open_plugin; class->get_identifier = expand_get_identifier; class->get_description = expand_get_description; class->dispose = expand_class_dispose; return class;}static post_plugin_t *expand_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target){ post_expand_t *this = (post_expand_t *)xine_xmalloc(sizeof(post_expand_t)); post_in_t *input; xine_post_in_t *input_param; post_out_t *output; post_video_port_t *port; static xine_post_api_t post_api = { expand_set_parameters, expand_get_parameters, expand_get_param_descr, expand_get_help }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } _x_post_init(&this->post, 0, 1); this->enable_automatic_shift = 0; this->overlay_y_offset = 0; this->aspect = 4.0 / 3.0; this->centre_cut_out_mode = 0; this->cropping_active = 0; port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_port.get_frame = expand_get_frame; port->new_frame->draw = expand_draw; port->intercept_ovl = expand_intercept_ovl; port->new_manager->add_event = expand_overlay_add_event; input_param = &this->parameter_input; input_param->name = "parameters"; input_param->type = XINE_POST_DATA_PARAMETERS; input_param->data = &post_api; xine_list_push_back(this->post.input, input_param); input->xine_in.name = "video"; output->xine_out.name = "expanded video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = expand_dispose; return &this->post;}static char *expand_get_identifier(post_class_t *class_gen){ return "expand";}static char *expand_get_description(post_class_t *class_gen){ return "add black borders to top and bottom of video to expand it to 4:3 aspect ratio";}static void expand_class_dispose(post_class_t *class_gen){ free(class_gen);}static void expand_dispose(post_plugin_t *this_gen){ post_expand_t *this = (post_expand_t *)this_gen; if (_x_post_dispose(this_gen)) free(this);}static xine_post_api_descr_t *expand_get_param_descr(void){ return &expand_param_descr;}static int expand_set_parameters(xine_post_t *this_gen, void *param_gen){ post_expand_t *this = (post_expand_t *)this_gen; expand_parameters_t *param = (expand_parameters_t *)param_gen;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?