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, &param_set[0], size);
292   buf += size;
293 
294   *out = buf;
295   *out_size -= buf - start;
296   return true;
297 }
298 
299 }  // namespace media
300