| Index: media/video/h264_poc_unittest.cc
|
| diff --git a/media/video/h264_poc_unittest.cc b/media/video/h264_poc_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..67baf9378be1061fb212238f6cc7678d5ca1e2d6
|
| --- /dev/null
|
| +++ b/media/video/h264_poc_unittest.cc
|
| @@ -0,0 +1,245 @@
|
| +// Copyright 2014 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 "base/files/file_path.h"
|
| +#include "base/files/memory_mapped_file.h"
|
| +#include "media/base/test_data_util.h"
|
| +#include "media/filters/h264_parser.h"
|
| +#include "media/video/h264_poc.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace media {
|
| +
|
| +class H264POCTest : public testing::Test {
|
| + public:
|
| + H264POCTest() : sps_(), slice_hdr_() {
|
| + // Default every frame to be a reference frame.
|
| + slice_hdr_.nal_ref_idc = 1;
|
| + }
|
| +
|
| + protected:
|
| + bool ComputePOC() {
|
| + return h264_poc_.ComputePicOrderCnt(&sps_, slice_hdr_, &poc_);
|
| + }
|
| +
|
| + // Also sets as a reference frame and unsets IDR, which is required for
|
| + // memory management control operations to be parsed.
|
| + void SetMMCO5() {
|
| + slice_hdr_.nal_ref_idc = 1;
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.adaptive_ref_pic_marking_mode_flag = true;
|
| + slice_hdr_.ref_pic_marking[0].memory_mgmnt_control_operation = 6;
|
| + slice_hdr_.ref_pic_marking[1].memory_mgmnt_control_operation = 5;
|
| + slice_hdr_.ref_pic_marking[2].memory_mgmnt_control_operation = 0;
|
| + }
|
| +
|
| + int32_t poc_;
|
| +
|
| + H264SPS sps_;
|
| + H264SliceHeader slice_hdr_;
|
| + H264POC h264_poc_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(H264POCTest);
|
| +};
|
| +
|
| +TEST_F(H264POCTest, PicOrderCntType0) {
|
| + sps_.pic_order_cnt_type = 0;
|
| + sps_.log2_max_pic_order_cnt_lsb_minus4 = 0; // 16
|
| +
|
| + // Initial IDR with POC 0.
|
| + slice_hdr_.idr_pic_flag = true;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(0, poc_);
|
| +
|
| + // Ref frame with POC lsb 8.
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.pic_order_cnt_lsb = 8;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(8, poc_);
|
| +
|
| + // Ref frame with POC lsb 0. This should be detected as wrapping, as the
|
| + // (negative) gap is at least half the maximum.
|
| + slice_hdr_.pic_order_cnt_lsb = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(16, poc_);
|
| +
|
| + // Ref frame with POC lsb 9. This should be detected as negative wrapping,
|
| + // as the (positive) gap is more than half the maximum.
|
| + slice_hdr_.pic_order_cnt_lsb = 9;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(9, poc_);
|
| +}
|
| +
|
| +TEST_F(H264POCTest, PicOrderCntType0_WithMMCO5) {
|
| + sps_.pic_order_cnt_type = 0;
|
| + sps_.log2_max_pic_order_cnt_lsb_minus4 = 0; // 16
|
| +
|
| + // Initial IDR with POC 0.
|
| + slice_hdr_.idr_pic_flag = true;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(0, poc_);
|
| +
|
| + // Skip ahead.
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.pic_order_cnt_lsb = 8;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(8, poc_);
|
| +
|
| + slice_hdr_.pic_order_cnt_lsb = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(16, poc_);
|
| +
|
| + slice_hdr_.pic_order_cnt_lsb = 8;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(24, poc_);
|
| +
|
| + SetMMCO5();
|
| + slice_hdr_.pic_order_cnt_lsb = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(32, poc_);
|
| +
|
| + // Due to the MMCO5 above, this is relative to 0, but also detected as
|
| + // positive wrapping.
|
| + slice_hdr_.pic_order_cnt_lsb = 8;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(24, poc_);
|
| +}
|
| +
|
| +TEST_F(H264POCTest, PicOrderCntType1) {
|
| + sps_.pic_order_cnt_type = 1;
|
| + sps_.log2_max_frame_num_minus4 = 0; // 16
|
| + sps_.num_ref_frames_in_pic_order_cnt_cycle = 2;
|
| + sps_.expected_delta_per_pic_order_cnt_cycle = 3;
|
| + sps_.offset_for_ref_frame[0] = 1;
|
| + sps_.offset_for_ref_frame[1] = 2;
|
| +
|
| + // Initial IDR with POC 0.
|
| + slice_hdr_.idr_pic_flag = true;
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(0, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.frame_num = 1;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(1, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.frame_num = 2;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(3, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.frame_num = 3;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(4, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.frame_num = 4;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(6, poc_);
|
| +
|
| + // Ref frame, detected as wrapping (ie, this is frame 16).
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(24, poc_);
|
| +}
|
| +
|
| +TEST_F(H264POCTest, PicOrderCntType1_WithMMCO5) {
|
| + sps_.pic_order_cnt_type = 1;
|
| + sps_.log2_max_frame_num_minus4 = 0; // 16
|
| + sps_.num_ref_frames_in_pic_order_cnt_cycle = 2;
|
| + sps_.expected_delta_per_pic_order_cnt_cycle = 3;
|
| + sps_.offset_for_ref_frame[0] = 1;
|
| + sps_.offset_for_ref_frame[1] = 2;
|
| +
|
| + // Initial IDR with POC 0.
|
| + slice_hdr_.idr_pic_flag = true;
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(0, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.frame_num = 1;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(1, poc_);
|
| +
|
| + // Ref frame, detected as wrapping.
|
| + SetMMCO5();
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(24, poc_);
|
| +
|
| + // Ref frame, wrapping from before has been cleared.
|
| + slice_hdr_.frame_num = 1;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(1, poc_);
|
| +}
|
| +
|
| +TEST_F(H264POCTest, PicOrderCntType2) {
|
| + sps_.pic_order_cnt_type = 2;
|
| +
|
| + // Initial IDR with POC 0.
|
| + slice_hdr_.idr_pic_flag = true;
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(0, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.frame_num = 1;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(2, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.frame_num = 2;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(4, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.frame_num = 3;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(6, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.frame_num = 4;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(8, poc_);
|
| +
|
| + // Ref frame, detected as wrapping (ie, this is frame 16).
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(32, poc_);
|
| +}
|
| +
|
| +TEST_F(H264POCTest, PicOrderCntType2_WithMMCO5) {
|
| + sps_.pic_order_cnt_type = 2;
|
| +
|
| + // Initial IDR with POC 0.
|
| + slice_hdr_.idr_pic_flag = true;
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(0, poc_);
|
| +
|
| + // Ref frame.
|
| + slice_hdr_.idr_pic_flag = false;
|
| + slice_hdr_.frame_num = 1;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(2, poc_);
|
| +
|
| + // Ref frame, detected as wrapping.
|
| + SetMMCO5();
|
| + slice_hdr_.frame_num = 0;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(32, poc_);
|
| +
|
| + // Ref frame, wrapping from before has been cleared.
|
| + slice_hdr_.frame_num = 1;
|
| + ASSERT_TRUE(ComputePOC());
|
| + ASSERT_EQ(2, poc_);
|
| +}
|
| +
|
| +} // namespace media
|
|
|