diff --git a/webrtc/modules/video_coding/encoded_frame.h b/webrtc/modules/video_coding/encoded_frame.h index 96f9d00d06..fc17264130 100644 --- a/webrtc/modules/video_coding/encoded_frame.h +++ b/webrtc/modules/video_coding/encoded_frame.h @@ -46,6 +46,11 @@ class VCMEncodedFrame : protected EncodedImage { _encodedWidth = width; _encodedHeight = height; } + + void SetPlayoutDelay(PlayoutDelay playout_delay) { + playout_delay_ = playout_delay; + } + /** * Get the encoded image */ diff --git a/webrtc/modules/video_coding/frame_buffer2.cc b/webrtc/modules/video_coding/frame_buffer2.cc index 4dcea53f6a..8d86a6412a 100644 --- a/webrtc/modules/video_coding/frame_buffer2.cc +++ b/webrtc/modules/video_coding/frame_buffer2.cc @@ -43,6 +43,7 @@ FrameBuffer::FrameBuffer(Clock* clock, jitter_estimator_(jitter_estimator), timing_(timing), inter_frame_delay_(clock_->TimeInMilliseconds()), + last_decoded_frame_timestamp_(0), last_decoded_frame_it_(frames_.end()), last_continuous_frame_it_(frames_.end()), num_frames_history_(0), @@ -207,6 +208,16 @@ void FrameBuffer::Stop() { new_continuous_frame_event_.Set(); } +void FrameBuffer::UpdatePlayoutDelays(const FrameObject& frame) { + TRACE_EVENT0("webrtc", "FrameBuffer::UpdatePlayoutDelays"); + PlayoutDelay playout_delay = frame.EncodedImage().playout_delay_; + if (playout_delay.min_ms >= 0) + timing_->set_min_playout_delay(playout_delay.min_ms); + + if (playout_delay.max_ms >= 0) + timing_->set_max_playout_delay(playout_delay.max_ms); +} + int FrameBuffer::InsertFrame(std::unique_ptr frame) { TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame"); RTC_DCHECK(frame); @@ -283,7 +294,7 @@ int FrameBuffer::InsertFrame(std::unique_ptr frame) { if (!UpdateFrameInfoWithIncomingFrame(*frame, info)) return last_continuous_picture_id; - + UpdatePlayoutDelays(*frame); info->second.frame = std::move(frame); ++num_frames_buffered_; diff --git a/webrtc/modules/video_coding/frame_buffer2.h b/webrtc/modules/video_coding/frame_buffer2.h index 120103fd3d..4695631ec5 100644 --- a/webrtc/modules/video_coding/frame_buffer2.h +++ b/webrtc/modules/video_coding/frame_buffer2.h @@ -120,6 +120,11 @@ class FrameBuffer { using FrameMap = std::map; + // Updates the minimal and maximal playout delays + // depending on the frame. + void UpdatePlayoutDelays(const FrameObject& frame) + EXCLUSIVE_LOCKS_REQUIRED(crit_); + // Update all directly dependent and indirectly dependent frames and mark // them as continuous if all their references has been fulfilled. void PropagateContinuity(FrameMap::iterator start) diff --git a/webrtc/modules/video_coding/frame_buffer2_unittest.cc b/webrtc/modules/video_coding/frame_buffer2_unittest.cc index 4f1c6369dc..488b785335 100644 --- a/webrtc/modules/video_coding/frame_buffer2_unittest.cc +++ b/webrtc/modules/video_coding/frame_buffer2_unittest.cc @@ -260,6 +260,15 @@ TEST_F(TestFrameBuffer2, OneSuperFrame) { CheckFrame(1, pid, 1); } +TEST_F(TestFrameBuffer2, SetPlayoutDelay) { + const PlayoutDelay kPlayoutDelayMs = {123, 321}; + std::unique_ptr test_frame(new FrameObjectFake()); + test_frame->SetPlayoutDelay(kPlayoutDelayMs); + buffer_.InsertFrame(std::move(test_frame)); + EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_.min_playout_delay()); + EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_.max_playout_delay()); +} + // Flaky test, see bugs.webrtc.org/7068. TEST_F(TestFrameBuffer2, DISABLED_OneUnorderedSuperFrame) { uint16_t pid = Rand(); diff --git a/webrtc/modules/video_coding/frame_object.cc b/webrtc/modules/video_coding/frame_object.cc index 9e5ce09770..ec3e9757b3 100644 --- a/webrtc/modules/video_coding/frame_object.cc +++ b/webrtc/modules/video_coding/frame_object.cc @@ -48,6 +48,10 @@ RtpFrameObject::RtpFrameObject(PacketBuffer* packet_buffer, _timeStamp = first_packet->timestamp; ntp_time_ms_ = first_packet->ntp_time_ms_; + // Setting frame's playout delays to the same values + // as of the first packet's. + SetPlayoutDelay(first_packet->video_header.playout_delay); + // Since FFmpeg use an optimized bitstream reader that reads in chunks of // 32/64 bits we have to add at least that much padding to the buffer // to make sure the decoder doesn't read out of bounds.