📄 deinterlace.c
字号:
p_in += p_pic->p[i_plane].i_pitch; p_out += p_pic->p[i_plane].i_pitch; p_vout->p_vlc->pf_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); } } EndMerge();}static void RenderMean( vout_thread_t *p_vout, picture_t *p_outpic, picture_t *p_pic ){ int i_plane; /* Copy image and skip lines */ for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { uint8_t *p_in, *p_out_end, *p_out; p_in = p_pic->p[i_plane].p_pixels; p_out = p_outpic->p[i_plane].p_pixels; p_out_end = p_out + p_outpic->p[i_plane].i_pitch * p_outpic->p[i_plane].i_lines; /* All lines: mean value */ for( ; p_out < p_out_end ; ) { Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch, p_pic->p[i_plane].i_pitch ); p_out += p_pic->p[i_plane].i_pitch; p_in += 2 * p_pic->p[i_plane].i_pitch; } } EndMerge();}static void RenderBlend( vout_thread_t *p_vout, picture_t *p_outpic, picture_t *p_pic ){ int i_plane; /* Copy image and skip lines */ for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { uint8_t *p_in, *p_out_end, *p_out; p_in = p_pic->p[i_plane].p_pixels; p_out = p_outpic->p[i_plane].p_pixels; p_out_end = p_out + p_outpic->p[i_plane].i_pitch * p_outpic->p[i_plane].i_lines; switch( p_vout->render.i_chroma ) { case VLC_FOURCC('I','4','2','0'): case VLC_FOURCC('I','Y','U','V'): case VLC_FOURCC('Y','V','1','2'): /* First line: simple copy */ p_vout->p_vlc->pf_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); p_out += p_pic->p[i_plane].i_pitch; /* Remaining lines: mean value */ for( ; p_out < p_out_end ; ) { Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch, p_pic->p[i_plane].i_pitch ); p_out += p_pic->p[i_plane].i_pitch; p_in += p_pic->p[i_plane].i_pitch; } break; case VLC_FOURCC('I','4','2','2'): /* First line: simple copy */ p_vout->p_vlc->pf_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); p_out += p_pic->p[i_plane].i_pitch; /* Remaining lines: mean value */ if( i_plane == Y_PLANE ) { for( ; p_out < p_out_end ; ) { Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch, p_pic->p[i_plane].i_pitch ); p_out += p_pic->p[i_plane].i_pitch; p_in += p_pic->p[i_plane].i_pitch; } } else { for( ; p_out < p_out_end ; ) { Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch, p_pic->p[i_plane].i_pitch ); p_out += p_pic->p[i_plane].i_pitch; p_in += 2*p_pic->p[i_plane].i_pitch; } } break; } } EndMerge();}#undef Mergestatic void MergeGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2, size_t i_bytes ){ uint8_t* p_dest = (uint8_t*)_p_dest; const uint8_t *p_s1 = (const uint8_t *)_p_s1; const uint8_t *p_s2 = (const uint8_t *)_p_s2; uint8_t* p_end = p_dest + i_bytes - 8; while( p_dest < p_end ) { *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; } p_end += 8; while( p_dest < p_end ) { *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; }}#if defined(CAN_COMPILE_MMX)static void MergeMMX( void *_p_dest, const void *_p_s1, const void *_p_s2, size_t i_bytes ){ uint8_t* p_dest = (uint8_t*)_p_dest; const uint8_t *p_s1 = (const uint8_t *)_p_s1; const uint8_t *p_s2 = (const uint8_t *)_p_s2; uint8_t* p_end = p_dest + i_bytes - 8; while( p_dest < p_end ) { __asm__ __volatile__( "movq %2,%%mm1;" "pavgb %1, %%mm1;" "movq %%mm1, %0" :"=m" (*p_dest): "m" (*p_s1), "m" (*p_s2) ); p_dest += 8; p_s1 += 8; p_s2 += 8; } p_end += 8; while( p_dest < p_end ) { *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; }}#endif#if defined(CAN_COMPILE_SSE)static void MergeSSE2( void *_p_dest, const void *_p_s1, const void *_p_s2, size_t i_bytes ){ uint8_t* p_dest = (uint8_t*)_p_dest; const uint8_t *p_s1 = (const uint8_t *)_p_s1; const uint8_t *p_s2 = (const uint8_t *)_p_s2; uint8_t* p_end = p_dest + i_bytes - 16; while( p_dest < p_end ) { __asm__ __volatile__( "movdqu %2,%%xmm1;" "pavgb %1, %%xmm1;" "movdqu %%xmm1, %0" :"=m" (*p_dest): "m" (*p_s1), "m" (*p_s2) ); p_dest += 16; p_s1 += 16; p_s2 += 16; } p_end += 16; while( p_dest < p_end ) { *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; }}#endif#if defined(CAN_COMPILE_MMX) || defined(CAN_COMPILE_SSE)static void EndMMX( void ){ __asm__ __volatile__( "emms" :: );}#endif#ifdef CAN_COMPILE_C_ALTIVECstatic void MergeAltivec( void *_p_dest, const void *_p_s1, const void *_p_s2, size_t i_bytes ){ uint8_t *p_dest = (uint8_t*)_p_dest; const uint8_t *p_s1 = (const uint8_t *)_p_s1; const uint8_t *p_s2 = (const uint8_t *)_p_s2; uint8_t *p_end = p_dest + i_bytes - 16; if( ( (int)p_s1 & 0xF ) | ( (int)p_s2 & 0xF ) | ( (int)p_dest & 0xF ) ) { /* TODO Handle non 16-bytes aligned planes */ MergeGeneric( _p_dest, _p_s1, _p_s2, i_bytes ); return; } while( p_dest < p_end ) { vec_st( vec_avg( vec_ld( 0, p_s1 ), vec_ld( 0, p_s2 ) ), 0, p_dest ); p_s1 += 16; p_s2 += 16; p_dest += 16; } p_end += 16; while( p_dest < p_end ) { *p_dest++ = ( (uint16_t)(*p_s1++) + (uint16_t)(*p_s2++) ) >> 1; }}#endif/***************************************************************************** * SendEvents: forward mouse and keyboard events to the parent p_vout *****************************************************************************/static int SendEvents( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *_p_vout ){ vout_thread_t *p_vout = (vout_thread_t *)_p_vout; vlc_value_t sentval = newval; if( !strcmp( psz_var, "mouse-y" ) ) { switch( p_vout->p_sys->i_mode ) { case DEINTERLACE_MEAN: case DEINTERLACE_DISCARD: sentval.i_int *= 2; break; } } var_Set( p_vout, psz_var, sentval ); return VLC_SUCCESS;}/***************************************************************************** * FilterCallback: called when changing the deinterlace method on the fly. *****************************************************************************/static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ vout_thread_t * p_vout = (vout_thread_t *)p_this; int i_old_mode = p_vout->p_sys->i_mode; msg_Dbg( p_vout, "using %s deinterlace mode", newval.psz_string ); vlc_mutex_lock( &p_vout->p_sys->filter_lock ); SetFilterMethod( p_vout, newval.psz_string ); switch( p_vout->render.i_chroma ) { case VLC_FOURCC('I','4','2','2'): vlc_mutex_unlock( &p_vout->p_sys->filter_lock ); return VLC_SUCCESS; break; case VLC_FOURCC('I','4','2','0'): case VLC_FOURCC('I','Y','U','V'): case VLC_FOURCC('Y','V','1','2'): switch( p_vout->p_sys->i_mode ) { case DEINTERLACE_MEAN: case DEINTERLACE_DISCARD: if( ( i_old_mode == DEINTERLACE_MEAN ) || ( i_old_mode == DEINTERLACE_DISCARD ) ) { vlc_mutex_unlock( &p_vout->p_sys->filter_lock ); return VLC_SUCCESS; } break; case DEINTERLACE_BOB: case DEINTERLACE_BLEND: case DEINTERLACE_LINEAR: if( ( i_old_mode == DEINTERLACE_BOB ) || ( i_old_mode == DEINTERLACE_BLEND ) || ( i_old_mode == DEINTERLACE_LINEAR ) ) { vlc_mutex_unlock( &p_vout->p_sys->filter_lock ); return VLC_SUCCESS; } break; } break; default: break; } /* We need to kill the old vout */ DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vlc_object_detach( p_vout->p_sys->p_vout ); vout_Destroy( p_vout->p_sys->p_vout ); /* Try to open a new video output */ p_vout->p_sys->p_vout = SpawnRealVout( p_vout ); if( p_vout->p_sys->p_vout == NULL ) { /* Everything failed */ msg_Err( p_vout, "cannot open vout, aborting" ); vlc_mutex_unlock( &p_vout->p_sys->filter_lock ); return VLC_EGENERIC; } ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vlc_mutex_unlock( &p_vout->p_sys->filter_lock ); return VLC_SUCCESS;}/***************************************************************************** * SendEventsToChild: forward events to the child/children vout *****************************************************************************/static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; var_Set( p_vout->p_sys->p_vout, psz_var, newval ); return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -