1// Copyright (c) 2013 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/webm/webm_audio_client.h"
6
7#include "media/base/audio_decoder_config.h"
8#include "media/base/channel_layout.h"
9#include "media/webm/webm_constants.h"
10
11namespace media {
12
13WebMAudioClient::WebMAudioClient(const LogCB& log_cb)
14    : log_cb_(log_cb) {
15  Reset();
16}
17
18WebMAudioClient::~WebMAudioClient() {
19}
20
21void WebMAudioClient::Reset() {
22  channels_ = -1;
23  samples_per_second_ = -1;
24  output_samples_per_second_ = -1;
25}
26
27bool WebMAudioClient::InitializeConfig(
28    const std::string& codec_id, const std::vector<uint8>& codec_private,
29    bool is_encrypted, AudioDecoderConfig* config) {
30  DCHECK(config);
31
32  AudioCodec audio_codec = kUnknownAudioCodec;
33  if (codec_id == "A_VORBIS") {
34    audio_codec = kCodecVorbis;
35  } else {
36    MEDIA_LOG(log_cb_) << "Unsupported audio codec_id " << codec_id;
37    return false;
38  }
39
40  if (samples_per_second_ <= 0)
41    return false;
42
43  // Set channel layout default if a Channels element was not present.
44  if (channels_ == -1)
45    channels_ = 1;
46
47  ChannelLayout channel_layout =  GuessChannelLayout(channels_);
48
49  if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) {
50    MEDIA_LOG(log_cb_) << "Unsupported channel count " << channels_;
51    return false;
52  }
53
54  int samples_per_second = samples_per_second_;
55  if (output_samples_per_second_ > 0)
56    samples_per_second = output_samples_per_second_;
57
58  const uint8* extra_data = NULL;
59  size_t extra_data_size = 0;
60  if (codec_private.size() > 0) {
61    extra_data = &codec_private[0];
62    extra_data_size = codec_private.size();
63  }
64
65  config->Initialize(
66      audio_codec, kSampleFormatPlanarF32, channel_layout,
67      samples_per_second, extra_data, extra_data_size, is_encrypted, true);
68  return config->IsValidConfig();
69}
70
71bool WebMAudioClient::OnUInt(int id, int64 val) {
72  if (id == kWebMIdChannels) {
73    if (channels_ != -1) {
74      MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
75                         << " specified. (" << channels_ << " and " << val
76                         << ")";
77      return false;
78    }
79
80    channels_ = val;
81  }
82  return true;
83}
84
85bool WebMAudioClient::OnFloat(int id, double val) {
86  double* dst = NULL;
87
88  switch (id) {
89    case kWebMIdSamplingFrequency:
90      dst = &samples_per_second_;
91      break;
92    case kWebMIdOutputSamplingFrequency:
93      dst = &output_samples_per_second_;
94      break;
95    default:
96      return true;
97  }
98
99  if (val <= 0)
100    return false;
101
102  if (*dst != -1) {
103    MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
104                       << " specified (" << *dst << " and " << val << ")";
105    return false;
106  }
107
108  *dst = val;
109  return true;
110}
111
112}  // namespace media
113