Add processing time to VideoFrame
Bug: chromium:1011581
Change-Id: Icd675cb98b8b5052933b9a8eebe718be94c2fef2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166162
Commit-Queue: Johannes Kron <kron@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30281}
diff --git a/api/video/video_frame.h b/api/video/video_frame.h
index f312e7a..08c939d 100644
--- a/api/video/video_frame.h
+++ b/api/video/video_frame.h
@@ -72,6 +72,12 @@
int scaled_height) const;
};
+ struct RTC_EXPORT ProcessingTime {
+ TimeDelta Elapsed() const { return finish - start; }
+ Timestamp start;
+ Timestamp finish;
+ };
+
// Preferred way of building VideoFrame objects.
class RTC_EXPORT Builder {
public:
@@ -223,6 +229,13 @@
packet_infos_ = std::move(value);
}
+ const absl::optional<ProcessingTime> processing_time() const {
+ return processing_time_;
+ }
+ void set_processing_time(const ProcessingTime& processing_time) {
+ processing_time_ = processing_time;
+ }
+
private:
VideoFrame(uint16_t id,
const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
@@ -252,6 +265,11 @@
// MediaStreamTrack, in order to implement getContributingSources(). See:
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
RtpPacketInfos packet_infos_;
+ // Processing timestamps of the frame. For received video frames these are the
+ // timestamps when the frame is sent to the decoder and the decoded image
+ // returned from the decoder.
+ // Currently, not set for locally captured video frames.
+ absl::optional<ProcessingTime> processing_time_;
};
} // namespace webrtc
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index 2cd3204..100686d 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -99,11 +99,13 @@
decodedImage.set_packet_infos(frameInfo->packet_infos);
decodedImage.set_rotation(frameInfo->rotation);
- const int64_t now_ms = _clock->TimeInMilliseconds();
+ const Timestamp now = _clock->CurrentTime();
+ RTC_DCHECK(frameInfo->decodeStart);
if (!decode_time_ms) {
- decode_time_ms = now_ms - frameInfo->decodeStartTimeMs;
+ decode_time_ms = (now - *frameInfo->decodeStart).ms();
}
- _timing->StopDecodeTimer(*decode_time_ms, now_ms);
+ _timing->StopDecodeTimer(*decode_time_ms, now.ms());
+ decodedImage.set_processing_time({*frameInfo->decodeStart, now});
// Report timing information.
TimingFrameInfo timing_frame_info;
@@ -147,8 +149,8 @@
}
timing_frame_info.flags = frameInfo->timing.flags;
- timing_frame_info.decode_start_ms = frameInfo->decodeStartTimeMs;
- timing_frame_info.decode_finish_ms = now_ms;
+ timing_frame_info.decode_start_ms = frameInfo->decodeStart->ms();
+ timing_frame_info.decode_finish_ms = now.ms();
timing_frame_info.render_time_ms = frameInfo->renderTimeMs;
timing_frame_info.rtp_timestamp = decodedImage.timestamp();
timing_frame_info.receive_start_ms = frameInfo->timing.receive_start_ms;
@@ -210,10 +212,10 @@
return decoder_->InitDecode(settings, numberOfCores);
}
-int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) {
+int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, Timestamp now) {
TRACE_EVENT1("webrtc", "VCMGenericDecoder::Decode", "timestamp",
frame.Timestamp());
- _frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs;
+ _frameInfos[_nextFrameInfoIdx].decodeStart = now;
_frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs();
_frameInfos[_nextFrameInfoIdx].rotation = frame.rotation();
_frameInfos[_nextFrameInfoIdx].timing = frame.video_timing();
diff --git a/modules/video_coding/generic_decoder.h b/modules/video_coding/generic_decoder.h
index a9d9698..4b4d83e 100644
--- a/modules/video_coding/generic_decoder.h
+++ b/modules/video_coding/generic_decoder.h
@@ -30,14 +30,14 @@
struct VCMFrameInformation {
int64_t renderTimeMs;
- int64_t decodeStartTimeMs;
+ absl::optional<Timestamp> decodeStart;
void* userData;
VideoRotation rotation;
VideoContentType content_type;
EncodedImage::Timing timing;
int64_t ntp_time_ms;
RtpPacketInfos packet_infos;
- // ColorSpace is not storred here, as it might be modified by decoders.
+ // ColorSpace is not stored here, as it might be modified by decoders.
};
class VCMDecodedFrameCallback : public DecodedImageCallback {
@@ -92,7 +92,7 @@
*
* inputVideoBuffer reference to encoded video frame
*/
- int32_t Decode(const VCMEncodedFrame& inputFrame, int64_t nowMs);
+ int32_t Decode(const VCMEncodedFrame& inputFrame, Timestamp now);
/**
* Set decode callback. Deregistering while decoding is illegal.
diff --git a/modules/video_coding/generic_decoder_unittest.cc b/modules/video_coding/generic_decoder_unittest.cc
index 66167eb..3e07a2a 100644
--- a/modules/video_coding/generic_decoder_unittest.cc
+++ b/modules/video_coding/generic_decoder_unittest.cc
@@ -93,7 +93,7 @@
RtpPacketInfos packet_infos = CreatePacketInfos(3);
VCMEncodedFrame encoded_frame;
encoded_frame.SetPacketInfos(packet_infos);
- generic_decoder_.Decode(encoded_frame, clock_.TimeInMilliseconds());
+ generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
ASSERT_TRUE(decoded_frame.has_value());
EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
@@ -107,7 +107,7 @@
// Ensure the original frame is destroyed before the decoding is completed.
VCMEncodedFrame encoded_frame;
encoded_frame.SetPacketInfos(packet_infos);
- generic_decoder_.Decode(encoded_frame, clock_.TimeInMilliseconds());
+ generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
}
absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(200);
diff --git a/modules/video_coding/video_receiver.cc b/modules/video_coding/video_receiver.cc
index e52abf2..44d5526 100644
--- a/modules/video_coding/video_receiver.cc
+++ b/modules/video_coding/video_receiver.cc
@@ -259,7 +259,7 @@
if (decoder == nullptr) {
return VCM_NO_CODEC_REGISTERED;
}
- return decoder->Decode(frame, clock_->TimeInMilliseconds());
+ return decoder->Decode(frame, clock_->CurrentTime());
}
// Register possible receive codecs, can be called multiple times
diff --git a/modules/video_coding/video_receiver2.cc b/modules/video_coding/video_receiver2.cc
index d1e57d1..8eaefbb 100644
--- a/modules/video_coding/video_receiver2.cc
+++ b/modules/video_coding/video_receiver2.cc
@@ -91,7 +91,7 @@
if (decoder == nullptr) {
return VCM_NO_CODEC_REGISTERED;
}
- return decoder->Decode(*frame, clock_->TimeInMilliseconds());
+ return decoder->Decode(*frame, clock_->CurrentTime());
}
// Register possible receive codecs, can be called multiple times