Question

I am encoding a live rendered video to mpg and/or mp4 (depends on the later usage of the video) using the ffmpeg C API. When encoding to mp4, everything is well. But when encoding to mpg, the resulting video cannot be played by any player. A quick call to ffprobe on it reveals that the header is missing. But this seems pretty much impossible, as I am explicitly writing it.

This is how I write the header, before any frame is encoded:

// ptr->oc is the AVFormatContext
int error = avformat_write_header(ptr->oc, NULL);
if (error < 0)
{
    s_logFile << "Could not write header. Error: " << error << endl;
    fprintf(stderr, "Could not write header. Error: '%i'\n", error);
    return 1;
}

There never is any error when writing the header.

For encoding, I am following the official muxing.c example, so I do set the CODEC_FLAG_GLOBAL_HEADER flag. I use CODEC_ID_MPEG2VIDEO (for video) and CODEC_ID_MP2 (for audio).

The result mpg does work when I "encode" it in an additional step with an external ffmpeg executable like this: "ffmpeg -i ownEncoded.mpg -sameq -y working.mpg". So it seems all the data is there, only the header is missing for some reason...

Here is the only thing ffmpeg is reporting before/when writing the header:

mpeg -------------------
lvl: 24
msg: VBV buffer size not set, muxing may fail

Could that be the problem?

I wonder what could be wrong here as I encode mp4 with the exact same function, except setting some special values like qmin, qmax, me_method, etc. when encoding to mp4. Do I probably have to set any special values so that ffmpeg really does write the header correctly?

Was it helpful?

Solution 2

Oh my!

Turns out I had a typo that lead to CODEC_ID_MPEG2VIDEO not being set properly, instead using H264 as default. Of course that doesn't work that good inside .mpg.

Thanks for the hint in the comments, that made me look at it again! :)

OTHER TIPS

Maybe you have to set flag CODEC_FLAG_GLOBAL_HEADER for AVCodecContext. It is needed in case outputFormat->oformat->flags & AVFMT_GLOBALHEADER == true, where outputFormat is AVOutputFormat

Thus you should write

if(outputFormat->oformat->flags & AVFMT_GLOBALHEADER) 
  codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

It is also necessary to see the ffmpeg output, maybe there are warnings.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top