Use absl::Cleanup to perform callbacks on encoding error.

Bug: b/336978562
Change-Id: I8cf9bbea5192fd470c02b7f40dafce00f199cada
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/351040
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42357}
This commit is contained in:
philipel 2024-05-21 09:25:08 +02:00 committed by WebRTC LUCI CQ
parent 44e63aaf0a
commit af0c18c594
2 changed files with 28 additions and 38 deletions

View File

@ -379,7 +379,10 @@ rtc_library("libaom_av1_encoder_factory") {
"//third_party/libaom",
]
absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
absl_deps = [
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/cleanup",
]
}
rtc_library("libaom_av1_encoder_factory_test") {

View File

@ -18,6 +18,7 @@
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/cleanup/cleanup.h"
#include "api/video_codecs/video_encoder_interface.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
@ -25,10 +26,9 @@
#include "third_party/libaom/source/libaom/aom/aom_encoder.h"
#include "third_party/libaom/source/libaom/aom/aomcx.h"
#define SET_OR_DO_ERROR_CALLBACK_AND_RETURN(param_id, param_value) \
#define SET_OR_RETURN(param_id, param_value) \
do { \
if (!SetEncoderControlParameters(&ctx_, param_id, param_value)) { \
DoErrorCallback(frame_settings); \
return; \
} \
} while (0)
@ -616,36 +616,33 @@ aom_svc_params_t GetSvcParams(
return svc_params;
}
void DoErrorCallback(std::vector<FrameEncodeSettings>& frame_settings) {
for (FrameEncodeSettings& settings : frame_settings) {
if (settings.frame_output) {
settings.frame_output->EncodeComplete({});
// To avoid invoking any callback more than once.
settings.frame_output = nullptr;
}
}
}
void LibaomAv1Encoder::Encode(
rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer,
const TemporalUnitSettings& tu_settings,
std::vector<FrameEncodeSettings> frame_settings) {
absl::Cleanup on_return = [&] {
// On return call `EncodeComplete` with EncodingError result unless they
// were already called with an EncodedData result.
for (FrameEncodeSettings& settings : frame_settings) {
if (settings.frame_output) {
settings.frame_output->EncodeComplete(EncodingError());
}
}
};
if (!ValidateEncodeParams(*frame_buffer, tu_settings, frame_settings,
last_resolution_in_buffer_, cfg_.rc_end_usage)) {
DoErrorCallback(frame_settings);
return;
}
if (current_content_type_ != tu_settings.content_hint) {
if (tu_settings.content_hint == VideoCodecMode::kScreensharing) {
// TD: Set speed 11?
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_TUNE_CONTENT,
AOM_CONTENT_SCREEN);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_ENABLE_PALETTE, 1);
SET_OR_RETURN(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN);
SET_OR_RETURN(AV1E_SET_ENABLE_PALETTE, 1);
} else {
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_TUNE_CONTENT,
AOM_CONTENT_DEFAULT);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_ENABLE_PALETTE, 0);
SET_OR_RETURN(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT);
SET_OR_RETURN(AV1E_SET_ENABLE_PALETTE, 0);
}
current_content_type_ = tu_settings.content_hint;
}
@ -668,12 +665,9 @@ void LibaomAv1Encoder::Encode(
<< frame_buffer->height();
ThreadTilesAndSuperblockSizeInfo ttsbi = GetThreadingTilesAndSuperblockSize(
frame_buffer->width(), frame_buffer->height(), max_number_of_threads_);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_SUPERBLOCK_SIZE,
ttsbi.superblock_size);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_TILE_ROWS,
ttsbi.exp_tile_rows);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_TILE_COLUMNS,
ttsbi.exp_tile_colums);
SET_OR_RETURN(AV1E_SET_SUPERBLOCK_SIZE, ttsbi.superblock_size);
SET_OR_RETURN(AV1E_SET_TILE_ROWS, ttsbi.exp_tile_rows);
SET_OR_RETURN(AV1E_SET_TILE_COLUMNS, ttsbi.exp_tile_colums);
cfg_.g_threads = ttsbi.num_threads;
cfg_.g_w = frame_buffer->width();
cfg_.g_h = frame_buffer->height();
@ -687,11 +681,10 @@ void LibaomAv1Encoder::Encode(
if (aom_codec_err_t ret = aom_codec_enc_config_set(&ctx_, &cfg_);
ret != AOM_CODEC_OK) {
RTC_LOG(LS_ERROR) << "aom_codec_enc_config_set returned " << ret;
DoErrorCallback(frame_settings);
return;
}
aom_svc_params_t svc_params = GetSvcParams(*frame_buffer, frame_settings);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_SVC_PARAMS, &svc_params);
SET_OR_RETURN(AV1E_SET_SVC_PARAMS, &svc_params);
// The libaom AV1 encoder requires that `aom_codec_encode` is called for
// every spatial layer, even if no frame should be encoded for that layer.
@ -714,10 +707,9 @@ void LibaomAv1Encoder::Encode(
.spatial_layer_id = sid,
.temporal_layer_id = settings.temporal_id,
};
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_SVC_LAYER_ID, &layer_id);
SET_OR_RETURN(AV1E_SET_SVC_LAYER_ID, &layer_id);
aom_svc_ref_frame_config_t ref_config = GetSvcRefFrameConfig(settings);
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AV1E_SET_SVC_REF_FRAME_CONFIG,
&ref_config);
SET_OR_RETURN(AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_config);
// TD: Duration can't be zero, what does it matter when the layer is
// not being encoded?
@ -733,8 +725,7 @@ void LibaomAv1Encoder::Encode(
if (settings.effort_level != current_effort_level_[settings.spatial_id]) {
// For RTC we use speed level 6 to 10, with 8 being the default. Note
// that low effort means higher speed.
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AOME_SET_CPUUSED,
8 - settings.effort_level);
SET_OR_RETURN(AOME_SET_CPUUSED, 8 - settings.effort_level);
current_effort_level_[settings.spatial_id] = settings.effort_level;
}
}
@ -751,7 +742,6 @@ void LibaomAv1Encoder::Encode(
settings.frame_type == FrameType::kKeyframe ? AOM_EFLAG_FORCE_KF : 0);
if (ret != AOM_CODEC_OK) {
RTC_LOG(LS_WARNING) << "aom_codec_encode returned " << ret;
DoErrorCallback(frame_settings);
return;
}
@ -773,8 +763,7 @@ void LibaomAv1Encoder::Encode(
while (const aom_codec_cx_pkt_t* pkt =
aom_codec_get_cx_data(&ctx_, &iter)) {
if (pkt->kind == AOM_CODEC_CX_FRAME_PKT && pkt->data.frame.sz > 0) {
SET_OR_DO_ERROR_CALLBACK_AND_RETURN(AOME_GET_LAST_QUANTIZER_64,
&result.encoded_qp);
SET_OR_RETURN(AOME_GET_LAST_QUANTIZER_64, &result.encoded_qp);
result.frame_type = pkt->data.frame.flags & AOM_EFLAG_FORCE_KF
? FrameType::kKeyframe
: FrameType::kDeltaFrame;
@ -782,7 +771,6 @@ void LibaomAv1Encoder::Encode(
settings.frame_output->GetBitstreamOutputBuffer(
DataSize::Bytes(pkt->data.frame.sz));
if (output_buffer.size() != pkt->data.frame.sz) {
DoErrorCallback(frame_settings);
return;
}
memcpy(output_buffer.data(), pkt->data.frame.buf, pkt->data.frame.sz);
@ -792,7 +780,6 @@ void LibaomAv1Encoder::Encode(
}
if (!bitstream_produced) {
DoErrorCallback(frame_settings);
return;
} else {
RTC_CHECK(settings.frame_output);