From 8a9ab1147cc5a4ec6102286d39e6f17449411dc5 Mon Sep 17 00:00:00 2001 From: Jacob Su Date: Tue, 12 Nov 2024 16:45:34 +0800 Subject: [PATCH] issue #3993: fix av off sync for mp4 dvr. --- trunk/src/kernel/srs_kernel_mp4.cpp | 23 +++++++++++++++++++++-- trunk/src/kernel/srs_kernel_mp4.hpp | 5 +++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index b4d597f7ee..970ef57f62 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -4820,6 +4820,10 @@ uint32_t SrsMp4Sample::pts_ms() SrsMp4SampleManager::SrsMp4SampleManager() { + video_start_dts_ = 0; + audio_start_dts_ = 0; + has_first_video_ = false; + has_first_audio_ = false; } SrsMp4SampleManager::~SrsMp4SampleManager() @@ -4900,6 +4904,16 @@ SrsMp4Sample* SrsMp4SampleManager::at(uint32_t index) void SrsMp4SampleManager::append(SrsMp4Sample* sample) { + if (!has_first_audio_ && sample->type == SrsFrameTypeAudio) { + has_first_audio_ = true; + audio_start_dts_ = sample->dts; + } + + if (!has_first_video_ && sample->type == SrsFrameTypeVideo) { + has_first_video_ = true; + video_start_dts_ = sample->dts; + } + samples.push_back(sample); } @@ -4920,7 +4934,7 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieBox* moov) } SrsMp4SampleTableBox* stbl = vide->stbl(); - + SrsMp4DecodingTime2SampleBox* stts = new SrsMp4DecodingTime2SampleBox(); stbl->set_stts(stts); @@ -4950,7 +4964,7 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieBox* moov) co = new SrsMp4ChunkLargeOffsetBox(); stbl->set_co64(static_cast(co)); } - + if ((err = write_track(SrsFrameTypeVideo, stts, stss, ctts, stsc, stsz, co)) != srs_success) { return srs_error_wrap(err, "write vide track"); } @@ -5077,6 +5091,11 @@ srs_error_t SrsMp4SampleManager::write_track(SrsFrameType track, } else { // The first sample always in the STTS table. stts_entry.sample_count++; + if (track == SrsFrameTypeVideo) { + stts_entry.sample_delta = video_start_dts_ > audio_start_dts_ ? video_start_dts_ - audio_start_dts_ : 0; + } else if (track == SrsFrameTypeAudio) { + stts_entry.sample_delta = audio_start_dts_ > video_start_dts_ ? audio_start_dts_ - video_start_dts_ : 0; + } } } diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index 23805773e6..4275f5b7a0 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -1914,6 +1914,11 @@ class SrsMp4Sample // The keyframe is specified by stss. class SrsMp4SampleManager { +private: + uint64_t video_start_dts_; + uint64_t audio_start_dts_; + bool has_first_video_; + bool has_first_audio_; public: std::vector samples; public: