diff --git a/src/media/media_filter.cpp b/src/media/media_filter.cpp index c00181e91965ce94ee898f9a52269a6230c51fbc..8bc730e65cea38c8e0631a27cf9ef55921bdda01 100644 --- a/src/media/media_filter.cpp +++ b/src/media/media_filter.cpp @@ -161,6 +161,9 @@ MediaFilter::feedInput(AVFrame* frame, const std::string& inputName) if (!initialized_) return fail("Filter not initialized", -1); + if (!frame) + return 0; + for (size_t i = 0; i < inputs_.size(); ++i) { auto& ms = inputParams_[i]; if (ms.name != inputName) @@ -210,6 +213,13 @@ MediaFilter::readOutput() return nullptr; } +void +MediaFilter::flush() +{ + for (size_t i = 0; i < inputs_.size(); ++i) + av_buffersrc_add_frame_flags(inputs_[i], nullptr, 0); +} + int MediaFilter::initOutputFilter(AVFilterInOut* out) { diff --git a/src/media/media_filter.h b/src/media/media_filter.h index 3b05a13db2cc0abe65f1bb91b70532f3465fb03f..0ca66dbdd4e26ba3192c209fcc55bf9891bc31d7 100644 --- a/src/media/media_filter.h +++ b/src/media/media_filter.h @@ -99,6 +99,11 @@ class MediaFilter { */ AVFrame* readOutput(); + /** + * Flush filter to indicate EOF. + */ + void flush(); + private: NON_COPYABLE(MediaFilter); diff --git a/src/media/media_recorder.cpp b/src/media/media_recorder.cpp index 1b8005fdd9c47f3394fc21dff97916ec85959497..f57d0acb95ba1f5a94b7b080118fd7b19daf60c9 100644 --- a/src/media/media_recorder.cpp +++ b/src/media/media_recorder.cpp @@ -156,9 +156,10 @@ MediaRecorder::onFrame(const std::string& name, const std::shared_ptr<MediaFrame // copy frame to not mess with the original frame's pts (does not actually copy frame data) MediaFrame clone; + const auto& ms = streams_[name]->info; clone.copyFrom(*frame); - clone.pointer()->pts -= streams_[name]->info.firstTimestamp; - if (clone.pointer()->width > 0 && clone.pointer()->height > 0) + clone.pointer()->pts -= ms.firstTimestamp; + if (ms.isVideo) videoFilter_->feedInput(clone.pointer(), name); else audioFilter_->feedInput(clone.pointer(), name); @@ -417,8 +418,12 @@ void MediaRecorder::flush() { std::lock_guard<std::mutex> lk(mutex_); + if (videoFilter_) + videoFilter_->flush(); + if (audioFilter_) + audioFilter_->flush(); filterAndEncode(videoFilter_.get(), videoIdx_); - filterAndEncode(audioFilter_.get(), videoIdx_); + filterAndEncode(audioFilter_.get(), audioIdx_); encoder_->flush(); }