首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ffmpeg进行H264解码

使用ffmpeg进行H264解码
EN

Stack Overflow用户
提问于 2016-03-10 16:06:29
回答 3查看 9.9K关注 0票数 1

我正在尝试用ffmpeg库解码一个视频流,这就是我基本上是怎么做的:

代码语言:javascript
复制
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;
            }
    }               
    }  
}

但我得到了以下输出:

代码语言:javascript
复制
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的经验吗?任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2016-03-11 01:22:25

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

票数 3
EN

Stack Overflow用户

发布于 2016-07-14 21:14:10

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

如果你的ffmpeg安装目录是默认的"usr/local/“,你可以像下面这样独立编译这个文件。

代码语言:javascript
复制
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

如果安装目录更改为类似于"ffmpeg_ins_dir“,请将上述命令中的"usr/local/”替换为"path upto to ffmpef_ins_dir/“。

运行二进制文件,如下所示。

代码语言:javascript
复制
./demuxing_decoding test.h264 v_out.yuv a_out.yuv

注意:这个例子有许多你可能根本不需要的东西,删除不需要的东西,然后重新编译它。

票数 0
EN

Stack Overflow用户

发布于 2019-05-18 10:28:58

也许你应该尝试在你的fread()和avcodec_decode_video2();av_parser_parse2()之间使用AVCODECPARSER。让你的原始数据变成h264,从to数据提供给你的解码器。像这样的C代码:

代码语言:javascript
复制
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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35910824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档