新增媒体流flush机制:#1996

This commit is contained in:
ziyue
2022-10-16 19:49:56 +08:00
parent 80eef693c6
commit ac1abb34da
44 changed files with 287 additions and 124 deletions

View File

@@ -16,7 +16,7 @@
namespace mediakit {
class HlsRecorder : public MediaSourceEventInterceptor, public MpegMuxer, public std::enable_shared_from_this<HlsRecorder> {
class HlsRecorder final : public MediaSourceEventInterceptor, public MpegMuxer, public std::enable_shared_from_this<HlsRecorder> {
public:
using Ptr = std::shared_ptr<HlsRecorder>;
@@ -30,7 +30,7 @@ public:
_hls->clearCache();
}
~HlsRecorder() = default;
~HlsRecorder() { MpegMuxer::flush(); };
void setMediaSource(const std::string &vhost, const std::string &app, const std::string &stream_id) {
_hls->setMediaSource(vhost, app, stream_id);

View File

@@ -79,6 +79,10 @@ void MP4MuxerInterface::resetTracks() {
_codec_to_trackid.clear();
}
void MP4MuxerInterface::flush() {
_frame_merger.flush();
}
bool MP4MuxerInterface::inputFrame(const Frame::Ptr &frame) {
auto it = _codec_to_trackid.find(frame->getCodecId());
if (it == _codec_to_trackid.end()) {
@@ -98,12 +102,12 @@ bool MP4MuxerInterface::inputFrame(const Frame::Ptr &frame) {
//mp4文件时间戳需要从0开始
auto &track_info = it->second;
int64_t dts_out, pts_out;
switch (frame->getCodecId()) {
case CodecH264:
case CodecH265: {
//这里的代码逻辑是让SPS、PPS、IDR这些时间戳相同的帧打包到一起当做一个帧处理
_frame_merger.inputFrame(frame, [&](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool have_idr) {
_frame_merger.inputFrame(frame, [this, &track_info](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool have_idr) {
int64_t dts_out, pts_out;
track_info.stamp.revise(dts, pts, dts_out, pts_out);
mp4_writer_write(_mov_writter.get(),
track_info.track_id,
@@ -117,6 +121,7 @@ bool MP4MuxerInterface::inputFrame(const Frame::Ptr &frame) {
}
default: {
int64_t dts_out, pts_out;
track_info.stamp.revise(frame->dts(), frame->pts(), dts_out, pts_out);
mp4_writer_write(_mov_writter.get(),
track_info.track_id,

View File

@@ -43,6 +43,11 @@ public:
*/
void resetTracks() override;
/**
* 刷新输出所有frame缓存
*/
void flush() override;
/**
* 是否包含视频
*/

View File

@@ -33,6 +33,7 @@ MP4Recorder::MP4Recorder(const string &path, const string &vhost, const string &
}
MP4Recorder::~MP4Recorder() {
flush();
closeFile();
}
@@ -96,6 +97,12 @@ void MP4Recorder::closeFile() {
}
}
void MP4Recorder::flush() {
if (_muxer) {
_muxer->flush();
}
}
bool MP4Recorder::inputFrame(const Frame::Ptr &frame) {
if (!(_have_video && frame->getTrackType() == TrackAudio)) {
//如果有视频且输入的是音频,那么应该忽略切片逻辑

View File

@@ -24,7 +24,7 @@
namespace mediakit {
#ifdef ENABLE_MP4
class MP4Recorder : public MediaSinkInterface {
class MP4Recorder final : public MediaSinkInterface {
public:
using Ptr = std::shared_ptr<MP4Recorder>;
@@ -41,6 +41,11 @@ public:
*/
bool inputFrame(const Frame::Ptr &frame) override;
/**
* 刷新输出所有frame缓存
*/
void flush() override;
/**
* 添加ready状态的track
*/

View File

@@ -63,7 +63,7 @@ bool MpegMuxer::inputFrame(const Frame::Ptr &frame) {
case CodecH264:
case CodecH265: {
//这里的代码逻辑是让SPS、PPS、IDR这些时间戳相同的帧打包到一起当做一个帧处理
return _frame_merger.inputFrame(frame,[&](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool have_idr) {
return _frame_merger.inputFrame(frame,[this, track_id](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool have_idr) {
_key_pos = have_idr;
//取视频时间戳为TS的时间戳
_timestamp = dts;
@@ -153,6 +153,10 @@ void MpegMuxer::releaseContext() {
_frame_merger.clear();
}
void MpegMuxer::flush() {
_frame_merger.flush();
}
}//mediakit
#endif

View File

@@ -45,6 +45,11 @@ public:
*/
bool inputFrame(const Frame::Ptr &frame) override;
/**
* 刷新输出所有frame缓存
*/
void flush() override;
protected:
/**
* 输出ts/ps数据回调