Muxing AVPackets into mp4 file - revisited

▼魔方 西西 提交于 2019-12-08 18:03:24

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...

char outputFileName[] = "camera.mp4";

av_log_set_level(AV_LOG_DEBUG);

AVOutputFormat * outFmt = av_guess_format("mp4", NULL, NULL);
AVFormatContext *outFmtCtx = NULL;
avformat_alloc_output_context2(&outFmtCtx, outFmt, NULL, NULL);
AVStream * outStrm = avformat_new_stream(outFmtCtx, NULL);
outStrm->id = 0;
outStrm->time_base = {1, 30};
outStrm->avg_frame_rate = {1, 30};

AVCodec * codec = NULL;
avcodec_get_context_defaults3(outStrm->codec, codec);

outFmtCtx->video_codec_id = AV_CODEC_ID_H264;

///....
/// 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->codecpar->codec_id = AV_CODEC_ID_H264;
outStrm->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
/// outStrm->codec->time_base
/// outStrm->codec->extradata 
/// outStrm->codec->extradata_size
/// outStrm->codec->pix_fmt
outStrm->codecpar->width = 1920;
outStrm->codecpar->height = 1080;
/// outStrm->codec->sample_aspect_ratio
/// see ffmpeg.c for details  

avio_open(&outFmtCtx->pb, outputFileName, AVIO_FLAG_WRITE);

avformat_write_header(outFmtCtx, NULL); 

*** Camera access loop via GenICam API starts here ***
n++;
av_init_packet(&avPacket);
avPacket.data = static_cast<uint8_t*>(pPtr); // raw data from the Camera with H264 encoded frame
avPacket.size = datasize; // datasize received from the GenICam API along with pPtr (the raw data)
avPacket.pts = (1/30) * n; // stupid try to set pts and dts somehow... Working on this...
avPacket.dts = (1/30) * (n-1);
avPacket.pos = n;
avPacket.stream_index = outStrm->index;

av_write_frame(outFmtCtx, &avPacket);

**** Camera access loop ends here ****

av_write_trailer(outFmtCtx);
avio_close(outFmtCtx->pb);
avformat_free_context(outFmtCtx);

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!