Shaka Packager SDK
h26x_byte_to_unit_stream_converter.cc
1 // Copyright 2016 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include <packager/media/codecs/h26x_byte_to_unit_stream_converter.h>
8 
9 #include <limits>
10 
11 #include <absl/flags/flag.h>
12 #include <absl/log/check.h>
13 #include <absl/log/log.h>
14 #include <absl/strings/escaping.h>
15 
16 #include <packager/macros/logging.h>
17 #include <packager/media/base/buffer_writer.h>
18 #include <packager/utils/bytes_to_string_view.h>
19 
20 // TODO(kqyang): Move byte to unit stream convertion to muxer and make it a
21 // muxer option.
22 ABSL_FLAG(bool,
23  strip_parameter_set_nalus,
24  true,
25  "When converting from NAL byte stream (AnnexB stream) to NAL unit "
26  "stream, this flag determines whether to strip parameter sets NAL "
27  "units, i.e. SPS/PPS for H264 and SPS/PPS/VPS for H265, from the "
28  "frames. Note that avc1/hvc1 is generated if this flag is enabled; "
29  "otherwise avc3/hev1 is generated.");
30 
31 namespace shaka {
32 namespace media {
33 
34 namespace {
35 // Additional space to reserve for output frame. This value ought to be enough
36 // to acommodate frames consisting of 100 NAL units with 3-byte start codes.
37 const size_t kStreamConversionOverhead = 100;
38 } // namespace
39 
41  Nalu::CodecType type)
42  : type_(type),
43  stream_format_(
44  absl::GetFlag(FLAGS_strip_parameter_set_nalus)
45  ? H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus
46  : H26xStreamFormat::kNalUnitStreamWithParameterSetNalus) {}
47 
49  Nalu::CodecType type,
50  H26xStreamFormat stream_format)
51  : type_(type), stream_format_(stream_format) {}
52 
53 H26xByteToUnitStreamConverter::~H26xByteToUnitStreamConverter() {}
54 
56  const uint8_t* input_frame,
57  size_t input_frame_size,
58  std::vector<uint8_t>* output_frame) {
59  DCHECK(input_frame);
60  DCHECK(output_frame);
61 
62  BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
63 
64  Nalu nalu;
65  NaluReader reader(type_, kIsAnnexbByteStream, input_frame, input_frame_size);
66  if (!reader.StartsWithStartCode()) {
67  LOG(ERROR) << "H.26x byte stream frame did not begin with start code.";
68  return false;
69  }
70 
71  while (reader.Advance(&nalu) == NaluReader::kOk) {
72  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
73  DCHECK_LE(nalu_size, std::numeric_limits<uint32_t>::max());
74 
75  if (ProcessNalu(nalu))
76  continue;
77 
78  // Append 4-byte length and NAL unit data to the buffer.
79  output_buffer.AppendInt(static_cast<uint32_t>(nalu_size));
80  output_buffer.AppendArray(nalu.data(), nalu_size);
81  }
82 
83  output_buffer.SwapBuffer(output_frame);
84  return true;
85 }
86 
87 void H26xByteToUnitStreamConverter::WarnIfNotMatch(
88  int nalu_type,
89  const uint8_t* nalu_ptr,
90  size_t nalu_size,
91  const std::vector<uint8_t>& vector) {
92  if (vector.empty())
93  return;
94  if (vector.size() != nalu_size ||
95  memcmp(vector.data(), nalu_ptr, nalu_size) != 0) {
96  LOG(WARNING) << "Seeing varying NAL unit of type " << nalu_type
97  << ". You may need to set --strip_parameter_set_nalus=false "
98  "during packaging to generate a playable stream.";
99  VLOG(1) << "Old: "
100  << absl::BytesToHexString(byte_vector_to_string_view(vector));
101  VLOG(1) << "New: "
102  << absl::BytesToHexString(
103  byte_array_to_string_view(nalu_ptr, nalu_size));
104  }
105 }
106 
107 } // namespace media
108 } // namespace shaka
bool ConvertByteStreamToNalUnitStream(const uint8_t *input_frame, size_t input_frame_size, std::vector< uint8_t > *output_frame)
Result Advance(Nalu *nalu)
Definition: nalu_reader.cc:244
const uint8_t * data() const
This is the pointer to the Nalu data, pointing to the header.
Definition: nalu_reader.h:96
uint64_t header_size() const
The size of the header, e.g. 1 for H.264.
Definition: nalu_reader.h:99
uint64_t payload_size() const
Size of this Nalu minus header_size().
Definition: nalu_reader.h:101
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66
std::string_view byte_vector_to_string_view(const std::vector< uint8_t > &bytes)
Convert byte vector to string_view.
std::string_view byte_array_to_string_view(const uint8_t *bytes, size_t bytes_size)
Convert byte array to string_view.