Commit cdba214e by xiongziliang

MP4录制修复兼容性问题

parent d482dc1c
...@@ -73,10 +73,6 @@ void MP4Muxer::resetTracks() { ...@@ -73,10 +73,6 @@ void MP4Muxer::resetTracks() {
} }
void MP4Muxer::inputFrame(const Frame::Ptr &frame) { void MP4Muxer::inputFrame(const Frame::Ptr &frame) {
if(frame->configFrame()){
//忽略配置帧
return;
}
auto it = _codec_to_trackid.find(frame->getCodecId()); auto it = _codec_to_trackid.find(frame->getCodecId());
if(it == _codec_to_trackid.end()){ if(it == _codec_to_trackid.end()){
//该Track不存在或初始化失败 //该Track不存在或初始化失败
...@@ -93,32 +89,66 @@ void MP4Muxer::inputFrame(const Frame::Ptr &frame) { ...@@ -93,32 +89,66 @@ void MP4Muxer::inputFrame(const Frame::Ptr &frame) {
_started = true; _started = true;
} }
int with_nalu_size ; //mp4文件时间戳需要从0开始
switch (frame->getCodecId()){ auto &track_info = it->second;
int64_t dts_out, pts_out;
switch (frame->getCodecId()) {
case CodecH264: case CodecH264:
case CodecH265: case CodecH265: {
//我们输入264、265是没有头四个字节表明数据长度的 //这里的代码逻辑是让SPS、PPS、IDR这些时间戳相同的帧打包到一起当做一个帧处理,
with_nalu_size = 0; if (!_frameCached.empty() && _frameCached.back()->dts() != frame->dts()) {
Frame::Ptr back = _frameCached.back();
//求相对时间戳
track_info.stamp.revise(back->dts(), back->pts(), dts_out, pts_out);
if (_frameCached.size() != 1) {
//缓存中有多帧,需要按照mp4格式合并一起
string merged;
_frameCached.for_each([&](const Frame::Ptr &frame) {
uint32_t nalu_size = frame->size() - frame->prefixSize();
nalu_size = htonl(nalu_size);
merged.append((char *) &nalu_size, 4);
merged.append(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize());
});
mov_writer_write_l(_mov_writter.get(),
track_info.track_id,
merged.data(),
merged.size(),
pts_out,
dts_out,
back->keyFrame() ? MOV_AV_FLAG_KEYFREAME : 0,
1/*我们合并时已经生成了4个字节的MP4格式start code*/);
} else {
//缓存中只有一帧视频
mov_writer_write_l(_mov_writter.get(),
track_info.track_id,
back->data() + back->prefixSize(),
back->size() - back->prefixSize(),
pts_out,
dts_out,
back->keyFrame() ? MOV_AV_FLAG_KEYFREAME : 0,
0/*需要生成头4个字节的MP4格式start code*/);
}
_frameCached.clear();
}
//缓存帧,时间戳相同的帧合并一起写入mp4
_frameCached.emplace_back(Frame::getCacheAbleFrame(frame));
}
break; break;
default: default: {
//aac或其他类型frame不用添加4个nalu_size的字节 track_info.stamp.revise(frame->dts(), frame->pts(), dts_out, pts_out);
with_nalu_size = 1; mov_writer_write_l(_mov_writter.get(),
track_info.track_id,
frame->data() + frame->prefixSize(),
frame->size() - frame->prefixSize(),
pts_out,
dts_out,
frame->keyFrame() ? MOV_AV_FLAG_KEYFREAME : 0,
1/*aac或其他类型frame不用添加4个nalu_size的字节*/);
}
break; break;
} }
//mp4文件时间戳需要从0开始
auto &track_info = it->second;
int64_t dts_out, pts_out;
track_info.stamp.revise(frame->dts(),frame->pts(),dts_out,pts_out);
mov_writer_write_l(_mov_writter.get(),
track_info.track_id,
frame->data() + frame->prefixSize(),
frame->size() - frame->prefixSize(),
pts_out,
dts_out,
frame->keyFrame() ? MOV_AV_FLAG_KEYFREAME : 0,
with_nalu_size);
} }
void MP4Muxer::addTrack(const Track::Ptr &track) { void MP4Muxer::addTrack(const Track::Ptr &track) {
......
...@@ -82,6 +82,7 @@ private: ...@@ -82,6 +82,7 @@ private:
}; };
unordered_map<int,track_info> _codec_to_trackid; unordered_map<int,track_info> _codec_to_trackid;
bool _started = false; bool _started = false;
List<Frame::Ptr> _frameCached;
}; };
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论