Roll ANGLE e754fb8..6ffeb74
[chromium-blink-merge.git] / media / formats / webm / webm_audio_client.cc
blobea911ec290e8f3a3d28501c4916aefeb7912e6ac
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 LogCB& log_cb)
14 : log_cb_(log_cb) {
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, log_cb_) << "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, log_cb_) << "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 true,
94 base::TimeDelta::FromMicroseconds(
95 (seek_preroll != -1 ? seek_preroll : 0) / 1000),
96 codec_delay_in_frames);
97 return config->IsValidConfig();
100 bool WebMAudioClient::OnUInt(int id, int64 val) {
101 if (id == kWebMIdChannels) {
102 if (channels_ != -1) {
103 MEDIA_LOG(ERROR, log_cb_) << "Multiple values for id " << std::hex << id
104 << " specified. (" << channels_ << " and "
105 << val << ")";
106 return false;
109 channels_ = val;
111 return true;
114 bool WebMAudioClient::OnFloat(int id, double val) {
115 double* dst = NULL;
117 switch (id) {
118 case kWebMIdSamplingFrequency:
119 dst = &samples_per_second_;
120 break;
121 case kWebMIdOutputSamplingFrequency:
122 dst = &output_samples_per_second_;
123 break;
124 default:
125 return true;
128 if (val <= 0)
129 return false;
131 if (*dst != -1) {
132 MEDIA_LOG(ERROR, log_cb_) << "Multiple values for id " << std::hex << id
133 << " specified (" << *dst << " and " << val
134 << ")";
135 return false;
138 *dst = val;
139 return true;
142 } // namespace media