• Home
  • 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 
33   AudioCodec audio_codec = kUnknownAudioCodec;
34   if (codec_id == "A_VORBIS") {
35     audio_codec = kCodecVorbis;
36   } else if (codec_id == "A_OPUS") {
37     audio_codec = kCodecOpus;
38   } else {
39     MEDIA_LOG(log_cb_) << "Unsupported audio codec_id " << codec_id;
40     return false;
41   }
42 
43   if (samples_per_second_ <= 0)
44     return false;
45 
46   // Set channel layout default if a Channels element was not present.
47   if (channels_ == -1)
48     channels_ = 1;
49 
50   ChannelLayout channel_layout =  GuessChannelLayout(channels_);
51 
52   if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) {
53     MEDIA_LOG(log_cb_) << "Unsupported channel count " << channels_;
54     return false;
55   }
56 
57   int samples_per_second = samples_per_second_;
58   if (output_samples_per_second_ > 0)
59     samples_per_second = output_samples_per_second_;
60 
61   const uint8* extra_data = NULL;
62   size_t extra_data_size = 0;
63   if (codec_private.size() > 0) {
64     extra_data = &codec_private[0];
65     extra_data_size = codec_private.size();
66   }
67 
68   // Convert |codec_delay| from nanoseconds into frames.
69   int codec_delay_in_frames = 0;
70   if (codec_delay != -1) {
71     codec_delay_in_frames =
72         0.5 +
73         samples_per_second * (static_cast<double>(codec_delay) /
74                               base::Time::kNanosecondsPerSecond);
75   }
76 
77   config->Initialize(
78       audio_codec,
79       (audio_codec == kCodecOpus) ? kSampleFormatS16 : kSampleFormatPlanarF32,
80       channel_layout,
81       samples_per_second,
82       extra_data,
83       extra_data_size,
84       is_encrypted,
85       true,
86       base::TimeDelta::FromMicroseconds(
87           (seek_preroll != -1 ? seek_preroll : 0) / 1000),
88       codec_delay_in_frames);
89   return config->IsValidConfig();
90 }
91 
OnUInt(int id,int64 val)92 bool WebMAudioClient::OnUInt(int id, int64 val) {
93   if (id == kWebMIdChannels) {
94     if (channels_ != -1) {
95       MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
96                          << " specified. (" << channels_ << " and " << val
97                          << ")";
98       return false;
99     }
100 
101     channels_ = val;
102   }
103   return true;
104 }
105 
OnFloat(int id,double val)106 bool WebMAudioClient::OnFloat(int id, double val) {
107   double* dst = NULL;
108 
109   switch (id) {
110     case kWebMIdSamplingFrequency:
111       dst = &samples_per_second_;
112       break;
113     case kWebMIdOutputSamplingFrequency:
114       dst = &output_samples_per_second_;
115       break;
116     default:
117       return true;
118   }
119 
120   if (val <= 0)
121     return false;
122 
123   if (*dst != -1) {
124     MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
125                        << " specified (" << *dst << " and " << val << ")";
126     return false;
127   }
128 
129   *dst = val;
130   return true;
131 }
132 
133 }  // namespace media
134