1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/files/file_path.h"
6 #include "base/files/memory_mapped_file.h"
7 #include "media/base/test_data_util.h"
8 #include "media/filters/h264_parser.h"
9 #include "media/video/h264_poc.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 class H264POCTest
: public testing::Test
{
16 H264POCTest() : sps_(), slice_hdr_() {
17 // Default every frame to be a reference frame.
18 slice_hdr_
.nal_ref_idc
= 1;
23 return h264_poc_
.ComputePicOrderCnt(&sps_
, slice_hdr_
, &poc_
);
26 // Also sets as a reference frame and unsets IDR, which is required for
27 // memory management control operations to be parsed.
29 slice_hdr_
.nal_ref_idc
= 1;
30 slice_hdr_
.idr_pic_flag
= false;
31 slice_hdr_
.adaptive_ref_pic_marking_mode_flag
= true;
32 slice_hdr_
.ref_pic_marking
[0].memory_mgmnt_control_operation
= 6;
33 slice_hdr_
.ref_pic_marking
[1].memory_mgmnt_control_operation
= 5;
34 slice_hdr_
.ref_pic_marking
[2].memory_mgmnt_control_operation
= 0;
40 H264SliceHeader slice_hdr_
;
43 DISALLOW_COPY_AND_ASSIGN(H264POCTest
);
46 TEST_F(H264POCTest
, PicOrderCntType0
) {
47 sps_
.pic_order_cnt_type
= 0;
48 sps_
.log2_max_pic_order_cnt_lsb_minus4
= 0; // 16
50 // Initial IDR with POC 0.
51 slice_hdr_
.idr_pic_flag
= true;
52 ASSERT_TRUE(ComputePOC());
55 // Ref frame with POC lsb 8.
56 slice_hdr_
.idr_pic_flag
= false;
57 slice_hdr_
.pic_order_cnt_lsb
= 8;
58 ASSERT_TRUE(ComputePOC());
61 // Ref frame with POC lsb 0. This should be detected as wrapping, as the
62 // (negative) gap is at least half the maximum.
63 slice_hdr_
.pic_order_cnt_lsb
= 0;
64 ASSERT_TRUE(ComputePOC());
67 // Ref frame with POC lsb 9. This should be detected as negative wrapping,
68 // as the (positive) gap is more than half the maximum.
69 slice_hdr_
.pic_order_cnt_lsb
= 9;
70 ASSERT_TRUE(ComputePOC());
74 TEST_F(H264POCTest
, PicOrderCntType0_WithMMCO5
) {
75 sps_
.pic_order_cnt_type
= 0;
76 sps_
.log2_max_pic_order_cnt_lsb_minus4
= 0; // 16
78 // Initial IDR with POC 0.
79 slice_hdr_
.idr_pic_flag
= true;
80 ASSERT_TRUE(ComputePOC());
84 slice_hdr_
.idr_pic_flag
= false;
85 slice_hdr_
.pic_order_cnt_lsb
= 8;
86 ASSERT_TRUE(ComputePOC());
89 slice_hdr_
.pic_order_cnt_lsb
= 0;
90 ASSERT_TRUE(ComputePOC());
93 slice_hdr_
.pic_order_cnt_lsb
= 8;
94 ASSERT_TRUE(ComputePOC());
98 slice_hdr_
.pic_order_cnt_lsb
= 0;
99 ASSERT_TRUE(ComputePOC());
102 // Due to the MMCO5 above, this is relative to 0, but also detected as
103 // positive wrapping.
104 slice_hdr_
.pic_order_cnt_lsb
= 8;
105 ASSERT_TRUE(ComputePOC());
109 TEST_F(H264POCTest
, PicOrderCntType1
) {
110 sps_
.pic_order_cnt_type
= 1;
111 sps_
.log2_max_frame_num_minus4
= 0; // 16
112 sps_
.num_ref_frames_in_pic_order_cnt_cycle
= 2;
113 sps_
.expected_delta_per_pic_order_cnt_cycle
= 3;
114 sps_
.offset_for_ref_frame
[0] = 1;
115 sps_
.offset_for_ref_frame
[1] = 2;
117 // Initial IDR with POC 0.
118 slice_hdr_
.idr_pic_flag
= true;
119 slice_hdr_
.frame_num
= 0;
120 ASSERT_TRUE(ComputePOC());
124 slice_hdr_
.idr_pic_flag
= false;
125 slice_hdr_
.frame_num
= 1;
126 ASSERT_TRUE(ComputePOC());
130 slice_hdr_
.frame_num
= 2;
131 ASSERT_TRUE(ComputePOC());
135 slice_hdr_
.frame_num
= 3;
136 ASSERT_TRUE(ComputePOC());
140 slice_hdr_
.frame_num
= 4;
141 ASSERT_TRUE(ComputePOC());
144 // Ref frame, detected as wrapping (ie, this is frame 16).
145 slice_hdr_
.frame_num
= 0;
146 ASSERT_TRUE(ComputePOC());
150 TEST_F(H264POCTest
, PicOrderCntType1_WithMMCO5
) {
151 sps_
.pic_order_cnt_type
= 1;
152 sps_
.log2_max_frame_num_minus4
= 0; // 16
153 sps_
.num_ref_frames_in_pic_order_cnt_cycle
= 2;
154 sps_
.expected_delta_per_pic_order_cnt_cycle
= 3;
155 sps_
.offset_for_ref_frame
[0] = 1;
156 sps_
.offset_for_ref_frame
[1] = 2;
158 // Initial IDR with POC 0.
159 slice_hdr_
.idr_pic_flag
= true;
160 slice_hdr_
.frame_num
= 0;
161 ASSERT_TRUE(ComputePOC());
165 slice_hdr_
.idr_pic_flag
= false;
166 slice_hdr_
.frame_num
= 1;
167 ASSERT_TRUE(ComputePOC());
170 // Ref frame, detected as wrapping.
172 slice_hdr_
.frame_num
= 0;
173 ASSERT_TRUE(ComputePOC());
176 // Ref frame, wrapping from before has been cleared.
177 slice_hdr_
.frame_num
= 1;
178 ASSERT_TRUE(ComputePOC());
182 TEST_F(H264POCTest
, PicOrderCntType2
) {
183 sps_
.pic_order_cnt_type
= 2;
185 // Initial IDR with POC 0.
186 slice_hdr_
.idr_pic_flag
= true;
187 slice_hdr_
.frame_num
= 0;
188 ASSERT_TRUE(ComputePOC());
192 slice_hdr_
.idr_pic_flag
= false;
193 slice_hdr_
.frame_num
= 1;
194 ASSERT_TRUE(ComputePOC());
198 slice_hdr_
.frame_num
= 2;
199 ASSERT_TRUE(ComputePOC());
203 slice_hdr_
.frame_num
= 3;
204 ASSERT_TRUE(ComputePOC());
208 slice_hdr_
.frame_num
= 4;
209 ASSERT_TRUE(ComputePOC());
212 // Ref frame, detected as wrapping (ie, this is frame 16).
213 slice_hdr_
.frame_num
= 0;
214 ASSERT_TRUE(ComputePOC());
218 TEST_F(H264POCTest
, PicOrderCntType2_WithMMCO5
) {
219 sps_
.pic_order_cnt_type
= 2;
221 // Initial IDR with POC 0.
222 slice_hdr_
.idr_pic_flag
= true;
223 slice_hdr_
.frame_num
= 0;
224 ASSERT_TRUE(ComputePOC());
228 slice_hdr_
.idr_pic_flag
= false;
229 slice_hdr_
.frame_num
= 1;
230 ASSERT_TRUE(ComputePOC());
233 // Ref frame, detected as wrapping.
235 slice_hdr_
.frame_num
= 0;
236 ASSERT_TRUE(ComputePOC());
239 // Ref frame, wrapping from before has been cleared.
240 slice_hdr_
.frame_num
= 1;
241 ASSERT_TRUE(ComputePOC());