(轉)利用ffmpeg來進行視頻解碼的完整示例代碼(H.264)
- Decode()?
- {?
- FILE ?*?inpf;?
- ?
- int ?nWrite;?
- int ?i,p;?
- int ?nalLen;?
- unsigned?char *?Buf;?
- int ?got_picture,?consumed_bytes;?
- unsigned?char ?*DisplayBuf;?
- DisplayBuf=(unsigned?char ?*)malloc(60000);?
- ?
- char ?outfile[]?=? "test.pgm" ;?
- ?
- //1.打開輸入文件 ?
- inpf?=?fopen("test.264" ,? "rb" );?
- ?
- //outf?=?fopen("out.yuv",?"wb"); ?
- ?
- if (!inpf)?
- {?
- goto ?Decodereturn;?
- }?
- ?
- nalLen?=?0;?
- Buf?=?(unsigned?char *)calloc?(?1000000,? sizeof ( char ));? //準備解碼文件緩沖 ?
- ?
- //2.注冊解碼器,并且找到H264解碼器 ?
- avcodec_init();?
- avcodec_register_all();?
- codec?=?avcodec_find_decoder(CODEC_ID_H264);?
- ?
- if ?(!codec)?{?
- return ?0;?
- }?
- //allocate?codec?context ?
- //分配解碼器內存 ?
- c?=?avcodec_alloc_context();?
- ?
- if (!c){?
- return ?0;?
- }?
- //open?codec ?
- //3.打開解碼器 ?
- if ?(avcodec_open(c,?codec)?<?0)?{?
- return ?0;?
- }?
- ?
- //allocate?frame?buffer ?
- //分配解碼器用的幀緩沖 ?
- picture?=?avcodec_alloc_frame();?
- if (!picture){?
- return ?0;?
- }?
- ?
- rgbdatanew?=?(unsigned?char ?*)malloc( sizeof (unsigned? char )*(3?*?width?*?height));?
- ?
- while (!feof(inpf))?
- {?
- ?
- //4.獲取下一個NAL的長度,并且將NAL放入Buf ?
- nalLen?=?getNextNal(inpf,?Buf);?
- ?
- //5.對改NAL解碼,解碼的YUV數據存在picture中 ?
- consumed_bytes=?avcodec_decode_video(c,?picture,?&got_picture,?Buf,?nalLen);?
- ?
- if (consumed_bytes?>?0)?
- {?
- ?
- //6.將picture中的YUV數據顯示或者保存到文件 ?
- p=0;?
- for (i=0;?i<c->height;?i++)?
- {?
- memcpy(DisplayBuf+p,picture->data[0]?+?i?*?picture->linesize[0],?c->width);?
- p+=c->width;?
- }?
- for (i=0;?i<c->height/2;?i++)?
- {?
- memcpy(DisplayBuf+p,picture->data[1]?+?i?*?picture->linesize[1],?c->width/2);?
- p+=c->width/2;?
- }?
- for (i=0;?i<c->height/2;?i++)?
- {?
- memcpy(DisplayBuf+p,picture->data[2]?+?i?*?picture->linesize[2],?c->width/2);?
- p+=c->width/2;?
- }?
- //顯示畫面 ?
- DisplayVideo(DisplayBuf);?
- }?
- }?
- ?
- //7.關閉輸入文件 ?
- if (inpf)?
- fclose(inpf);?
- ?
- Decodereturn:?
- ?
- //8.關閉解碼器,釋放解碼器內存 ?
- if (c)?{?
- avcodec_close(c);?
- av_free(c);?
- c?=?NULL;?
- }?
- //9.釋放解碼畫面內存 ?
- if (picture)?{?
- av_free(picture);?
- picture?=?NULL;?
- }?
- ?
- //10.釋放解碼文件緩沖 ?
- if (Buf)?
- {?
- free(Buf);?
- Buf?=?NULL;?
- }?
- ?
- free(DisplayBuf);?
- }