| OLD | NEW |
| 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 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 buffer->insert(buffer->end(), temp.begin() + pos, | 100 buffer->insert(buffer->end(), temp.begin() + pos, |
| 101 temp.begin() + pos + nal_length); | 101 temp.begin() + pos + nal_length); |
| 102 pos += nal_length; | 102 pos += nal_length; |
| 103 } | 103 } |
| 104 return pos == temp.size(); | 104 return pos == temp.size(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 // static | 107 // static |
| 108 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config, | 108 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config, |
| 109 std::vector<uint8_t>* buffer, | 109 std::vector<uint8_t>* buffer, |
| 110 std::vector<SubsampleEntry>* subsamples) { | 110 std::vector<SubsampleEntry>* subsamples, |
| 111 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); | 111 bool annexb_validation) { |
| 112 if (annexb_validation) |
| 113 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); |
| 112 | 114 |
| 113 std::unique_ptr<H264Parser> parser(new H264Parser()); | 115 std::unique_ptr<H264Parser> parser(new H264Parser()); |
| 114 const uint8_t* start = &(*buffer)[0]; | 116 const uint8_t* start = &(*buffer)[0]; |
| 115 parser->SetEncryptedStream(start, buffer->size(), *subsamples); | 117 parser->SetEncryptedStream(start, buffer->size(), *subsamples); |
| 116 | 118 |
| 117 H264NALU nalu; | 119 H264NALU nalu; |
| 118 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk) | 120 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk) |
| 119 return false; | 121 return false; |
| 120 | 122 |
| 121 std::vector<uint8_t>::iterator config_insert_point = buffer->begin(); | 123 std::vector<uint8_t>::iterator config_insert_point = buffer->begin(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 136 if (subsamples && !subsamples->empty()) { | 138 if (subsamples && !subsamples->empty()) { |
| 137 int subsample_index = FindSubsampleIndex(*buffer, subsamples, | 139 int subsample_index = FindSubsampleIndex(*buffer, subsamples, |
| 138 &(*config_insert_point)); | 140 &(*config_insert_point)); |
| 139 // Update the size of the subsample where SPS/PPS is to be inserted. | 141 // Update the size of the subsample where SPS/PPS is to be inserted. |
| 140 (*subsamples)[subsample_index].clear_bytes += param_sets.size(); | 142 (*subsamples)[subsample_index].clear_bytes += param_sets.size(); |
| 141 } | 143 } |
| 142 | 144 |
| 143 buffer->insert(config_insert_point, | 145 buffer->insert(config_insert_point, |
| 144 param_sets.begin(), param_sets.end()); | 146 param_sets.begin(), param_sets.end()); |
| 145 | 147 |
| 146 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); | 148 if (annexb_validation) |
| 149 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); |
| 147 return true; | 150 return true; |
| 148 } | 151 } |
| 149 | 152 |
| 150 // static | 153 // static |
| 151 bool AVC::ConvertConfigToAnnexB(const AVCDecoderConfigurationRecord& avc_config, | 154 bool AVC::ConvertConfigToAnnexB(const AVCDecoderConfigurationRecord& avc_config, |
| 152 std::vector<uint8_t>* buffer) { | 155 std::vector<uint8_t>* buffer) { |
| 153 DCHECK(buffer->empty()); | 156 DCHECK(buffer->empty()); |
| 154 buffer->clear(); | 157 buffer->clear(); |
| 155 int total_size = 0; | 158 int total_size = 0; |
| 156 for (size_t i = 0; i < avc_config.sps_list.size(); i++) | 159 for (size_t i = 0; i < avc_config.sps_list.size(); i++) |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 case H264Parser::kEOStream: | 312 case H264Parser::kEOStream: |
| 310 done = true; | 313 done = true; |
| 311 } | 314 } |
| 312 } | 315 } |
| 313 | 316 |
| 314 return order_state >= kAfterFirstVCL; | 317 return order_state >= kAfterFirstVCL; |
| 315 } | 318 } |
| 316 | 319 |
| 317 AVCBitstreamConverter::AVCBitstreamConverter( | 320 AVCBitstreamConverter::AVCBitstreamConverter( |
| 318 std::unique_ptr<AVCDecoderConfigurationRecord> avc_config) | 321 std::unique_ptr<AVCDecoderConfigurationRecord> avc_config) |
| 319 : avc_config_(std::move(avc_config)) { | 322 : avc_config_(std::move(avc_config)), post_annexb_validation_(true) { |
| 320 DCHECK(avc_config_); | 323 DCHECK(avc_config_); |
| 321 } | 324 } |
| 322 | 325 |
| 323 AVCBitstreamConverter::~AVCBitstreamConverter() { | 326 AVCBitstreamConverter::~AVCBitstreamConverter() { |
| 324 } | 327 } |
| 325 | 328 |
| 326 bool AVCBitstreamConverter::ConvertFrame( | 329 bool AVCBitstreamConverter::ConvertFrame( |
| 327 std::vector<uint8_t>* frame_buf, | 330 std::vector<uint8_t>* frame_buf, |
| 328 bool is_keyframe, | 331 bool is_keyframe, |
| 329 std::vector<SubsampleEntry>* subsamples) const { | 332 std::vector<SubsampleEntry>* subsamples) const { |
| 330 // Convert the AVC NALU length fields to Annex B headers, as expected by | 333 // Convert the AVC NALU length fields to Annex B headers, as expected by |
| 331 // decoding libraries. Since this may enlarge the size of the buffer, we also | 334 // decoding libraries. Since this may enlarge the size of the buffer, we also |
| 332 // update the clear byte count for each subsample if encryption is used to | 335 // update the clear byte count for each subsample if encryption is used to |
| 333 // account for the difference in size between the length prefix and Annex B | 336 // account for the difference in size between the length prefix and Annex B |
| 334 // start code. | 337 // start code. |
| 335 RCHECK(AVC::ConvertFrameToAnnexB(avc_config_->length_size, frame_buf, | 338 RCHECK(AVC::ConvertFrameToAnnexB(avc_config_->length_size, frame_buf, |
| 336 subsamples)); | 339 subsamples)); |
| 337 | 340 |
| 338 if (is_keyframe) { | 341 if (is_keyframe) { |
| 339 // If this is a keyframe, we (re-)inject SPS and PPS headers at the start of | 342 // If this is a keyframe, we (re-)inject SPS and PPS headers at the start of |
| 340 // a frame. If subsample info is present, we also update the clear byte | 343 // a frame. If subsample info is present, we also update the clear byte |
| 341 // count for that first subsample. | 344 // count for that first subsample. |
| 342 RCHECK(AVC::InsertParamSetsAnnexB(*avc_config_, frame_buf, subsamples)); | 345 RCHECK(AVC::InsertParamSetsAnnexB(*avc_config_, frame_buf, subsamples, |
| 346 post_annexb_validation_)); |
| 343 } | 347 } |
| 344 | 348 |
| 345 DCHECK(AVC::IsValidAnnexB(*frame_buf, *subsamples)); | 349 DCHECK(AVC::IsValidAnnexB(*frame_buf, *subsamples)); |
| 346 return true; | 350 return true; |
| 347 } | 351 } |
| 348 | 352 |
| 349 } // namespace mp4 | 353 } // namespace mp4 |
| 350 } // namespace media | 354 } // namespace media |
| OLD | NEW |