blob: 0cb5ad70d7fc5743b1af9f3111722ff457c748cf [file] [log] [blame]
// Copyright 2019 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/formats/mp4/hevc.h"
#include "base/cxx17_backports.h"
#include "media/formats/mp4/nalu_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
namespace mp4 {
TEST(HEVCAnalyzeAnnexBTest, ValidAnnexBConstructs) {
struct {
const char* case_string;
const bool is_keyframe;
} test_cases[] = {
{"I", true}, {"I I I I", true}, {"AUD I", true},
{"AUD SPS I", true}, {"I EOS", true}, {"I EOS EOB", true},
{"I EOB", true}, {"P", false}, {"P P P P", false},
{"AUD SPS P", false}, {"AUD,I", true}, {"AUD,SPS,I", true},
};
for (size_t i = 0; i < base::size(test_cases); ++i) {
std::vector<uint8_t> buf;
std::vector<SubsampleEntry> subsamples;
HevcStringToAnnexB(test_cases[i].case_string, &buf, nullptr);
BitstreamConverter::AnalysisResult expected;
expected.is_conformant = true;
expected.is_keyframe = test_cases[i].is_keyframe;
EXPECT_PRED2(AnalysesMatch,
HEVC::AnalyzeAnnexB(buf.data(), buf.size(), subsamples),
expected)
<< "'" << test_cases[i].case_string << "' failed";
}
}
TEST(HEVCAnalyzeAnnexBTest, InvalidAnnexBConstructs) {
struct {
const char* case_string;
const absl::optional<bool> is_keyframe;
} test_cases[] = {
// For these cases, lack of conformance is determined before detecting any
// IDR or non-IDR slices, so the non-conformant frames' keyframe analysis
// reports absl::nullopt (which means undetermined analysis result).
{"AUD", absl::nullopt}, // No VCL present.
{"AUD,SPS", absl::nullopt}, // No VCL present.
{"SPS AUD I", absl::nullopt}, // Parameter sets must come after AUD.
{"EOS", absl::nullopt}, // EOS must come after a VCL.
{"EOB", absl::nullopt}, // EOB must come after a VCL.
// For these cases, IDR slice is first VCL and is detected before
// conformance failure, so the non-conformant frame is reported as a
// keyframe.
{"I EOB EOS", true}, // EOS must come before EOB.
{"I SPS", true}, // SPS must come before first VCL.
// For this case, P slice is first VCL and is detected before conformance
// failure, so the non-conformant frame is reported as a non-keyframe.
{"P SPS P",
false}, // SPS after first VCL would indicate a new access unit.
};
BitstreamConverter::AnalysisResult expected;
expected.is_conformant = false;
for (size_t i = 0; i < base::size(test_cases); ++i) {
std::vector<uint8_t> buf;
std::vector<SubsampleEntry> subsamples;
HevcStringToAnnexB(test_cases[i].case_string, &buf, nullptr);
expected.is_keyframe = test_cases[i].is_keyframe;
EXPECT_PRED2(AnalysesMatch,
HEVC::AnalyzeAnnexB(buf.data(), buf.size(), subsamples),
expected)
<< "'" << test_cases[i].case_string << "' failed";
}
}
} // namespace mp4
} // namespace media