Clean VideoReceiveStream2::HandleEncodedFrameOnDecodeQueue
Encapsulate the results in a struct and move the post back to the packet sequence in the original method. This allows the calls to ReceiveStatisticsProxy::OnPreDecode to be moved to the main thread always. Bug: webrtc:11993 Change-Id: I37516444efeabdb330868733bccb1e842ea4d54f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/271285 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37823}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
fb5fc4307d
commit
a535ee664c
@ -959,16 +959,12 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) {
|
||||
}
|
||||
|
||||
void ReceiveStatisticsProxy::OnPreDecode(VideoCodecType codec_type, int qp) {
|
||||
RTC_DCHECK_RUN_ON(&decode_queue_);
|
||||
worker_thread_->PostTask(
|
||||
SafeTask(task_safety_.flag(), [codec_type, qp, this]() {
|
||||
RTC_DCHECK_RUN_ON(&main_thread_);
|
||||
last_codec_type_ = codec_type;
|
||||
if (last_codec_type_ == kVideoCodecVP8 && qp != -1) {
|
||||
qp_counters_.vp8.Add(qp);
|
||||
qp_sample_.Add(qp);
|
||||
}
|
||||
}));
|
||||
RTC_DCHECK_RUN_ON(&main_thread_);
|
||||
last_codec_type_ = codec_type;
|
||||
if (last_codec_type_ == kVideoCodecVP8 && qp != -1) {
|
||||
qp_counters_.vp8.Add(qp);
|
||||
qp_sample_.Add(qp);
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiveStatisticsProxy::OnStreamInactive() {
|
||||
|
@ -801,15 +801,45 @@ void VideoReceiveStream2::OnEncodedFrame(std::unique_ptr<EncodedFrame> frame) {
|
||||
const bool keyframe_request_is_due =
|
||||
!last_keyframe_request_ ||
|
||||
now >= (*last_keyframe_request_ + max_wait_for_keyframe_);
|
||||
const bool received_frame_is_keyframe =
|
||||
frame->FrameType() == VideoFrameType::kVideoFrameKey;
|
||||
|
||||
decode_queue_.PostTask([this, frame = std::move(frame), now,
|
||||
keyframe_request_is_due,
|
||||
// Current OnPreDecode only cares about QP for VP8.
|
||||
int qp = -1;
|
||||
if (frame->CodecSpecific()->codecType == kVideoCodecVP8) {
|
||||
if (!vp8::GetQp(frame->data(), frame->size(), &qp)) {
|
||||
RTC_LOG(LS_WARNING) << "Failed to extract QP from VP8 video frame";
|
||||
}
|
||||
}
|
||||
stats_proxy_.OnPreDecode(frame->CodecSpecific()->codecType, qp);
|
||||
|
||||
decode_queue_.PostTask([this, now, keyframe_request_is_due,
|
||||
received_frame_is_keyframe, frame = std::move(frame),
|
||||
keyframe_required = keyframe_required_]() mutable {
|
||||
RTC_DCHECK_RUN_ON(&decode_queue_);
|
||||
if (decoder_stopped_)
|
||||
return;
|
||||
HandleEncodedFrameOnDecodeQueue(std::move(frame), now,
|
||||
keyframe_request_is_due, keyframe_required);
|
||||
DecodeFrameResult result = HandleEncodedFrameOnDecodeQueue(
|
||||
std::move(frame), keyframe_request_is_due, keyframe_required);
|
||||
|
||||
// TODO(bugs.webrtc.org/11993): Make this PostTask to the network thread.
|
||||
call_->worker_thread()->PostTask(
|
||||
SafeTask(task_safety_.flag(),
|
||||
[this, now, result = std::move(result),
|
||||
received_frame_is_keyframe, keyframe_request_is_due]() {
|
||||
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
|
||||
keyframe_required_ = result.keyframe_required;
|
||||
|
||||
if (result.decoded_frame_picture_id) {
|
||||
rtp_video_stream_receiver_.FrameDecoded(
|
||||
*result.decoded_frame_picture_id);
|
||||
}
|
||||
|
||||
HandleKeyFrameGeneration(received_frame_is_keyframe, now,
|
||||
result.force_request_key_frame,
|
||||
keyframe_request_is_due);
|
||||
buffer_->StartNextDecode(keyframe_required_);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@ -840,24 +870,15 @@ void VideoReceiveStream2::OnDecodableFrameTimeout(TimeDelta wait) {
|
||||
buffer_->StartNextDecode(keyframe_required_);
|
||||
}
|
||||
|
||||
void VideoReceiveStream2::HandleEncodedFrameOnDecodeQueue(
|
||||
VideoReceiveStream2::DecodeFrameResult
|
||||
VideoReceiveStream2::HandleEncodedFrameOnDecodeQueue(
|
||||
std::unique_ptr<EncodedFrame> frame,
|
||||
Timestamp now,
|
||||
bool keyframe_request_is_due,
|
||||
bool keyframe_required) {
|
||||
RTC_DCHECK_RUN_ON(&decode_queue_);
|
||||
|
||||
// Current OnPreDecode only cares about QP for VP8.
|
||||
int qp = -1;
|
||||
if (frame->CodecSpecific()->codecType == kVideoCodecVP8) {
|
||||
if (!vp8::GetQp(frame->data(), frame->size(), &qp)) {
|
||||
RTC_LOG(LS_WARNING) << "Failed to extract QP from VP8 video frame";
|
||||
}
|
||||
}
|
||||
stats_proxy_.OnPreDecode(frame->CodecSpecific()->codecType, qp);
|
||||
|
||||
bool force_request_key_frame = false;
|
||||
int64_t decoded_frame_picture_id = -1;
|
||||
absl::optional<int64_t> decoded_frame_picture_id;
|
||||
|
||||
if (!video_receiver_.IsExternalDecoderRegistered(frame->PayloadType())) {
|
||||
// Look for the decoder with this payload type.
|
||||
@ -870,8 +891,6 @@ void VideoReceiveStream2::HandleEncodedFrameOnDecodeQueue(
|
||||
}
|
||||
|
||||
int64_t frame_id = frame->Id();
|
||||
bool received_frame_is_keyframe =
|
||||
frame->FrameType() == VideoFrameType::kVideoFrameKey;
|
||||
int decode_result = DecodeAndMaybeDispatchEncodedFrame(std::move(frame));
|
||||
if (decode_result == WEBRTC_VIDEO_CODEC_OK ||
|
||||
decode_result == WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME) {
|
||||
@ -889,24 +908,11 @@ void VideoReceiveStream2::HandleEncodedFrameOnDecodeQueue(
|
||||
force_request_key_frame = true;
|
||||
}
|
||||
|
||||
{
|
||||
// TODO(bugs.webrtc.org/11993): Make this PostTask to the network thread.
|
||||
call_->worker_thread()->PostTask(SafeTask(
|
||||
task_safety_.flag(), [this, now, received_frame_is_keyframe,
|
||||
force_request_key_frame, decoded_frame_picture_id,
|
||||
keyframe_request_is_due, keyframe_required]() {
|
||||
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
|
||||
keyframe_required_ = keyframe_required;
|
||||
|
||||
if (decoded_frame_picture_id != -1)
|
||||
rtp_video_stream_receiver_.FrameDecoded(decoded_frame_picture_id);
|
||||
|
||||
HandleKeyFrameGeneration(received_frame_is_keyframe, now,
|
||||
force_request_key_frame,
|
||||
keyframe_request_is_due);
|
||||
buffer_->StartNextDecode(keyframe_required_);
|
||||
}));
|
||||
}
|
||||
return DecodeFrameResult{
|
||||
.force_request_key_frame = force_request_key_frame,
|
||||
.decoded_frame_picture_id = std::move(decoded_frame_picture_id),
|
||||
.keyframe_required = keyframe_required,
|
||||
};
|
||||
}
|
||||
|
||||
int VideoReceiveStream2::DecodeAndMaybeDispatchEncodedFrame(
|
||||
|
@ -203,11 +203,33 @@ class VideoReceiveStream2
|
||||
void OnDecodableFrameTimeout(TimeDelta wait) override;
|
||||
|
||||
void CreateAndRegisterExternalDecoder(const Decoder& decoder);
|
||||
void HandleEncodedFrameOnDecodeQueue(std::unique_ptr<EncodedFrame> frame,
|
||||
Timestamp now,
|
||||
bool keyframe_request_is_due,
|
||||
bool keyframe_required)
|
||||
RTC_RUN_ON(decode_queue_);
|
||||
|
||||
struct DecodeFrameResult {
|
||||
DecodeFrameResult(const DecodeFrameResult&) = delete;
|
||||
DecodeFrameResult& operator=(const DecodeFrameResult&) = delete;
|
||||
DecodeFrameResult(DecodeFrameResult&&) = default;
|
||||
DecodeFrameResult& operator=(DecodeFrameResult&&) = default;
|
||||
|
||||
// True if the decoder returned code WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME,
|
||||
// or if the decoder failed and a keyframe is required. When true, a
|
||||
// keyframe request should be sent even if a keyframe request was sent
|
||||
// recently.
|
||||
bool force_request_key_frame;
|
||||
|
||||
// The picture id of the frame that was decoded, or nullopt if the frame was
|
||||
// not decoded.
|
||||
absl::optional<int64_t> decoded_frame_picture_id;
|
||||
|
||||
// True if the next frame decoded must be a keyframe. This value will set
|
||||
// the value of `keyframe_required_`, which will force the frame buffer to
|
||||
// drop all frames that are not keyframes.
|
||||
bool keyframe_required;
|
||||
};
|
||||
|
||||
DecodeFrameResult HandleEncodedFrameOnDecodeQueue(
|
||||
std::unique_ptr<EncodedFrame> frame,
|
||||
bool keyframe_request_is_due,
|
||||
bool keyframe_required) RTC_RUN_ON(decode_queue_);
|
||||
void UpdatePlayoutDelays() const
|
||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(worker_sequence_checker_);
|
||||
void RequestKeyFrame(Timestamp now) RTC_RUN_ON(packet_sequence_checker_);
|
||||
|
Reference in New Issue
Block a user