📄 xcommon.c
字号:
p_vout->p_sys->old_subpic, 0, 0, p_vout->p_sys->xvmc_width, p_vout->p_sys->xvmc_height, 0, 0, p_vout->p_sys->xvmc_width, p_vout->p_sys->xvmc_height ); } XVMCUNLOCKDISPLAY(p_vout->p_sys->p_display); } } else { XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); if( p_vout->p_sys->xvmc_backend_subpic ) { XvMCBlendSubpicture( p_vout->p_sys->p_display, p_pic->p_sys->xvmc_surf, p_vout->p_sys->old_subpic, 0, 0, p_vout->p_sys->xvmc_width, p_vout->p_sys->xvmc_height, 0, 0, p_vout->p_sys->xvmc_width, p_vout->p_sys->xvmc_height ); } else { XvMCBlendSubpicture2( p_vout->p_sys->p_display, p_pic->p_sys->xvmc_surf, p_pic->p_sys->xvmc_surf, p_vout->p_sys->old_subpic, 0, 0, p_vout->p_sys->xvmc_width, p_vout->p_sys->xvmc_height, 0, 0, p_vout->p_sys->xvmc_width, p_vout->p_sys->xvmc_height ); } XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); } } p_vout->p_sys->p_last_subtitle_save = p_vout->p_last_subtitle; vlc_mutex_unlock( &p_vout->lastsubtitle_lock );#endif xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock ); vlc_mutex_unlock( &p_vout->p_sys->lock );}#endif#ifdef HAVE_XSP/***************************************************************************** * EnablePixelDoubling: Enables pixel doubling ***************************************************************************** * Checks if the double size image fits in current window, and enables pixel * doubling accordingly. The i_hw_scale is the integer scaling factor. *****************************************************************************/static void EnablePixelDoubling( vout_thread_t *p_vout ){ int i_hor_scale = ( p_vout->p_sys->p_win->i_width ) / p_vout->render.i_width; int i_vert_scale = ( p_vout->p_sys->p_win->i_height ) / p_vout->render.i_height; if ( ( i_hor_scale > 1 ) && ( i_vert_scale > 1 ) ) { p_vout->p_sys->i_hw_scale = 2; msg_Dbg( p_vout, "Enabling pixel doubling, scaling factor %d", p_vout->p_sys->i_hw_scale ); XSPSetPixelDoubling( p_vout->p_sys->p_display, 0, 1 ); }}/***************************************************************************** * DisablePixelDoubling: Disables pixel doubling ***************************************************************************** * The scaling factor i_hw_scale is reset to the no-scaling value 1. *****************************************************************************/static void DisablePixelDoubling( vout_thread_t *p_vout ){ if ( p_vout->p_sys->i_hw_scale > 1 ) { msg_Dbg( p_vout, "Disabling pixel doubling" ); XSPSetPixelDoubling( p_vout->p_sys->p_display, 0, 0 ); p_vout->p_sys->i_hw_scale = 1; }}#endif/***************************************************************************** * InitVideo: initialize X11 video thread output method ***************************************************************************** * This function create the XImages needed by the output thread. It is called * at the beginning of the thread, but also each time the window is resized. *****************************************************************************/static int InitVideo( vout_thread_t *p_vout ){ unsigned int i_index = 0; picture_t *p_pic; I_OUTPUTPICTURES = 0;#if defined(MODULE_NAME_IS_xvideo) || defined(MODULE_NAME_IS_xvmc) /* Initialize the output structure; we already found an XVideo port, * and the corresponding chroma we will be using. Since we can * arbitrary scale, stick to the coordinates and aspect. */ p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_aspect = p_vout->render.i_aspect; p_vout->fmt_out = p_vout->fmt_in; p_vout->fmt_out.i_chroma = p_vout->output.i_chroma;#if XvVersion < 2 || ( XvVersion == 2 && XvRevision < 2 ) switch( p_vout->output.i_chroma ) { case VLC_FOURCC('R','V','1','6'):#if defined( WORDS_BIGENDIAN ) p_vout->output.i_rmask = 0xf800; p_vout->output.i_gmask = 0x07e0; p_vout->output.i_bmask = 0x001f;#else p_vout->output.i_rmask = 0x001f; p_vout->output.i_gmask = 0x07e0; p_vout->output.i_bmask = 0xf800;#endif break; case VLC_FOURCC('R','V','1','5'):#if defined( WORDS_BIGENDIAN ) p_vout->output.i_rmask = 0x7c00; p_vout->output.i_gmask = 0x03e0; p_vout->output.i_bmask = 0x001f;#else p_vout->output.i_rmask = 0x001f; p_vout->output.i_gmask = 0x03e0; p_vout->output.i_bmask = 0x7c00;#endif break; }#endif#elif defined(MODULE_NAME_IS_x11) /* Initialize the output structure: RGB with square pixels, whatever * the input format is, since it's the only format we know */ switch( p_vout->p_sys->i_screen_depth ) { case 8: /* FIXME: set the palette */ p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); break; case 15: p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); break; case 16: p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6'); break; case 24: case 32: p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); break; default: msg_Err( p_vout, "unknown screen depth %i", p_vout->p_sys->i_screen_depth ); return VLC_SUCCESS; }#ifdef HAVE_XSP vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width / p_vout->p_sys->i_hw_scale, p_vout->p_sys->p_win->i_height / p_vout->p_sys->i_hw_scale, &i_index, &i_index, &p_vout->fmt_out.i_visible_width, &p_vout->fmt_out.i_visible_height );#else vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width, p_vout->p_sys->p_win->i_height, &i_index, &i_index, &p_vout->fmt_out.i_visible_width, &p_vout->fmt_out.i_visible_height );#endif p_vout->fmt_out.i_chroma = p_vout->output.i_chroma; p_vout->output.i_width = p_vout->fmt_out.i_width = p_vout->fmt_out.i_visible_width * p_vout->fmt_in.i_width / p_vout->fmt_in.i_visible_width; p_vout->output.i_height = p_vout->fmt_out.i_height = p_vout->fmt_out.i_visible_height * p_vout->fmt_in.i_height / p_vout->fmt_in.i_visible_height; p_vout->fmt_out.i_x_offset = p_vout->fmt_out.i_visible_width * p_vout->fmt_in.i_x_offset / p_vout->fmt_in.i_visible_width; p_vout->fmt_out.i_y_offset = p_vout->fmt_out.i_visible_height * p_vout->fmt_in.i_y_offset / p_vout->fmt_in.i_visible_height; p_vout->fmt_out.i_sar_num = p_vout->fmt_out.i_sar_den = 1; p_vout->output.i_aspect = p_vout->fmt_out.i_aspect = p_vout->fmt_out.i_width * VOUT_ASPECT_FACTOR /p_vout->fmt_out.i_height; msg_Dbg( p_vout, "x11 image size %ix%i (%i,%i,%ix%i)", p_vout->fmt_out.i_width, p_vout->fmt_out.i_height, p_vout->fmt_out.i_x_offset, p_vout->fmt_out.i_y_offset, p_vout->fmt_out.i_visible_width, p_vout->fmt_out.i_visible_height );#endif /* Try to initialize up to MAX_DIRECTBUFFERS direct buffers */ while( I_OUTPUTPICTURES < MAX_DIRECTBUFFERS ) { p_pic = NULL; /* Find an empty picture slot */ for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) { if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) { p_pic = p_vout->p_picture + i_index; break; } } /* Allocate the picture */ if( p_pic == NULL || NewPicture( p_vout, p_pic ) ) { break; } p_pic->i_status = DESTROYED_PICTURE; p_pic->i_type = DIRECT_PICTURE; PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; I_OUTPUTPICTURES++; } if( p_vout->output.i_chroma == VLC_FOURCC('Y','V','1','2') ) { /* U and V inverted compared to I420 * Fixme: this should be handled by the vout core */ p_vout->output.i_chroma = VLC_FOURCC('I','4','2','0'); p_vout->fmt_out.i_chroma = VLC_FOURCC('I','4','2','0'); } return VLC_SUCCESS;}/***************************************************************************** * DisplayVideo: displays previously rendered output ***************************************************************************** * This function sends the currently rendered image to X11 server. * (The Xv extension takes care of "double-buffering".) *****************************************************************************/static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic ){ unsigned int i_width, i_height, i_x, i_y; vout_PlacePicture( p_vout, p_vout->p_sys->p_win->i_width, p_vout->p_sys->p_win->i_height, &i_x, &i_y, &i_width, &i_height ); vlc_mutex_lock( &p_vout->p_sys->lock );#ifdef MODULE_NAME_IS_xvmc xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock ); vlc_xxmc_t *xxmc = &p_pic->p_sys->xxmc_data; if( !xxmc->decoded || !xxmc_xvmc_surface_valid( p_vout, p_pic->p_sys->xvmc_surf ) ) { msg_Dbg( p_vout, "DisplayVideo decoded=%d\tsurfacevalid=%d", xxmc->decoded, xxmc_xvmc_surface_valid( p_vout, p_pic->p_sys->xvmc_surf ) ); vlc_mutex_unlock( &p_vout->p_sys->lock ); xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock ); return; } int src_width = p_vout->output.i_width; int src_height = p_vout->output.i_height; int src_x, src_y; if( p_vout->p_sys->xvmc_crop_style == 1 ) { src_x = 20; src_y = 20; src_width -= 40; src_height -= 40; } else if( p_vout->p_sys->xvmc_crop_style == 2 ) { src_x = 20; src_y = 40; src_width -= 40; src_height -= 80; } else if( p_vout->p_sys->xvmc_crop_style == 3 ) { src_x = 40; src_y = 20; src_width -= 80; src_height -= 40; } else { src_x = 0; src_y = 0; } int first_field; if( p_vout->p_sys->xvmc_deinterlace_method > 0 ) { /* BOB DEINTERLACE */ if( (p_pic->p_sys->nb_display == 0) || (p_vout->p_sys->xvmc_deinterlace_method == 1) ) { first_field = (p_pic->b_top_field_first) ? XVMC_BOTTOM_FIELD : XVMC_TOP_FIELD; } else { first_field = (p_pic->b_top_field_first) ? XVMC_TOP_FIELD : XVMC_BOTTOM_FIELD; } } else { first_field = XVMC_FRAME_PICTURE; } XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); XvMCFlushSurface( p_vout->p_sys->p_display, p_pic->p_sys->xvmc_surf ); /* XvMCSyncSurface(p_vout->p_sys->p_display, p_picture->p_sys->xvmc_surf); */ XvMCPutSurface( p_vout->p_sys->p_display, p_pic->p_sys->xvmc_surf, p_vout->p_sys->p_win->video_window, src_x, src_y, src_width, src_height, 0 /*dest_x*/, 0 /*dest_y*/, i_width, i_height, first_field); XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); if( p_vout->p_sys->xvmc_deinterlace_method == 2 ) { /* BOB DEINTERLACE */ if( p_pic->p_sys->nb_display == 0 )/* && ((t2-t1) < 15000)) */ { mtime_t last_date = p_pic->date; vlc_mutex_lock( &p_vout->picture_lock ); if( !p_vout->p_sys->last_date ) { p_pic->date += 20000; } else { p_pic->date = ((3 * p_pic->date - p_vout->p_sys->last_date) / 2 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -