Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / formats / webm / webm_audio_client.cc
blobbde7233254243312ac928ae431e77a98d337abf2
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
3 // found in the LICENSE file.
5 #include "media/formats/webm/webm_audio_client.h"
7 #include "media/base/audio_decoder_config.h"
8 #include "media/base/channel_layout.h"
9 #include "media/formats/webm/webm_constants.h"
11 namespace media {
13 WebMAudioClient::WebMAudioClient(const scoped_refptr<MediaLog>& media_log)
14 : media_log_(media_log) {
15 Reset();
18 WebMAudioClient::~WebMAudioClient() {
21 void WebMAudioClient::Reset() {
22 channels_ = -1;
23 samples_per_second_ = -1;
24 output_samples_per_second_ = -1;
27 bool WebMAudioClient::InitializeConfig(
28 const std::string& codec_id, const std::vector<uint8>& codec_private,
29 int64 seek_preroll, int64 codec_delay, bool is_encrypted,
30 AudioDecoderConfig* config) {
31 DCHECK(config);
32 SampleFormat sample_format = kSampleFormatPlanarF32;
34 AudioCodec audio_codec = kUnknownAudioCodec;
35 if (codec_id == "A_VORBIS") {
36 audio_codec = kCodecVorbis;
37 } else if (codec_id == "A_OPUS") {
38 audio_codec = kCodecOpus;
39 } else {
40 MEDIA_LOG(ERROR, media_log_) << "Unsupported audio codec_id " << codec_id;
41 return false;
44 if (samples_per_second_ <= 0)
45 return false;
47 // Set channel layout default if a Channels element was not present.
48 if (channels_ == -1)
49 channels_ = 1;
51 ChannelLayout channel_layout = GuessChannelLayout(channels_);
53 if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) {
54 MEDIA_LOG(ERROR, media_log_) << "Unsupported channel count " << channels_;
55 return false;
58 int samples_per_second = samples_per_second_;
59 if (output_samples_per_second_ > 0)
60 samples_per_second = output_samples_per_second_;
62 // Always use 48kHz for OPUS. See the "Input Sample Rate" section of the
63 // spec: http://tools.ietf.org/html/draft-terriberry-oggopus-01#page-11
64 if (audio_codec == kCodecOpus) {
65 samples_per_second = 48000;
66 sample_format = kSampleFormatF32;
69 const uint8* extra_data = NULL;
70 size_t extra_data_size = 0;
71 if (codec_private.size() > 0) {
72 extra_data = &codec_private[0];
73 extra_data_size = codec_private.size();
76 // Convert |codec_delay| from nanoseconds into frames.
77 int codec_delay_in_frames = 0;
78 if (codec_delay != -1) {
79 codec_delay_in_frames =
80 0.5 +
81 samples_per_second * (static_cast<double>(codec_delay) /
82 base::Time::kNanosecondsPerSecond);
85 config->Initialize(
86 audio_codec,
87 sample_format,
88 channel_layout,
89 samples_per_second,
90 extra_data,
91 extra_data_size,
92 is_encrypted,
93 base::TimeDelta::FromMicroseconds(
94 (seek_preroll != -1 ? seek_preroll : 0) / 1000),
95 codec_delay_in_frames);
96 return config->IsValidConfig();
99 bool WebMAudioClient::OnUInt(int id, int64 val) {
100 if (id == kWebMIdChannels) {
101 if (channels_ != -1) {
102 MEDIA_LOG(ERROR, media_log_) << "Multiple values for id " << std::hex
103 << id << " specified. (" << channels_
104 << " and " << val << ")";
105 return false;
108 channels_ = val;
110 return true;
113 bool WebMAudioClient::OnFloat(int id, double val) {
114 double* dst = NULL;
116 switch (id) {
117 case kWebMIdSamplingFrequency:
118 dst = &samples_per_second_;
119 break;
120 case kWebMIdOutputSamplingFrequency:
121 dst = &output_samples_per_second_;
122 break;
123 default:
124 return true;
127 if (val <= 0)
128 return false;
130 if (*dst != -1) {
131 MEDIA_LOG(ERROR, media_log_) << "Multiple values for id " << std::hex << id
132 << " specified (" << *dst << " and " << val
133 << ")";
134 return false;
137 *dst = val;
138 return true;
141 } // namespace media