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);
}