1 // Copyright (c) 2012 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.
4
5 #include "media/filters/h264_to_annex_b_bitstream_converter.h"
6
7 #include <stddef.h>
8
9 #include "base/logging.h"
10 #include "media/formats/mp4/box_definitions.h"
11 #include "media/video/h264_parser.h"
12
13 namespace media {
14
15 static const uint8_t kStartCodePrefix[3] = {0, 0, 1};
16 static const uint32_t kParamSetStartCodeSize = 1 + sizeof(kStartCodePrefix);
17
18 // Helper function which determines whether NAL unit of given type marks
19 // access unit boundary.
IsAccessUnitBoundaryNal(int nal_unit_type)20 static bool IsAccessUnitBoundaryNal(int nal_unit_type) {
21 // Check if this packet marks access unit boundary by checking the
22 // packet type.
23 if (nal_unit_type == 6 || // Supplemental enhancement information
24 nal_unit_type == 7 || // Picture parameter set
25 nal_unit_type == 8 || // Sequence parameter set
26 nal_unit_type == 9 || // Access unit delimiter
27 (nal_unit_type >= 14 && nal_unit_type <= 18)) { // Reserved types
28 return true;
29 }
30 return false;
31 }
32
H264ToAnnexBBitstreamConverter()33 H264ToAnnexBBitstreamConverter::H264ToAnnexBBitstreamConverter()
34 : configuration_processed_(false),
35 first_nal_unit_in_access_unit_(true),
36 nal_unit_length_field_width_(0) {
37 }
38
39 H264ToAnnexBBitstreamConverter::~H264ToAnnexBBitstreamConverter() = default;
40
ParseConfiguration(const uint8_t * configuration_record,int configuration_record_size,mp4::AVCDecoderConfigurationRecord * avc_config)41 bool H264ToAnnexBBitstreamConverter::ParseConfiguration(
42 const uint8_t* configuration_record,
43 int configuration_record_size,
44 mp4::AVCDecoderConfigurationRecord* avc_config) {
45 DCHECK(configuration_record);
46 DCHECK_GT(configuration_record_size, 0);
47 DCHECK(avc_config);
48
49 if (!avc_config->Parse(configuration_record, configuration_record_size))
50 return false; // Error: invalid input
51
52 // We're done processing the AVCDecoderConfigurationRecord,
53 // store the needed information for parsing actual payload
54 nal_unit_length_field_width_ = avc_config->length_size;
55 configuration_processed_ = true;
56 return true;
57 }
58
GetConfigSize(const mp4::AVCDecoderConfigurationRecord & avc_config) const59 uint32_t H264ToAnnexBBitstreamConverter::GetConfigSize(
60 const mp4::AVCDecoderConfigurationRecord& avc_config) const {
61 uint32_t config_size = 0;
62
63 for (size_t i = 0; i < avc_config.sps_list.size(); ++i)
64 config_size += kParamSetStartCodeSize + avc_config.sps_list[i].size();
65
66 for (size_t i = 0; i < avc_config.pps_list.size(); ++i)
67 config_size += kParamSetStartCodeSize + avc_config.pps_list[i].size();
68
69 return config_size;
70 }
71
CalculateNeededOutputBufferSize(const uint8_t * input,uint32_t input_size,const mp4::AVCDecoderConfigurationRecord * avc_config) const72 uint32_t H264ToAnnexBBitstreamConverter::CalculateNeededOutputBufferSize(
73 const uint8_t* input,
74 uint32_t input_size,
75 const mp4::AVCDecoderConfigurationRecord* avc_config) const {
76 uint32_t output_size = 0;
77 uint32_t data_left = input_size;
78 bool first_nal_in_this_access_unit = first_nal_unit_in_access_unit_;
79
80 if (input_size == 0)
81 return 0; // Error: invalid input data
82
83 if (!configuration_processed_) {
84 return 0; // Error: configuration not handled, we don't know nal unit width
85 }
86
87 if (avc_config)
88 output_size += GetConfigSize(*avc_config);
89
90 CHECK(nal_unit_length_field_width_ == 1 ||
91 nal_unit_length_field_width_ == 2 ||
92 nal_unit_length_field_width_ == 4);
93
94 // Then add the needed size for the actual packet
95 while (data_left > 0) {
96 if (data_left < nal_unit_length_field_width_) {
97 return 0; // Error: not enough data for correct conversion.
98 }
99
100 // Read the next NAL unit length from the input buffer
101 uint8_t size_of_len_field;
102 uint32_t nal_unit_length;
103 for (nal_unit_length = 0, size_of_len_field = nal_unit_length_field_width_;
104 size_of_len_field > 0;
105 input++, size_of_len_field--, data_left--) {
106 nal_unit_length <<= 8;
107 nal_unit_length |= *input;
108 }
109
110 if (nal_unit_length == 0) {
111 break; // Signifies that no more data left in the buffer
112 } else if (nal_unit_length > data_left) {
113 return 0; // Error: Not enough data for correct conversion
114 }
115 data_left -= nal_unit_length;
116
117 // five least significant bits of first NAL unit byte signify nal_unit_type
118 int nal_unit_type = *input & 0x1F;
119 if (first_nal_in_this_access_unit ||
120 IsAccessUnitBoundaryNal(nal_unit_type)) {
121 output_size += 1; // Extra zero_byte for these nal units
122 first_nal_in_this_access_unit = false;
123 }
124 // Start code prefix
125 output_size += sizeof(kStartCodePrefix);
126 // Actual NAL unit size
127 output_size += nal_unit_length;
128 input += nal_unit_length;
129 // No need for trailing zero bits
130 }
131 return output_size;
132 }
133
ConvertAVCDecoderConfigToByteStream(const mp4::AVCDecoderConfigurationRecord & avc_config,uint8_t * output,uint32_t * output_size)134 bool H264ToAnnexBBitstreamConverter::ConvertAVCDecoderConfigToByteStream(
135 const mp4::AVCDecoderConfigurationRecord& avc_config,
136 uint8_t* output,
137 uint32_t* output_size) {
138 uint8_t* out = output;
139 uint32_t out_size = *output_size;
140 *output_size = 0;
141 for (size_t i = 0; i < avc_config.sps_list.size(); ++i) {
142 if (!WriteParamSet(avc_config.sps_list[i], &out, &out_size))
143 return false;
144 }
145
146 for (size_t i = 0; i < avc_config.pps_list.size(); ++i) {
147 if (!WriteParamSet(avc_config.pps_list[i], &out, &out_size))
148 return false;
149 }
150
151 nal_unit_length_field_width_ = avc_config.length_size;
152 configuration_processed_ = true;
153 *output_size = out - output;
154 return true;
155 }
156
ConvertNalUnitStreamToByteStream(const uint8_t * input,uint32_t input_size,const mp4::AVCDecoderConfigurationRecord * avc_config,uint8_t * output,uint32_t * output_size)157 bool H264ToAnnexBBitstreamConverter::ConvertNalUnitStreamToByteStream(
158 const uint8_t* input,
159 uint32_t input_size,
160 const mp4::AVCDecoderConfigurationRecord* avc_config,
161 uint8_t* output,
162 uint32_t* output_size) {
163 const uint8_t* inscan = input; // We read the input from here progressively
164 uint8_t* outscan = output; // We write the output to here progressively
165 uint32_t data_left = input_size;
166
167 if (input_size == 0 || *output_size == 0) {
168 *output_size = 0;
169 return false; // Error: invalid input
170 }
171
172 // NAL unit width should be known at this point
173 CHECK(nal_unit_length_field_width_ == 1 ||
174 nal_unit_length_field_width_ == 2 ||
175 nal_unit_length_field_width_ == 4);
176
177 // Do the actual conversion for the actual input packet
178 int nal_unit_count = 0;
179 while (data_left > 0) {
180 uint8_t i;
181 uint32_t nal_unit_length;
182
183 // Read the next NAL unit length from the input buffer by scanning
184 // the input stream with the specific length field width
185 for (nal_unit_length = 0, i = nal_unit_length_field_width_;
186 i > 0 && data_left > 0;
187 inscan++, i--, data_left--) {
188 nal_unit_length <<= 8;
189 nal_unit_length |= *inscan;
190 }
191
192 if (nal_unit_length == 0) {
193 break; // Successful conversion, end of buffer
194 } else if (nal_unit_length > data_left) {
195 *output_size = 0;
196 return false; // Error: not enough data for correct conversion
197 }
198
199 // Five least significant bits of first NAL unit byte signify
200 // nal_unit_type.
201 int nal_unit_type = *inscan & 0x1F;
202 nal_unit_count++;
203
204 // Insert the config after the AUD if an AUD is the first NAL unit or
205 // before all NAL units if the first one isn't an AUD.
206 if (avc_config &&
207 (nal_unit_type != H264NALU::kAUD || nal_unit_count > 1)) {
208 uint32_t output_bytes_used = outscan - output;
209
210 DCHECK_GE(*output_size, output_bytes_used);
211
212 uint32_t config_size = *output_size - output_bytes_used;
213 if (!ConvertAVCDecoderConfigToByteStream(*avc_config,
214 outscan,
215 &config_size)) {
216 DVLOG(1) << "Failed to insert parameter sets.";
217 *output_size = 0;
218 return false; // Failed to convert the buffer.
219 }
220 outscan += config_size;
221 avc_config = NULL;
222 }
223 uint32_t start_code_len;
224 first_nal_unit_in_access_unit_ ?
225 start_code_len = sizeof(kStartCodePrefix) + 1 :
226 start_code_len = sizeof(kStartCodePrefix);
227 if (static_cast<uint32_t>(outscan - output) + start_code_len +
228 nal_unit_length >
229 *output_size) {
230 *output_size = 0;
231 return false; // Error: too small output buffer
232 }
233
234 // Check if this packet marks access unit boundary by checking the
235 // packet type.
236 if (IsAccessUnitBoundaryNal(nal_unit_type)) {
237 first_nal_unit_in_access_unit_ = true;
238 }
239
240 // Write extra zero-byte before start code prefix if this packet
241 // signals next access unit.
242 if (first_nal_unit_in_access_unit_) {
243 *outscan = 0;
244 outscan++;
245 first_nal_unit_in_access_unit_ = false;
246 }
247
248 // No need to write leading zero bits.
249 // Write start-code prefix.
250 memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix));
251 outscan += sizeof(kStartCodePrefix);
252 // Then write the actual NAL unit from the input buffer.
253 memcpy(outscan, inscan, nal_unit_length);
254 inscan += nal_unit_length;
255 data_left -= nal_unit_length;
256 outscan += nal_unit_length;
257 // No need for trailing zero bits.
258 }
259 // Successful conversion, output the freshly allocated bitstream buffer.
260 *output_size = static_cast<uint32_t>(outscan - output);
261 return true;
262 }
263
WriteParamSet(const std::vector<uint8_t> & param_set,uint8_t ** out,uint32_t * out_size) const264 bool H264ToAnnexBBitstreamConverter::WriteParamSet(
265 const std::vector<uint8_t>& param_set,
266 uint8_t** out,
267 uint32_t* out_size) const {
268 // Strip trailing null bytes.
269 size_t size = param_set.size();
270 while (size && param_set[size - 1] == 0)
271 size--;
272 if (!size)
273 return false;
274
275 // Verify space.
276 uint32_t bytes_left = *out_size;
277 if (bytes_left < kParamSetStartCodeSize ||
278 bytes_left - kParamSetStartCodeSize < size) {
279 return false;
280 }
281
282 uint8_t* start = *out;
283 uint8_t* buf = start;
284
285 // Write the 4 byte Annex B start code.
286 *buf++ = 0; // zero byte
287 memcpy(buf, kStartCodePrefix, sizeof(kStartCodePrefix));
288 buf += sizeof(kStartCodePrefix);
289
290 // Copy the data.
291 memcpy(buf, ¶m_set[0], size);
292 buf += size;
293
294 *out = buf;
295 *out_size -= buf - start;
296 return true;
297 }
298
299 } // namespace media
300