[Libav-user] global headers problem when encoding/decoding h264

Alex Cohn alexcohn at netvision.net.il
Sun Apr 22 11:36:22 CEST 2012


On Thu, Apr 19, 2012 at 15:25, "Matthias Bühlmann" <genesys at gmx.ch> wrote:
> I'm developing an application with ffmpeg that should do the following:
>
> -encode h264 video with 0-frame delay (i.e. output packet already after first frame was encoded)
> -write video to an MP4 file
> -simultaneously decode every frame after it was encoded and display it on screen
>
> setting up the encoder for 0-frame delay encoding works. What I do then is:
>
> after each avcodec_encode_video2() I create a copy of the packet. one packet I feed into
> av_interleaved_write_frame(m_fctx, &pkt);
> to write the MP4 file.
>
> The copy of the packet i feed into
> avcodec_decode_video2(m_cctx, m_frame, &got_picture, &pkt);
> which uses a separate codecContext.
>
> Now the problem is that, if i set CODEC_FLAG_GLOBAL_HEADER in the encoder flags, then the resulting MP4 file will be perfectly readable (I can open it in quicktime) but calling avcodec_decode_video2() with the packet fails already on the first packet with the error:
>
> [h264 @ 000000000270F760] non-existing PPS 0 referenced
> [h264 @ 000000000270F760] decode_slice_header error
> [h264 @ 000000000270F760] no frame!

h264 decoder needs SPS/PPS data to start the process. You can find
these "NAL units" in the encoder context extradata, and send them
along with the first video packet to avcodec_decode_video2().

> if I however disable the CODEC_FLAG_GLOBAL_HEADER flag in the encoder, then avcodec_encode_video2() will decode the packet fine, but the resulting MP4 file will not be valid (quicktime opens it, but shows only black).

I suggest you to use this case as a yardstick to prepare the SPS/PPS
data exactly in format that avcodec_decode_video2() expects.

> The issue seems to be in X264_init() in libx264.h where the function sets
>
> if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER)
>    x4->params.b_repeat_headers = 0;
>
> and I found no way to set b_repeat_headers=1 directly (is there any?).

As you noticed, you can make the packets compatible with mp4 container
or with "streaming" context, but not both.

> I'm developing in MSVC++ and use precompiled libraries and thus would like to avoid having to alter the FFMPEG code. Is there any other way how I can either get the global headers into my decoder, so that it can decode the packets on the fly without the need of headers in every packet, or to tell the encoder to add the headers to each frame AND to use global headers?

The decoder needs SPS/PPS "headers" only for the first packet.

> Thanks!
> --
> NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone!
> Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a

Good luck,
Alex Cohn


More information about the Libav-user mailing list