转载 调用xvid 实现解码
view plaincopy to clipboardprint?
///??
intinit_decoder()???
{??
??? intret;??
???xvid_gbl_init_t??xvid_gbl_init;??
???xvid_dec_create_txvid_dec_create;??
????
???memset(&xvid_gbl_init, 0,sizeof(xvid_gbl_init_t));??
???memset(&xvid_dec_create, 0,sizeof(xvid_dec_create_t));??
????
??? XDIM = 0;???
??? YDIM = 0;???
??? FORMAT = 0;???
??? CSP =XVID_CSP_BGR;??
??? BPP =3;??
??????
??? dec_handle =NULL ;??
??????
??? mp4_buffer =NULL ;???
??? out_buffer =NULL ;???
??? mp4_ptr =NULL ;???
????
???xvid_gbl_init.version =XVID_VERSION;??
????
???xvid_gbl_init.cpu_flags = 0;? // use assemblyoptimized???
???xvid_gbl_init.debug = 0;????// set debug level 0, no debugoutput???
???xvid_global(NULL, 0, &xvid_gbl_init, NULL);//XVID初始化??
????
????
???xvid_dec_create.version =XVID_VERSION;??
????
???xvid_dec_create.width = 0;//解碼后圖像的寬度?如果事先已經知道那么這里就填寫 否則設置0??
???xvid_dec_create.height = 0;//解碼后圖像的高度 如果事先已經知道那么這里就填寫否則設置0??
??? ret =xvid_decore(NULL, XVID_DEC_CREATE,&xvid_dec_create, NULL);//創建xvid解碼實例??
??? dec_handle =xvid_dec_create.handle;將創建的句柄 賦值 給dec_handle??
???return(ret);??
}??
//??
int decode_one_frame(unsigned char *istream, unsigned char*ostream,??
?????????????????????????????????????int istream_size, xvid_dec_stats_t*xvid_dec_stats)??
{??
??? intret;??
???xvid_dec_frame_txvid_dec_frame;??
????
???memset(&xvid_dec_frame, 0,sizeof(xvid_dec_frame_t));??
???memset(xvid_dec_stats, 0,sizeof(xvid_dec_stats_t));??
????
???xvid_dec_frame.version =XVID_VERSION;??
???xvid_dec_stats->version =XVID_VERSION;????
????
???xvid_dec_frame.general?????????= 0;??
????
???xvid_dec_frame.bitstream???????= istream;//待解碼的數據??
???xvid_dec_frame.length??????????= istream_size;//待解碼數據的長度??
????
???xvid_dec_frame.output.plane[0]? =ostream;//解碼完成后存放原始視頻流的緩沖區??
???xvid_dec_frame.output.stride[0] =XDIM*BPP;//步長即一行像素所占的空間大小??
???xvid_dec_frame.output.csp = CSP;//輸出時 采用的色場空間 這里 XVID_CSP_BGR即采用RGB??
??? ret =xvid_decore(dec_handle, XVID_DEC_DECODE,&xvid_dec_frame, xvid_dec_stats);//ret 值解碼前幀的長度??
???return(ret);??
}??
///調用方式??
do {??
????????????
???????????used_bytes = decode_one_frame(mp4_ptr, out_buffer, useful_bytes,&xvid_dec_stats);??
????????????
???????????if(xvid_dec_stats.type == XVID_TYPE_VOL)//如果輸入一幀包含 VOL重新獲得輸出圖像的寬度和高度??
???????????{??
????????????????
???????????????if(XDIM*YDIM <xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height)???
???????????????{??
????????????????????
???????????????????XDIM =xvid_dec_stats.data.vol.width;??
???????????????????YDIM =xvid_dec_stats.data.vol.height;??
??????????????????????
????????????????????
???????????????????if(out_buffer)free(out_buffer);??
????????????????????
???????????????????out_buffer = (unsigned char*)malloc(XDIM*YDIM*4);//動態調整輸出流存儲空間的大小??
???????????????????if(out_buffer == NULL)??
???????????????????????goto free_all_memory;??
???????????????}??
???????????}??
????????????
???????????if(used_bytes > 0){??
???????????????mp4_ptr += used_bytes;??
???????????????useful_bytes -=used_bytes;??
???????????}??
???????} while (xvid_dec_stats.type <= 0&& useful_bytes >MIN_USEFUL_BYTES);??
??????????
????????
???????draw_image(out_buffer) ;??
///
int init_decoder()
{
?int ret;
?xvid_gbl_init_t??xvid_gbl_init;
?xvid_dec_create_t xvid_dec_create;
?
?memset(&xvid_gbl_init, 0,sizeof(xvid_gbl_init_t));
?memset(&xvid_dec_create, 0,sizeof(xvid_dec_create_t));
?
?XDIM = 0 ;
?YDIM = 0 ;
?FORMAT = 0 ;
?CSP = XVID_CSP_BGR;
?BPP = 3;
?
?dec_handle = NULL ;
?
?mp4_buffer = NULL ;
?out_buffer = NULL ;
?mp4_ptr = NULL ;
?
?xvid_gbl_init.version = XVID_VERSION;
?
?xvid_gbl_init.cpu_flags = 0;? //use assembly optimized
?xvid_gbl_init.debug = 0;????// set debug level 0, no debug output
?xvid_global(NULL, 0,&xvid_gbl_init, NULL);//XVID 初始化
?
?
?xvid_dec_create.version = XVID_VERSION;
?
?xvid_dec_create.width =0;//解碼后圖像的寬度? 如果事先已經知道 那么這里就填寫 否則設置0
?xvid_dec_create.height = 0;//解碼后圖像的高度如果事先已經知道那么這里就填寫 否則設置0
?ret = xvid_decore(NULL, XVID_DEC_CREATE,&xvid_dec_create, NULL);//創建xvid 解碼實例
?dec_handle = xvid_dec_create.handle;將創建的句柄賦值給 dec_handle
?return(ret);
}
//
int decode_one_frame(unsigned char *istream, unsigned char*ostream,
??????????int istream_size, xvid_dec_stats_t *xvid_dec_stats)
{
?int ret;
?xvid_dec_frame_t xvid_dec_frame;
?
?memset(&xvid_dec_frame, 0,sizeof(xvid_dec_frame_t));
?memset(xvid_dec_stats, 0,sizeof(xvid_dec_stats_t));
?
?xvid_dec_frame.version = XVID_VERSION;
?xvid_dec_stats->version =XVID_VERSION;?
?
?xvid_dec_frame.general?????????= 0;
?
?xvid_dec_frame.bitstream???????= istream;//待解碼的數據
?xvid_dec_frame.length??????????= istream_size;//待解碼數據的長度
?
?xvid_dec_frame.output.plane[0]?= ostream;//解碼完成后 存放原始視頻流的緩沖區
?xvid_dec_frame.output.stride[0] =XDIM*BPP;//步長即一行像素所占的空間大小
?xvid_dec_frame.output.csp = CSP;//輸出時 采用的色場空間 這里XVID_CSP_BGR 即采用RGB
?ret = xvid_decore(dec_handle, XVID_DEC_DECODE,&xvid_dec_frame, xvid_dec_stats);//ret 值解碼前幀的長度
?return(ret);
}
///調用方式
do {
???
???used_bytes =decode_one_frame(mp4_ptr, out_buffer, useful_bytes,&xvid_dec_stats);
???
???if(xvid_dec_stats.type== XVID_TYPE_VOL)//如果輸入一幀包含 VOL 重新獲得 輸出圖像的寬度和高度
???{
????
????if(XDIM*YDIM<xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height)
????{
?????
?????XDIM= xvid_dec_stats.data.vol.width;
?????YDIM= xvid_dec_stats.data.vol.height;
?????
?????
?????if(out_buffer)free(out_buffer);
?????
?????out_buffer= (unsigned char*)malloc(XDIM*YDIM*4);//動態調整 輸出流 存儲空間的大小
?????if(out_buffer== NULL)
??????gotofree_all_memory;
????}
???}
???
???if(used_bytes> 0) {
????mp4_ptr+= used_bytes;
????useful_bytes-= used_bytes;
???}
??} while (xvid_dec_stats.type<= 0 && useful_bytes> MIN_USEFUL_BYTES);
??
??
??draw_image(out_buffer);?
2 Xvid編解碼 實踐
?? 關于編碼器輸入格式設置:
?其中 en->width圖像采集時的寬度(以像素為單位)
? switch( input->format )
? {
? case FORMAT_RAW_BGR24:
?? xvid_enc_frame.input.csp =XVID_CSP_BGR;
?? xvid_enc_frame.input.stride[0]= en->width * 3;
?? break;
? case FORMAT_RAW_UYVY:
?? xvid_enc_frame.input.csp =XVID_CSP_UYVY;
?? xvid_enc_frame.input.stride[0]= en->width * 2;
?? break;
? case FORMAT_RAW_YUY2:
?? xvid_enc_frame.input.csp =XVID_CSP_YUY2;
?? xvid_enc_frame.input.stride[0]= en->width * 2;
?? break;
? }
?解碼器輸出格式設置:
?switch( output->format )
? {
? case FORMAT_RAW_BGR24:
??xvid_dec_frame.output.stride[0] = m_width*3;
?? xvid_dec_frame.output.csp=XVID_CSP_BGR;
?? break;
?? case FORMAT_RAW_YUY2:
?? xvid_dec_frame.output.csp =XVID_CSP_YUY2;
??xvid_dec_frame.output.stride[0]= en->width *2;
?? break;
? }
特別注意的是:
在xvid 中stride 步長與 視頻格式有密切格式 一旦設置錯誤導致 編解碼異常終止。
xvid使用小技巧:
(1)解決:使用xvid編解碼rtp傳輸directshow播放遠程視頻時開始會出現綠屏但可以看到圖像輪廓,在經過幾秒后正常
很可能的一個原因是 關鍵幀丟失 方法:
減小關鍵幀的間隔
//最大I幀(關鍵幀)間隔,一般設置成幀數的10倍
xvid_enc_create.max_key_interval =1;//(int)-1;???//--default 10s
(2)(獲得編碼后 幀長度)
ret = xvid_encore(m_enc_handle, XVID_ENC_ENCODE,&xvid_enc_frame,&xvid_enc_stats);
m_enc_frame_length=xvid_enc_stats.length;//編碼獲得的幀長度
?
總結
以上是生活随笔為你收集整理的转载 调用xvid 实现解码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STL中list的使用(理论)
- 下一篇: Linq(拓展方法+select())