diff --git a/packager/media/filters/filters.gyp b/packager/media/filters/filters.gyp index 8410654f7e..faf9acbede 100644 --- a/packager/media/filters/filters.gyp +++ b/packager/media/filters/filters.gyp @@ -23,10 +23,14 @@ 'h264_byte_to_unit_stream_converter.h', 'h264_parser.cc', 'h264_parser.h', + 'h265_byte_to_unit_stream_converter.cc', + 'h265_byte_to_unit_stream_converter.h', 'h265_parser.cc', 'h265_parser.h', 'h26x_bit_reader.cc', 'h26x_bit_reader.h', + 'h26x_byte_to_unit_stream_converter.cc', + 'h26x_byte_to_unit_stream_converter.h', 'hevc_decoder_configuration.cc', 'hevc_decoder_configuration.h', 'nal_unit_to_byte_stream_converter.cc', @@ -53,6 +57,7 @@ 'ec3_audio_util_unittest.cc', 'h264_byte_to_unit_stream_converter_unittest.cc', 'h264_parser_unittest.cc', + 'h265_byte_to_unit_stream_converter_unittest.cc', 'h265_parser_unittest.cc', 'h26x_bit_reader_unittest.cc', 'hevc_decoder_configuration_unittest.cc', diff --git a/packager/media/filters/h264_byte_to_unit_stream_converter.cc b/packager/media/filters/h264_byte_to_unit_stream_converter.cc index 7be8bb1688..3fd734e45c 100644 --- a/packager/media/filters/h264_byte_to_unit_stream_converter.cc +++ b/packager/media/filters/h264_byte_to_unit_stream_converter.cc @@ -15,74 +15,12 @@ namespace edash_packager { namespace media { -namespace { -// Additional space to reserve for output frame. This value ought to be enough -// to acommodate frames consisting of 100 NAL units with 3-byte start codes. -const size_t kStreamConversionOverhead = 100; -} - -H264ByteToUnitStreamConverter::H264ByteToUnitStreamConverter() {} - +H264ByteToUnitStreamConverter::H264ByteToUnitStreamConverter() + : H26xByteToUnitStreamConverter(NaluReader::kH264) {} H264ByteToUnitStreamConverter::~H264ByteToUnitStreamConverter() {} -bool H264ByteToUnitStreamConverter::ConvertByteStreamToNalUnitStream( - const uint8_t* input_frame, - size_t input_frame_size, - std::vector* output_frame) { - DCHECK(input_frame); - DCHECK(output_frame); - - BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead); - - Nalu nalu; - NaluReader reader(NaluReader::kH264, kIsAnnexbByteStream, input_frame, - input_frame_size); - if (!reader.StartsWithStartCode()) { - LOG(ERROR) << "H.264 byte stream frame did not begin with start code."; - return false; - } - while (reader.Advance(&nalu) == NaluReader::kOk) { - ProcessNalu(nalu, &output_buffer); - } - - output_buffer.SwapBuffer(output_frame); - return true; -} - -void H264ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu, - BufferWriter* output_buffer) { - DCHECK(nalu.data()); - DCHECK(output_buffer); - - // Skip the start code, but keep the 1-byte NALU type. - const uint8_t* nalu_ptr = nalu.data(); - const uint64_t nalu_size = nalu.payload_size() + nalu.header_size(); - DCHECK_LE(nalu_size, std::numeric_limits::max()); - - switch (nalu.type()) { - case Nalu::H264_SPS: - // Grab SPS NALU. - last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size); - return; - case Nalu::H264_PPS: - // Grab PPS NALU. - last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size); - return; - case Nalu::H264_AUD: - // Ignore AUD NALU. - return; - default: - // Copy all other NALUs. - break; - } - - // Append 4-byte length and NAL unit data to the buffer. - output_buffer->AppendInt(static_cast(nalu_size)); - output_buffer->AppendArray(nalu_ptr, nalu_size); -} - -bool H264ByteToUnitStreamConverter::GetAVCDecoderConfigurationRecord( - std::vector* decoder_config) { +bool H264ByteToUnitStreamConverter::GetDecoderConfigurationRecord( + std::vector* decoder_config) const { DCHECK(decoder_config); if ((last_sps_.size() < 4) || last_pps_.empty()) { @@ -108,10 +46,35 @@ bool H264ByteToUnitStreamConverter::GetAVCDecoderConfigurationRecord( buffer.AppendInt(num_pps); buffer.AppendInt(static_cast(last_pps_.size())); buffer.AppendVector(last_pps_); - buffer.SwapBuffer(decoder_config); + buffer.SwapBuffer(decoder_config); return true; } +bool H264ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu) { + DCHECK(nalu.data()); + + // Skip the start code, but keep the 1-byte NALU type. + const uint8_t* nalu_ptr = nalu.data(); + const uint64_t nalu_size = nalu.payload_size() + nalu.header_size(); + + switch (nalu.type()) { + case Nalu::H264_SPS: + // Grab SPS NALU. + last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size); + return true; + case Nalu::H264_PPS: + // Grab PPS NALU. + last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size); + return true; + case Nalu::H264_AUD: + // Ignore AUD NALU. + return true; + default: + // Have the base class handle other NALU types. + return false; + } +} + } // namespace media } // namespace edash_packager diff --git a/packager/media/filters/h264_byte_to_unit_stream_converter.h b/packager/media/filters/h264_byte_to_unit_stream_converter.h index 1cd5816a79..88837ce662 100644 --- a/packager/media/filters/h264_byte_to_unit_stream_converter.h +++ b/packager/media/filters/h264_byte_to_unit_stream_converter.h @@ -12,46 +12,31 @@ #include +#include "packager/media/filters/h26x_byte_to_unit_stream_converter.h" + namespace edash_packager { namespace media { -class BufferWriter; -class Nalu; - /// Class which converts H.264 byte streams (as specified in ISO/IEC 14496-10 /// Annex B) into H.264 NAL unit streams (as specified in ISO/IEC 14496-15). -class H264ByteToUnitStreamConverter { +class H264ByteToUnitStreamConverter : public H26xByteToUnitStreamConverter { public: - static const size_t kUnitStreamNaluLengthSize = 4; - H264ByteToUnitStreamConverter(); - ~H264ByteToUnitStreamConverter(); + ~H264ByteToUnitStreamConverter() override; - /// Converts a whole AVC byte stream encoded video frame to NAL unit stream - /// format. - /// @param input_frame is a buffer containing a whole H.264 frame in byte - /// stream format. - /// @param input_frame_size is the size of the H.264 frame, in bytes. - /// @param output_frame is a pointer to a vector which will receive the - /// converted frame. - /// @return true if successful, false otherwise. - bool ConvertByteStreamToNalUnitStream(const uint8_t* input_frame, - size_t input_frame_size, - std::vector* output_frame); - - /// Synthesizes an AVCDecoderConfigurationRecord from the SPS and PPS NAL - /// units extracted from the AVC byte stream. - /// @param decoder_config is a pointer to a vector, which on successful - /// return will contain the computed AVCDecoderConfigurationRecord. - /// @return true if successful, or false otherwise. - bool GetAVCDecoderConfigurationRecord(std::vector* decoder_config); + /// @name H26xByteToUnitStreamConverter implementation override. + /// @{ + bool GetDecoderConfigurationRecord( + std::vector* decoder_config) const override; + /// @} private: - void ProcessNalu(const Nalu& nalu, - BufferWriter* output_buffer); + bool ProcessNalu(const Nalu& nalu) override; std::vector last_sps_; std::vector last_pps_; + + DISALLOW_COPY_AND_ASSIGN(H264ByteToUnitStreamConverter); }; } // namespace media diff --git a/packager/media/filters/h264_byte_to_unit_stream_converter_unittest.cc b/packager/media/filters/h264_byte_to_unit_stream_converter_unittest.cc index 2a20e70a57..d5606bb0a0 100644 --- a/packager/media/filters/h264_byte_to_unit_stream_converter_unittest.cc +++ b/packager/media/filters/h264_byte_to_unit_stream_converter_unittest.cc @@ -40,7 +40,7 @@ TEST(H264ByteToUnitStreamConverter, ConversionSuccess) { ASSERT_TRUE(base::HexStringToBytes(kExpectedConfigRecord, &expected_decoder_config)); std::vector decoder_config; - ASSERT_TRUE(converter.GetAVCDecoderConfigurationRecord(&decoder_config)); + ASSERT_TRUE(converter.GetDecoderConfigurationRecord(&decoder_config)); EXPECT_EQ(expected_decoder_config, decoder_config); } @@ -56,7 +56,7 @@ TEST(H264ByteToUnitStreamConverter, ConversionFailure) { input_frame.size(), &output_frame)); std::vector decoder_config; - EXPECT_FALSE(converter.GetAVCDecoderConfigurationRecord(&decoder_config)); + EXPECT_FALSE(converter.GetDecoderConfigurationRecord(&decoder_config)); } } // namespace media diff --git a/packager/media/filters/h265_byte_to_unit_stream_converter.cc b/packager/media/filters/h265_byte_to_unit_stream_converter.cc new file mode 100644 index 0000000000..db9a2c7785 --- /dev/null +++ b/packager/media/filters/h265_byte_to_unit_stream_converter.cc @@ -0,0 +1,120 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "packager/media/filters/h265_byte_to_unit_stream_converter.h" + +#include + +#include "packager/base/logging.h" +#include "packager/media/base/buffer_writer.h" +#include "packager/media/base/rcheck.h" +#include "packager/media/filters/h265_parser.h" + +namespace edash_packager { +namespace media { + +H265ByteToUnitStreamConverter::H265ByteToUnitStreamConverter() + : H26xByteToUnitStreamConverter(NaluReader::kH265) {} +H265ByteToUnitStreamConverter::~H265ByteToUnitStreamConverter() {} + +bool H265ByteToUnitStreamConverter::GetDecoderConfigurationRecord( + std::vector* decoder_config) const { + DCHECK(decoder_config); + + if (last_sps_.empty() || last_pps_.empty() || last_vps_.empty()) { + // No data available to construct HEVCDecoderConfigurationRecord. + return false; + } + + // We need to parse the SPS to get the data to add to the record. + int id; + Nalu nalu; + H265Parser parser; + RCHECK(nalu.InitializeFromH265(last_sps_.data(), last_sps_.size())); + RCHECK(parser.ParseSps(nalu, &id) == H265Parser::kOk); + const H265Sps* sps = parser.GetSps(id); + + // Construct an HEVCDecoderConfigurationRecord containing a single SPS, PPS, + // and VPS NALU. Please refer to ISO/IEC 14496-15 for format specifics. + BufferWriter buffer(last_sps_.size() + last_pps_.size() + last_vps_.size() + + 100); + buffer.AppendInt(static_cast(1) /* version */); + // (1) general_profile_space, general_tier_flag, general_profile_idc + // (4) general_profile_compatibility_flags + // (6) general_constraint_indicator_flags + // (1) general_level_idc + // Skip Nalu header (2) and the first byte of the SPS to get the + // profile_tier_level. + buffer.AppendArray(&last_sps_[2+1], 12); + // min_spacial_segmentation_idc = 0 (Unknown) + // TODO(modmaker): Parse vui_parameters and update this. + buffer.AppendInt(static_cast(0xf000)); + buffer.AppendInt(static_cast(0xfc) /* parallelismType = 0 */); + buffer.AppendInt(static_cast(0xfc | sps->chroma_format_idc)); + buffer.AppendInt(static_cast(0xf8 | sps->bit_depth_luma_minus8)); + buffer.AppendInt(static_cast(0xf8 | sps->bit_depth_chroma_minus8)); + buffer.AppendInt(static_cast(0) /* avgFrameRate */); + // Following flags are 0: + // constantFrameRate + // numTemporalLayers + // temporalIdNested + buffer.AppendInt(static_cast(kUnitStreamNaluLengthSize - 1)); + buffer.AppendInt(static_cast(3) /* numOfArrays */); + + // SPS + const uint8_t kArrayCompleteness = 0x80; + buffer.AppendInt(static_cast(kArrayCompleteness | Nalu::H265_SPS)); + buffer.AppendInt(static_cast(1) /* numNalus */); + buffer.AppendInt(static_cast(last_sps_.size())); + buffer.AppendVector(last_sps_); + + // PPS + buffer.AppendInt(static_cast(kArrayCompleteness | Nalu::H265_PPS)); + buffer.AppendInt(static_cast(1) /* numNalus */); + buffer.AppendInt(static_cast(last_pps_.size())); + buffer.AppendVector(last_pps_); + + // VPS + buffer.AppendInt(static_cast(kArrayCompleteness | Nalu::H265_VPS)); + buffer.AppendInt(static_cast(1) /* numNalus */); + buffer.AppendInt(static_cast(last_vps_.size())); + buffer.AppendVector(last_vps_); + + buffer.SwapBuffer(decoder_config); + return true; +} + +bool H265ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu) { + DCHECK(nalu.data()); + + // Skip the start code, but keep the 2-byte NALU header. + const uint8_t* nalu_ptr = nalu.data(); + const uint64_t nalu_size = nalu.payload_size() + nalu.header_size(); + + switch (nalu.type()) { + case Nalu::H265_SPS: + // Grab SPS NALU. + last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size); + return true; + case Nalu::H265_PPS: + // Grab PPS NALU. + last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size); + return true; + case Nalu::H265_VPS: + // Grab VPS NALU. + last_vps_.assign(nalu_ptr, nalu_ptr + nalu_size); + return true; + case Nalu::H265_AUD: + // Ignore AUD NALU. + return true; + default: + // Have the base class handle other NALU types. + return false; + } +} + +} // namespace media +} // namespace edash_packager diff --git a/packager/media/filters/h265_byte_to_unit_stream_converter.h b/packager/media/filters/h265_byte_to_unit_stream_converter.h new file mode 100644 index 0000000000..8aab2d595f --- /dev/null +++ b/packager/media/filters/h265_byte_to_unit_stream_converter.h @@ -0,0 +1,46 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef MEDIA_FILTERS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_ +#define MEDIA_FILTERS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_ + +#include +#include + +#include + +#include "packager/media/filters/h26x_byte_to_unit_stream_converter.h" + +namespace edash_packager { +namespace media { + +/// Class which converts H.265 byte streams (as specified in ISO/IEC 14496-10 +/// Annex B) into H.265 NAL unit streams (as specified in ISO/IEC 14496-15). +class H265ByteToUnitStreamConverter : public H26xByteToUnitStreamConverter { + public: + H265ByteToUnitStreamConverter(); + ~H265ByteToUnitStreamConverter() override; + + /// @name H26xByteToUnitStreamConverter implementation override. + /// @{ + bool GetDecoderConfigurationRecord( + std::vector* decoder_config) const override; + /// @} + + private: + bool ProcessNalu(const Nalu& nalu) override; + + std::vector last_sps_; + std::vector last_pps_; + std::vector last_vps_; + + DISALLOW_COPY_AND_ASSIGN(H265ByteToUnitStreamConverter); +}; + +} // namespace media +} // namespace edash_packager + +#endif // MEDIA_FILTERS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_ diff --git a/packager/media/filters/h265_byte_to_unit_stream_converter_unittest.cc b/packager/media/filters/h265_byte_to_unit_stream_converter_unittest.cc new file mode 100644 index 0000000000..a1fcd13f09 --- /dev/null +++ b/packager/media/filters/h265_byte_to_unit_stream_converter_unittest.cc @@ -0,0 +1,75 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include +#include + +#include "packager/base/strings/string_number_conversions.h" +#include "packager/media/filters/h265_byte_to_unit_stream_converter.h" +#include "packager/media/filters/hevc_decoder_configuration.h" +#include "packager/media/test/test_data_util.h" + +namespace { +const char kExpectedConfigRecord[] = + "01016000000300900000030000f000fcfdf8f800000303a10001002e42010101600000" + "030090000003000003005da0028080241f265999a4932bffc0d5c0d640400000030040" + "00000602a2000100074401c172b46240a00001001840010c01ffff0160000003009000" + "0003000003005d999809"; +} + +namespace edash_packager { +namespace media { + +TEST(H265ByteToUnitStreamConverter, ConversionSuccess) { + std::vector input_frame = + ReadTestDataFile("hevc-byte-stream-frame.h265"); + ASSERT_FALSE(input_frame.empty()); + + std::vector expected_output_frame = + ReadTestDataFile("hevc-unit-stream-frame.h265"); + ASSERT_FALSE(expected_output_frame.empty()); + + H265ByteToUnitStreamConverter converter; + std::vector output_frame; + ASSERT_TRUE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(), + input_frame.size(), + &output_frame)); + EXPECT_EQ(expected_output_frame, output_frame); + + std::vector expected_decoder_config; + ASSERT_TRUE(base::HexStringToBytes(kExpectedConfigRecord, + &expected_decoder_config)); + std::vector decoder_config; + ASSERT_TRUE(converter.GetDecoderConfigurationRecord(&decoder_config)); + EXPECT_EQ(expected_decoder_config, decoder_config); + + // Double-check that it can be parsed. + HEVCDecoderConfiguration conf; + ASSERT_TRUE(conf.Parse(decoder_config)); + // The order is SPS, PPS, VPS. + ASSERT_EQ(3u, conf.nalu_count()); + EXPECT_EQ(Nalu::H265_SPS, conf.nalu(0).type()); + EXPECT_EQ(Nalu::H265_PPS, conf.nalu(1).type()); + EXPECT_EQ(Nalu::H265_VPS, conf.nalu(2).type()); +} + +TEST(H265ByteToUnitStreamConverter, ConversionFailure) { + std::vector input_frame(100, 0); + + H265ByteToUnitStreamConverter converter; + std::vector output_frame; + EXPECT_FALSE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(), + 0, + &output_frame)); + EXPECT_FALSE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(), + input_frame.size(), + &output_frame)); + std::vector decoder_config; + EXPECT_FALSE(converter.GetDecoderConfigurationRecord(&decoder_config)); +} + +} // namespace media +} // namespace edash_packager diff --git a/packager/media/filters/h26x_byte_to_unit_stream_converter.cc b/packager/media/filters/h26x_byte_to_unit_stream_converter.cc new file mode 100644 index 0000000000..38c39db074 --- /dev/null +++ b/packager/media/filters/h26x_byte_to_unit_stream_converter.cc @@ -0,0 +1,62 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "packager/media/filters/h26x_byte_to_unit_stream_converter.h" + +#include + +#include "packager/base/logging.h" +#include "packager/media/base/buffer_writer.h" + +namespace edash_packager { +namespace media { + +namespace { +// Additional space to reserve for output frame. This value ought to be enough +// to acommodate frames consisting of 100 NAL units with 3-byte start codes. +const size_t kStreamConversionOverhead = 100; +} + +H26xByteToUnitStreamConverter::H26xByteToUnitStreamConverter( + NaluReader::CodecType type) + : type_(type) {} +H26xByteToUnitStreamConverter::~H26xByteToUnitStreamConverter() {} + +bool H26xByteToUnitStreamConverter::ConvertByteStreamToNalUnitStream( + const uint8_t* input_frame, + size_t input_frame_size, + std::vector* output_frame) { + DCHECK(input_frame); + DCHECK(output_frame); + + BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead); + + Nalu nalu; + NaluReader reader(type_, kIsAnnexbByteStream, input_frame, input_frame_size); + if (!reader.StartsWithStartCode()) { + LOG(ERROR) << "H.26x byte stream frame did not begin with start code."; + return false; + } + + while (reader.Advance(&nalu) == NaluReader::kOk) { + const uint64_t nalu_size = nalu.payload_size() + nalu.header_size(); + DCHECK_LE(nalu_size, std::numeric_limits::max()); + + if (ProcessNalu(nalu)) + continue; + + // Append 4-byte length and NAL unit data to the buffer. + output_buffer.AppendInt(static_cast(nalu_size)); + output_buffer.AppendArray(nalu.data(), nalu_size); + } + + output_buffer.SwapBuffer(output_frame); + return true; +} + +} // namespace media +} // namespace edash_packager + diff --git a/packager/media/filters/h26x_byte_to_unit_stream_converter.h b/packager/media/filters/h26x_byte_to_unit_stream_converter.h new file mode 100644 index 0000000000..3cbc0c6306 --- /dev/null +++ b/packager/media/filters/h26x_byte_to_unit_stream_converter.h @@ -0,0 +1,64 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef MEDIA_FILTERS_H26X_BYTE_TO_UNIT_STREAM_CONVERTER_H_ +#define MEDIA_FILTERS_H26X_BYTE_TO_UNIT_STREAM_CONVERTER_H_ + +#include + +#include + +#include "packager/media/filters/nalu_reader.h" + +namespace edash_packager { +namespace media { + +class BufferWriter; + +/// A base class that is used to convert H.26x byte streams to NAL unit streams. +class H26xByteToUnitStreamConverter { + public: + static const size_t kUnitStreamNaluLengthSize = 4; + + H26xByteToUnitStreamConverter(NaluReader::CodecType type); + virtual ~H26xByteToUnitStreamConverter(); + + /// Converts a whole byte stream encoded video frame to NAL unit stream + /// format. + /// @param input_frame is a buffer containing a whole H.26x frame in byte + /// stream format. + /// @param input_frame_size is the size of the H.26x frame, in bytes. + /// @param output_frame is a pointer to a vector which will receive the + /// converted frame. + /// @return true if successful, false otherwise. + bool ConvertByteStreamToNalUnitStream(const uint8_t* input_frame, + size_t input_frame_size, + std::vector* output_frame); + + /// Creates either an AVCDecoderConfigurationRecord or a + /// HEVCDecoderConfigurationRecord from the units extracted from the byte + /// stream. + /// @param decoder_config is a pointer to a vector, which on successful + /// return will contain the computed record. + /// @return true if successful, or false otherwise. + virtual bool GetDecoderConfigurationRecord( + std::vector* decoder_config) const = 0; + + private: + // Process the given Nalu. If this returns true, it was handled and should + // not be copied to the buffer. + virtual bool ProcessNalu(const Nalu& nalu) = 0; + + NaluReader::CodecType type_; + + DISALLOW_COPY_AND_ASSIGN(H26xByteToUnitStreamConverter); +}; + +} // namespace media +} // namespace edash_packager + +#endif // MEDIA_FILTERS_H26x_BYTE_TO_UNIT_STREAM_CONVERTER_H_ + diff --git a/packager/media/filters/nal_unit_to_byte_stream_converter.cc b/packager/media/filters/nal_unit_to_byte_stream_converter.cc index 355747373f..06009d5fbb 100644 --- a/packager/media/filters/nal_unit_to_byte_stream_converter.cc +++ b/packager/media/filters/nal_unit_to_byte_stream_converter.cc @@ -155,7 +155,7 @@ bool NalUnitToByteStreamConverter::ConvertUnitToByteStream( if (is_key_frame) buffer_writer.AppendVector(decoder_configuration_in_byte_stream_); - NaluReader nalu_reader(NaluReader::NaluType::kH264, nalu_length_size_, sample, + NaluReader nalu_reader(NaluReader::kH264, nalu_length_size_, sample, sample_size); Nalu nalu; NaluReader::Result result = nalu_reader.Advance(&nalu); diff --git a/packager/media/filters/nalu_reader.cc b/packager/media/filters/nalu_reader.cc index 5272cf44e7..bfb50f20ba 100644 --- a/packager/media/filters/nalu_reader.cc +++ b/packager/media/filters/nalu_reader.cc @@ -142,7 +142,7 @@ bool Nalu::InitializeFromH265(const uint8_t* data, uint64_t size) { return true; } -NaluReader::NaluReader(NaluType type, +NaluReader::NaluReader(CodecType type, uint8_t nal_length_size, const uint8_t* stream, uint64_t stream_size) diff --git a/packager/media/filters/nalu_reader.h b/packager/media/filters/nalu_reader.h index 9f526544f2..ac3b0ac001 100644 --- a/packager/media/filters/nalu_reader.h +++ b/packager/media/filters/nalu_reader.h @@ -125,7 +125,7 @@ class NaluReader { kInvalidStream, // error in stream kEOStream, // end of stream }; - enum NaluType { + enum CodecType { kH264, kH265, }; @@ -133,7 +133,7 @@ class NaluReader { /// @param nalu_length_size should be set to 0 for AnnexB byte streams; /// otherwise, it indicates the size of NAL unit length for the NAL /// unit stream. - NaluReader(NaluType type, + NaluReader(CodecType type, uint8_t nal_length_size, const uint8_t* stream, uint64_t stream_size); @@ -183,7 +183,7 @@ class NaluReader { // The remaining size of the stream. uint64_t stream_size_; // The type of NALU being read. - NaluType nalu_type_; + CodecType nalu_type_; // The number of bytes the prefix length is; only valid if format is // kAnnexbByteStreamFormat. uint8_t nalu_length_size_; diff --git a/packager/media/formats/mp2t/es_parser_h264.cc b/packager/media/formats/mp2t/es_parser_h264.cc index aae88d542f..c6d59c3fef 100644 --- a/packager/media/formats/mp2t/es_parser_h264.cc +++ b/packager/media/formats/mp2t/es_parser_h264.cc @@ -329,7 +329,7 @@ bool EsParserH264::EmitFrame(int64_t access_unit_pos, bool EsParserH264::UpdateVideoDecoderConfig(const H264Sps* sps) { std::vector decoder_config_record; - if (!stream_converter_->GetAVCDecoderConfigurationRecord( + if (!stream_converter_->GetDecoderConfigurationRecord( &decoder_config_record)) { DLOG(ERROR) << "Failure to construct an AVCDecoderConfigurationRecord"; return false; diff --git a/packager/media/formats/mp4/encrypting_fragmenter.cc b/packager/media/formats/mp4/encrypting_fragmenter.cc index 7de34f9f04..d28d08f205 100644 --- a/packager/media/formats/mp4/encrypting_fragmenter.cc +++ b/packager/media/formats/mp4/encrypting_fragmenter.cc @@ -238,7 +238,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr sample) { data += frame.frame_size; } } else { - const NaluReader::NaluType nalu_type = + const NaluReader::CodecType nalu_type = (video_codec_ == kCodecHVC1 || video_codec_ == kCodecHEV1) ? NaluReader::kH265 : NaluReader::kH264; diff --git a/packager/media/formats/wvm/wvm_media_parser.cc b/packager/media/formats/wvm/wvm_media_parser.cc index 32d9ea7aeb..2aa02e9dfb 100644 --- a/packager/media/formats/wvm/wvm_media_parser.cc +++ b/packager/media/formats/wvm/wvm_media_parser.cc @@ -827,7 +827,7 @@ bool WvmMediaParser::Output(bool output_encrypted_sample) { // Set extra data for video stream from AVC Decoder Config Record. // Also, set codec string from the AVC Decoder Config Record. std::vector decoder_config_record; - byte_to_unit_stream_converter_.GetAVCDecoderConfigurationRecord( + byte_to_unit_stream_converter_.GetDecoderConfigurationRecord( &decoder_config_record); for (uint32_t i = 0; i < stream_infos_.size(); i++) { if (stream_infos_[i]->stream_type() == media::kStreamVideo && diff --git a/packager/media/test/data/README b/packager/media/test/data/README index 007ae3fe60..682241bca9 100644 --- a/packager/media/test/data/README +++ b/packager/media/test/data/README @@ -87,3 +87,6 @@ bear_no_i_frame_start.h264 avc-byte-stream-frame.h264 - Single IDR frame extracted from test-25fps.h264 in Annex B byte stream format. avc-unit-stream-frame.h264 - Single IDR frame from avc-byte-stream-frame.h264 converted to unit stream format. + +hevc-byte-stream-frame.h265 - Several video frames with SPS/PPS/VPS manually extracted from an H.265 stream, in Annex B byte stream format. +hevc-byte-stream-frame.h265 - hevc-byte-stream-frame.h265 converted to unit stream format. diff --git a/packager/media/test/data/hevc-byte-stream-frame.h265 b/packager/media/test/data/hevc-byte-stream-frame.h265 new file mode 100644 index 0000000000..623ae99049 Binary files /dev/null and b/packager/media/test/data/hevc-byte-stream-frame.h265 differ diff --git a/packager/media/test/data/hevc-unit-stream-frame.h265 b/packager/media/test/data/hevc-unit-stream-frame.h265 new file mode 100644 index 0000000000..4be242ff8b Binary files /dev/null and b/packager/media/test/data/hevc-unit-stream-frame.h265 differ