diff --git a/src/Rtp/Decoder.cpp b/src/Rtp/Decoder.cpp index 61cbdd7c..79ead826 100644 --- a/src/Rtp/Decoder.cpp +++ b/src/Rtp/Decoder.cpp @@ -125,8 +125,14 @@ void DecoderImp::onDecode(int stream, int codecid, int flags, int64_t pts, int64 auto frame = Factory::getFrameFromPtr(codec, (char *)data, bytes, dts, pts); if (getTrackType(codec) != TrackVideo) { onFrame(stream, frame); + if (_last_is_keyframe && _video_merge) { + // 上次是关键帧,收到音频后,说明帧收齐了 + _video_merge->flush(); + } return; } + _last_is_keyframe = frame->keyFrame(); + _video_merge = &ref.second; ref.second.inputFrame(frame, [this, stream, codec](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) { onFrame(stream, Factory::getFrameFromBuffer(codec, buffer, dts, pts)); }); diff --git a/src/Rtp/Decoder.h b/src/Rtp/Decoder.h index 4902157c..8a8b90a1 100644 --- a/src/Rtp/Decoder.h +++ b/src/Rtp/Decoder.h @@ -59,13 +59,14 @@ private: private: bool _finished = false; bool _have_video = false; + bool _last_is_keyframe = false; Decoder::Ptr _decoder; MediaSinkInterface *_sink; - class FrameMergerImp : public FrameMerger { public: FrameMergerImp() : FrameMerger(FrameMerger::none) {} }; + FrameMergerImp *_video_merge = nullptr; std::unordered_map > _tracks; };