使用libavcodec,C解码H264video

我正在尝试使用ffmpeg / libavcodec解码原始h264文件,但无法使其正常工作。 输出应该是现在的原始YUV文件。 可以使用GCC编译代码

gcc -o decoder decoder.c -L./lib/ -llibavcodec -llibavutil 

avcodec.dll,avutil.dll和swresample.dll必须放在.exe开始的目录中。 CMD中的输出看起来像这样(只是它的一部分,但它总是这样):

 [h264 @ 00a80f20] reference picture missing during reorder [h264 @ 00a80f20] Missing reference picture, default is 65562 [h264 @ 00a80f20] error while decoding MB 80 54, bytestream -10 [h264 @ 00a80f20] concealing 1649 DC, 1649 AC, 1649 MV errors in B frame [h264 @ 00a80f20] reference picture missing during reorder [h264 @ 00a80f20] reference picture missing during reorder [h264 @ 00a80f20] reference picture missing during reorder [h264 @ 00a80f20] Missing reference picture, default is 65566 [h264 @ 00a80f20] Missing reference picture, default is 65566 [h264 @ 00a80f20] Missing reference picture, default is 65566 [h264 @ 00a80f20] reference picture missing during reorder [h264 @ 00a80f20] Missing reference picture, default is 65568 [h264 @ 00a80f20] reference picture missing during reorder [h264 @ 00a80f20] Missing reference picture, default is 65570 [h264 @ 00a80f20] reference picture missing during reorder 

inheritance我的代码

 #include  #include  #ifdef HAVE_AV_CONFIG_H #undef HAVE_AV_CONFIG_H #endif #include "libavcodec/avcodec.h" //#include "libavcodec/libavutil/mathematics.h" #define INBUF_SIZE 4096 void video_decode(char *outfilename, char *filename) { AVCodec *codec; AVCodecContext *c= NULL; int frame, got_picture, len; FILE *f, *outf; AVFrame *picture; uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; AVPacket avpkt; int i; av_init_packet(&avpkt); memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); picture = av_frame_alloc(); if((codec->capabilities)&CODEC_CAP_TRUNCATED) (c->flags) |= CODEC_FLAG_TRUNCATED; c->height = 1080; c->width = 1920; if (avcodec_open2(c, codec, NULL)  0) { len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); if (len < 0) { fprintf(stderr, "Error while decoding frame %d\n", frame); exit(1); } if (got_picture) { printf("saving frame %3d\n", frame); fflush(stdout); for(i=0; iheight; i++) fwrite(picture->data[0] + i * picture->linesize[0], 1, c->width, outf ); for(i=0; iheight/2; i++) fwrite(picture->data[1] + i * picture->linesize[1], 1, c->width/2, outf ); for(i=0; iheight/2; i++) fwrite(picture->data[2] + i * picture->linesize[2], 1, c->width/2, outf ); frame++; } avpkt.size -= len; avpkt.data += len; } } avpkt.data = NULL; avpkt.size = 0; len = avcodec_decode_video2(c,picture, &got_picture, &avpkt); if(got_picture) { printf("saving last frame %d\n",frame); fflush(stdout); for(i=0; iheight; i++) fwrite(picture->data[0] + i * picture->linesize[0], 1, c->width, outf ); for(i=0; iheight/2; i++) fwrite(picture->data[1] + i * picture->linesize[1], 1, c->width/2, outf ); for(i=0; iheight/2; i++) fwrite(picture->data[2] + i * picture->linesize[2], 1, c->width/2, outf ); frame++; } fclose(f); fclose(outf); avcodec_close(c); av_free(c); av_frame_free(&picture); printf("\n"); } int main(int argc, char **argv){ avcodec_register_all(); video_decode("test", "trailer.264"); return 0; } 

我还尝试了不同格式的不同video(当然我在这种情况下改变了代码中的编解码器),如MPEG1,H263,H265,但这些都没有正常工作。 我希望有人可以帮助我,告诉我这里我做错了什么。 谢谢

avcodec_decode_video2的每个输入包(avpkt)应包含一帧的完整(且仅)数据,即它不应在帧NAL的中间被截断。 因此,以4096字节块的forms读取和发送数据的代码将无法正常工作。 您需要通过解析附件B数据并查找起始代码和分析NAL类型(在帧具有多于1个切片的情况下甚至更多)或使用用于H.264的libavformat解析器来自行打包。 作为H.264的解决方法,你可以尝试使用CODEC_FLAG2_CHUNKS标志,但我不确定它有多可靠,仍然认为4096字节的块太小了。