1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/filters/h265_to_annex_b_bitstream_converter.h"
11 #include "media/formats/mp4/box_definitions.h"
12 #include "media/formats/mp4/hevc.h"
13 #include "testing/gtest/include/gtest/gtest.h"
17 class H265ToAnnexBBitstreamConverterTest : public testing::Test {
19 H265ToAnnexBBitstreamConverterTest(
20 const H265ToAnnexBBitstreamConverterTest&) = delete;
21 H265ToAnnexBBitstreamConverterTest& operator=(
22 const H265ToAnnexBBitstreamConverterTest&) = delete;
25 H265ToAnnexBBitstreamConverterTest() = default;
27 ~H265ToAnnexBBitstreamConverterTest() override = default;
30 mp4::HEVCDecoderConfigurationRecord hevc_config_;
33 static const uint8_t kHeaderDataOkWithFieldLen4[] = {
34 0x01, 0x01, 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x96, 0xf0, 0x00, 0xfc, 0xfd, 0xf8, 0xf8, 0x00, 0x00, 0x0f,
36 0x03, 0xa0, 0x00, 0x01, 0x00, 0x18, 0x40, 0x01, 0x0c, 0x01, 0xff,
37 0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03,
38 0x00, 0x00, 0x03, 0x00, 0x96, 0x9d, 0xc0, 0x90, 0xa1, 0x00, 0x01,
39 0x00, 0x29, 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00,
40 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03,
41 0xc0, 0x80, 0x10, 0xe5, 0x96, 0x77, 0x92, 0x46, 0xda, 0xf0, 0x10,
42 0x10, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x06, 0x1a, 0x80, 0x80, 0xa2,
43 0x00, 0x01, 0x00, 0x06, 0x44, 0x01, 0xc1, 0x73, 0xd1, 0x89};
45 static const uint8_t kPacketDataOkWithFieldLen4[] = {
46 0x00, 0x00, 0x00, 0x2d, 0x00, 0x01, 0xe0, 0xa6, 0xf5, 0xd7,
47 0xd2, 0x24, 0x0a, 0x19, 0x1a, 0xa0, 0xdc, 0x8c, 0x68, 0x5e,
48 0x35, 0x20, 0x40, 0x64, 0x1c, 0x86, 0x81, 0x8a, 0x25, 0x5d,
49 0x65, 0x6c, 0xfe, 0x80, 0x7a, 0xe3, 0xf4, 0x63, 0xe1, 0xcf,
50 0xf2, 0x6e, 0x92, 0x1e, 0xff, 0xd3, 0x65, 0xd9, 0x60};
52 TEST_F(H265ToAnnexBBitstreamConverterTest, Success) {
53 // Initialize converter.
54 std::unique_ptr<uint8_t[]> output;
55 H265ToAnnexBBitstreamConverter converter;
58 EXPECT_TRUE(converter.ParseConfiguration(kHeaderDataOkWithFieldLen4,
59 sizeof(kHeaderDataOkWithFieldLen4),
61 uint32_t config_size = converter.GetConfigSize(hevc_config_);
62 EXPECT_GT(config_size, 0U);
64 // Go on with converting the headers.
65 output = std::make_unique<uint8_t[]>(config_size);
66 EXPECT_TRUE(output.get() != nullptr);
67 EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
68 hevc_config_, output.get(), &config_size));
70 // Calculate buffer size for actual NAL unit.
71 uint32_t output_size = converter.CalculateNeededOutputBufferSize(
72 kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
74 EXPECT_GT(output_size, 0U);
75 output = std::make_unique<uint8_t[]>(output_size);
76 EXPECT_TRUE(output.get() != nullptr);
78 uint32_t output_size_left_for_nal_unit = output_size;
79 // Do the conversion for actual NAL unit.
80 EXPECT_TRUE(converter.ConvertNalUnitStreamToByteStream(
81 kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
82 &hevc_config_, output.get(), &output_size_left_for_nal_unit));
85 TEST_F(H265ToAnnexBBitstreamConverterTest, FailureHeaderBufferOverflow) {
86 // Initialize converter
87 H265ToAnnexBBitstreamConverter converter;
89 // Simulate 10 nalu_array HEVCDecoderConfigurationRecord,
90 // which would extend beyond the buffer.
91 uint8_t corrupted_header[sizeof(kHeaderDataOkWithFieldLen4)];
92 memcpy(corrupted_header, kHeaderDataOkWithFieldLen4,
93 sizeof(kHeaderDataOkWithFieldLen4));
94 // 23th byte contain the number of nalu arrays
95 corrupted_header[22] = corrupted_header[22] | 0xA;
98 EXPECT_FALSE(converter.ParseConfiguration(
99 corrupted_header, sizeof(corrupted_header), &hevc_config_));
102 TEST_F(H265ToAnnexBBitstreamConverterTest, FailureNalUnitBreakage) {
103 // Initialize converter.
104 std::unique_ptr<uint8_t[]> output;
105 H265ToAnnexBBitstreamConverter converter;
107 // Parse the headers.
108 EXPECT_TRUE(converter.ParseConfiguration(kHeaderDataOkWithFieldLen4,
109 sizeof(kHeaderDataOkWithFieldLen4),
111 uint32_t config_size = converter.GetConfigSize(hevc_config_);
112 EXPECT_GT(config_size, 0U);
114 // Go on with converting the headers.
115 output = std::make_unique<uint8_t[]>(config_size);
116 EXPECT_TRUE(output.get() != nullptr);
117 EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
118 hevc_config_, output.get(), &config_size));
120 // Simulate NAL unit broken in middle by writing only some of the data.
121 uint8_t corrupted_nal_unit[sizeof(kPacketDataOkWithFieldLen4) - 30];
122 memcpy(corrupted_nal_unit, kPacketDataOkWithFieldLen4,
123 sizeof(kPacketDataOkWithFieldLen4) - 30);
125 // Calculate buffer size for actual NAL unit, should return 0 because of
126 // incomplete input buffer.
127 uint32_t output_size = converter.CalculateNeededOutputBufferSize(
128 corrupted_nal_unit, sizeof(corrupted_nal_unit), &hevc_config_);
129 EXPECT_EQ(output_size, 0U);
131 // Ignore the error and try to go on with conversion simulating wrong usage.
132 output_size = sizeof(kPacketDataOkWithFieldLen4);
133 output = std::make_unique<uint8_t[]>(output_size);
134 EXPECT_TRUE(output.get() != nullptr);
136 uint32_t output_size_left_for_nal_unit = output_size;
137 // Do the conversion for actual NAL unit, expecting failure.
138 EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(
139 corrupted_nal_unit, sizeof(corrupted_nal_unit), &hevc_config_,
140 output.get(), &output_size_left_for_nal_unit));
141 EXPECT_EQ(output_size_left_for_nal_unit, 0U);
144 TEST_F(H265ToAnnexBBitstreamConverterTest, FailureTooSmallOutputBuffer) {
145 // Initialize converter.
146 std::unique_ptr<uint8_t[]> output;
147 H265ToAnnexBBitstreamConverter converter;
149 // Parse the headers.
150 EXPECT_TRUE(converter.ParseConfiguration(kHeaderDataOkWithFieldLen4,
151 sizeof(kHeaderDataOkWithFieldLen4),
153 uint32_t config_size = converter.GetConfigSize(hevc_config_);
154 EXPECT_GT(config_size, 0U);
155 uint32_t real_config_size = config_size;
157 // Go on with converting the headers with too small buffer.
159 output = std::make_unique<uint8_t[]>(config_size);
160 EXPECT_TRUE(output.get() != nullptr);
161 EXPECT_FALSE(converter.ConvertHEVCDecoderConfigToByteStream(
162 hevc_config_, output.get(), &config_size));
163 EXPECT_EQ(config_size, 0U);
165 // Still too small (but only 1 byte short).
166 config_size = real_config_size - 1;
167 output = std::make_unique<uint8_t[]>(config_size);
168 EXPECT_TRUE(output.get() != nullptr);
169 EXPECT_FALSE(converter.ConvertHEVCDecoderConfigToByteStream(
170 hevc_config_, output.get(), &config_size));
171 EXPECT_EQ(config_size, 0U);
173 // Finally, retry with valid buffer.
174 config_size = real_config_size;
175 output = std::make_unique<uint8_t[]>(config_size);
176 EXPECT_TRUE(output.get() != nullptr);
177 EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
178 hevc_config_, output.get(), &config_size));
180 // Calculate buffer size for actual NAL unit.
181 uint32_t output_size = converter.CalculateNeededOutputBufferSize(
182 kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
184 EXPECT_GT(output_size, 0U);
185 // Simulate too small output buffer.
187 output = std::make_unique<uint8_t[]>(output_size);
188 EXPECT_TRUE(output.get() != nullptr);
190 uint32_t output_size_left_for_nal_unit = output_size;
191 // Do the conversion for actual NAL unit (expect failure).
192 EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(
193 kPacketDataOkWithFieldLen4, sizeof(kPacketDataOkWithFieldLen4),
194 &hevc_config_, output.get(), &output_size_left_for_nal_unit));
195 EXPECT_EQ(output_size_left_for_nal_unit, 0U);
198 static const uint8_t kCorruptedPacketConfiguration[] = {
199 0x01, 0x01, 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x96, 0xf0, 0x00, 0xfc, 0xfd, 0xf8, 0xf8, 0x00, 0x00, 0x0f,
201 0x03, 0xa0, 0x00, 0x01, 0x00, 0x18, 0x40, 0x01, 0x0c, 0x01, 0xff,
202 0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03,
203 0x00, 0x00, 0x03, 0x00, 0x96, 0x9d, 0xc0, 0x90, 0xa1, 0x00, 0x01,
204 0x00, 0x29, 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00,
205 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x96, 0xa0, 0x03,
206 0xc0, 0x80, 0x10, 0xe5, 0x96, 0x77, 0x92, 0x46, 0xda, 0xf0, 0x10,
207 0x10, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x06, 0x1a, 0x80, 0x80, 0xa2,
208 0x00, 0x01, 0x00, 0x06, 0x44, 0x01, 0xc1, 0x73, 0xd1, 0x89};
210 static const uint8_t kCorruptedPacketData[] = {
211 0x00, 0x00, 0x00, 0x15, 0x01, 0x9f, 0x6e, 0xbc, 0x85, 0x3f,
212 0x0f, 0x87, 0x47, 0xa8, 0xd7, 0x5b, 0xfc, 0xb8, 0xfd, 0x3f,
213 0x57, 0x0e, 0xac, 0xf5, 0x4c, 0x01, 0x2e, 0x57};
215 TEST_F(H265ToAnnexBBitstreamConverterTest, CorruptedPacket) {
216 // Initialize converter.
217 std::unique_ptr<uint8_t[]> output;
218 H265ToAnnexBBitstreamConverter converter;
220 // Parse the headers.
221 EXPECT_TRUE(converter.ParseConfiguration(
222 kCorruptedPacketConfiguration, sizeof(kCorruptedPacketConfiguration),
224 uint32_t config_size = converter.GetConfigSize(hevc_config_);
225 EXPECT_GT(config_size, 0U);
227 // Go on with converting the headers.
228 output = std::make_unique<uint8_t[]>(config_size);
229 EXPECT_TRUE(converter.ConvertHEVCDecoderConfigToByteStream(
230 hevc_config_, output.get(), &config_size));
232 // Expect an error here.
233 uint32_t output_size = converter.CalculateNeededOutputBufferSize(
234 kCorruptedPacketData, sizeof(kCorruptedPacketData), &hevc_config_);
235 EXPECT_EQ(output_size, 0U);