#ifndef MEDIA_BASE_AUDIO_PARAMETERS_H_
#define MEDIA_BASE_AUDIO_PARAMETERS_H_
#include <stdint.h>
#include <optional>
#include <string>
#include <vector>
#include "base/atomicops.h"
#include "base/compiler_specific.h"
#include "base/numerics/checked_math.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/audio_latency.h"
#include "media/base/audio_point.h"
#include "media/base/channel_layout.h"
#include "media/base/media_shmem_export.h"
#include "media/base/sample_format.h"
namespace media {
#if BUILDFLAG(IS_WIN)
#pragma warning(push)
#pragma warning(disable : 4324)
#endif
constexpr int kParametersAlignment = 16;
struct MEDIA_SHMEM_EXPORT alignas(kParametersAlignment)
AudioInputBufferParameters {
double volume;
int64_t capture_time_us;
int64_t glitch_duration_us;
uint32_t glitch_count;
uint32_t size;
uint32_t id;
base::subtle::Atomic32 has_unread_data;
};
struct MEDIA_SHMEM_EXPORT alignas(kParametersAlignment)
AudioOutputBufferParameters {
int64_t delay_us;
int64_t delay_timestamp_us;
int64_t glitch_duration_us;
uint32_t glitch_count;
uint32_t bitstream_data_size;
uint32_t bitstream_frames;
};
#if BUILDFLAG(IS_WIN)
#pragma warning(pop)
#endif
struct MEDIA_SHMEM_EXPORT AudioInputBuffer {
AudioInputBufferParameters params;
int8_t audio[1];
};
struct MEDIA_SHMEM_EXPORT AudioOutputBuffer {
AudioOutputBufferParameters params;
int8_t audio[1];
};
struct MEDIA_SHMEM_EXPORT AudioRendererAlgorithmParameters {
base::TimeDelta max_capacity;
base::TimeDelta starting_capacity;
base::TimeDelta starting_capacity_for_encrypted;
};
class AudioParameters;
MEDIA_SHMEM_EXPORT base::CheckedNumeric<uint32_t>
ComputeAudioInputBufferSizeChecked(const AudioParameters& parameters,
uint32_t audio_bus_count);
MEDIA_SHMEM_EXPORT uint32_t
ComputeAudioInputBufferSize(const AudioParameters& parameters,
uint32_t audio_bus_count);
MEDIA_SHMEM_EXPORT uint32_t
ComputeAudioInputBufferSize(int channels, int frames, uint32_t audio_bus_count);
MEDIA_SHMEM_EXPORT base::CheckedNumeric<uint32_t>
ComputeAudioOutputBufferSizeChecked(const AudioParameters& parameters);
MEDIA_SHMEM_EXPORT uint32_t
ComputeAudioOutputBufferSize(const AudioParameters& parameters);
MEDIA_SHMEM_EXPORT uint32_t ComputeAudioOutputBufferSize(int channels,
int frames);
class MEDIA_SHMEM_EXPORT ChannelLayoutConfig {
public:
ChannelLayoutConfig(const ChannelLayoutConfig& other);
ChannelLayoutConfig& operator=(const ChannelLayoutConfig& other);
ChannelLayoutConfig();
ChannelLayoutConfig(ChannelLayout channel_layout, int channels);
~ChannelLayoutConfig();
template <ChannelLayout layout>
static ChannelLayoutConfig FromLayout() {
return ChannelLayoutConfig(layout, ChannelLayoutToChannelCount(layout));
}
static ChannelLayoutConfig Mono();
static ChannelLayoutConfig Stereo();
static ChannelLayoutConfig Guess(int channels);
ChannelLayout channel_layout() const { return channel_layout_; }
int channels() const { return channels_; }
private:
ChannelLayout channel_layout_;
int channels_;
};
template <>
ChannelLayoutConfig ChannelLayoutConfig::FromLayout<CHANNEL_LAYOUT_DISCRETE>() =
delete;
class MEDIA_SHMEM_EXPORT AudioParameters {
public:
enum Format {
AUDIO_FAKE = 0x000,
AUDIO_PCM_LINEAR = 0x001,
AUDIO_PCM_LOW_LATENCY = 0x002,
AUDIO_BITSTREAM_AC3 = 0x004,
AUDIO_BITSTREAM_EAC3 = 0x008,
AUDIO_BITSTREAM_DTS = 0x010,
AUDIO_BITSTREAM_DTS_HD = 0x020,
AUDIO_BITSTREAM_DTSX_P2 = 0x040,
AUDIO_BITSTREAM_IEC61937 = 0x080,
AUDIO_BITSTREAM_DTS_HD_MA =
0x100,
AUDIO_FORMAT_LAST =
AUDIO_BITSTREAM_DTS_HD_MA,
};
enum {
kTelephoneSampleRate = 8000,
kAudioCDSampleRate = 44100,
};
enum {
kMaxFramesPerCompressedAudioBuffer = 4096,
};
enum PlatformEffectsMask {
NO_EFFECTS = 0x0,
ECHO_CANCELLER = 1 << 0,
DUCKING = 1 << 1,
HOTWORD = 1 << 3,
NOISE_SUPPRESSION = 1 << 4,
AUTOMATIC_GAIN_CONTROL = 1 << 5,
MULTIZONE = 1 << 7,
AUDIO_PREFETCH = 1 << 8,
ALLOW_DSP_ECHO_CANCELLER = 1 << 9,
ALLOW_DSP_NOISE_SUPPRESSION = 1 << 10,
ALLOW_DSP_AUTOMATIC_GAIN_CONTROL = 1 << 11,
FUCHSIA_RENDER_USAGE_BACKGROUND = 1 << 12,
FUCHSIA_RENDER_USAGE_MEDIA = 1 << 13,
FUCHSIA_RENDER_USAGE_INTERRUPTION = 1 << 14,
FUCHSIA_RENDER_USAGE_SYSTEM_AGENT = 1 << 15,
FUCHSIA_RENDER_USAGE_COMMUNICATION = 1 << 16,
IGNORE_UI_GAINS = 1 << 17,
VOICE_ISOLATION_SUPPORTED = 1 << 18,
CLIENT_CONTROLLED_VOICE_ISOLATION =
1 << 19,
VOICE_ISOLATION = 1 << 20,
DEEP_NOISE_SUPPRESSION = 1 << 21,
};
struct HardwareCapabilities {
HardwareCapabilities(int min_frames_per_buffer,
int max_frames_per_buffer,
int default_frames_per_buffer,
bool require_offload)
: min_frames_per_buffer(min_frames_per_buffer),
max_frames_per_buffer(max_frames_per_buffer),
default_frames_per_buffer(default_frames_per_buffer),
require_audio_offload(require_offload) {}
HardwareCapabilities(int min_frames_per_buffer, int max_frames_per_buffer)
: min_frames_per_buffer(min_frames_per_buffer),
max_frames_per_buffer(max_frames_per_buffer) {}
HardwareCapabilities(int bitstream_formats, bool require_encapsulation)
: bitstream_formats(bitstream_formats),
require_encapsulation(require_encapsulation) {}
HardwareCapabilities() = default;
int min_frames_per_buffer = 0;
int max_frames_per_buffer = 0;
int default_frames_per_buffer = 0;
int bitstream_formats = 0;
bool require_encapsulation = false;
bool require_audio_offload = false;
};
static std::string EffectsMaskToString(int mask);
AudioParameters();
AudioParameters(Format format,
ChannelLayoutConfig channel_layout_config,
int sample_rate,
int frames_per_buffer);
AudioParameters(Format format,
ChannelLayoutConfig channel_layout_config,
int sample_rate,
int frames_per_buffer,
const HardwareCapabilities& hardware_capabilities);
~AudioParameters();
void Reset(Format format,
ChannelLayoutConfig channel_layout_config,
int sample_rate,
int frames_per_buffer);
bool IsValid() const;
std::string AsHumanReadableString() const;
int GetBytesPerBuffer(SampleFormat fmt) const;
int GetBytesPerFrame(SampleFormat fmt) const;
double GetMicrosecondsPerFrame() const;
base::TimeDelta GetBufferDuration() const;
bool Equals(const AudioParameters& other) const;
bool IsBitstreamFormat() const;
bool IsFormatSupportedByHardware(Format format) const;
bool RequireEncapsulation() const;
bool RequireOffload() const;
void set_format(Format format) { format_ = format; }
Format format() const { return format_; }
void SetChannelLayoutConfig(ChannelLayout layout, int channels);
const ChannelLayoutConfig& channel_layout_config() const {
return channel_layout_config_;
}
ChannelLayout channel_layout() const {
return channel_layout_config_.channel_layout();
}
int channels() const { return channel_layout_config_.channels(); }
void set_sample_rate(int sample_rate) { sample_rate_ = sample_rate; }
int sample_rate() const { return sample_rate_; }
void set_frames_per_buffer(int frames_per_buffer) {
frames_per_buffer_ = frames_per_buffer;
}
int frames_per_buffer() const { return frames_per_buffer_; }
std::optional<HardwareCapabilities> hardware_capabilities() const {
return hardware_capabilities_;
}
void set_hardware_capabilities(
const std::optional<HardwareCapabilities>& hwc) {
hardware_capabilities_ = hwc;
}
void set_effects(int effects) { effects_ = effects; }
int effects() const { return effects_; }
#if BUILDFLAG(IS_OHOS)
void set_render_process_id(int render_process_id) {
render_process_id_ = render_process_id;
}
int render_process_id() const { return render_process_id_; }
void set_render_frame_id(int render_frame_id) {
render_frame_id_ = render_frame_id;
}
int render_frame_id() const { return render_frame_id_; }
void SetStreamPrivacy(bool is_stream_privacy) {
is_stream_privacy_ = is_stream_privacy;
}
bool GetStreamPrivacy() const {
return is_stream_privacy_;
}
#endif
void set_mic_positions(const std::vector<Point>& mic_positions) {
mic_positions_ = mic_positions;
}
const std::vector<Point>& mic_positions() const { return mic_positions_; }
void set_latency_tag(AudioLatency::Type latency_tag) {
latency_tag_ = latency_tag;
}
AudioLatency::Type latency_tag() const { return latency_tag_; }
AudioParameters(const AudioParameters&);
AudioParameters& operator=(const AudioParameters&);
static AudioParameters UnavailableDeviceParams();
private:
Format format_;
ChannelLayoutConfig channel_layout_config_;
int sample_rate_;
int frames_per_buffer_;
int effects_;
#if BUILDFLAG(IS_OHOS)
int render_process_id_;
int render_frame_id_;
bool is_stream_privacy_ = false;
#endif
std::vector<Point> mic_positions_;
AudioLatency::Type latency_tag_;
std::optional<HardwareCapabilities> hardware_capabilities_;
};
inline bool operator<(const AudioParameters& a, const AudioParameters& b) {
if (a.format() != b.format())
return a.format() < b.format();
if (a.channels() != b.channels())
return a.channels() < b.channels();
if (a.sample_rate() != b.sample_rate())
return a.sample_rate() < b.sample_rate();
return a.frames_per_buffer() < b.frames_per_buffer();
}
}
#endif