Index: media/base/h264_bitstream_converter.cc |
diff --git a/media/base/h264_bitstream_converter.cc b/media/base/h264_bitstream_converter.cc |
deleted file mode 100644 |
index 4e154f218d4f4fc17e29c8d09a41e39f904c70fb..0000000000000000000000000000000000000000 |
--- a/media/base/h264_bitstream_converter.cc |
+++ /dev/null |
@@ -1,312 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "media/base/h264_bitstream_converter.h" |
- |
-#include "base/logging.h" |
- |
-namespace media { |
- |
-static const uint8 kStartCodePrefix[3] = {0, 0, 1}; |
- |
-// Helper function which determines whether NAL unit of given type marks |
-// access unit boundary. |
-static bool IsAccessUnitBoundaryNal(int nal_unit_type) { |
- // Check if this packet marks access unit boundary by checking the |
- // packet type. |
- if (nal_unit_type == 6 || // Supplemental enhancement information |
- nal_unit_type == 7 || // Picture parameter set |
- nal_unit_type == 8 || // Sequence parameter set |
- nal_unit_type == 9 || // Access unit delimiter |
- (nal_unit_type >= 14 && nal_unit_type <= 18)) { // Reserved types |
- return true; |
- } |
- return false; |
-} |
- |
-H264BitstreamConverter::H264BitstreamConverter() |
- : configuration_processed_(false), |
- first_nal_unit_in_access_unit_(true), |
- nal_unit_length_field_width_(0) { |
-} |
- |
-H264BitstreamConverter::~H264BitstreamConverter() {} |
- |
-uint32 H264BitstreamConverter::ParseConfigurationAndCalculateSize( |
- const uint8* configuration_record, |
- uint32 configuration_record_size) { |
- // FFmpeg's AVCodecContext's extradata field contains the Decoder Specific |
- // Information from MP4 headers that contain the H.264 SPS and PPS members. |
- // ISO 14496-15 Chapter 5.2.4 AVCDecoderConfigurationRecord. |
- // AVCConfigurationRecord must be at least 7 bytes long. |
- if (configuration_record == NULL || configuration_record_size < 7) { |
- return 0; // Error: invalid input |
- } |
- const uint8* decoder_configuration = configuration_record; |
- uint32 parameter_set_size_bytes = 0; |
- |
- // We can skip the four first bytes as they're only profile information |
- decoder_configuration += 4; |
- // Fifth byte's two LSBs contain the interleaving field's size minus one |
- uint8 size_of_len_field = (*decoder_configuration & 0x3) + 1; |
- if (size_of_len_field != 1 && size_of_len_field != 2 && |
- size_of_len_field != 4) { |
- return 0; // Error: invalid input, NAL unit field len is not correct |
- } |
- decoder_configuration++; |
- // Sixth byte's five LSBs contain the number of SPSs |
- uint8 sps_count = *decoder_configuration & 0x1F; |
- decoder_configuration++; |
- // Then we have N * SPS's with two byte length field and actual SPS |
- while (sps_count-- > 0) { |
- if ((decoder_configuration - configuration_record) + 2 > |
- static_cast<int32>(configuration_record_size)) { |
- return 0; // Error: ran out of data |
- } |
- uint16 sps_len = decoder_configuration[0] << 8 | decoder_configuration[1]; |
- decoder_configuration += 2; |
- // write the SPS to output, always with zero byte + start code prefix |
- parameter_set_size_bytes += 1 + sizeof(kStartCodePrefix); |
- decoder_configuration += sps_len; |
- parameter_set_size_bytes += sps_len; |
- } |
- // Then we have the numner of pps in one byte |
- uint8 pps_count = *decoder_configuration; |
- decoder_configuration++; |
- // And finally, we have N * PPS with two byte length field and actual PPS |
- while (pps_count-- > 0) { |
- if ((decoder_configuration - configuration_record) + 2 > |
- static_cast<int32>(configuration_record_size)) { |
- return 0; // Error: ran out of data |
- } |
- uint16 pps_len = decoder_configuration[0] << 8 | decoder_configuration[1]; |
- decoder_configuration += 2; |
- // write the SPS to output, always with zero byte + start code prefix |
- parameter_set_size_bytes += 1 + sizeof(kStartCodePrefix); |
- decoder_configuration += pps_len; |
- parameter_set_size_bytes += pps_len; |
- } |
- // We're done processing the AVCDecoderConfigurationRecord, |
- // store the needed information for parsing actual payload |
- nal_unit_length_field_width_ = size_of_len_field; |
- configuration_processed_ = true; |
- return parameter_set_size_bytes; |
-} |
- |
-uint32 H264BitstreamConverter::CalculateNeededOutputBufferSize( |
- const uint8* input, |
- uint32 input_size) const { |
- uint32 output_size = 0; |
- uint32 data_left = input_size; |
- bool first_nal_in_this_access_unit = first_nal_unit_in_access_unit_; |
- |
- if (input == NULL || input_size == 0) { |
- return 0; // Error: invalid input data |
- } |
- if (!configuration_processed_) { |
- return 0; // Error: configuration not handled, we don't know nal unit width |
- } |
- CHECK(nal_unit_length_field_width_ == 1 || |
- nal_unit_length_field_width_ == 2 || |
- nal_unit_length_field_width_ == 4); |
- |
- // Then add the needed size for the actual packet |
- while (data_left > 0) { |
- // Read the next NAL unit length from the input buffer |
- uint8 size_of_len_field; |
- uint32 nal_unit_length; |
- for (nal_unit_length = 0, size_of_len_field = nal_unit_length_field_width_; |
- size_of_len_field > 0; |
- input++, size_of_len_field--, data_left--) { |
- nal_unit_length <<= 8; |
- nal_unit_length |= *input; |
- } |
- |
- if (nal_unit_length == 0) { |
- break; // Signifies that no more data left in the buffer |
- } else if (nal_unit_length > data_left) { |
- return 0; // Error: Not enough data for correct conversion |
- } |
- data_left -= nal_unit_length; |
- |
- // five least significant bits of first NAL unit byte signify nal_unit_type |
- int nal_unit_type = *input & 0x1F; |
- if (first_nal_in_this_access_unit || |
- IsAccessUnitBoundaryNal(nal_unit_type)) { |
- output_size += 1; // Extra zero_byte for these nal units |
- first_nal_in_this_access_unit = false; |
- } |
- // Start code prefix |
- output_size += sizeof(kStartCodePrefix); |
- // Actual NAL unit size |
- output_size += nal_unit_length; |
- input += nal_unit_length; |
- // No need for trailing zero bits |
- } |
- return output_size; |
-} |
- |
-bool H264BitstreamConverter::ConvertAVCDecoderConfigurationRecordToByteStream( |
- const uint8* input, |
- uint32 input_size, |
- uint8* output, |
- uint32* output_size) { |
- uint8* outscan = output; |
- // FFmpeg's AVCodecContext's extradata field contains the Decoder Specific |
- // Information from MP4 headers that contain the H.264 SPS and PPS members. |
- // ISO 14496-15 Chapter 5.2.4 AVCDecoderConfigurationRecord. |
- const uint8* decoder_configuration = input; |
- uint32 decoderconfiguration_size = input_size; |
- uint32 out_size = 0; |
- |
- if (decoder_configuration == NULL || decoderconfiguration_size == 0) { |
- return 0; // Error: input invalid |
- } |
- |
- // We can skip the four first bytes as they're only profile information. |
- decoder_configuration += 4; |
- // Fifth byte's two LSBs contain the interleaving field's size minus one |
- uint8 size_of_len_field = (*decoder_configuration & 0x3) + 1; |
- if (size_of_len_field != 1 && size_of_len_field != 2 && |
- size_of_len_field != 4) { |
- return 0; // Error: invalid input, NAL unit field len is not correct |
- } |
- decoder_configuration++; |
- // Sixth byte's five LSBs contain the number of SPSs |
- uint8 sps_count = *decoder_configuration & 0x1F; |
- decoder_configuration++; |
- // Then we have N * SPS's with two byte length field and actual SPS |
- while (sps_count-- > 0) { |
- uint16 sps_len = decoder_configuration[0] << 8 | |
- decoder_configuration[1]; |
- decoder_configuration += 2; |
- if (out_size + 1 + sizeof(kStartCodePrefix) + sps_len > |
- *output_size) { |
- *output_size = 0; |
- return 0; // too small output buffer; |
- } |
- // write the SPS to output, always with zero byte + start code prefix |
- *outscan = 0; // zero byte |
- outscan += 1; |
- memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix)); |
- outscan += sizeof(kStartCodePrefix); |
- memcpy(outscan, decoder_configuration, sps_len); |
- decoder_configuration += sps_len; |
- outscan += sps_len; |
- out_size += 1 + sizeof(kStartCodePrefix) + sps_len; |
- } |
- // Then we have the numner of pps in one byte |
- uint8 pps_count = *decoder_configuration; |
- decoder_configuration++; |
- // And finally, we have N * PPS with two byte length field and actual PPS |
- while (pps_count-- > 0) { |
- uint16 pps_len = decoder_configuration[0] << 8 | decoder_configuration[1]; |
- decoder_configuration += 2; |
- if (out_size + 1 + sizeof(kStartCodePrefix) + pps_len > |
- *output_size) { |
- *output_size = 0; |
- return 0; // too small output buffer; |
- } |
- // write the SPS to output, always with zero byte + start code prefix |
- *outscan = 0; // zero byte |
- outscan += 1; |
- memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix)); |
- outscan += sizeof(kStartCodePrefix); |
- memcpy(outscan, decoder_configuration, pps_len); |
- decoder_configuration += pps_len; |
- outscan += pps_len; |
- out_size += 1 + sizeof(kStartCodePrefix) + pps_len; |
- } |
- // We're done processing the AVCDecoderConfigurationRecord, store the needed |
- // information |
- nal_unit_length_field_width_ = size_of_len_field; |
- configuration_processed_ = true; |
- *output_size = out_size; |
- return true; |
-} |
- |
-bool H264BitstreamConverter::ConvertNalUnitStreamToByteStream( |
- const uint8* input, uint32 input_size, |
- uint8* output, uint32* output_size) { |
- const uint8* inscan = input; // We read the input from here progressively |
- uint8* outscan = output; // We write the output to here progressively |
- uint32 data_left = input_size; |
- |
- if (inscan == NULL || input_size == 0 || |
- outscan == NULL || *output_size == 0) { |
- *output_size = 0; |
- return false; // Error: invalid input |
- } |
- |
- // NAL unit width should be known at this point |
- CHECK(nal_unit_length_field_width_ == 1 || |
- nal_unit_length_field_width_ == 2 || |
- nal_unit_length_field_width_ == 4); |
- |
- // Do the actual conversion for the actual input packet |
- while (data_left > 0) { |
- uint8 i; |
- uint32 nal_unit_length; |
- |
- // Read the next NAL unit length from the input buffer by scanning |
- // the input stream with the specific length field width |
- for (nal_unit_length = 0, i = nal_unit_length_field_width_; |
- i > 0 && data_left > 0; |
- inscan++, i--, data_left--) { |
- nal_unit_length <<= 8; |
- nal_unit_length |= *inscan; |
- } |
- |
- if (nal_unit_length == 0) { |
- break; // Successful conversion, end of buffer |
- } else if (nal_unit_length > data_left) { |
- *output_size = 0; |
- return false; // Error: not enough data for correct conversion |
- } |
- |
- uint32 start_code_len; |
- first_nal_unit_in_access_unit_ ? |
- start_code_len = sizeof(kStartCodePrefix) + 1 : |
- start_code_len = sizeof(kStartCodePrefix); |
- if (static_cast<uint32>(outscan - output) + |
- start_code_len + nal_unit_length > *output_size) { |
- *output_size = 0; |
- return false; // Error: too small output buffer |
- } |
- |
- // Five least significant bits of first NAL unit byte signify |
- // nal_unit_type. |
- int nal_unit_type = *inscan & 0x1F; |
- |
- // Check if this packet marks access unit boundary by checking the |
- // packet type. |
- if (IsAccessUnitBoundaryNal(nal_unit_type)) { |
- first_nal_unit_in_access_unit_ = true; |
- } |
- |
- // Write extra zero-byte before start code prefix if this packet |
- // signals next access unit. |
- if (first_nal_unit_in_access_unit_) { |
- *outscan = 0; |
- outscan++; |
- first_nal_unit_in_access_unit_ = false; |
- } |
- |
- // No need to write leading zero bits. |
- // Write start-code prefix. |
- memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix)); |
- outscan += sizeof(kStartCodePrefix); |
- // Then write the actual NAL unit from the input buffer. |
- memcpy(outscan, inscan, nal_unit_length); |
- inscan += nal_unit_length; |
- data_left -= nal_unit_length; |
- outscan += nal_unit_length; |
- // No need for trailing zero bits. |
- } |
- // Successful conversion, output the freshly allocated bitstream buffer. |
- *output_size = static_cast<uint32>(outscan - output); |
- return true; |
-} |
- |
-} // namespace media |