diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index fed0541b50..f14fa00c78 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include @@ -3177,6 +3178,7 @@ SrsMp4Sample::SrsMp4Sample() data = NULL; frame_type = SrsCodecVideoAVCFrameForbidden; tbn = 0; + adjust = 0; } SrsMp4Sample::~SrsMp4Sample() @@ -3186,12 +3188,12 @@ SrsMp4Sample::~SrsMp4Sample() uint32_t SrsMp4Sample::dts_ms() { - return (uint32_t)(dts * 1000 / tbn); + return (uint32_t)(dts * 1000 / tbn) + adjust; } uint32_t SrsMp4Sample::pts_ms() { - return (uint32_t)(pts * 1000 / tbn); + return (uint32_t)(pts * 1000 / tbn) + adjust; } SrsMp4SampleManager::SrsMp4SampleManager() @@ -3226,11 +3228,42 @@ int SrsMp4SampleManager::load(SrsMp4MovieBox* moov) } // Dumps temp samples. + // Adjust the sequence diff. + int32_t maxp = 0; + int32_t maxn = 0; if (true) { + uint32_t tbn = 0; + SrsMp4Sample* pvideo = NULL; map::iterator it; for (it = tses.begin(); it != tses.end(); ++it) { SrsMp4Sample* sample = it->second; samples.push_back(sample); + + if (sample->type == SrsCodecFlvTagVideo) { + pvideo = sample; + } else if (pvideo) { + tbn = sample->tbn; + int32_t diff = sample->dts_ms() - pvideo->dts_ms(); + if (diff > 0) { + maxp = srs_max(maxp, diff); + } else { + maxn = srs_min(maxn, diff); + } + pvideo = NULL; + } + } + } + + // Adjust when one of maxp and maxn is zero, + // that means we can adjust by add maxn or sub maxp, + // notice that maxn is negative and maxp is positive. + if (maxp * maxn == 0 && maxp + maxn != 0) { + map::iterator it; + for (it = tses.begin(); it != tses.end(); ++it) { + SrsMp4Sample* sample = it->second; + if (sample->type == SrsCodecFlvTagAudio) { + sample->adjust = 0 - maxp - maxn; + } } } diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index 16a590c348..2c15e18fa7 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -1427,6 +1427,9 @@ class SrsMp4Sample uint32_t tbn; // For video, the frame type, whether keyframe. SrsCodecVideoAVCFrame frame_type; + // The adjust timestamp in milliseconds. + // For example, we can adjust a timestamp for A/V to monotonically increase. + int32_t adjust; // The sample data. uint32_t nb_data; uint8_t* data; @@ -1434,9 +1437,9 @@ class SrsMp4Sample SrsMp4Sample(); virtual ~SrsMp4Sample(); public: - // Get the dts in ms. + // Get the adjusted dts in ms. virtual uint32_t dts_ms(); - // Get the pts in ms. + // Get the adjusted pts in ms. virtual uint32_t pts_ms(); };