xine_plugin.c
来自「linux下的MPEG1」· C语言 代码 · 共 927 行 · 第 1/3 页
C
927 行
register_deinterlace_method( linear_get_method() ); register_deinterlace_method( linearblend_get_method() ); register_deinterlace_method( greedy_get_method() ); register_deinterlace_method( greedy2frame_get_method() ); register_deinterlace_method( weave_get_method() ); register_deinterlace_method( double_get_method() ); register_deinterlace_method( vfir_get_method() ); register_deinterlace_method( scalerbob_get_method() ); register_deinterlace_method( dscaler_greedyh_get_method() ); register_deinterlace_method( dscaler_tomsmocomp_get_method() ); filter_deinterlace_methods( config_flags, 5 /*fieldsavailable*/ ); if( !get_num_deinterlace_methods() ) { xprintf(xine, XINE_VERBOSITY_LOG, _("tvtime: No deinterlacing methods available, exiting.\n")); return NULL; } help_string = xine_buffer_init(1024); xine_buffer_strcat( help_string, get_static_help() ); enum_methods[0] = "use_vo_driver"; for(i = 0; i < get_num_deinterlace_methods(); i++ ) { deinterlace_method_t *method; method = get_deinterlace_method(i); enum_methods[i+1] = method->short_name; xine_buffer_strcat( help_string, "[" ); xine_buffer_strcat( help_string, method->short_name ); xine_buffer_strcat( help_string, "] " ); xine_buffer_strcat( help_string, method->name ); xine_buffer_strcat( help_string, ":\n" ); if (method->description) xine_buffer_strcat( help_string, method->description ); xine_buffer_strcat( help_string, "\n---\n" ); } enum_methods[i+1] = NULL; /* Some default values */ class->init_param.method = 1; /* First (plugin) method available */ class->init_param.enabled = 1; class->init_param.pulldown = 1; /* vektor */ class->init_param.framerate_mode = 0; /* full */ class->init_param.judder_correction = 1; class->init_param.use_progressive_frame_flag = 1; class->init_param.chroma_filter = 0; class->init_param.cheap_mode = 0; return &class->class;}static post_plugin_t *deinterlace_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target){ post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)xine_xmalloc(sizeof(post_plugin_deinterlace_t)); post_in_t *input; xine_post_in_t *input_api; post_out_t *output; post_class_deinterlace_t *class = (post_class_deinterlace_t *)class_gen; post_video_port_t *port; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } _x_post_init(&this->post, 0, 1); this->tvtime = tvtime_new_context(); this->tvtime_changed++; this->tvtime_last_filmmode = 0; pthread_mutex_init (&this->lock, NULL); set_parameters ((xine_post_t *)&this->post, &class->init_param); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); /* replace with our own get_frame function */ port->new_port.open = deinterlace_open; port->new_port.close = deinterlace_close; port->new_port.get_property = deinterlace_get_property; port->new_port.set_property = deinterlace_set_property; port->new_port.flush = deinterlace_flush; port->intercept_frame = deinterlace_intercept_frame; port->new_frame->draw = deinterlace_draw; input_api = &this->parameter_input; input_api->name = "parameters"; input_api->type = XINE_POST_DATA_PARAMETERS; input_api->data = &post_api; xine_list_push_back(this->post.input, input_api); input->xine_in.name = "video"; output->xine_out.name = "deinterlaced video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = deinterlace_dispose; return &this->post;}static char *deinterlace_get_identifier(post_class_t *class_gen){ return "tvtime";}static char *deinterlace_get_description(post_class_t *class_gen){ return "advanced deinterlacer plugin with pulldown detection";}static void deinterlace_class_dispose(post_class_t *class_gen){ xine_buffer_free(help_string); free(class_gen);}static void deinterlace_dispose(post_plugin_t *this_gen){ post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)this_gen; if (_x_post_dispose(this_gen)) { _flush_frames(this); pthread_mutex_destroy(&this->lock); free(this); }}static int deinterlace_get_property(xine_video_port_t *port_gen, int property) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; if( property == XINE_PARAM_VO_DEINTERLACE && this->cur_method ) return this->enabled; else return port->original_port->get_property(port->original_port, property);}static int deinterlace_set_property(xine_video_port_t *port_gen, int property, int value) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; if( property == XINE_PARAM_VO_DEINTERLACE ) { pthread_mutex_lock (&this->lock); if( this->enabled != value ) _flush_frames(this); this->enabled = value; pthread_mutex_unlock (&this->lock); this->vo_deinterlace_enabled = this->enabled && (!this->cur_method); port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, this->vo_deinterlace_enabled); return this->enabled; } else return port->original_port->set_property(port->original_port, property, value);}static void deinterlace_flush(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; _flush_frames(this); port->original_port->flush(port->original_port);}static void deinterlace_open(xine_video_port_t *port_gen, xine_stream_t *stream){ post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; (port->original_port->open) (port->original_port, stream); this->vo_deinterlace_enabled = !this->cur_method; port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, this->vo_deinterlace_enabled);}static void deinterlace_close(xine_video_port_t *port_gen, xine_stream_t *stream){ post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; port->stream = NULL; _flush_frames(this); port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, 0); port->original_port->close(port->original_port, stream); _x_post_dec_usage(port);}static int deinterlace_intercept_frame(post_video_port_t *port, vo_frame_t *frame){ post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; int vo_deinterlace_enabled = 0; vo_deinterlace_enabled = ( frame->format != XINE_IMGFMT_YV12 && frame->format != XINE_IMGFMT_YUY2 && this->enabled ); if( this->cur_method && this->vo_deinterlace_enabled != vo_deinterlace_enabled ) { this->vo_deinterlace_enabled = vo_deinterlace_enabled; port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, this->vo_deinterlace_enabled); } return (this->enabled && this->cur_method && (frame->flags & VO_INTERLACED_FLAG) && (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2) );}static void apply_chroma_filter( uint8_t *data, int stride, int width, int height ){ int i; /* ok, using linearblend inplace is a bit weird: the result of a scanline * interpolation will affect the next scanline. this might not be a problem * at all, we just want a kind of filter here. */ for( i = 0; i < height; i++, data += stride ) { vfilter_chroma_332_packed422_scanline( data, width, data, (i) ? (data - stride) : data, (i < height-1) ? (data + stride) : data ); }}/* Build the output frame from the specified field. */static int deinterlace_build_output_field( post_plugin_deinterlace_t *this, post_video_port_t *port, xine_stream_t *stream, vo_frame_t *frame, vo_frame_t *yuy2_frame, int bottom_field, int second_field, int64_t pts, int64_t duration, int skip){ vo_frame_t *deinterlaced_frame; int scaler = 1; int force24fps; force24fps = this->judder_correction && !this->cheap_mode && ( this->pulldown == PULLDOWN_VEKTOR && this->tvtime->filmmode ); if( this->tvtime->curmethod->doscalerbob ) { scaler = 2; } pthread_mutex_unlock (&this->lock); deinterlaced_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height / scaler, frame->ratio, yuy2_frame->format, frame->flags | VO_BOTH_FIELDS); pthread_mutex_lock (&this->lock); deinterlaced_frame->crop_left = frame->crop_left; deinterlaced_frame->crop_right = frame->crop_right; deinterlaced_frame->crop_top = frame->crop_top; deinterlaced_frame->crop_bottom = frame->crop_bottom; _x_extra_info_merge(deinterlaced_frame->extra_info, frame->extra_info); if( skip > 0 && !this->pulldown ) { deinterlaced_frame->bad_frame = 1; } else { if( this->tvtime->curmethod->doscalerbob ) { if( yuy2_frame->format == XINE_IMGFMT_YUY2 ) { deinterlaced_frame->bad_frame = !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[0], yuy2_frame->base[0], bottom_field, frame->width, frame->height, yuy2_frame->pitches[0], deinterlaced_frame->pitches[0] ); } else { deinterlaced_frame->bad_frame = !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[0], yuy2_frame->base[0], bottom_field, frame->width/2, frame->height, yuy2_frame->pitches[0], deinterlaced_frame->pitches[0] ); deinterlaced_frame->bad_frame += !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[1], yuy2_frame->base[1], bottom_field, frame->width/4, frame->height/2, yuy2_frame->pitches[1], deinterlaced_frame->pitches[1] ); deinterlaced_frame->bad_frame += !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[2], yuy2_frame->base[2], bottom_field, frame->width/4, frame->height/2, yuy2_frame->pitches[2], deinterlaced_frame->pitches[2] ); } } else { if( yuy2_frame->format == XINE_IMGFMT_YUY2 ) { deinterlaced_frame->bad_frame = !tvtime_build_deinterlaced_frame(this->tvtime,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?