| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h" | 5 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 | 134 |
| 135 FFmpegCdmAudioDecoder::FFmpegCdmAudioDecoder(ClearKeyCdmHost* host) | 135 FFmpegCdmAudioDecoder::FFmpegCdmAudioDecoder(ClearKeyCdmHost* host) |
| 136 : is_initialized_(false), | 136 : is_initialized_(false), |
| 137 host_(host), | 137 host_(host), |
| 138 samples_per_second_(0), | 138 samples_per_second_(0), |
| 139 channels_(0), | 139 channels_(0), |
| 140 av_sample_format_(0), | 140 av_sample_format_(0), |
| 141 bytes_per_frame_(0), | 141 bytes_per_frame_(0), |
| 142 last_input_timestamp_(kNoTimestamp()), | 142 last_input_timestamp_(kNoTimestamp), |
| 143 output_bytes_to_drop_(0) { | 143 output_bytes_to_drop_(0) {} |
| 144 } | |
| 145 | 144 |
| 146 FFmpegCdmAudioDecoder::~FFmpegCdmAudioDecoder() { | 145 FFmpegCdmAudioDecoder::~FFmpegCdmAudioDecoder() { |
| 147 ReleaseFFmpegResources(); | 146 ReleaseFFmpegResources(); |
| 148 } | 147 } |
| 149 | 148 |
| 150 bool FFmpegCdmAudioDecoder::Initialize(const cdm::AudioDecoderConfig& config) { | 149 bool FFmpegCdmAudioDecoder::Initialize(const cdm::AudioDecoderConfig& config) { |
| 151 DVLOG(1) << "Initialize()"; | 150 DVLOG(1) << "Initialize()"; |
| 152 if (!IsValidConfig(config)) { | 151 if (!IsValidConfig(config)) { |
| 153 LOG(ERROR) << "Initialize(): invalid audio decoder configuration."; | 152 LOG(ERROR) << "Initialize(): invalid audio decoder configuration."; |
| 154 return false; | 153 return false; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 int32_t compressed_buffer_size, | 225 int32_t compressed_buffer_size, |
| 227 int64_t input_timestamp, | 226 int64_t input_timestamp, |
| 228 cdm::AudioFrames* decoded_frames) { | 227 cdm::AudioFrames* decoded_frames) { |
| 229 DVLOG(1) << "DecodeBuffer()"; | 228 DVLOG(1) << "DecodeBuffer()"; |
| 230 const bool is_end_of_stream = !compressed_buffer; | 229 const bool is_end_of_stream = !compressed_buffer; |
| 231 base::TimeDelta timestamp = | 230 base::TimeDelta timestamp = |
| 232 base::TimeDelta::FromMicroseconds(input_timestamp); | 231 base::TimeDelta::FromMicroseconds(input_timestamp); |
| 233 | 232 |
| 234 bool is_vorbis = codec_context_->codec_id == AV_CODEC_ID_VORBIS; | 233 bool is_vorbis = codec_context_->codec_id == AV_CODEC_ID_VORBIS; |
| 235 if (!is_end_of_stream) { | 234 if (!is_end_of_stream) { |
| 236 if (last_input_timestamp_ == kNoTimestamp()) { | 235 if (last_input_timestamp_ == kNoTimestamp) { |
| 237 if (is_vorbis && timestamp < base::TimeDelta()) { | 236 if (is_vorbis && timestamp < base::TimeDelta()) { |
| 238 // Dropping frames for negative timestamps as outlined in section A.2 | 237 // Dropping frames for negative timestamps as outlined in section A.2 |
| 239 // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html | 238 // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html |
| 240 int frames_to_drop = floor( | 239 int frames_to_drop = floor( |
| 241 0.5 + -timestamp.InSecondsF() * samples_per_second_); | 240 0.5 + -timestamp.InSecondsF() * samples_per_second_); |
| 242 output_bytes_to_drop_ = bytes_per_frame_ * frames_to_drop; | 241 output_bytes_to_drop_ = bytes_per_frame_ * frames_to_drop; |
| 243 } else { | 242 } else { |
| 244 last_input_timestamp_ = timestamp; | 243 last_input_timestamp_ = timestamp; |
| 245 } | 244 } |
| 246 } else if (timestamp != kNoTimestamp()) { | 245 } else if (timestamp != kNoTimestamp) { |
| 247 if (timestamp < last_input_timestamp_) { | 246 if (timestamp < last_input_timestamp_) { |
| 248 base::TimeDelta diff = timestamp - last_input_timestamp_; | 247 base::TimeDelta diff = timestamp - last_input_timestamp_; |
| 249 DVLOG(1) << "Input timestamps are not monotonically increasing! " | 248 DVLOG(1) << "Input timestamps are not monotonically increasing! " |
| 250 << " ts " << timestamp.InMicroseconds() << " us" | 249 << " ts " << timestamp.InMicroseconds() << " us" |
| 251 << " diff " << diff.InMicroseconds() << " us"; | 250 << " diff " << diff.InMicroseconds() << " us"; |
| 252 return cdm::kDecodeError; | 251 return cdm::kDecodeError; |
| 253 } | 252 } |
| 254 | 253 |
| 255 last_input_timestamp_ = timestamp; | 254 last_input_timestamp_ = timestamp; |
| 256 } | 255 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 << compressed_buffer_size << " bytes"; | 291 << compressed_buffer_size << " bytes"; |
| 293 | 292 |
| 294 return cdm::kDecodeError; | 293 return cdm::kDecodeError; |
| 295 } | 294 } |
| 296 | 295 |
| 297 // Update packet size and data pointer in case we need to call the decoder | 296 // Update packet size and data pointer in case we need to call the decoder |
| 298 // with the remaining bytes from this packet. | 297 // with the remaining bytes from this packet. |
| 299 packet.size -= result; | 298 packet.size -= result; |
| 300 packet.data += result; | 299 packet.data += result; |
| 301 | 300 |
| 302 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() && | 301 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp && |
| 303 !is_end_of_stream) { | 302 !is_end_of_stream) { |
| 304 DCHECK(timestamp != kNoTimestamp()); | 303 DCHECK(timestamp != kNoTimestamp); |
| 305 if (output_bytes_to_drop_ > 0) { | 304 if (output_bytes_to_drop_ > 0) { |
| 306 // Currently Vorbis is the only codec that causes us to drop samples. | 305 // Currently Vorbis is the only codec that causes us to drop samples. |
| 307 // If we have to drop samples it always means the timeline starts at 0. | 306 // If we have to drop samples it always means the timeline starts at 0. |
| 308 DCHECK_EQ(codec_context_->codec_id, AV_CODEC_ID_VORBIS); | 307 DCHECK_EQ(codec_context_->codec_id, AV_CODEC_ID_VORBIS); |
| 309 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); | 308 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); |
| 310 } else { | 309 } else { |
| 311 output_timestamp_helper_->SetBaseTimestamp(timestamp); | 310 output_timestamp_helper_->SetBaseTimestamp(timestamp); |
| 312 } | 311 } |
| 313 } | 312 } |
| 314 | 313 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 decoded_frames->FrameBuffer()->SetSize(serialized_audio_frames_.size()); | 402 decoded_frames->FrameBuffer()->SetSize(serialized_audio_frames_.size()); |
| 404 serialized_audio_frames_.clear(); | 403 serialized_audio_frames_.clear(); |
| 405 | 404 |
| 406 return cdm::kSuccess; | 405 return cdm::kSuccess; |
| 407 } | 406 } |
| 408 | 407 |
| 409 return cdm::kNeedMoreData; | 408 return cdm::kNeedMoreData; |
| 410 } | 409 } |
| 411 | 410 |
| 412 void FFmpegCdmAudioDecoder::ResetTimestampState() { | 411 void FFmpegCdmAudioDecoder::ResetTimestampState() { |
| 413 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); | 412 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp); |
| 414 last_input_timestamp_ = kNoTimestamp(); | 413 last_input_timestamp_ = kNoTimestamp; |
| 415 output_bytes_to_drop_ = 0; | 414 output_bytes_to_drop_ = 0; |
| 416 } | 415 } |
| 417 | 416 |
| 418 void FFmpegCdmAudioDecoder::ReleaseFFmpegResources() { | 417 void FFmpegCdmAudioDecoder::ReleaseFFmpegResources() { |
| 419 DVLOG(1) << "ReleaseFFmpegResources()"; | 418 DVLOG(1) << "ReleaseFFmpegResources()"; |
| 420 | 419 |
| 421 codec_context_.reset(); | 420 codec_context_.reset(); |
| 422 av_frame_.reset(); | 421 av_frame_.reset(); |
| 423 } | 422 } |
| 424 | 423 |
| 425 void FFmpegCdmAudioDecoder::SerializeInt64(int64_t value) { | 424 void FFmpegCdmAudioDecoder::SerializeInt64(int64_t value) { |
| 426 const size_t previous_size = serialized_audio_frames_.size(); | 425 const size_t previous_size = serialized_audio_frames_.size(); |
| 427 serialized_audio_frames_.resize(previous_size + sizeof(value)); | 426 serialized_audio_frames_.resize(previous_size + sizeof(value)); |
| 428 memcpy(&serialized_audio_frames_[0] + previous_size, &value, sizeof(value)); | 427 memcpy(&serialized_audio_frames_[0] + previous_size, &value, sizeof(value)); |
| 429 } | 428 } |
| 430 | 429 |
| 431 } // namespace media | 430 } // namespace media |
| OLD | NEW |