Aravind A
Aravind A

Reputation: 466

How to put H264 encoded data, inside a container like .mp4 using libAV libraries (ffmpeg)?

I have been playing around with the libAV* family of libraries, that comes along with FFMPEG and I am learning how to implement things like encoding, decoding, muxing etc.

I came across this code : https://libav.org/documentation/doxygen/master/encode_video_8c-example.html , that encodes, YUV frames, to a file, using an encoder. In my implementation, I will change the encoder to H264 using avcodec_find_encoder(AV_CODEC_ID_H264) But I do not know, how to put this encoded data, into a proper container (.mp4) using libav libraries, so that the output file, can be played by any media player like VLC, QuickTime, etc...

Can anyone please help me on that? Every help will be greatly appreciated!

Upvotes: 3

Views: 1142

Answers (1)

syntheticgio
syntheticgio

Reputation: 608

You should be able to write the frames to a file you initialize something like this:

// Have the library guess the format
AVOutputFormat *fmt = av_guess_format(NULL, "my_video.mp4", NULL);

// Set the AVOutputFormat in your output context (init not shown)
pOutFormatContext->oformat = fmt;

// Open the output, error handling not shown
avio_open2(&pOutFormatContext->pb, "my_video.mp4", AVIO_FLAG_WRITE, NULL, NULL);

// Create output stream
AVStream * outStream;
outStream = avformat_new_stream(pOutFormatContext, NULL);

// Set any output stream options you would want, example of setting the aspect ratio from the input coded 'inCodecContext' (init not shown for this)
outStream->sample_aspect_ratio.num = inCodecContext->sample_aspect_ratio.num;
outStream->sample_aspect_ratio.den = inCodecContext->sample_aspect_ratio.den;

// There may be other things you want to set like the time base, but will depend on what you're doing

// Write the header to the context, error handling not shown
avformat_write_header(pOutFormatContext, NULL);

// Dump out the format and check
av_dump_format(pOutFormatContext, 0, pOutFormatContext->filename, 1);

You then have to read the packets and encode them which it sounds like you're already doing, and then when you write to the output context it should be writing to the file in the container you specified.

Upvotes: 1

Related Questions