Shaka Packager SDK
Loading...
Searching...
No Matches
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.
22ABSL_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
31namespace shaka {
32namespace media {
33
34namespace {
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.
37const 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
53H26xByteToUnitStreamConverter::~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
87void 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)
uint64_t header_size() const
The size of the header, e.g. 1 for H.264.
Definition nalu_reader.h:99
const uint8_t * data() const
This is the pointer to the Nalu data, pointing to the header.
Definition nalu_reader.h:96
uint64_t payload_size() const
Size of this Nalu minus header_size().
All the methods that are virtual are virtual for mocking.
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.