📄 realvideo.c
字号:
{ b_so_opened = true; break; } if( asprintf( &g_decode_path, "%s/drv3.so.6.0", psz_paths + i ) != -1 ) { p_sys->rv_handle = load_syms_linux(p_dec, g_decode_path); free( g_decode_path ); } if( p_sys->rv_handle ) { b_so_opened = true; break; } msg_Dbg( p_dec, "Cannot load real decoder library: %s", g_decode_path); }#endif if(!b_so_opened ) { msg_Err( p_dec, "Cannot any real decoder library" ); free( p_sys ); return VLC_EGENERIC; } lock = var_AcquireMutex( "rm_mutex" ); if ( lock == NULL ) return VLC_EGENERIC; p_sys->handle=NULL; #ifdef WIN32 if (dll_type == 1) result=(*wrvyuv_init)(&init_data, &p_sys->handle); else #endif result=(*rvyuv_init)(&init_data, &p_sys->handle); if (result) { msg_Err( p_dec, "Cannot Init real decoder library: %s", g_decode_path); free( p_sys ); return VLC_EGENERIC; } /* setup rv30 codec (codec sub-type and image dimensions): */ /*if ( p_dec->fmt_in.i_codec == VLC_FOURCC('R','V','3','0') )*/ if (p_vide[1]>=0x20200002) { int i, cmsg_cnt; uint32_t cmsg24[16]={p_dec->fmt_in.video.i_width,p_dec->fmt_in.video.i_height}; cmsg_data_t cmsg_data={0x24,1+(p_vide[1]&7), &cmsg24[0]}; cmsg_cnt = (p_vide[1]&7)*2; if (i_vide - 8 < cmsg_cnt) { cmsg_cnt = i_vide - 8; } for (i = 0; i < cmsg_cnt; i++) cmsg24[2+i] = p_vide[8+i]*4; #ifdef WIN32 if (dll_type == 1) (*wrvyuv_custom_message)(&cmsg_data,p_sys->handle); else #endif (*rvyuv_custom_message)(&cmsg_data,p_sys->handle); } /* es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_FOURCC( 'Y','V','1','2' )); es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_FOURCC( 'Y','U','Y','2' )); */ es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_FOURCC( 'I', '4', '2', '0')); p_dec->fmt_out.video.i_width = p_dec->fmt_in.video.i_width; p_dec->fmt_out.video.i_height= p_dec->fmt_in.video.i_height; p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->fmt_in.video.i_width / p_dec->fmt_in.video.i_height; p_sys->inited = 0; vlc_mutex_unlock( lock ); return VLC_SUCCESS;}/***************************************************************************** * Open: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to choose. *****************************************************************************/static int Open( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t*)p_this; /* create a mutex */ var_Create( p_this->p_libvlc, "rm_mutex", VLC_VAR_MUTEX ); switch ( p_dec->fmt_in.i_codec ) { case VLC_FOURCC('R','V','1','0'): case VLC_FOURCC('R','V','2','0'): case VLC_FOURCC('R','V','3','0'): case VLC_FOURCC('R','V','4','0'): p_dec->p_sys = NULL; p_dec->pf_decode_video = DecodeVideo; return InitVideo(p_dec); default: return VLC_EGENERIC; }}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys = p_dec->p_sys; vlc_mutex_t *lock; /* get lock, avoid segfault */ lock = var_AcquireMutex( "rm_mutex" ); #ifdef WIN32 if (dll_type == 1) { if (wrvyuv_free) wrvyuv_free(p_sys->handle); } else #endif if (rvyuv_free) rvyuv_free(p_sys->handle);#ifdef WIN32 if (dll_type == 1) { if (p_sys->rv_handle) FreeLibrary(p_sys->rv_handle); } else#endif p_sys->rv_handle=NULL; if (p_sys->plane) { free(p_sys->plane); p_sys->plane = NULL; } msg_Dbg( p_dec, "FreeLibrary ok." );#ifdef LOADER Restore_LDT_Keeper( p_sys->ldt_fs ); msg_Dbg( p_dec, "Restore_LDT_Keeper" );#endif p_sys->inited = 0; if ( lock ) vlc_mutex_unlock( lock ); if ( p_sys ) free( p_sys );}/***************************************************************************** * DecodeVideo: *****************************************************************************/static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ){ decoder_sys_t *p_sys = p_dec->p_sys; vlc_mutex_t *lock; block_t *p_block; picture_t *p_pic; mtime_t i_pts; int result; /* We must do open and close in the same thread (unless we do * Setup_LDT_Keeper in the main thread before all others */ if ( pp_block == NULL || *pp_block == NULL ) { return NULL; } p_block = *pp_block; *pp_block = NULL; i_pts = p_block->i_pts ? p_block->i_pts : p_block->i_dts; lock = var_AcquireMutex( "rm_mutex" ); if ( lock == NULL ) return NULL; p_pic = p_dec->pf_vout_buffer_new( p_dec ); if ( p_pic ) { unsigned int transform_out[5]; dp_hdr_t dp_hdr; transform_in_t transform_in; uint32_t pkg_len = ((uint32_t*)p_block->p_buffer)[0]; unsigned char* dp_data=((unsigned char*)p_block->p_buffer)+8; uint32_t* extra=(uint32_t*)(((char*)p_block->p_buffer)+8+pkg_len); uint32_t img_size; dp_hdr.len = pkg_len; dp_hdr.chunktab = 8 + pkg_len; dp_hdr.chunks = ((uint32_t*)p_block->p_buffer)[1]-1; dp_hdr.timestamp = i_pts; memset(&transform_in, 0, sizeof(transform_in_t)); transform_in.len = dp_hdr.len; transform_in.extra = extra; transform_in.chunks = dp_hdr.chunks; transform_in.timestamp = dp_hdr.timestamp; memset (p_sys->plane, 0, p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height *3/2 ); #ifdef WIN32 if (dll_type == 1) result=(*wrvyuv_transform)(dp_data, p_sys->plane, &transform_in, transform_out, p_sys->handle); else #endif result=(*rvyuv_transform)(dp_data, p_sys->plane, &transform_in, transform_out, p_sys->handle); /* msg_Warn(p_dec, "Real Size %d X %d", transform_out[3], transform_out[4]); */ /* some bug rm file will print the messages : [00000551] realvideo decoder warning: Real Size 320 X 240 [00000551] realvideo decoder warning: Real Size 480 X 272 [00000551] realvideo decoder warning: Real Size 320 X 240 [00000551] realvideo decoder warning: Real Size 320 X 240 ... so it needs fixing! */ if ( p_sys->inited == 0 ) { /* fix and get the correct image size! */ if ( p_dec->fmt_in.video.i_width != transform_out[3] || p_dec->fmt_in.video.i_height != transform_out[4] ) { msg_Warn(p_dec, "Warning, Real's Header give a wrong " "information about media's width and height!\n" "\tRealHeader: \t %d X %d \t %d X %d", p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height, transform_out[3],transform_out[4]); if ( p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height >= transform_out[3] * transform_out[4] ) { p_dec->fmt_out.video.i_width = p_dec->fmt_out.video.i_visible_width = p_dec->fmt_in.video.i_width = transform_out[3] ; p_dec->fmt_out.video.i_height= p_dec->fmt_out.video.i_visible_height = p_dec->fmt_in.video.i_height= transform_out[4]; p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->fmt_in.video.i_width / p_dec->fmt_in.video.i_height; } else { // TODO: realloc plane's size! but [in fact] it maybe not happen! msg_Err(p_dec,"plane space not enough ,skip"); } } p_sys->inited = 1; } img_size = p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height; memcpy( p_pic->p[0].p_pixels, p_sys->plane, img_size); memcpy( p_pic->p[1].p_pixels, p_sys->plane + img_size, img_size/4); memcpy( p_pic->p[2].p_pixels, p_sys->plane + img_size * 5/4, img_size/4); p_pic->date = i_pts ; /* real video frame is small( frame and frame's time-shift is short), so it will become late picture easier (when render-time changed)and droped by video-output.*/ p_pic->b_force = 1; } vlc_mutex_unlock( lock ); block_Release( p_block ); return p_pic;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -