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:
parent
44e63aaf0a
commit
af0c18c594
@ -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") {
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user