📄 opencv_wrapper.c
字号:
p_vout->output.i_aspect = p_vout->render.i_aspect; p_vout->fmt_out = p_vout->fmt_in; //set to input video format fmt = p_vout->fmt_out; if (p_sys->i_wrapper_output == PROCESSED) //set to processed video format { fmt.i_width = fmt.i_width * p_sys->f_scale; fmt.i_height = fmt.i_height * p_sys->f_scale; fmt.i_visible_width = fmt.i_visible_width * p_sys->f_scale; fmt.i_visible_height = fmt.i_visible_height * p_sys->f_scale; fmt.i_x_offset = fmt.i_x_offset * p_sys->f_scale; fmt.i_y_offset = fmt.i_y_offset * p_sys->f_scale; if (p_sys->i_internal_chroma == GREY) fmt.i_chroma = VLC_FOURCC('I','4','2','0'); else if (p_sys->i_internal_chroma == RGB) fmt.i_chroma = VLC_FOURCC('R','V','3','2'); } /* Load the internal opencv filter */ /* We don't need to set up video formats for this filter as it not actually using a picture_t */ p_sys->p_opencv = vlc_object_create( p_vout, sizeof(filter_t) ); vlc_object_attach( p_sys->p_opencv, p_vout ); if (p_vout->p_sys->psz_inner_name) p_sys->p_opencv->p_module = module_Need( p_sys->p_opencv, p_sys->psz_inner_name, 0, 0 ); if( !p_sys->p_opencv->p_module ) { msg_Err( p_vout, "can't open internal opencv filter: %s", p_vout->p_sys->psz_inner_name ); p_vout->p_sys->psz_inner_name = NULL; vlc_object_detach( p_sys->p_opencv ); vlc_object_release( p_sys->p_opencv ); p_sys->p_opencv = NULL; } /* Try to open the real video output */ if (p_sys->i_verbosity > VERB_WARN) msg_Dbg( p_vout, "spawning the real video output" ); p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt ); /* Everything failed */ if( p_vout->p_sys->p_vout == NULL ) { msg_Err( p_vout, "can't open vout, aborting" ); return VLC_EGENERIC; } ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); ADD_PARENT_CALLBACKS( SendEventsToChild ); return VLC_SUCCESS;}/***************************************************************************** * End: terminate opencv_wrapper video thread output method *****************************************************************************/static void End( vout_thread_t *p_vout ){ int i_index; DEL_PARENT_CALLBACKS( SendEventsToChild ); 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_opencv ) { //release the internal opencv filter if( p_vout->p_sys->p_opencv->p_module ) module_Unneed( p_vout->p_sys->p_opencv, p_vout->p_sys->p_opencv->p_module ); vlc_object_detach( p_vout->p_sys->p_opencv ); vlc_object_release( p_vout->p_sys->p_opencv ); p_vout->p_sys->p_opencv = NULL; } vout_CloseAndRelease( p_vout->p_sys->p_vout );}/***************************************************************************** * Destroy: destroy opencv_wrapper video thread output method ***************************************************************************** * Terminate an output method created by opencv_wrapperCreateOutputMethod *****************************************************************************/static void Destroy( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; ReleaseImages(p_vout); if( p_vout->p_sys->p_image ) image_HandlerDelete( p_vout->p_sys->p_image ); free( p_vout->p_sys );}/***************************************************************************** * ReleaseImages: Release OpenCV images in vout_sys_t. *****************************************************************************/static void ReleaseImages(vout_thread_t *p_vout){ int i = 0; if (p_vout->p_sys->p_cv_image) { for (i = 0; i < VOUT_MAX_PLANES; i++) { if (p_vout->p_sys->p_cv_image[i]) cvReleaseImageHeader(&(p_vout->p_sys->p_cv_image[i])); p_vout->p_sys->p_cv_image[i] = NULL; } } p_vout->p_sys->i_cv_image_size = 0; /* Release temp picture_t if it exists */ if (p_vout->p_sys->p_to_be_freed) { picture_Release( p_vout->p_sys->p_to_be_freed ); p_vout->p_sys->p_to_be_freed = NULL; } if (p_vout->p_sys->i_verbosity > VERB_WARN) msg_Dbg( p_vout, "images released" );}/***************************************************************************** * VlcPictureToIplImage: Convert picture_t to IplImage ***************************************************************************** * Converts given picture_t into IplImage(s) according to module config. * IplImage(s) are stored in vout_sys_t. *****************************************************************************/static void VlcPictureToIplImage( vout_thread_t *p_vout, picture_t *p_in ){ int planes = p_in->i_planes; //num input video planes // input video size CvSize sz = cvSize(abs(p_in->format.i_width), abs(p_in->format.i_height)); video_format_t fmt_out; clock_t start, finish; //performance measures double duration; int i = 0; vout_sys_t* p_sys = p_vout->p_sys; memset( &fmt_out, 0, sizeof(video_format_t) ); start = clock(); //do scale / color conversion according to p_sys config if ((p_sys->f_scale != 1) || (p_sys->i_internal_chroma != CINPUT)) { fmt_out = p_in->format; //calc the scaled video size fmt_out.i_width = p_in->format.i_width * p_sys->f_scale; fmt_out.i_height = p_in->format.i_height * p_sys->f_scale; if (p_sys->i_internal_chroma == RGB) { //rgb2 gives 3 separate planes, this gives 1 interleaved plane //rv24 gives is about 20% faster but gives r&b the wrong way round //and I cant think of an easy way to fix this fmt_out.i_chroma = VLC_FOURCC('R','V','3','2'); } else if (p_sys->i_internal_chroma == GREY) { //take the I (gray) plane (video seems to commonly be in this fmt so usually the //conversion does nothing) fmt_out.i_chroma = VLC_FOURCC('I','4','2','0'); } //convert from the input image p_sys->p_proc_image = image_Convert( p_sys->p_image, p_in, &(p_in->format), &fmt_out ); if (!p_sys->p_proc_image) { msg_Err(p_vout, "can't convert (unsupported formats?), aborting..."); return; } p_sys->p_to_be_freed = p_sys->p_proc_image; //remember this so we can free it later } else //((p_sys->f_scale != 1) || (p_sys->i_internal_chroma != CINPUT)) { //use the input image without conversion p_sys->p_proc_image = p_in; } //Convert to the IplImage array that is to be processed. //If there are multiple planes in p_sys->p_proc_image, then 1 IplImage //is created for each plane. planes = p_sys->p_proc_image->i_planes; p_sys->i_cv_image_size = planes; for ( i = 0; i < planes; i++ ) { sz = cvSize(abs(p_sys->p_proc_image->p[i].i_visible_pitch / p_sys->p_proc_image->p[i].i_pixel_pitch), abs(p_sys->p_proc_image->p[i].i_visible_lines)); p_sys->p_cv_image[i] = cvCreateImageHeader(sz, IPL_DEPTH_8U, p_sys->p_proc_image->p[i].i_pixel_pitch); cvSetData( p_sys->p_cv_image[i], (char*)(p_sys->p_proc_image->p[i].p_pixels), p_sys->p_proc_image->p[i].i_pitch ); } //Hack the above opencv image array into a picture_t so that it can be sent to //another video filter p_sys->hacked_pic.p_data_orig = p_sys->p_cv_image; p_sys->hacked_pic.i_planes = planes; p_sys->hacked_pic.format.i_chroma = fmt_out.i_chroma; //calculate duration of conversion finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; if (p_sys->i_verbosity > VERB_WARN) msg_Dbg( p_vout, "VlcPictureToIplImageRgb took %2.4f seconds\n", duration );}/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to the internal opencv * filter for processing. *****************************************************************************/static void Render( vout_thread_t *p_vout, picture_t *p_pic ){ picture_t *p_outpic = NULL; clock_t start, finish; double duration; 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 ) { return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); start = clock(); if (p_vout->p_sys->i_wrapper_output == VINPUT) //output = input video { //This copy is a bit unfortunate but image_Convert can't write into an existing image so it is better to copy the //(say) 16bit YUV image here than a 32bit RGB image somehwere else. //It is also not that expensive in time. vout_CopyPicture( p_vout, p_outpic, p_pic ); VlcPictureToIplImage( p_vout, p_pic); //pass the image to the internal opencv filter for processing if ((p_vout->p_sys->p_opencv) && (p_vout->p_sys->p_opencv->p_module)) p_vout->p_sys->p_opencv->pf_video_filter( p_vout->p_sys->p_opencv, &(p_vout->p_sys->hacked_pic)); } else //output = processed video (NONE option not working yet) { VlcPictureToIplImage( p_vout, p_pic); //pass the image to the internal opencv filter for processing if ((p_vout->p_sys->p_opencv) && (p_vout->p_sys->p_opencv->p_module)) p_vout->p_sys->p_opencv->pf_video_filter( p_vout->p_sys->p_opencv, &(p_vout->p_sys->hacked_pic)); //copy the processed image into the output image if ((p_vout->p_sys->p_proc_image) && (p_vout->p_sys->p_proc_image->p_data)) vout_CopyPicture( p_vout, p_outpic, p_vout->p_sys->p_proc_image ); } //calculate duration finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; if (p_vout->p_sys->i_verbosity > VERB_WARN) msg_Dbg( p_vout, "Render took %2.4f seconds\n", duration ); ReleaseImages(p_vout); vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date ); vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );}/***************************************************************************** * 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 + -