DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
avc_decoder_configuration.cc
1 // Copyright 2015 Google Inc. 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/filters/avc_decoder_configuration.h"
8 
9 #include "packager/base/strings/string_number_conversions.h"
10 #include "packager/base/strings/string_util.h"
11 #include "packager/media/base/buffer_reader.h"
12 #include "packager/media/base/rcheck.h"
13 #include "packager/media/filters/h264_parser.h"
14 
15 namespace shaka {
16 namespace media {
17 
18 AVCDecoderConfiguration::AVCDecoderConfiguration()
19  : version_(0),
20  profile_indication_(0),
21  profile_compatibility_(0),
22  avc_level_(0) {}
23 
24 AVCDecoderConfiguration::~AVCDecoderConfiguration() {}
25 
26 bool AVCDecoderConfiguration::ParseInternal() {
27  // See ISO 14496-15 sec 5.3.3.1.2
28  BufferReader reader(data(), data_size());
29 
30  RCHECK(reader.Read1(&version_) && version_ == 1 &&
31  reader.Read1(&profile_indication_) &&
32  reader.Read1(&profile_compatibility_) && reader.Read1(&avc_level_));
33 
34  uint8_t length_size_minus_one;
35  RCHECK(reader.Read1(&length_size_minus_one));
36  if ((length_size_minus_one & 0x3) == 2) {
37  LOG(ERROR) << "Invalid NALU length size.";
38  return false;
39  }
40  set_nalu_length_size((length_size_minus_one & 0x3) + 1);
41 
42  uint8_t num_sps;
43  RCHECK(reader.Read1(&num_sps));
44  num_sps &= 0x1f;
45  if (num_sps < 1) {
46  LOG(ERROR) << "No SPS found.";
47  return false;
48  }
49 
50  for (uint8_t i = 0; i < num_sps; i++) {
51  uint16_t size = 0;
52  RCHECK(reader.Read2(&size));
53  const uint8_t* nalu_data = reader.data() + reader.pos();
54  RCHECK(reader.SkipBytes(size));
55 
56  Nalu nalu;
57  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
58  RCHECK(nalu.type() == Nalu::H264_SPS);
59  AddNalu(nalu);
60 
61  if (i == 0) {
62  // It is unlikely to have more than one SPS in practice. Also there's
63  // no way to change the {coded,pixel}_{width,height} dynamically from
64  // VideoStreamInfo.
65  int sps_id = 0;
66  H264Parser parser;
67  RCHECK(parser.ParseSps(nalu, &sps_id) == H264Parser::kOk);
68  RCHECK(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width_,
69  &coded_height_, &pixel_width_,
70  &pixel_height_));
71  }
72  }
73 
74  uint8_t pps_count;
75  RCHECK(reader.Read1(&pps_count));
76  for (uint8_t i = 0; i < pps_count; i++) {
77  uint16_t size = 0;
78  RCHECK(reader.Read2(&size));
79  const uint8_t* nalu_data = reader.data() + reader.pos();
80  RCHECK(reader.SkipBytes(size));
81 
82  Nalu nalu;
83  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
84  RCHECK(nalu.type() == Nalu::H264_PPS);
85  AddNalu(nalu);
86  }
87 
88  return true;
89 }
90 
92  return GetCodecString(profile_indication_, profile_compatibility_,
93  avc_level_);
94 }
95 
97  uint8_t profile_indication,
98  uint8_t profile_compatibility,
99  uint8_t avc_level) {
100  const uint8_t bytes[] = {profile_indication, profile_compatibility,
101  avc_level};
102  return "avc1." +
103  base::StringToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
104 }
105 
106 } // namespace media
107 } // namespace shaka
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
void set_nalu_length_size(uint8_t nalu_length_size)
Sets the size of the NAL unit length field.
const Nalu & nalu(size_t i) const