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

Side by Side Diff: media/filters/android/media_codec_audio_decoder.cc

Issue 2572573007: Use passthrough decoder for (E)AC3 formats (Closed)
Patch Set: Use BitReader to unpack header fileds Created 4 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/filters/android/media_codec_audio_decoder.h" 5 #include "media/filters/android/media_codec_audio_decoder.h"
6 6
7 #include <cmath>
8
7 #include "base/android/build_info.h" 9 #include "base/android/build_info.h"
8 #include "base/bind.h" 10 #include "base/bind.h"
9 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
10 #include "base/logging.h" 12 #include "base/logging.h"
11 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
12 #include "media/base/android/sdk_media_codec_bridge.h" 14 #include "media/base/android/sdk_media_codec_bridge.h"
13 #include "media/base/audio_buffer.h" 15 #include "media/base/audio_buffer.h"
14 #include "media/base/audio_timestamp_helper.h" 16 #include "media/base/audio_timestamp_helper.h"
15 #include "media/base/bind_to_current_loop.h" 17 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/timestamp_constants.h" 18 #include "media/base/timestamp_constants.h"
19 #include "media/formats/ac3/ac3_util.h"
17 20
18 namespace media { 21 namespace media {
19 22
20 MediaCodecAudioDecoder::MediaCodecAudioDecoder( 23 MediaCodecAudioDecoder::MediaCodecAudioDecoder(
21 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 24 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
22 : task_runner_(task_runner), 25 : task_runner_(task_runner),
23 state_(STATE_UNINITIALIZED), 26 state_(STATE_UNINITIALIZED),
27 is_passthrough_(false),
28 sample_format_(kSampleFormatS16),
24 channel_count_(0), 29 channel_count_(0),
25 channel_layout_(CHANNEL_LAYOUT_NONE), 30 channel_layout_(CHANNEL_LAYOUT_NONE),
26 sample_rate_(0), 31 sample_rate_(0),
27 media_drm_bridge_cdm_context_(nullptr), 32 media_drm_bridge_cdm_context_(nullptr),
28 cdm_registration_id_(0), 33 cdm_registration_id_(0),
29 weak_factory_(this) { 34 weak_factory_(this) {
30 DVLOG(1) << __func__; 35 DVLOG(1) << __func__;
31 } 36 }
32 37
33 MediaCodecAudioDecoder::~MediaCodecAudioDecoder() { 38 MediaCodecAudioDecoder::~MediaCodecAudioDecoder() {
(...skipping 19 matching lines...) Expand all
53 } 58 }
54 59
55 void MediaCodecAudioDecoder::Initialize(const AudioDecoderConfig& config, 60 void MediaCodecAudioDecoder::Initialize(const AudioDecoderConfig& config,
56 CdmContext* cdm_context, 61 CdmContext* cdm_context,
57 const InitCB& init_cb, 62 const InitCB& init_cb,
58 const OutputCB& output_cb) { 63 const OutputCB& output_cb) {
59 DVLOG(1) << __func__ << ": " << config.AsHumanReadableString(); 64 DVLOG(1) << __func__ << ": " << config.AsHumanReadableString();
60 DCHECK_EQ(state_, STATE_UNINITIALIZED); 65 DCHECK_EQ(state_, STATE_UNINITIALIZED);
61 66
62 InitCB bound_init_cb = BindToCurrentLoop(init_cb); 67 InitCB bound_init_cb = BindToCurrentLoop(init_cb);
68 sample_format_ = kSampleFormatS16;
69 is_passthrough_ = false;
70
71 if (config.codec() == kCodecAC3) {
chcunningham 2016/12/16 22:03:14 You make the is_passthrough_ decision in two place
AndyWu 2017/05/02 23:41:03 Done, thanks for your comment. On 2016/12/16 22:0
72 sample_format_ = kSampleFormatAc3;
73 is_passthrough_ = true;
74 } else if (config.codec() == kCodecEAC3) {
75 sample_format_ = kSampleFormatEac3;
76 is_passthrough_ = true;
77 }
78
79 // TODO(tsunghung): Add |is_passthrough_| in the following statement
80 // to enable passthrough decoder.
63 81
64 // We can support only the codecs that AudioCodecBridge can decode. 82 // We can support only the codecs that AudioCodecBridge can decode.
65 const bool is_codec_supported = config.codec() == kCodecVorbis || 83 const bool is_codec_supported = config.codec() == kCodecVorbis ||
66 config.codec() == kCodecAAC || 84 config.codec() == kCodecAAC ||
67 config.codec() == kCodecOpus; 85 config.codec() == kCodecOpus;
68 if (!is_codec_supported) { 86 if (!is_codec_supported) {
69 DVLOG(1) << "Unsuported codec " << GetCodecName(config.codec()); 87 DVLOG(1) << "Unsuported codec " << GetCodecName(config.codec());
70 bound_init_cb.Run(false); 88 bound_init_cb.Run(false);
71 return; 89 return;
72 } 90 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 DCHECK_NE(out.size, 0U); 364 DCHECK_NE(out.size, 0U);
347 DCHECK_NE(out.index, MediaCodecLoop::kInvalidBufferIndex); 365 DCHECK_NE(out.index, MediaCodecLoop::kInvalidBufferIndex);
348 DCHECK(codec_loop_); 366 DCHECK(codec_loop_);
349 MediaCodecBridge* media_codec = codec_loop_->GetCodec(); 367 MediaCodecBridge* media_codec = codec_loop_->GetCodec();
350 DCHECK(media_codec); 368 DCHECK(media_codec);
351 369
352 // For proper |frame_count| calculation we need to use the actual number 370 // For proper |frame_count| calculation we need to use the actual number
353 // of channels which can be different from |config_| value. 371 // of channels which can be different from |config_| value.
354 DCHECK_GT(channel_count_, 0); 372 DCHECK_GT(channel_count_, 0);
355 373
356 // Android MediaCodec can only output 16bit PCM audio. 374 size_t frame_count = 0;
357 const int bytes_per_frame = sizeof(uint16_t) * channel_count_; 375 scoped_refptr<AudioBuffer> audio_buffer;
358 const size_t frame_count = out.size / bytes_per_frame;
359 376
360 // Create AudioOutput buffer based on current parameters. 377 if (is_passthrough_) {
361 scoped_refptr<AudioBuffer> audio_buffer = 378 const uint8_t* data = nullptr;
362 AudioBuffer::CreateBuffer(kSampleFormatS16, channel_layout_, 379 size_t data_size;
363 channel_count_, sample_rate_, frame_count); 380 MediaCodecStatus status = media_codec->GetOutputBufferAddress(
381 out.index, out.offset, &data, &data_size);
382
383 if (status != MEDIA_CODEC_OK || !data) {
384 media_codec->ReleaseOutputBuffer(out.index, false);
385 return false;
386 }
387
388 if (config_.codec() == kCodecAC3) {
389 frame_count = Ac3Util::ParseTotalAc3SampleCount(data, data_size);
390 } else if (config_.codec() == kCodecEAC3) {
391 frame_count = Ac3Util::ParseTotalEac3SampleCount(data, data_size);
392 } else {
393 NOTREACHED() << "Unsupported passthrough format.";
394 }
395
396 // Create AudioOutput buffer based on current parameters.
397 audio_buffer = AudioBuffer::CreateBitstreamBuffer(
398 sample_format_, channel_layout_, channel_count_, sample_rate_,
399 frame_count, out.size);
400 } else {
401 // Android MediaCodec can only output 16bit PCM audio.
402 const int bytes_per_frame = sizeof(uint16_t) * channel_count_;
403 frame_count = out.size / bytes_per_frame;
404
405 // Create AudioOutput buffer based on current parameters.
406 audio_buffer =
407 AudioBuffer::CreateBuffer(sample_format_, channel_layout_,
408 channel_count_, sample_rate_, frame_count);
409 }
364 410
365 // Copy data into AudioBuffer. 411 // Copy data into AudioBuffer.
366 CHECK_LE(out.size, audio_buffer->data_size()); 412 CHECK_LE(out.size, audio_buffer->data_size());
367 413
368 MediaCodecStatus status = media_codec->CopyFromOutputBuffer( 414 MediaCodecStatus status = media_codec->CopyFromOutputBuffer(
369 out.index, out.offset, audio_buffer->channel_data()[0], out.size); 415 out.index, out.offset, audio_buffer->channel_data()[0], out.size);
370 416
371 // Release MediaCodec output buffer. 417 // Release MediaCodec output buffer.
372 media_codec->ReleaseOutputBuffer(out.index, false); 418 media_codec->ReleaseOutputBuffer(out.index, false);
373 419
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 RETURN_STRING(STATE_READY); 508 RETURN_STRING(STATE_READY);
463 RETURN_STRING(STATE_ERROR); 509 RETURN_STRING(STATE_ERROR);
464 } 510 }
465 NOTREACHED() << "Unknown state " << state; 511 NOTREACHED() << "Unknown state " << state;
466 return nullptr; 512 return nullptr;
467 } 513 }
468 514
469 #undef RETURN_STRING 515 #undef RETURN_STRING
470 516
471 } // namespace media 517 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698