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 + -
显示快捷键?