OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chromecast/media/cma/decoder/cast_audio_decoder.h" | 5 #include "chromecast/media/cma/decoder/cast_audio_decoder.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <limits> | 8 #include <limits> |
9 #include <queue> | 9 #include <queue> |
10 #include <utility> | 10 #include <utility> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "chromecast/media/cma/base/decoder_buffer_adapter.h" | 18 #include "chromecast/media/cma/base/decoder_buffer_adapter.h" |
19 #include "chromecast/media/cma/base/decoder_buffer_base.h" | 19 #include "chromecast/media/cma/base/decoder_buffer_base.h" |
20 #include "chromecast/media/cma/base/decoder_config_adapter.h" | 20 #include "chromecast/media/cma/base/decoder_config_adapter.h" |
21 #include "media/base/audio_buffer.h" | 21 #include "media/base/audio_buffer.h" |
22 #include "media/base/audio_bus.h" | 22 #include "media/base/audio_bus.h" |
23 #include "media/base/cdm_context.h" | 23 #include "media/base/cdm_context.h" |
24 #include "media/base/channel_layout.h" | 24 #include "media/base/channel_layout.h" |
25 #include "media/base/channel_mixer.h" | 25 #include "media/base/channel_mixer.h" |
26 #include "media/base/decoder_buffer.h" | 26 #include "media/base/decoder_buffer.h" |
27 #include "media/base/sample_format.h" | 27 #include "media/base/sample_format.h" |
28 #include "media/filters/ffmpeg_audio_decoder.h" | 28 #include "media/filters/ffmpeg_audio_decoder.h" |
29 #include "media/filters/opus_audio_decoder.h" | |
30 | 29 |
31 namespace chromecast { | 30 namespace chromecast { |
32 namespace media { | 31 namespace media { |
33 | 32 |
34 namespace { | 33 namespace { |
35 | 34 |
36 const int kOpusSamplingRate = 48000; | |
37 const uint8_t kFakeOpusExtraData[19] = { | |
38 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd', // offset 0, OpusHead | |
39 0, // offset 8, version | |
40 2, // offset 9, channels | |
41 0, 0, // offset 10, skip | |
42 static_cast<uint8_t>(kOpusSamplingRate & 0xFF), // offset 12, LE | |
43 static_cast<uint8_t>((kOpusSamplingRate >> 8) & 0xFF), | |
44 static_cast<uint8_t>((kOpusSamplingRate >> 16) & 0xFF), | |
45 static_cast<uint8_t>((kOpusSamplingRate >> 24) & 0xFF), | |
46 0, 0, // offset 16, gain | |
47 0, // offset 18, stereo mapping | |
48 }; | |
49 | |
50 const int kOutputChannelCount = 2; // Always output stereo audio. | 35 const int kOutputChannelCount = 2; // Always output stereo audio. |
51 const int kMaxChannelInput = 2; | 36 const int kMaxChannelInput = 2; |
52 | 37 |
53 class CastAudioDecoderImpl : public CastAudioDecoder { | 38 class CastAudioDecoderImpl : public CastAudioDecoder { |
54 public: | 39 public: |
55 CastAudioDecoderImpl( | 40 CastAudioDecoderImpl( |
56 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 41 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
57 const InitializedCallback& initialized_callback, | 42 const InitializedCallback& initialized_callback, |
58 OutputFormat output_format) | 43 OutputFormat output_format) |
59 : task_runner_(task_runner), | 44 : task_runner_(task_runner), |
(...skipping 15 matching lines...) Expand all Loading... |
75 // the decoder will report kDecodeError when decoding. | 60 // the decoder will report kDecodeError when decoding. |
76 config_.encryption_scheme = Unencrypted(); | 61 config_.encryption_scheme = Unencrypted(); |
77 | 62 |
78 if (config_.channel_number == 1) { | 63 if (config_.channel_number == 1) { |
79 // If the input is mono, create a ChannelMixer to convert mono to stereo. | 64 // If the input is mono, create a ChannelMixer to convert mono to stereo. |
80 // TODO(kmackay) Support other channel format conversions? | 65 // TODO(kmackay) Support other channel format conversions? |
81 mixer_.reset(new ::media::ChannelMixer(::media::CHANNEL_LAYOUT_MONO, | 66 mixer_.reset(new ::media::ChannelMixer(::media::CHANNEL_LAYOUT_MONO, |
82 ::media::CHANNEL_LAYOUT_STEREO)); | 67 ::media::CHANNEL_LAYOUT_STEREO)); |
83 } | 68 } |
84 base::WeakPtr<CastAudioDecoderImpl> self = weak_factory_.GetWeakPtr(); | 69 base::WeakPtr<CastAudioDecoderImpl> self = weak_factory_.GetWeakPtr(); |
85 if (config.codec == media::kCodecOpus) { | 70 decoder_.reset(new ::media::FFmpegAudioDecoder( |
86 // Insert fake extradata to make OpusAudioDecoder work with v2mirroring. | 71 task_runner_, make_scoped_refptr(new ::media::MediaLog()))); |
87 if (config_.extra_data.empty() && | |
88 config_.samples_per_second == kOpusSamplingRate && | |
89 config_.channel_number == 2) | |
90 config_.extra_data.assign( | |
91 kFakeOpusExtraData, | |
92 kFakeOpusExtraData + sizeof(kFakeOpusExtraData)); | |
93 decoder_.reset(new ::media::OpusAudioDecoder(task_runner_)); | |
94 } else { | |
95 decoder_.reset(new ::media::FFmpegAudioDecoder( | |
96 task_runner_, make_scoped_refptr(new ::media::MediaLog()))); | |
97 } | |
98 decoder_->Initialize( | 72 decoder_->Initialize( |
99 media::DecoderConfigAdapter::ToMediaAudioDecoderConfig(config_), | 73 media::DecoderConfigAdapter::ToMediaAudioDecoderConfig(config_), |
100 nullptr, base::Bind(&CastAudioDecoderImpl::OnInitialized, self), | 74 nullptr, base::Bind(&CastAudioDecoderImpl::OnInitialized, self), |
101 base::Bind(&CastAudioDecoderImpl::OnDecoderOutput, self)); | 75 base::Bind(&CastAudioDecoderImpl::OnDecoderOutput, self)); |
102 // Unfortunately there is no result from decoder_->Initialize() until later | 76 // Unfortunately there is no result from decoder_->Initialize() until later |
103 // (the pipeline status callback is posted to the task runner). | 77 // (the pipeline status callback is posted to the task runner). |
104 } | 78 } |
105 | 79 |
106 // CastAudioDecoder implementation: | 80 // CastAudioDecoder implementation: |
107 bool Decode(const scoped_refptr<media::DecoderBufferBase>& data, | 81 bool Decode(const scoped_refptr<media::DecoderBufferBase>& data, |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 return 2; | 271 return 2; |
298 case CastAudioDecoder::OutputFormat::kOutputPlanarFloat: | 272 case CastAudioDecoder::OutputFormat::kOutputPlanarFloat: |
299 return 4; | 273 return 4; |
300 } | 274 } |
301 NOTREACHED(); | 275 NOTREACHED(); |
302 return 1; | 276 return 1; |
303 } | 277 } |
304 | 278 |
305 } // namespace media | 279 } // namespace media |
306 } // namespace chromecast | 280 } // namespace chromecast |
OLD | NEW |