📄 crop.c
字号:
( p_vout->output.i_width - p_vout->p_sys->i_width ) / 2; p_vout->p_sys->i_y = ( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2; } /* Check for validity */ if( p_vout->p_sys->i_x + p_vout->p_sys->i_width > p_vout->output.i_width ) { p_vout->p_sys->i_x = 0; if( p_vout->p_sys->i_width > p_vout->output.i_width ) { p_vout->p_sys->i_width = p_vout->output.i_width; } } if( p_vout->p_sys->i_y + p_vout->p_sys->i_height > p_vout->output.i_height ) { p_vout->p_sys->i_y = 0; if( p_vout->p_sys->i_height > p_vout->output.i_height ) { p_vout->p_sys->i_height = p_vout->output.i_height; } } free( psz_var ); } else#ifdef BEST_AUTOCROP if (p_vout->p_sys->i_ratio) { p_vout->p_sys->i_aspect = p_vout->p_sys->i_ratio * 432; p_vout->p_sys->i_width = p_vout->fmt_out.i_visible_width; p_vout->p_sys->i_height = p_vout->output.i_aspect * p_vout->output.i_height / p_vout->p_sys->i_aspect * p_vout->p_sys->i_width / p_vout->output.i_width; p_vout->p_sys->i_height += p_vout->p_sys->i_height % 2; p_vout->p_sys->i_x = p_vout->fmt_out.i_x_offset; p_vout->p_sys->i_y = (p_vout->output.i_height - p_vout->p_sys->i_height) / 2; } else#endif { p_vout->p_sys->i_width = p_vout->fmt_out.i_visible_width; p_vout->p_sys->i_height = p_vout->fmt_out.i_visible_height; p_vout->p_sys->i_x = p_vout->fmt_out.i_x_offset; p_vout->p_sys->i_y = p_vout->fmt_out.i_y_offset; } /* Pheeew. Parsing done. */ msg_Dbg( p_vout, "cropping at %ix%i+%i+%i, %sautocropping", p_vout->p_sys->i_width, p_vout->p_sys->i_height, p_vout->p_sys->i_x, p_vout->p_sys->i_y, p_vout->p_sys->b_autocrop ? "" : "not " ); /* Set current output image properties */ p_vout->p_sys->i_aspect = p_vout->fmt_out.i_aspect * p_vout->fmt_out.i_visible_height / p_vout->p_sys->i_height * p_vout->p_sys->i_width / p_vout->fmt_out.i_visible_width;#ifdef BEST_AUTOCROP msg_Info( p_vout, "ratio %d", p_vout->p_sys->i_aspect / 432);#endif fmt.i_width = fmt.i_visible_width = p_vout->p_sys->i_width; fmt.i_height = fmt.i_visible_height = p_vout->p_sys->i_height; fmt.i_x_offset = fmt.i_y_offset = 0; fmt.i_chroma = p_vout->render.i_chroma; fmt.i_aspect = p_vout->p_sys->i_aspect; fmt.i_sar_num = p_vout->p_sys->i_aspect * fmt.i_height / fmt.i_width; fmt.i_sar_den = VOUT_ASPECT_FACTOR; /* Try to open the real video output */ p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt ); if( p_vout->p_sys->p_vout == NULL ) { msg_Err( p_vout, "failed to create vout" ); intf_UserFatal( p_vout, false, _("Cropping failed"), _("VLC could not open the video output module.") ); return VLC_EGENERIC; }#ifdef BEST_AUTOCROP var_AddCallback( p_vout, "ratio-crop", FilterCallback, NULL );#endif ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); ADD_PARENT_CALLBACKS( SendEventsToChild ); return VLC_SUCCESS;}/***************************************************************************** * End: terminate Crop video thread output method *****************************************************************************/static void End( vout_thread_t *p_vout ){ int i_index; DEL_PARENT_CALLBACKS( SendEventsToChild ); if( p_vout->p_sys->p_vout ) DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); /* Free the fake output buffers we allocated */ for( i_index = I_OUTPUTPICTURES ; i_index ; ) { i_index--; free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); } if( p_vout->p_sys->p_vout ) vout_CloseAndRelease( p_vout->p_sys->p_vout );}/***************************************************************************** * Destroy: destroy Crop video thread output method ***************************************************************************** * Terminate an output method created by CropCreateOutputMethod *****************************************************************************/static void Destroy( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; free( p_vout->p_sys );}/***************************************************************************** * Manage: handle Crop events ***************************************************************************** * This function should be called regularly by video output thread. It manages * console events. It returns a non null value on error. *****************************************************************************/static int Manage( vout_thread_t *p_vout ){ video_format_t fmt; if( !p_vout->p_sys->b_changed ) { return VLC_SUCCESS; } memset( &fmt, 0, sizeof(video_format_t) );#ifdef BEST_AUTOCROP msg_Dbg( p_vout, "cropping at %ix%i+%i+%i, %sautocropping", p_vout->p_sys->i_width, p_vout->p_sys->i_height, p_vout->p_sys->i_x, p_vout->p_sys->i_y, p_vout->p_sys->b_autocrop ? "" : "not " ); msg_Info( p_vout, "ratio %d", p_vout->p_sys->i_aspect / 432);#endif if( p_vout->p_sys->p_vout ) { DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_CloseAndRelease( p_vout->p_sys->p_vout ); } fmt.i_width = fmt.i_visible_width = p_vout->p_sys->i_width; fmt.i_height = fmt.i_visible_height = p_vout->p_sys->i_height; fmt.i_x_offset = fmt.i_y_offset = 0; fmt.i_chroma = p_vout->render.i_chroma; fmt.i_aspect = p_vout->p_sys->i_aspect; fmt.i_sar_num = p_vout->p_sys->i_aspect * fmt.i_height / fmt.i_width; fmt.i_sar_den = VOUT_ASPECT_FACTOR; p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt ); if( p_vout->p_sys->p_vout == NULL ) { msg_Err( p_vout, "failed to create vout" ); intf_UserFatal( p_vout, false, _("Cropping failed"), _("VLC could not open the video output module.") ); return VLC_EGENERIC; } ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); p_vout->p_sys->b_changed = false; p_vout->p_sys->i_lastchange = 0; return VLC_SUCCESS;}/***************************************************************************** * Render: display previously rendered output ***************************************************************************** * This function sends the currently rendered image to Crop image, waits * until it is displayed and switches the two rendering buffers, preparing next * frame. *****************************************************************************/static void Render( vout_thread_t *p_vout, picture_t *p_pic ){ picture_t *p_outpic = NULL; int i_plane; if( p_vout->p_sys->b_changed ) { return; } while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) == NULL ) { if( !vlc_object_alive (p_vout) || p_vout->b_error ) { vout_DestroyPicture( p_vout->p_sys->p_vout, p_outpic ); return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date ); vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { uint8_t *p_in, *p_out, *p_out_end; int i_in_pitch = p_pic->p[i_plane].i_pitch; const int i_out_pitch = p_outpic->p[i_plane].i_pitch; const int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; p_in = p_pic->p[i_plane].p_pixels /* Skip the right amount of lines */ + i_in_pitch * ( p_pic->p[i_plane].i_visible_lines * p_vout->p_sys->i_y / p_vout->output.i_height ) /* Skip the right amount of columns */ + i_in_pitch * p_vout->p_sys->i_x / p_vout->output.i_width; p_out = p_outpic->p[i_plane].p_pixels; p_out_end = p_out + i_out_pitch * p_outpic->p[i_plane].i_visible_lines; while( p_out < p_out_end ) { vlc_memcpy( p_out, p_in, i_copy_pitch ); p_in += i_in_pitch; p_out += i_out_pitch; } } vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); /* The source image may still be in the cache ... parse it! */ if( p_vout->p_sys->b_autocrop ) { UpdateStats( p_vout, p_pic ); }}#ifdef BEST_AUTOCROPstatic bool NonBlackLine(uint8_t *p_in, int i_line, int i_pitch, int i_visible_pitch, int i_lines, int i_lumThreshold, int i_skipCountPercent, int i_nonBlackPixel, int i_chroma){ const int i_col = i_line * i_pitch / i_lines; int i_index, i_count = 0; int i_skipCount = 0; switch(i_chroma) { // planar YUV case VLC_FOURCC('I','4','4','4'): case VLC_FOURCC('I','4','2','2'): case VLC_FOURCC('I','4','2','0'): case VLC_FOURCC('Y','V','1','2'): case VLC_FOURCC('I','Y','U','V'): case VLC_FOURCC('I','4','1','1'): case VLC_FOURCC('I','4','1','0'): case VLC_FOURCC('Y','V','U','9'): case VLC_FOURCC('Y','U','V','A'): i_skipCount = (i_pitch * i_skipCountPercent) / 100; for (i_index = i_col/2 + i_skipCount/2; i_index <= i_visible_pitch/2 + i_col/2 - i_skipCount/2; i_index++) { i_count += (p_in[i_index] > i_lumThreshold); if (i_count > i_nonBlackPixel) break; } break; // packed RGB case VLC_FOURCC('R','G','B','2'): // packed by 1 i_skipCount = (i_pitch * i_skipCountPercent) / 100; for (i_index = i_col/2 + i_skipCount/2; i_index <= i_visible_pitch/2 + i_col/2 - i_skipCount/2; i_index++) { i_count += (p_in[i_index] > i_lumThreshold); if (i_count > i_nonBlackPixel) break; } break; case VLC_FOURCC('R','V','1','5'): // packed by 2 case VLC_FOURCC('R','V','1','6'): // packed by 2 i_skipCount = (i_pitch * i_skipCountPercent) / 100; for (i_index = i_col/2 + i_skipCount/2 - (i_col/2 + i_skipCount/2) % 2; i_index <= i_visible_pitch/2 + i_col/2 - i_skipCount/2; i_index+=2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -