Commit 1fc7d07f authored by Steve Cho's avatar Steve Cho Committed by Chromium LUCI CQ

video: fix vp9 uncompressed header parser issue, add unittest for

SetupPastIndependence

This CL fixes a bug reported about ref_frame_sign_bias issue in
Vp9UncompressedHeaderParser::SetupPastIndependence. Also, unittest
is added for SetupPastIndependence function.

There are two bugs:
 1. SetupPastIndependence() is not invoked in some cases.
 2. ref_frame_sign_bias is not reset in SetupPastIndependence().
Their triggering conditions are identical, that is
 !show_existing_frame && frame_type!=KEYFRAME && !intra_only
&& error_resilient_mode

According to VP9 Bitstream & Decoding Process Specification,
section 7.2 (page 64), ref_frame_sign_bias should be reset in
setup_past_independence.

Change-Id: I4928e8363406ae7ee0e3f7c59ea4926483c68bf8
Bug: b:176566296
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2629652
Commit-Queue: Steve Cho <stevecho@chromium.org>
Reviewed-by: default avatarKuang-che Wu <kcwu@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845245}
parent 0b9c0182
......@@ -300,6 +300,7 @@ source_set("unit_tests") {
"video_renderer_algorithm_unittest.cc",
"vp9_parser_unittest.cc",
"vp9_raw_bits_reader_unittest.cc",
"vp9_uncompressed_header_parser_unittest.cc",
]
deps = [
......
......@@ -300,7 +300,7 @@ class MEDIA_EXPORT Vp9Parser {
// The parsing context that persists across frames.
class Context {
public:
class Vp9FrameContextManager {
class MEDIA_EXPORT Vp9FrameContextManager {
public:
Vp9FrameContextManager();
~Vp9FrameContextManager();
......
......@@ -622,6 +622,11 @@ Vp9UncompressedHeaderParser::Vp9UncompressedHeaderParser(
Vp9Parser::Context* context)
: context_(context) {}
const Vp9FrameContext&
Vp9UncompressedHeaderParser::GetVp9DefaultFrameContextForTesting() const {
return kVp9DefaultFrameContext;
}
uint8_t Vp9UncompressedHeaderParser::ReadProfile() {
uint8_t profile = 0;
......@@ -765,6 +770,8 @@ Vp9InterpolationFilter Vp9UncompressedHeaderParser::ReadInterpolationFilter() {
void Vp9UncompressedHeaderParser::SetupPastIndependence(Vp9FrameHeader* fhdr) {
memset(&context_->segmentation_, 0, sizeof(context_->segmentation_));
memset(fhdr->ref_frame_sign_bias, 0, sizeof(fhdr->ref_frame_sign_bias));
ResetLoopfilter();
fhdr->frame_context = kVp9DefaultFrameContext;
DCHECK(fhdr->frame_context.IsValid());
......@@ -1069,7 +1076,7 @@ bool Vp9UncompressedHeaderParser::Parse(const uint8_t* stream,
fhdr->frame_context_idx_to_save_probs = fhdr->frame_context_idx =
reader_.ReadLiteral(kVp9NumFrameContextsLog2);
if (fhdr->IsIntra()) {
if (fhdr->IsIntra() || fhdr->error_resilient_mode) {
SetupPastIndependence(fhdr);
if (fhdr->IsKeyframe() || fhdr->error_resilient_mode ||
fhdr->reset_frame_context == 3) {
......
......@@ -8,9 +8,11 @@
#include "media/filters/vp9_parser.h"
#include "media/filters/vp9_raw_bits_reader.h"
#include "media/base/media_export.h"
namespace media {
class Vp9UncompressedHeaderParser {
class MEDIA_EXPORT Vp9UncompressedHeaderParser {
public:
Vp9UncompressedHeaderParser(Vp9Parser::Context* context);
......@@ -18,7 +20,11 @@ class Vp9UncompressedHeaderParser {
// Returns true if no error.
bool Parse(const uint8_t* stream, off_t frame_size, Vp9FrameHeader* fhdr);
const Vp9FrameContext& GetVp9DefaultFrameContextForTesting() const;
private:
friend class Vp9UncompressedHeaderParserTest;
uint8_t ReadProfile();
bool VerifySyncCode();
bool ReadColorConfig(Vp9FrameHeader* fhdr);
......
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/vp9_uncompressed_header_parser.h"
#include "media/filters/vp9_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
class Vp9UncompressedHeaderParserTest : public testing::Test {
public:
void SetupPastIndependence(Vp9FrameHeader* fhdr) {
vp9_uncompressed_header_parser_.SetupPastIndependence(fhdr);
}
const Vp9FrameContext& GetVp9DefaultFrameContextForTesting() const {
return vp9_uncompressed_header_parser_
.GetVp9DefaultFrameContextForTesting();
}
Vp9UncompressedHeaderParserTest()
: vp9_uncompressed_header_parser_((&vp9_parser_context_)) {}
protected:
const Vp9LoopFilterParams& GetLoopFilter() const {
return vp9_parser_context_.loop_filter();
}
Vp9Parser::Context vp9_parser_context_;
Vp9UncompressedHeaderParser vp9_uncompressed_header_parser_;
};
TEST_F(Vp9UncompressedHeaderParserTest, SetupPastIndependence) {
Vp9FrameHeader frame_header = {};
SetupPastIndependence(&frame_header);
EXPECT_EQ(0, frame_header.ref_frame_sign_bias[VP9_FRAME_INTRA]);
EXPECT_EQ(0, frame_header.ref_frame_sign_bias[VP9_FRAME_LAST]);
EXPECT_EQ(0, frame_header.ref_frame_sign_bias[VP9_FRAME_GOLDEN]);
EXPECT_EQ(0, frame_header.ref_frame_sign_bias[VP9_FRAME_ALTREF]);
// Verify ResetLoopfilter() result
const Vp9LoopFilterParams& lf = GetLoopFilter();
EXPECT_TRUE(lf.delta_enabled);
EXPECT_TRUE(lf.delta_update);
EXPECT_EQ(1, lf.ref_deltas[VP9_FRAME_INTRA]);
EXPECT_EQ(0, lf.ref_deltas[VP9_FRAME_LAST]);
EXPECT_EQ(-1, lf.ref_deltas[VP9_FRAME_GOLDEN]);
EXPECT_EQ(-1, lf.ref_deltas[VP9_FRAME_ALTREF]);
EXPECT_EQ(0, lf.mode_deltas[0]);
EXPECT_EQ(0, lf.mode_deltas[1]);
EXPECT_TRUE(frame_header.frame_context.IsValid());
static_assert(std::is_pod<Vp9FrameContext>::value,
"Vp9FrameContext is not POD, rewrite the next EXPECT_TRUE");
EXPECT_TRUE(std::memcmp(&frame_header.frame_context,
&GetVp9DefaultFrameContextForTesting(),
sizeof(GetVp9DefaultFrameContextForTesting())) == 0);
}
} // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment