Source code
Revision control
Copy as Markdown
Other Tools
/*
* Copyright (c) 2026, Alliance for Open Media. All rights reserved.
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <memory>
#include "gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/video_source.h"
namespace {
class CancellableVideoSource : public ::libaom_test::VideoSource {
public:
explicit CancellableVideoSource(::libaom_test::VideoSource *source)
: source_(source), cancel_after_(-1), current_pass_(0) {}
void Begin() override {
source_->Begin();
current_pass_++;
}
void Next() override { source_->Next(); }
aom_image_t *img() const override {
if (current_pass_ == 2 && cancel_after_ >= 0 &&
static_cast<int>(source_->frame()) >= cancel_after_) {
return nullptr;
}
return source_->img();
}
aom_codec_pts_t pts() const override { return source_->pts(); }
unsigned long duration() const override { return source_->duration(); }
aom_rational_t timebase() const override { return source_->timebase(); }
unsigned int frame() const override { return source_->frame(); }
unsigned int limit() const override { return source_->limit(); }
void set_cancel_after(int frame) { cancel_after_ = frame; }
private:
::libaom_test::VideoSource *source_;
int cancel_after_;
int current_pass_;
};
class CancellationTest
: public ::libaom_test::EncoderTest,
public ::libaom_test::CodecTestWithParam< ::libaom_test::TestMode> {
protected:
CancellationTest()
: EncoderTest(GET_PARAM(0)), tile_columns_(0), tile_rows_(0) {}
~CancellationTest() override = default;
void SetUp() override { InitializeConfig(GET_PARAM(1)); }
void PreEncodeFrameHook(::libaom_test::VideoSource *video,
::libaom_test::Encoder *encoder) override {
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, 4); // speed 4
encoder->Control(AV1E_SET_TILE_COLUMNS, tile_columns_);
encoder->Control(AV1E_SET_TILE_ROWS, tile_rows_);
}
}
void DoSimulateCancellationPass2(int threads, int tile_columns,
int tile_rows) {
cfg_.g_threads = threads;
tile_columns_ = tile_columns;
tile_rows_ = tile_rows;
::libaom_test::RandomVideoSource raw_video;
raw_video.SetSize(256, 256);
raw_video.set_limit(40); // 40 frames total
CancellableVideoSource video(&raw_video);
video.set_cancel_after(20); // Cancel after 20 frames in pass 2
// This should not crash
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
private:
int tile_columns_;
int tile_rows_;
};
TEST_P(CancellationTest, SimulateCancellationPass2) {
DoSimulateCancellationPass2(/*threads=*/1, /*tile_columns=*/0,
/*tile_rows=*/0);
}
TEST_P(CancellationTest, SimulateCancellationPass2Threads4) {
DoSimulateCancellationPass2(/*threads=*/4, /*tile_columns=*/1,
/*tile_rows=*/1);
}
// Test 2-pass good quality
AV1_INSTANTIATE_TEST_SUITE(CancellationTest,
::testing::Values(::libaom_test::kTwoPassGood));
} // namespace