使用ffmpeg进行H264解码

时间:2016-03-10 08:06:29

标签: c ffmpeg

我正在尝试使用ffmpeg库解码视频流,这就是我基本上这样做的方式:

void video_decode(const char *filename)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    int frame_count=0;
    FILE *f;
    AVFrame *frame;
    uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
    AVPacket avpkt;
    av_init_packet(&avpkt);
    memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    printf("Decoding video file...\n");
    /* find the h264 video decoder */
    codec = avcodec_find_decoder(AV_CODEC_ID_H264);
    c = avcodec_alloc_context3(codec);
    c->bit_rate = 400000;
    c->width = 1920;
    c->height = 1080;

    if (avcodec_open2(c, codec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        exit(1);
    }
    frame = av_frame_alloc();
    for (;;) {
        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);         
    if (avpkt.size == 0)
            break;
        avpkt.data = inbuf;
        while(avpkt.size > 0){

        int len, got_frame;
            len = avcodec_decode_video2(c, frame, &got_frame, &avpkt);          
        if (len < 0) {
                fprintf(stderr, "Errr while decding frame %d\n", frame_count);
                exit (1);
            }
            if (got_frame) {
                //Print out frame information..
        }
            if (avpkt.data) {
                avpkt.size -= len;
                avpkt.data += len;
            }
    }               
    }  
}

但我得到了以下输出:

Decoding video file...
[h264 @ 0x303c040] decode_slice_header error
[h264 @ 0x303c040] decode_slice_header error
[h264 @ 0x303c040] decode_slice_header error
[h264 @ 0x303c040] no frame!
Errr while decding frame 0

显然,编解码器的启动是不完整的。你有h264 api的经验吗?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:3)

您不能将随机数(INBUF_SIZE)的字节放入AV数据包。它应该是完整的AU或NALU,如果它不是附件B,则必须首先设置额外的数据字段。对于您的情况,我建议使用libavformat打开文件并阅读AVPackets。

答案 1 :(得分:0)

这个问题的答案在demuxing_decoding.c ffmpeg的例子中给出。

如果您的ffmpeg安装目录是默认的&#34; usr / local / &#34;

,可以单独编译此文件,如下所示。
gcc -I/usr/local/include  -c demuxing_decoding.c -o demuxing_decoding.o
gcc demuxing_decoding.o -pthread -L/usr/local/lib -lavdevice -lavfilter -lpostproc -lavformat -lavcodec -lva-x11 -lva -lxcb-xfixes -lxcb-render -lxcb-shape -lxcb -lX11 -lx264 -lpthread -ldl -lz -lswresample -lswscale -lavutil -lm  -o demuxing_decoding

如果安装目录更改为&#34; ffmpeg_ins_dir &#34;替换&#34; usr / local / &#34;在上面的命令中使用&#34; 路径到ffmpef_ins_dir / &#34;。

运行二进制文件如下。

./demuxing_decoding test.h264 v_out.yuv a_out.yuv

注意:此示例包含许多您可能根本不需要的内容,删除不需要的内容并重新编译它。

答案 2 :(得分:0)

也许您应该尝试在fread()和avcodec_decode_video2()之间使用AVCODECPARSER; av_parser_parse2()。将您的原始数据从原始数据更改为h264,以提供给解码器。 像这样的C代码:

while (1)
{
    cur_size = fread(in_buffer, 1, in_buffer_size, fp_in);
    cur_ptr = in_buffer;
    while (cur_size > 0)
    {
        int len = av_parser_parse2(pCodecParserCtx, pCodecCtx, &packet.data, &packet.size, cur_ptr, cur_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
        cur_ptr += len;
        cur_size -= len;

        ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);  
        if (ret < 0)
        {
            printf("Decode Error\n");
            return ret;
        }
        if (got_picture)
        {
            printf("Succeed to decode 1 frame!\n");
        }
    }

受此启发: https://blog.csdn.net/leixiaohua1020/article/details/42181571