summaryrefslogtreecommitdiff
path: root/chromium/media/base/audio_decoder_config.h
blob: 2f53e231bdc6d094c05448dfa2457ac85599acfe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_BASE_AUDIO_DECODER_CONFIG_H_
#define MEDIA_BASE_AUDIO_DECODER_CONFIG_H_

#include <stdint.h>

#include <string>
#include <vector>

#include "base/time/time.h"
#include "media/base/audio_codecs.h"
#include "media/base/channel_layout.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_export.h"
#include "media/base/sample_format.h"

namespace media {

// TODO(dalecurtis): FFmpeg API uses |bytes_per_channel| instead of
// |bits_per_channel|, we should switch over since bits are generally confusing
// to work with.
class MEDIA_EXPORT AudioDecoderConfig {
 public:
  // Constructs an uninitialized object. Clients should call Initialize() with
  // appropriate values before using.
  AudioDecoderConfig();

  // Constructs an initialized object.
  AudioDecoderConfig(AudioCodec codec,
                     SampleFormat sample_format,
                     ChannelLayout channel_layout,
                     int samples_per_second,
                     const std::vector<uint8_t>& extra_data,
                     EncryptionScheme encryption_scheme);

  AudioDecoderConfig(const AudioDecoderConfig& other);

  ~AudioDecoderConfig();

  // Resets the internal state of this object. |codec_delay| is in frames.
  void Initialize(AudioCodec codec,
                  SampleFormat sample_format,
                  ChannelLayout channel_layout,
                  int samples_per_second,
                  const std::vector<uint8_t>& extra_data,
                  EncryptionScheme encryption_scheme,
                  base::TimeDelta seek_preroll,
                  int codec_delay);

  // Returns true if this object has appropriate configuration values, false
  // otherwise.
  bool IsValidConfig() const;

  // Returns true if all fields in |config| match this config.
  // Note: The contents of |extra_data_| are compared not the raw pointers.
  bool Matches(const AudioDecoderConfig& config) const;

  // Returns a human-readable string describing |*this|.
  std::string AsHumanReadableString() const;

  // Sets the number of channels if |channel_layout_| is CHANNEL_LAYOUT_DISCRETE
  void SetChannelsForDiscrete(int channels);

  AudioCodec codec() const { return codec_; }
  int bits_per_channel() const { return bytes_per_channel_ * 8; }
  int bytes_per_channel() const { return bytes_per_channel_; }
  ChannelLayout channel_layout() const { return channel_layout_; }
  int channels() const { return channels_; }
  int samples_per_second() const { return samples_per_second_; }
  SampleFormat sample_format() const { return sample_format_; }
  int bytes_per_frame() const { return bytes_per_frame_; }
  base::TimeDelta seek_preroll() const { return seek_preroll_; }
  int codec_delay() const { return codec_delay_; }

  // Optional byte data required to initialize audio decoders such as Vorbis
  // codebooks or AAC AudioSpecificConfig.
  const std::vector<uint8_t>& extra_data() const { return extra_data_; }

  // Whether the audio stream is potentially encrypted.
  // Note that in a potentially encrypted audio stream, individual buffers
  // can be encrypted or not encrypted.
  bool is_encrypted() const {
    return encryption_scheme_ != EncryptionScheme::kUnencrypted;
  }

  // Encryption scheme used for encrypted buffers.
  EncryptionScheme encryption_scheme() const { return encryption_scheme_; }

  // Sets the config to be encrypted or not encrypted manually. This can be
  // useful for decryptors that decrypts an encrypted stream to a clear stream.
  void SetIsEncrypted(bool is_encrypted);

  // Optionally set if the AudioCodec has a profile which may preclude certain
  // decoders from having support.
  void set_profile(AudioCodecProfile profile) { profile_ = profile; }
  AudioCodecProfile profile() const { return profile_; }

  bool should_discard_decoder_delay() const {
    return should_discard_decoder_delay_;
  }
  void disable_discard_decoder_delay() {
    should_discard_decoder_delay_ = false;
  }

  // Optionally set by renderer to provide hardware layout when playback
  // starts. Intentionally not part of IsValid(). Layout is not updated for
  // device changes - use with care!
  void set_target_output_channel_layout(ChannelLayout output_layout) {
    target_output_channel_layout_ = output_layout;
  }
  ChannelLayout target_output_channel_layout() const {
    return target_output_channel_layout_;
  }

  // Optionally set by renderer to signal desired bitstream-passthru format.
  void set_target_output_sample_format(SampleFormat sample_format) {
    target_output_sample_format_ = sample_format;
  }
  SampleFormat target_output_sample_format() const {
    return target_output_sample_format_;
  }

  void set_aac_extra_data(std::vector<uint8_t> aac_extra_data) {
    aac_extra_data_ = std::move(aac_extra_data);
  }
  const std::vector<uint8_t>& aac_extra_data() const { return aac_extra_data_; }

 private:
  // WARNING: When modifying or adding any parameters, update the following:
  // - AudioDecoderConfig::AsHumanReadableString()
  // - AudioDecoderConfig::Matches()
  // - media::mojom::AudioDecoderConfig
  // - audio_decoder_config_mojom_traits.{h|cc}
  // - audio_decoder_config_mojom_traits_unittest.cc

  // Mandatory parameters passed in constructor:

  AudioCodec codec_ = AudioCodec::kUnknown;
  SampleFormat sample_format_ = kUnknownSampleFormat;
  ChannelLayout channel_layout_ = CHANNEL_LAYOUT_UNSUPPORTED;
  int samples_per_second_ = 0;
  std::vector<uint8_t> extra_data_;
  EncryptionScheme encryption_scheme_ = EncryptionScheme::kUnencrypted;

  // The duration of data that the decoder must decode before the decoded data
  // is valid.
  base::TimeDelta seek_preroll_;

  // The number of frames the decoder should discard before returning decoded
  // data. Can include both decoder delay and padding added during encoding.
  int codec_delay_ = 0;

  // Optional parameters that can be set later:

  AudioCodecProfile profile_ = AudioCodecProfile::kUnknown;

  // Layout of the output hardware. Optionally set. See setter comments.
  ChannelLayout target_output_channel_layout_ = CHANNEL_LAYOUT_NONE;

  // Desired output format of bitstream. Optionally set. See setter comments.
  SampleFormat target_output_sample_format_ = kUnknownSampleFormat;

  // This is a hack for backward compatibility. For AAC, to preserve existing
  // behavior, we set `aac_extra_data_` on all platforms but only set
  // `extra_data` on Android.
  // TODO(crbug.com/1250841): Remove this after we land a long term fix.
  std::vector<uint8_t> aac_extra_data_;

  // Indicates if a decoder should implicitly discard decoder delay without it
  // being explicitly marked in discard padding.
  bool should_discard_decoder_delay_ = true;

  // Derived values from mandatory and optional parameters above:

  int bytes_per_channel_ = 0;
  int bytes_per_frame_ = 0;

  // Count of channels. By default derived from `channel_layout_`, but can also
  // be manually set in `SetChannelsForDiscrete()`;
  int channels_ = 0;

  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
  // generated copy constructor and assignment operator. Since the extra data is
  // typically small, the performance impact is minimal.
};

}  // namespace media

#endif  // MEDIA_BASE_AUDIO_DECODER_CONFIG_H_