123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- // 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 <stdint.h>
- #include "base/files/file_path.h"
- #include "base/files/memory_mapped_file.h"
- #include "media/base/test_data_util.h"
- #include "media/video/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;
- }
- H264POCTest(const H264POCTest&) = delete;
- H264POCTest& operator=(const H264POCTest&) = delete;
- protected:
- void ComputePOC() {
- poc_ = h264_poc_.ComputePicOrderCnt(&sps_, slice_hdr_);
- // Clear MMCO5.
- slice_hdr_.adaptive_ref_pic_marking_mode_flag = false;
- slice_hdr_.ref_pic_marking[0].memory_mgmnt_control_operation = 0;
- slice_hdr_.ref_pic_marking[1].memory_mgmnt_control_operation = 0;
- slice_hdr_.ref_pic_marking[2].memory_mgmnt_control_operation = 0;
- }
- // 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;
- }
- absl::optional<int32_t> poc_;
- H264SPS sps_;
- H264SliceHeader slice_hdr_;
- H264POC h264_poc_;
- };
- 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;
- slice_hdr_.frame_num = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame with POC lsb 8.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- slice_hdr_.pic_order_cnt_lsb = 8;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- 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;
- slice_hdr_.frame_num = 2;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- 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;
- slice_hdr_.frame_num = 3;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- 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;
- slice_hdr_.frame_num = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Skip ahead.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- slice_hdr_.pic_order_cnt_lsb = 8;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(8, *poc_);
- slice_hdr_.frame_num = 2;
- slice_hdr_.pic_order_cnt_lsb = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(16, *poc_);
- slice_hdr_.frame_num = 3;
- slice_hdr_.pic_order_cnt_lsb = 8;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(24, *poc_);
- // MMCO5 resets to 0.
- slice_hdr_.frame_num = 4;
- slice_hdr_.pic_order_cnt_lsb = 0;
- SetMMCO5();
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Still detected as positive wrapping.
- slice_hdr_.frame_num = 5;
- slice_hdr_.pic_order_cnt_lsb = 8;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- 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;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(1, *poc_);
- // Ref frame.
- slice_hdr_.frame_num = 2;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(3, *poc_);
- // Ref frame.
- slice_hdr_.frame_num = 3;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(4, *poc_);
- // Ref frame.
- slice_hdr_.frame_num = 4;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(6, *poc_);
- // Ref frame, detected as wrapping (ie, this is frame 16).
- slice_hdr_.frame_num = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- 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;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(1, *poc_);
- // Ref frame, detected as wrapping.
- SetMMCO5();
- slice_hdr_.frame_num = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame, wrapping from before has been cleared.
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(1, *poc_);
- }
- // |frame_num| values may be duplicated by non-reference frames.
- TEST_F(H264POCTest, PicOrderCntType1_DupFrameNum) {
- 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;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(1, *poc_);
- // Duplicate |frame_num| frame.
- slice_hdr_.nal_ref_idc = 0;
- slice_hdr_.frame_num = 1;
- slice_hdr_.delta_pic_order_cnt0 = 2;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(2, *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;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(2, *poc_);
- // Ref frame.
- slice_hdr_.frame_num = 2;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(4, *poc_);
- // Ref frame.
- slice_hdr_.frame_num = 3;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(6, *poc_);
- // Ref frame.
- slice_hdr_.frame_num = 4;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(8, *poc_);
- // Ref frame, detected as wrapping (ie, this is frame 16).
- slice_hdr_.frame_num = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- 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;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame.
- slice_hdr_.idr_pic_flag = false;
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(2, *poc_);
- // Ref frame, detected as wrapping.
- SetMMCO5();
- slice_hdr_.frame_num = 0;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(0, *poc_);
- // Ref frame, wrapping from before has been cleared.
- slice_hdr_.frame_num = 1;
- ComputePOC();
- ASSERT_TRUE(poc_.has_value());
- ASSERT_EQ(2, *poc_);
- }
- } // namespace media
|