Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: media/formats/mp4/avc.cc

Issue 1534273002: Switch to standard integer types in media/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/formats/mp4/avc.h" 5 #include "media/formats/mp4/avc.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/decrypt_config.h" 10 #include "media/base/decrypt_config.h"
11 #include "media/filters/h264_parser.h" 11 #include "media/filters/h264_parser.h"
12 #include "media/formats/mp4/box_definitions.h" 12 #include "media/formats/mp4/box_definitions.h"
13 #include "media/formats/mp4/box_reader.h" 13 #include "media/formats/mp4/box_reader.h"
14 14
15 namespace media { 15 namespace media {
16 namespace mp4 { 16 namespace mp4 {
17 17
18 static const uint8 kAnnexBStartCode[] = {0, 0, 0, 1}; 18 static const uint8_t kAnnexBStartCode[] = {0, 0, 0, 1};
19 static const int kAnnexBStartCodeSize = 4; 19 static const int kAnnexBStartCodeSize = 4;
20 20
21 static bool ConvertAVCToAnnexBInPlaceForLengthSize4(std::vector<uint8>* buf) { 21 static bool ConvertAVCToAnnexBInPlaceForLengthSize4(std::vector<uint8_t>* buf) {
22 const int kLengthSize = 4; 22 const int kLengthSize = 4;
23 size_t pos = 0; 23 size_t pos = 0;
24 while (pos + kLengthSize < buf->size()) { 24 while (pos + kLengthSize < buf->size()) {
25 uint32 nal_length = (*buf)[pos]; 25 uint32_t nal_length = (*buf)[pos];
26 nal_length = (nal_length << 8) + (*buf)[pos+1]; 26 nal_length = (nal_length << 8) + (*buf)[pos+1];
27 nal_length = (nal_length << 8) + (*buf)[pos+2]; 27 nal_length = (nal_length << 8) + (*buf)[pos+2];
28 nal_length = (nal_length << 8) + (*buf)[pos+3]; 28 nal_length = (nal_length << 8) + (*buf)[pos+3];
29 29
30 if (nal_length == 0) { 30 if (nal_length == 0) {
31 DVLOG(1) << "nal_length is 0"; 31 DVLOG(1) << "nal_length is 0";
32 return false; 32 return false;
33 } 33 }
34 34
35 std::copy(kAnnexBStartCode, kAnnexBStartCode + kAnnexBStartCodeSize, 35 std::copy(kAnnexBStartCode, kAnnexBStartCode + kAnnexBStartCodeSize,
36 buf->begin() + pos); 36 buf->begin() + pos);
37 pos += kLengthSize + nal_length; 37 pos += kLengthSize + nal_length;
38 } 38 }
39 return pos == buf->size(); 39 return pos == buf->size();
40 } 40 }
41 41
42 // static 42 // static
43 int AVC::FindSubsampleIndex(const std::vector<uint8>& buffer, 43 int AVC::FindSubsampleIndex(const std::vector<uint8_t>& buffer,
44 const std::vector<SubsampleEntry>* subsamples, 44 const std::vector<SubsampleEntry>* subsamples,
45 const uint8* ptr) { 45 const uint8_t* ptr) {
46 DCHECK(ptr >= &buffer[0]); 46 DCHECK(ptr >= &buffer[0]);
47 DCHECK(ptr <= &buffer[buffer.size()-1]); 47 DCHECK(ptr <= &buffer[buffer.size()-1]);
48 if (!subsamples || subsamples->empty()) 48 if (!subsamples || subsamples->empty())
49 return 0; 49 return 0;
50 50
51 const uint8* p = &buffer[0]; 51 const uint8_t* p = &buffer[0];
52 for (size_t i = 0; i < subsamples->size(); ++i) { 52 for (size_t i = 0; i < subsamples->size(); ++i) {
53 p += (*subsamples)[i].clear_bytes + (*subsamples)[i].cypher_bytes; 53 p += (*subsamples)[i].clear_bytes + (*subsamples)[i].cypher_bytes;
54 if (p > ptr) 54 if (p > ptr)
55 return i; 55 return i;
56 } 56 }
57 NOTREACHED(); 57 NOTREACHED();
58 return 0; 58 return 0;
59 } 59 }
60 60
61 // static 61 // static
62 bool AVC::ConvertFrameToAnnexB(int length_size, std::vector<uint8>* buffer, 62 bool AVC::ConvertFrameToAnnexB(int length_size,
63 std::vector<uint8_t>* buffer,
63 std::vector<SubsampleEntry>* subsamples) { 64 std::vector<SubsampleEntry>* subsamples) {
64 RCHECK(length_size == 1 || length_size == 2 || length_size == 4); 65 RCHECK(length_size == 1 || length_size == 2 || length_size == 4);
65 66
66 if (length_size == 4) 67 if (length_size == 4)
67 return ConvertAVCToAnnexBInPlaceForLengthSize4(buffer); 68 return ConvertAVCToAnnexBInPlaceForLengthSize4(buffer);
68 69
69 std::vector<uint8> temp; 70 std::vector<uint8_t> temp;
70 temp.swap(*buffer); 71 temp.swap(*buffer);
71 buffer->reserve(temp.size() + 32); 72 buffer->reserve(temp.size() + 32);
72 73
73 size_t pos = 0; 74 size_t pos = 0;
74 while (pos + length_size < temp.size()) { 75 while (pos + length_size < temp.size()) {
75 int nal_length = temp[pos]; 76 int nal_length = temp[pos];
76 if (length_size == 2) nal_length = (nal_length << 8) + temp[pos+1]; 77 if (length_size == 2) nal_length = (nal_length << 8) + temp[pos+1];
77 pos += length_size; 78 pos += length_size;
78 79
79 if (nal_length == 0) { 80 if (nal_length == 0) {
80 DVLOG(1) << "nal_length is 0"; 81 DVLOG(1) << "nal_length is 0";
81 return false; 82 return false;
82 } 83 }
83 84
84 RCHECK(pos + nal_length <= temp.size()); 85 RCHECK(pos + nal_length <= temp.size());
85 buffer->insert(buffer->end(), kAnnexBStartCode, 86 buffer->insert(buffer->end(), kAnnexBStartCode,
86 kAnnexBStartCode + kAnnexBStartCodeSize); 87 kAnnexBStartCode + kAnnexBStartCodeSize);
87 if (subsamples && !subsamples->empty()) { 88 if (subsamples && !subsamples->empty()) {
88 uint8* buffer_pos = &(*(buffer->end() - kAnnexBStartCodeSize)); 89 uint8_t* buffer_pos = &(*(buffer->end() - kAnnexBStartCodeSize));
89 int subsample_index = FindSubsampleIndex(*buffer, subsamples, buffer_pos); 90 int subsample_index = FindSubsampleIndex(*buffer, subsamples, buffer_pos);
90 // We've replaced NALU size value with an AnnexB start code. 91 // We've replaced NALU size value with an AnnexB start code.
91 int size_adjustment = kAnnexBStartCodeSize - length_size; 92 int size_adjustment = kAnnexBStartCodeSize - length_size;
92 (*subsamples)[subsample_index].clear_bytes += size_adjustment; 93 (*subsamples)[subsample_index].clear_bytes += size_adjustment;
93 } 94 }
94 buffer->insert(buffer->end(), temp.begin() + pos, 95 buffer->insert(buffer->end(), temp.begin() + pos,
95 temp.begin() + pos + nal_length); 96 temp.begin() + pos + nal_length);
96 pos += nal_length; 97 pos += nal_length;
97 } 98 }
98 return pos == temp.size(); 99 return pos == temp.size();
99 } 100 }
100 101
101 // static 102 // static
102 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config, 103 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config,
103 std::vector<uint8>* buffer, 104 std::vector<uint8_t>* buffer,
104 std::vector<SubsampleEntry>* subsamples) { 105 std::vector<SubsampleEntry>* subsamples) {
105 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); 106 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples));
106 107
107 scoped_ptr<H264Parser> parser(new H264Parser()); 108 scoped_ptr<H264Parser> parser(new H264Parser());
108 const uint8* start = &(*buffer)[0]; 109 const uint8_t* start = &(*buffer)[0];
109 parser->SetEncryptedStream(start, buffer->size(), *subsamples); 110 parser->SetEncryptedStream(start, buffer->size(), *subsamples);
110 111
111 H264NALU nalu; 112 H264NALU nalu;
112 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk) 113 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk)
113 return false; 114 return false;
114 115
115 std::vector<uint8>::iterator config_insert_point = buffer->begin(); 116 std::vector<uint8_t>::iterator config_insert_point = buffer->begin();
116 117
117 if (nalu.nal_unit_type == H264NALU::kAUD) { 118 if (nalu.nal_unit_type == H264NALU::kAUD) {
118 // Move insert point to just after the AUD. 119 // Move insert point to just after the AUD.
119 config_insert_point += (nalu.data + nalu.size) - start; 120 config_insert_point += (nalu.data + nalu.size) - start;
120 } 121 }
121 122
122 // Clear |parser| and |start| since they aren't needed anymore and 123 // Clear |parser| and |start| since they aren't needed anymore and
123 // will hold stale pointers once the insert happens. 124 // will hold stale pointers once the insert happens.
124 parser.reset(); 125 parser.reset();
125 start = NULL; 126 start = NULL;
126 127
127 std::vector<uint8> param_sets; 128 std::vector<uint8_t> param_sets;
128 RCHECK(AVC::ConvertConfigToAnnexB(avc_config, &param_sets)); 129 RCHECK(AVC::ConvertConfigToAnnexB(avc_config, &param_sets));
129 130
130 if (subsamples && !subsamples->empty()) { 131 if (subsamples && !subsamples->empty()) {
131 int subsample_index = FindSubsampleIndex(*buffer, subsamples, 132 int subsample_index = FindSubsampleIndex(*buffer, subsamples,
132 &(*config_insert_point)); 133 &(*config_insert_point));
133 // Update the size of the subsample where SPS/PPS is to be inserted. 134 // Update the size of the subsample where SPS/PPS is to be inserted.
134 (*subsamples)[subsample_index].clear_bytes += param_sets.size(); 135 (*subsamples)[subsample_index].clear_bytes += param_sets.size();
135 } 136 }
136 137
137 buffer->insert(config_insert_point, 138 buffer->insert(config_insert_point,
138 param_sets.begin(), param_sets.end()); 139 param_sets.begin(), param_sets.end());
139 140
140 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); 141 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples));
141 return true; 142 return true;
142 } 143 }
143 144
144 // static 145 // static
145 bool AVC::ConvertConfigToAnnexB( 146 bool AVC::ConvertConfigToAnnexB(const AVCDecoderConfigurationRecord& avc_config,
146 const AVCDecoderConfigurationRecord& avc_config, 147 std::vector<uint8_t>* buffer) {
147 std::vector<uint8>* buffer) {
148 DCHECK(buffer->empty()); 148 DCHECK(buffer->empty());
149 buffer->clear(); 149 buffer->clear();
150 int total_size = 0; 150 int total_size = 0;
151 for (size_t i = 0; i < avc_config.sps_list.size(); i++) 151 for (size_t i = 0; i < avc_config.sps_list.size(); i++)
152 total_size += avc_config.sps_list[i].size() + kAnnexBStartCodeSize; 152 total_size += avc_config.sps_list[i].size() + kAnnexBStartCodeSize;
153 for (size_t i = 0; i < avc_config.pps_list.size(); i++) 153 for (size_t i = 0; i < avc_config.pps_list.size(); i++)
154 total_size += avc_config.pps_list[i].size() + kAnnexBStartCodeSize; 154 total_size += avc_config.pps_list[i].size() + kAnnexBStartCodeSize;
155 buffer->reserve(total_size); 155 buffer->reserve(total_size);
156 156
157 for (size_t i = 0; i < avc_config.sps_list.size(); i++) { 157 for (size_t i = 0; i < avc_config.sps_list.size(); i++) {
158 buffer->insert(buffer->end(), kAnnexBStartCode, 158 buffer->insert(buffer->end(), kAnnexBStartCode,
159 kAnnexBStartCode + kAnnexBStartCodeSize); 159 kAnnexBStartCode + kAnnexBStartCodeSize);
160 buffer->insert(buffer->end(), avc_config.sps_list[i].begin(), 160 buffer->insert(buffer->end(), avc_config.sps_list[i].begin(),
161 avc_config.sps_list[i].end()); 161 avc_config.sps_list[i].end());
162 } 162 }
163 163
164 for (size_t i = 0; i < avc_config.pps_list.size(); i++) { 164 for (size_t i = 0; i < avc_config.pps_list.size(); i++) {
165 buffer->insert(buffer->end(), kAnnexBStartCode, 165 buffer->insert(buffer->end(), kAnnexBStartCode,
166 kAnnexBStartCode + kAnnexBStartCodeSize); 166 kAnnexBStartCode + kAnnexBStartCodeSize);
167 buffer->insert(buffer->end(), avc_config.pps_list[i].begin(), 167 buffer->insert(buffer->end(), avc_config.pps_list[i].begin(),
168 avc_config.pps_list[i].end()); 168 avc_config.pps_list[i].end());
169 } 169 }
170 return true; 170 return true;
171 } 171 }
172 172
173 // Verifies AnnexB NALU order according to ISO/IEC 14496-10 Section 7.4.1.2.3 173 // Verifies AnnexB NALU order according to ISO/IEC 14496-10 Section 7.4.1.2.3
174 bool AVC::IsValidAnnexB(const std::vector<uint8>& buffer, 174 bool AVC::IsValidAnnexB(const std::vector<uint8_t>& buffer,
175 const std::vector<SubsampleEntry>& subsamples) { 175 const std::vector<SubsampleEntry>& subsamples) {
176 return IsValidAnnexB(&buffer[0], buffer.size(), subsamples); 176 return IsValidAnnexB(&buffer[0], buffer.size(), subsamples);
177 } 177 }
178 178
179 bool AVC::IsValidAnnexB(const uint8* buffer, size_t size, 179 bool AVC::IsValidAnnexB(const uint8_t* buffer,
180 size_t size,
180 const std::vector<SubsampleEntry>& subsamples) { 181 const std::vector<SubsampleEntry>& subsamples) {
181 DVLOG(1) << __FUNCTION__; 182 DVLOG(1) << __FUNCTION__;
182 DCHECK(buffer); 183 DCHECK(buffer);
183 184
184 if (size == 0) 185 if (size == 0)
185 return true; 186 return true;
186 187
187 H264Parser parser; 188 H264Parser parser;
188 parser.SetEncryptedStream(buffer, size, subsamples); 189 parser.SetEncryptedStream(buffer, size, subsamples);
189 190
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 AVCBitstreamConverter::AVCBitstreamConverter( 312 AVCBitstreamConverter::AVCBitstreamConverter(
312 scoped_ptr<AVCDecoderConfigurationRecord> avc_config) 313 scoped_ptr<AVCDecoderConfigurationRecord> avc_config)
313 : avc_config_(avc_config.Pass()) { 314 : avc_config_(avc_config.Pass()) {
314 DCHECK(avc_config_); 315 DCHECK(avc_config_);
315 } 316 }
316 317
317 AVCBitstreamConverter::~AVCBitstreamConverter() { 318 AVCBitstreamConverter::~AVCBitstreamConverter() {
318 } 319 }
319 320
320 bool AVCBitstreamConverter::ConvertFrame( 321 bool AVCBitstreamConverter::ConvertFrame(
321 std::vector<uint8>* frame_buf, 322 std::vector<uint8_t>* frame_buf,
322 bool is_keyframe, 323 bool is_keyframe,
323 std::vector<SubsampleEntry>* subsamples) const { 324 std::vector<SubsampleEntry>* subsamples) const {
324 // Convert the AVC NALU length fields to Annex B headers, as expected by 325 // Convert the AVC NALU length fields to Annex B headers, as expected by
325 // decoding libraries. Since this may enlarge the size of the buffer, we also 326 // decoding libraries. Since this may enlarge the size of the buffer, we also
326 // update the clear byte count for each subsample if encryption is used to 327 // update the clear byte count for each subsample if encryption is used to
327 // account for the difference in size between the length prefix and Annex B 328 // account for the difference in size between the length prefix and Annex B
328 // start code. 329 // start code.
329 RCHECK(AVC::ConvertFrameToAnnexB(avc_config_->length_size, frame_buf, 330 RCHECK(AVC::ConvertFrameToAnnexB(avc_config_->length_size, frame_buf,
330 subsamples)); 331 subsamples));
331 332
332 if (is_keyframe) { 333 if (is_keyframe) {
333 // If this is a keyframe, we (re-)inject SPS and PPS headers at the start of 334 // If this is a keyframe, we (re-)inject SPS and PPS headers at the start of
334 // a frame. If subsample info is present, we also update the clear byte 335 // a frame. If subsample info is present, we also update the clear byte
335 // count for that first subsample. 336 // count for that first subsample.
336 RCHECK(AVC::InsertParamSetsAnnexB(*avc_config_, frame_buf, subsamples)); 337 RCHECK(AVC::InsertParamSetsAnnexB(*avc_config_, frame_buf, subsamples));
337 } 338 }
338 339
339 DCHECK(AVC::IsValidAnnexB(*frame_buf, *subsamples)); 340 DCHECK(AVC::IsValidAnnexB(*frame_buf, *subsamples));
340 return true; 341 return true;
341 } 342 }
342 343
343 } // namespace mp4 344 } // namespace mp4
344 } // namespace media 345 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698