• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "media/formats/webm/webm_audio_client.h"
6 
7 #include "media/base/audio_decoder_config.h"
8 #include "media/base/channel_layout.h"
9 #include "media/formats/webm/webm_constants.h"
10 
11 namespace media {
12 
WebMAudioClient(const LogCB & log_cb)13 WebMAudioClient::WebMAudioClient(const LogCB& log_cb)
14     : log_cb_(log_cb) {
15   Reset();
16 }
17 
~WebMAudioClient()18 WebMAudioClient::~WebMAudioClient() {
19 }
20 
Reset()21 void WebMAudioClient::Reset() {
22   channels_ = -1;
23   samples_per_second_ = -1;
24   output_samples_per_second_ = -1;
25 }
26 
InitializeConfig(const std::string & codec_id,const std::vector<uint8> & codec_private,int64 seek_preroll,int64 codec_delay,bool is_encrypted,AudioDecoderConfig * config)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;
33 
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(log_cb_) << "Unsupported audio codec_id " << codec_id;
41     return false;
42   }
43 
44   if (samples_per_second_ <= 0)
45     return false;
46 
47   // Set channel layout default if a Channels element was not present.
48   if (channels_ == -1)
49     channels_ = 1;
50 
51   ChannelLayout channel_layout =  GuessChannelLayout(channels_);
52 
53   if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) {
54     MEDIA_LOG(log_cb_) << "Unsupported channel count " << channels_;
55     return false;
56   }
57 
58   int samples_per_second = samples_per_second_;
59   if (output_samples_per_second_ > 0)
60     samples_per_second = output_samples_per_second_;
61 
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;
67   }
68 
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();
74   }
75 
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);
83   }
84 
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();
98 }
99 
OnUInt(int id,int64 val)100 bool WebMAudioClient::OnUInt(int id, int64 val) {
101   if (id == kWebMIdChannels) {
102     if (channels_ != -1) {
103       MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
104                          << " specified. (" << channels_ << " and " << val
105                          << ")";
106       return false;
107     }
108 
109     channels_ = val;
110   }
111   return true;
112 }
113 
OnFloat(int id,double val)114 bool WebMAudioClient::OnFloat(int id, double val) {
115   double* dst = NULL;
116 
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;
126   }
127 
128   if (val <= 0)
129     return false;
130 
131   if (*dst != -1) {
132     MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
133                        << " specified (" << *dst << " and " << val << ")";
134     return false;
135   }
136 
137   *dst = val;
138   return true;
139 }
140 
141 }  // namespace media
142