如何通过libavformat将H264流复制到MP4文件中

时间:2012-12-27 09:37:55

标签: ffmpeg h.264 mp4 libavformat

我想实现一个首先解码多媒体文件的应用程序(例如test.mp4文件,视频编解码器ID为H264),获取视频流和音频流,然后在音频流中做一些不同的事情,最后将视频流(使用libx264)和音频流编码为结果文件(result.mp4)。为了提高效率,我省略了视频流的解码和编码,我通过函数“av_read_frame”获取视频包,然后通过函数“av_write_frame”将其直接输出到结果文件中。但是输出文件中没有图片,输出文件的大小相当小。

我跟踪了ffmpeg代码并发现在函数“av_write_frame-> mov_write_packet-> ff_mov_write_packet”中,它将调用函数“ff_avc_parse_nal_units”来获取nal单元的大小,但返回值非常小(如为208字节)。

我发现MP4文件中的H264流没有以Annex-B格式存储,因此找不到起始码(0x000001),现在我的问题是如何将H264流改为Annex-B格式,并使其工作? 我手动在每个帧的开头添加了开始代码,但它仍然不起作用。

任何人都可以给我任何暗示吗?非常感谢。 以下是类似于我的代码:

    // write the stream header, if any
    av_write_header(pFormatCtxEnc);

    .........
    /**
    * Init of Encoder and Decoder
    */

    bool KeyFlag = false;
    bool KeyFlagEx = false;
    // Read frames and save frames to disk
    int iPts = 1;
    av_init_packet(&packet);
    while(av_read_frame(pFormatCtxDec, &packet)>=0)
    {
            if (packet.flags == 1)
                    KeyFlag = true;

            if (!KeyFlag)
                    continue;

            if (m_bStop)
            {
                    break;
            }

            // Is this a packet from the video stream?
            if(packet.stream_index == videoStream)
            {
                    currentframeNum ++;
                    if (progressCB != NULL && currentframeNum%20 == 0)
                    {
                            float fpercent = (float)currentframeNum/frameNum;
                            progressCB(fpercent,m_pUser);
                    }

                    if (currentframeNum >= beginFrame && currentframeNum <= endFrane)
                    {
                            if (packet.flags == 1)
                                    KeyFlagEx = true;

                            if (!KeyFlagEx)
                                    continue;
                            packet.dts = iPts ++;
                            av_write_frame(pFormatCtxEnc, &packet);

                    }
            }
            // Free the packet that was allocated by av_read_frame
    }

    // write the trailer, if any
    av_write_trailer(pFormatCtxEnc);

    /**
    * Release of encoder and decoder
    */

    return true;

1 个答案:

答案 0 :(得分:0)

您可以尝试:libavcodec/h264_mp4toannexb_bsf.c。它将没有起始码的比特流转换为带有起始码的比特流。

使用您的源文件,ffmpeg -i src.mp4 -vcodec copy -an dst.mp4是否有效?如果添加-bsf h264_mp4toannexb,它会起作用吗? (所有使用与您尝试以编程方式使用的ffmpeg相同的版本/版本)