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