I'm refering to this thread here: Muxing AVPackets into mp4 file
The question over there is mainly the same that I have and the first answer looks very promising. The source (somkind of pseudo) code that the user pogorskiy provides seems to do exactly what I need:
AVOutputFormat * outFmt = av_guess_format("mp4", NULL, NULL);
AVFormatContext *outFmtCtx = NULL;
avformat_alloc_output_context2(&outFmtCtx, outFmt, NULL, NULL);
AVStream * outStrm = av_new_stream(outFmtCtx, 0);
AVCodec * codec = NULL;
avcodec_get_context_defaults3(outStrm->codec, codec);
outStrm->codec->coder_type = AVMEDIA_TYPE_VIDEO;
///....
/// set some required value, such as
/// outStrm->codec->flags
/// outStrm->codec->sample_aspect_ratio
/// outStrm->disposition
/// outStrm->codec->codec_tag
/// outStrm->codec->bits_per_raw_sample
/// outStrm->codec->chroma_sample_location
/// outStrm->codec->codec_id
/// outStrm->codec->codec_tag
/// outStrm->codec->time_base
/// outStrm->codec->extradata
/// outStrm->codec->extradata_size
/// outStrm->codec->pix_fmt
/// outStrm->codec->width
/// outStrm->codec->height
/// outStrm->codec->sample_aspect_ratio
/// see ffmpeg.c for details
avio_open(&outFmtCtx->pb, outputFileName, AVIO_FLAG_WRITE);
avformat_write_header(outFmtCtx, NULL);
for (...)
{
av_write_frame(outFmtCtx, &pkt);
}
av_write_trailer(outFmtCtx);
avio_close(outFmtCtx->pb);
avformat_free_context(outFmtCtx);
The pkt data, I receive from a third party API from my connectec camera. There is no file to open, to read the input data from and there is no RTSP stream to be received from the camera. It is just an API call, that gives me the pointer to a H264 encoded frame which is exactly the raw data for an AVPacket.
Anyway, I try to use this code as base for my applicatio, but the first problem that occurs is, that I get a runtime error:
Could not find tag for codec none in stream #0, codec not currently supported in container
So I started adding some more information to the codec, as pogorskiy suggested:
outStrm->codec->codec_id = AV_CODEC_ID_H264;
outStrm->codec->width = 1920;
outStrm->codec->height = 1080;
Now that I provided a codec_id, I was hoping, that the runtime message changes to at least something different, but it still ist the same:
Could not find tag for codec none in stream #0, codec not currently supported in container
Any idea on how I can set up the structures, so that I can open an mp4 file for writing my packets to?
Okay, I got it working. At least I can open an mp4 file and write my H264 encoded packets to it. The file even opens in VLC and shows the very first frame... Nothing more, but it is a start.
So I place the code her, in order to show this minimal solution. I still am very happy if somebody would give his/hers opinion on it, because it still does not work perfectly...
As I said, the resulting mp4 file shows the very first frame for a split second and after that it stops playing. I think the first frame is displayed, because I make sure that this is an I-frame, containing the complete image.
I don't know if I have to provide some additional data to the muxer in order to get a working mp4 file. I'm still working on this.
Any comments and ideas are highly welcome!
Thanks, Maik