You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.6 KiB
C++

/*
* DVD-Audio Decoder plugin
* Copyright (c) 2009-2025 Maxim V.Anisiutkin <maxim.anisiutkin@gmail.com>
*
* DVD-Audio Decoder is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* DVD-Audio Decoder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "audio_stream_info.h"
#include <string.h>
#include <memory>
class audio_stream_t {
static constexpr int AVG_BITRATE_SIZE = 256;
int instant_bits_read[AVG_BITRATE_SIZE];
int instant_bits_decoded[AVG_BITRATE_SIZE];
int instant_bit_index;
int avg_bits_read;
int avg_bits_decoded;
protected:
audio_stream_info_t info;
bool do_check;
bool do_downmix;
double LR_dmx_coef[8][2];
int64_t bits_read;
int64_t bits_decoded;
void reset_stats() {
memset(instant_bits_read, 0, sizeof(instant_bits_read));
memset(instant_bits_decoded, 0, sizeof(instant_bits_decoded));
instant_bit_index = 0;
avg_bits_read = avg_bits_decoded = 0;
bits_read = bits_decoded = 0;
}
void update_stats(int decoder_bits_read, int decoder_bits_decoded) {
if (instant_bit_index >= AVG_BITRATE_SIZE)
instant_bit_index = 0;
avg_bits_read -= instant_bits_read[instant_bit_index];
instant_bits_read[instant_bit_index] = decoder_bits_read;
avg_bits_read += instant_bits_read[instant_bit_index];
avg_bits_decoded -= instant_bits_decoded[instant_bit_index];
instant_bits_decoded[instant_bit_index] = decoder_bits_decoded;
avg_bits_decoded += instant_bits_decoded[instant_bit_index];
instant_bit_index++;
bits_read += decoder_bits_read;
bits_decoded += decoder_bits_decoded;
}
int32_t conv_sample(double sample);
void reorder_channels(uint8_t* data, int* data_size);
void downmix_channels(uint8_t* data, int* data_size);
public:
static const int MAX_CHUNK_SIZE = 2 * 4096 + 4;
static const int RETCODE_REINIT = -128;
static const int RETCODE_EXCEPT = -256;
static std::unique_ptr<audio_stream_t> create_stream(stream_id_e stream_id);
audio_stream_t() {
do_check = false;
do_downmix = false;
bits_read = 0;
bits_decoded = 0;
reset_stats();
}
virtual ~audio_stream_t() {
}
audio_stream_info_t get_info() {
return info;
}
stream_id_e get_stream_id() {
return info.stream_id;
}
bool get_downmix() {
return do_downmix;
}
void set_check(bool check) {
do_check = check;
}
double get_compression() {
if (bits_read > 0 && bits_decoded > 0) {
return (double)bits_decoded / (double)bits_read;
}
return info.estimate_compression();
}
double get_instant_bitrate() {
return (avg_bits_decoded > 0 ? (double)avg_bits_read / (double)avg_bits_decoded : 1.0) * (double)info.bitrate;
}
void set_downmix_coef();
void set_downmix_coef(double dmx_coef[8][2]);
virtual audio_stream_info_t get_info(uint8_t* buf, int buf_size) = 0;
virtual int init(uint8_t* buf, int buf_size, bool downmix, bool reset_statistics = true) = 0;
virtual int decode(uint8_t* data, int* data_size, uint8_t* buf, int buf_size) = 0;
virtual int resync(uint8_t* buf, int buf_size) = 0;
};