blob: 5d6a72241c655dd61b19dadfcc4b71e2705194ea [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_MEDIA_SOUNDS_SOUNDPLAYER_OPUS_DECODER_H_
#define SRC_MEDIA_SOUNDS_SOUNDPLAYER_OPUS_DECODER_H_
#include <inttypes.h>
#include <lib/zx/vmo.h>
#include <cstdlib>
#include <memory>
#include <vector>
#include "src/media/sounds/soundplayer/sound.h"
#include "third_party/opus/include/opus.h"
namespace soundplayer {
class OpusDecoder {
public:
// Checks an initial stream packet to see if the stream is in Opus format.
static bool CheckHeaderPacket(const uint8_t* data, size_t size);
OpusDecoder() = default;
~OpusDecoder() = default;
// Processes a packet. |first| indicates whether the packet is the first in the stream. |last|
// indicates whether the packet is the last in the stream. Returns false on failure.
bool ProcessPacket(const uint8_t* data, size_t size, bool first, bool last,
DiscardableSound& sound);
private:
struct DecoderDeleter {
void operator()(::OpusDecoder* decoder) const { opus_decoder_destroy(decoder); }
};
struct OutputBuffer {
OutputBuffer(std::unique_ptr<int16_t[]> samples, uint32_t frame_count)
: samples_(std::move(samples)), frame_count_(frame_count) {}
std::unique_ptr<int16_t[]> samples_;
uint32_t frame_count_;
};
// Processes the first packet, which contains the ID header. Returns false on failure.
bool ProcessIdHeader(const uint8_t* data, size_t size);
// Processes the second packet, which contains the comment header. Returns false on failure.
bool ProcessCommentHeader(const uint8_t* data, size_t size);
// Handles a buffer containing decoded PCM audio.
void HandleOutputBuffer(std::unique_ptr<int16_t[]> buffer, uint32_t frame_count);
// Performs end-of-stream tasks. Returns false on failure.
bool HandleEndOfStream(DiscardableSound& sound);
uint32_t channels_;
uint16_t preskip_;
uint32_t input_frames_per_second_;
std::unique_ptr<::OpusDecoder, DecoderDeleter> decoder_;
bool second_packet_processed_;
uint32_t total_frame_count_;
std::vector<OutputBuffer> output_buffers_;
};
} // namespace soundplayer
#endif // SRC_MEDIA_SOUNDS_SOUNDPLAYER_OPUS_DECODER_H_