📄 distort.c
字号:
*****************************************************************************/static void Destroy( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; if( p_vout->p_sys->p_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 ); } DEL_PARENT_CALLBACKS( SendEventsToChild ); free( p_vout->p_sys );}/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Distort image, waits * until it is displayed and switch the two rendering buffers, preparing next * frame. *****************************************************************************/static void Render( vout_thread_t *p_vout, picture_t *p_pic ){ picture_t *p_outpic; /* This is a new frame. Get a structure from the video_output. */ while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) == NULL ) { if( p_vout->b_die || p_vout->b_error ) { return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date ); switch( p_vout->p_sys->i_mode ) { case DISTORT_MODE_WAVE: DistortWave( p_vout, p_pic, p_outpic ); break; case DISTORT_MODE_RIPPLE: DistortRipple( p_vout, p_pic, p_outpic ); break; default: break; } vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );}/***************************************************************************** * DistortWave: draw a wave effect on the picture *****************************************************************************/static void DistortWave( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int i_index; double f_angle; mtime_t new_date = mdate(); p_vout->p_sys->f_angle += (new_date - p_vout->p_sys->last_date) / 200000.0; p_vout->p_sys->last_date = new_date; f_angle = p_vout->p_sys->f_angle; for( i_index = 0 ; i_index < p_inpic->i_planes ; i_index++ ) { int i_line, i_num_lines, i_offset; uint8_t black_pixel; uint8_t *p_in, *p_out; p_in = p_inpic->p[i_index].p_pixels; p_out = p_outpic->p[i_index].p_pixels; i_num_lines = p_inpic->p[i_index].i_visible_lines; black_pixel = ( i_index == Y_PLANE ) ? 0x00 : 0x80; /* Ok, we do 3 times the sin() calculation for each line. So what ? */ for( i_line = 0 ; i_line < i_num_lines ; i_line++ ) { /* Calculate today's offset, don't go above 1/20th of the screen */ i_offset = (int)( (double)(p_inpic->p[i_index].i_visible_pitch) * sin( f_angle + 10.0 * (double)i_line / (double)i_num_lines ) / 20.0 ); if( i_offset ) { if( i_offset < 0 ) { p_vout->p_vlc->pf_memcpy( p_out, p_in - i_offset, p_inpic->p[i_index].i_visible_pitch + i_offset ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; memset( p_out + i_offset, black_pixel, -i_offset ); } else { p_vout->p_vlc->pf_memcpy( p_out + i_offset, p_in, p_inpic->p[i_index].i_visible_pitch - i_offset ); memset( p_out, black_pixel, i_offset ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } else { p_vout->p_vlc->pf_memcpy( p_out, p_in, p_inpic->p[i_index].i_visible_pitch ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } }}/***************************************************************************** * DistortRipple: draw a ripple effect at the bottom of the picture *****************************************************************************/static void DistortRipple( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int i_index; double f_angle; mtime_t new_date = mdate(); p_vout->p_sys->f_angle -= (p_vout->p_sys->last_date - new_date) / 100000.0; p_vout->p_sys->last_date = new_date; f_angle = p_vout->p_sys->f_angle; for( i_index = 0 ; i_index < p_inpic->i_planes ; i_index++ ) { int i_line, i_first_line, i_num_lines, i_offset; uint8_t black_pixel; uint8_t *p_in, *p_out; black_pixel = ( i_index == Y_PLANE ) ? 0x00 : 0x80; i_num_lines = p_inpic->p[i_index].i_visible_lines; i_first_line = i_num_lines * 4 / 5; p_in = p_inpic->p[i_index].p_pixels; p_out = p_outpic->p[i_index].p_pixels; for( i_line = 0 ; i_line < i_first_line ; i_line++ ) { p_vout->p_vlc->pf_memcpy( p_out, p_in, p_inpic->p[i_index].i_visible_pitch ); p_in += p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } /* Ok, we do 3 times the sin() calculation for each line. So what ? */ for( i_line = i_first_line ; i_line < i_num_lines ; i_line++ ) { /* Calculate today's offset, don't go above 1/20th of the screen */ i_offset = (int)( (double)(p_inpic->p[i_index].i_pitch) * sin( f_angle + 2.0 * (double)i_line / (double)( 1 + i_line - i_first_line) ) * (double)(i_line - i_first_line) / (double)i_num_lines / 8.0 ); if( i_offset ) { if( i_offset < 0 ) { p_vout->p_vlc->pf_memcpy( p_out, p_in - i_offset, p_inpic->p[i_index].i_visible_pitch + i_offset ); p_in -= p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; memset( p_out + i_offset, black_pixel, -i_offset ); } else { p_vout->p_vlc->pf_memcpy( p_out + i_offset, p_in, p_inpic->p[i_index].i_visible_pitch - i_offset ); memset( p_out, black_pixel, i_offset ); p_in -= p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } else { p_vout->p_vlc->pf_memcpy( p_out, p_in, p_inpic->p[i_index].i_visible_pitch ); p_in -= p_inpic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch; } } }}/***************************************************************************** * 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_data ){ var_Set( (vlc_object_t *)p_data, psz_var, newval ); 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 + -