decoder: rename the struct to "Decoder"
This commit is contained in:
src
DecoderAPI.cxxDecoderAPI.hxxDecoderBuffer.cxxDecoderBuffer.hxxDecoderInternal.cxxDecoderInternal.hxxDecoderPlugin.hxxDecoderThread.cxx
decoder
AdPlugDecoderPlugin.cxxAudiofileDecoderPlugin.cxxDsdLib.cxxDsdLib.hxxDsdiffDecoderPlugin.cxxDsfDecoderPlugin.cxxFaadDecoderPlugin.cxxFfmpegDecoderPlugin.cxxFlacCommon.cxxFlacCommon.hxxFlacDecoderPlugin.cxxFlacInput.cxxFlacInput.hxxFluidsynthDecoderPlugin.cxxGmeDecoderPlugin.cxxMadDecoderPlugin.cxxMikmodDecoderPlugin.cxxModplugDecoderPlugin.cxxMpcdecDecoderPlugin.cxxMpg123DecoderPlugin.cxxOggCodec.cxxOggCodec.hxxOggSyncState.hxxOggUtil.cxxOggUtil.hxxOpusDecoderPlugin.cxxPcmDecoderPlugin.cxxSidplayDecoderPlugin.cxxSndfileDecoderPlugin.cxxVorbisDecoderPlugin.cxxWavpackDecoderPlugin.cxxWildmidiDecoderPlugin.cxx
test
@ -37,19 +37,18 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_initialized(struct decoder *decoder,
|
decoder_initialized(Decoder &decoder,
|
||||||
const AudioFormat audio_format,
|
const AudioFormat audio_format,
|
||||||
bool seekable, float total_time)
|
bool seekable, float total_time)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
struct audio_format_string af_string;
|
struct audio_format_string af_string;
|
||||||
|
|
||||||
assert(dc.state == DecoderState::START);
|
assert(dc.state == DecoderState::START);
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
assert(decoder != nullptr);
|
assert(decoder.stream_tag == nullptr);
|
||||||
assert(decoder->stream_tag == nullptr);
|
assert(decoder.decoder_tag == nullptr);
|
||||||
assert(decoder->decoder_tag == nullptr);
|
assert(!decoder.seeking);
|
||||||
assert(!decoder->seeking);
|
|
||||||
assert(audio_format.IsDefined());
|
assert(audio_format.IsDefined());
|
||||||
assert(audio_format.IsValid());
|
assert(audio_format.IsValid());
|
||||||
|
|
||||||
@ -80,9 +79,9 @@ decoder_initialized(struct decoder *decoder,
|
|||||||
*/
|
*/
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
decoder_prepare_initial_seek(struct decoder *decoder)
|
decoder_prepare_initial_seek(Decoder &decoder)
|
||||||
{
|
{
|
||||||
const decoder_control &dc = decoder->dc;
|
const decoder_control &dc = decoder.dc;
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
|
|
||||||
if (dc.state != DecoderState::DECODE)
|
if (dc.state != DecoderState::DECODE)
|
||||||
@ -91,30 +90,30 @@ decoder_prepare_initial_seek(struct decoder *decoder)
|
|||||||
virtual "SEEK" command */
|
virtual "SEEK" command */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (decoder->initial_seek_running)
|
if (decoder.initial_seek_running)
|
||||||
/* initial seek has already begun - override any other
|
/* initial seek has already begun - override any other
|
||||||
command */
|
command */
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (decoder->initial_seek_pending) {
|
if (decoder.initial_seek_pending) {
|
||||||
if (!dc.seekable) {
|
if (!dc.seekable) {
|
||||||
/* seeking is not possible */
|
/* seeking is not possible */
|
||||||
decoder->initial_seek_pending = false;
|
decoder.initial_seek_pending = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc.command == DecoderCommand::NONE) {
|
if (dc.command == DecoderCommand::NONE) {
|
||||||
/* begin initial seek */
|
/* begin initial seek */
|
||||||
|
|
||||||
decoder->initial_seek_pending = false;
|
decoder.initial_seek_pending = false;
|
||||||
decoder->initial_seek_running = true;
|
decoder.initial_seek_running = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip initial seek when there's another command
|
/* skip initial seek when there's another command
|
||||||
(e.g. STOP) */
|
(e.g. STOP) */
|
||||||
|
|
||||||
decoder->initial_seek_pending = false;
|
decoder.initial_seek_pending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -127,9 +126,9 @@ decoder_prepare_initial_seek(struct decoder *decoder)
|
|||||||
*/
|
*/
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static DecoderCommand
|
static DecoderCommand
|
||||||
decoder_get_virtual_command(struct decoder *decoder)
|
decoder_get_virtual_command(Decoder &decoder)
|
||||||
{
|
{
|
||||||
const decoder_control &dc = decoder->dc;
|
const decoder_control &dc = decoder.dc;
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
|
|
||||||
if (decoder_prepare_initial_seek(decoder))
|
if (decoder_prepare_initial_seek(decoder))
|
||||||
@ -139,49 +138,49 @@ decoder_get_virtual_command(struct decoder *decoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_get_command(struct decoder *decoder)
|
decoder_get_command(Decoder &decoder)
|
||||||
{
|
{
|
||||||
return decoder_get_virtual_command(decoder);
|
return decoder_get_virtual_command(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_command_finished(struct decoder *decoder)
|
decoder_command_finished(Decoder &decoder)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
|
|
||||||
dc.Lock();
|
dc.Lock();
|
||||||
|
|
||||||
assert(dc.command != DecoderCommand::NONE ||
|
assert(dc.command != DecoderCommand::NONE ||
|
||||||
decoder->initial_seek_running);
|
decoder.initial_seek_running);
|
||||||
assert(dc.command != DecoderCommand::SEEK ||
|
assert(dc.command != DecoderCommand::SEEK ||
|
||||||
decoder->initial_seek_running ||
|
decoder.initial_seek_running ||
|
||||||
dc.seek_error || decoder->seeking);
|
dc.seek_error || decoder.seeking);
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
|
|
||||||
if (decoder->initial_seek_running) {
|
if (decoder.initial_seek_running) {
|
||||||
assert(!decoder->seeking);
|
assert(!decoder.seeking);
|
||||||
assert(decoder->chunk == nullptr);
|
assert(decoder.chunk == nullptr);
|
||||||
assert(dc.pipe->IsEmpty());
|
assert(dc.pipe->IsEmpty());
|
||||||
|
|
||||||
decoder->initial_seek_running = false;
|
decoder.initial_seek_running = false;
|
||||||
decoder->timestamp = dc.start_ms / 1000.;
|
decoder.timestamp = dc.start_ms / 1000.;
|
||||||
dc.Unlock();
|
dc.Unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoder->seeking) {
|
if (decoder.seeking) {
|
||||||
decoder->seeking = false;
|
decoder.seeking = false;
|
||||||
|
|
||||||
/* delete frames from the old song position */
|
/* delete frames from the old song position */
|
||||||
|
|
||||||
if (decoder->chunk != nullptr) {
|
if (decoder.chunk != nullptr) {
|
||||||
dc.buffer->Return(decoder->chunk);
|
dc.buffer->Return(decoder.chunk);
|
||||||
decoder->chunk = nullptr;
|
decoder.chunk = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc.pipe->Clear(*dc.buffer);
|
dc.pipe->Clear(*dc.buffer);
|
||||||
|
|
||||||
decoder->timestamp = dc.seek_where;
|
decoder.timestamp = dc.seek_where;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc.command = DecoderCommand::NONE;
|
dc.command = DecoderCommand::NONE;
|
||||||
@ -189,39 +188,39 @@ decoder_command_finished(struct decoder *decoder)
|
|||||||
dc.Unlock();
|
dc.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
double decoder_seek_where(gcc_unused struct decoder * decoder)
|
double decoder_seek_where(gcc_unused Decoder & decoder)
|
||||||
{
|
{
|
||||||
const decoder_control &dc = decoder->dc;
|
const decoder_control &dc = decoder.dc;
|
||||||
|
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
|
|
||||||
if (decoder->initial_seek_running)
|
if (decoder.initial_seek_running)
|
||||||
return dc.start_ms / 1000.;
|
return dc.start_ms / 1000.;
|
||||||
|
|
||||||
assert(dc.command == DecoderCommand::SEEK);
|
assert(dc.command == DecoderCommand::SEEK);
|
||||||
|
|
||||||
decoder->seeking = true;
|
decoder.seeking = true;
|
||||||
|
|
||||||
return dc.seek_where;
|
return dc.seek_where;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_seek_error(struct decoder * decoder)
|
void decoder_seek_error(Decoder & decoder)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
|
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
|
|
||||||
if (decoder->initial_seek_running) {
|
if (decoder.initial_seek_running) {
|
||||||
/* d'oh, we can't seek to the sub-song start position,
|
/* d'oh, we can't seek to the sub-song start position,
|
||||||
what now? - no idea, ignoring the problem for now. */
|
what now? - no idea, ignoring the problem for now. */
|
||||||
decoder->initial_seek_running = false;
|
decoder.initial_seek_running = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(dc.command == DecoderCommand::SEEK);
|
assert(dc.command == DecoderCommand::SEEK);
|
||||||
|
|
||||||
dc.seek_error = true;
|
dc.seek_error = true;
|
||||||
decoder->seeking = false;
|
decoder.seeking = false;
|
||||||
|
|
||||||
decoder_command_finished(decoder);
|
decoder_command_finished(decoder);
|
||||||
}
|
}
|
||||||
@ -232,7 +231,7 @@ void decoder_seek_error(struct decoder * decoder)
|
|||||||
*/
|
*/
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static inline bool
|
static inline bool
|
||||||
decoder_check_cancel_read(const struct decoder *decoder)
|
decoder_check_cancel_read(const Decoder *decoder)
|
||||||
{
|
{
|
||||||
if (decoder == nullptr)
|
if (decoder == nullptr)
|
||||||
return false;
|
return false;
|
||||||
@ -250,9 +249,10 @@ decoder_check_cancel_read(const struct decoder *decoder)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t decoder_read(struct decoder *decoder,
|
size_t
|
||||||
struct input_stream *is,
|
decoder_read(Decoder *decoder,
|
||||||
void *buffer, size_t length)
|
struct input_stream *is,
|
||||||
|
void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
/* XXX don't allow decoder==nullptr */
|
/* XXX don't allow decoder==nullptr */
|
||||||
|
|
||||||
@ -293,12 +293,11 @@ size_t decoder_read(struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_timestamp(struct decoder *decoder, double t)
|
decoder_timestamp(Decoder &decoder, double t)
|
||||||
{
|
{
|
||||||
assert(decoder != nullptr);
|
|
||||||
assert(t >= 0);
|
assert(t >= 0);
|
||||||
|
|
||||||
decoder->timestamp = t;
|
decoder.timestamp = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -306,23 +305,23 @@ decoder_timestamp(struct decoder *decoder, double t)
|
|||||||
* (decoder.chunk) if there is one.
|
* (decoder.chunk) if there is one.
|
||||||
*/
|
*/
|
||||||
static DecoderCommand
|
static DecoderCommand
|
||||||
do_send_tag(struct decoder *decoder, const Tag &tag)
|
do_send_tag(Decoder &decoder, const Tag &tag)
|
||||||
{
|
{
|
||||||
struct music_chunk *chunk;
|
struct music_chunk *chunk;
|
||||||
|
|
||||||
if (decoder->chunk != nullptr) {
|
if (decoder.chunk != nullptr) {
|
||||||
/* there is a partial chunk - flush it, we want the
|
/* there is a partial chunk - flush it, we want the
|
||||||
tag in a new chunk */
|
tag in a new chunk */
|
||||||
decoder_flush_chunk(decoder);
|
decoder_flush_chunk(decoder);
|
||||||
decoder->dc.client_cond.signal();
|
decoder.dc.client_cond.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(decoder->chunk == nullptr);
|
assert(decoder.chunk == nullptr);
|
||||||
|
|
||||||
chunk = decoder_get_chunk(decoder);
|
chunk = decoder_get_chunk(decoder);
|
||||||
if (chunk == nullptr) {
|
if (chunk == nullptr) {
|
||||||
assert(decoder->dc.command != DecoderCommand::NONE);
|
assert(decoder.dc.command != DecoderCommand::NONE);
|
||||||
return decoder->dc.command;
|
return decoder.dc.command;
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk->tag = new Tag(tag);
|
chunk->tag = new Tag(tag);
|
||||||
@ -330,7 +329,7 @@ do_send_tag(struct decoder *decoder, const Tag &tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
update_stream_tag(struct decoder *decoder, struct input_stream *is)
|
update_stream_tag(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
Tag *tag;
|
Tag *tag;
|
||||||
|
|
||||||
@ -338,27 +337,27 @@ update_stream_tag(struct decoder *decoder, struct input_stream *is)
|
|||||||
? is->LockReadTag()
|
? is->LockReadTag()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (tag == nullptr) {
|
if (tag == nullptr) {
|
||||||
tag = decoder->song_tag;
|
tag = decoder.song_tag;
|
||||||
if (tag == nullptr)
|
if (tag == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* no stream tag present - submit the song tag
|
/* no stream tag present - submit the song tag
|
||||||
instead */
|
instead */
|
||||||
decoder->song_tag = nullptr;
|
decoder.song_tag = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete decoder->stream_tag;
|
delete decoder.stream_tag;
|
||||||
decoder->stream_tag = tag;
|
decoder.stream_tag = tag;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_data(struct decoder *decoder,
|
decoder_data(Decoder &decoder,
|
||||||
struct input_stream *is,
|
struct input_stream *is,
|
||||||
const void *data, size_t length,
|
const void *data, size_t length,
|
||||||
uint16_t kbit_rate)
|
uint16_t kbit_rate)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
DecoderCommand cmd;
|
DecoderCommand cmd;
|
||||||
|
|
||||||
assert(dc.state == DecoderState::DECODE);
|
assert(dc.state == DecoderState::DECODE);
|
||||||
@ -376,15 +375,15 @@ decoder_data(struct decoder *decoder,
|
|||||||
/* send stream tags */
|
/* send stream tags */
|
||||||
|
|
||||||
if (update_stream_tag(decoder, is)) {
|
if (update_stream_tag(decoder, is)) {
|
||||||
if (decoder->decoder_tag != nullptr) {
|
if (decoder.decoder_tag != nullptr) {
|
||||||
/* merge with tag from decoder plugin */
|
/* merge with tag from decoder plugin */
|
||||||
Tag *tag = Tag::Merge(*decoder->decoder_tag,
|
Tag *tag = Tag::Merge(*decoder.decoder_tag,
|
||||||
*decoder->stream_tag);
|
*decoder.stream_tag);
|
||||||
cmd = do_send_tag(decoder, *tag);
|
cmd = do_send_tag(decoder, *tag);
|
||||||
delete tag;
|
delete tag;
|
||||||
} else
|
} else
|
||||||
/* send only the stream tag */
|
/* send only the stream tag */
|
||||||
cmd = do_send_tag(decoder, *decoder->stream_tag);
|
cmd = do_send_tag(decoder, *decoder.stream_tag);
|
||||||
|
|
||||||
if (cmd != DecoderCommand::NONE)
|
if (cmd != DecoderCommand::NONE)
|
||||||
return cmd;
|
return cmd;
|
||||||
@ -392,7 +391,7 @@ decoder_data(struct decoder *decoder,
|
|||||||
|
|
||||||
if (dc.in_audio_format != dc.out_audio_format) {
|
if (dc.in_audio_format != dc.out_audio_format) {
|
||||||
Error error;
|
Error error;
|
||||||
data = decoder->conv_state.Convert(dc.in_audio_format,
|
data = decoder.conv_state.Convert(dc.in_audio_format,
|
||||||
data, length,
|
data, length,
|
||||||
dc.out_audio_format,
|
dc.out_audio_format,
|
||||||
&length,
|
&length,
|
||||||
@ -418,7 +417,7 @@ decoder_data(struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *dest = chunk->Write(dc.out_audio_format,
|
void *dest = chunk->Write(dc.out_audio_format,
|
||||||
decoder->timestamp -
|
decoder.timestamp -
|
||||||
dc.song->start_ms / 1000.0,
|
dc.song->start_ms / 1000.0,
|
||||||
kbit_rate, &nbytes);
|
kbit_rate, &nbytes);
|
||||||
if (dest == nullptr) {
|
if (dest == nullptr) {
|
||||||
@ -449,11 +448,11 @@ decoder_data(struct decoder *decoder,
|
|||||||
data = (const uint8_t *)data + nbytes;
|
data = (const uint8_t *)data + nbytes;
|
||||||
length -= nbytes;
|
length -= nbytes;
|
||||||
|
|
||||||
decoder->timestamp += (double)nbytes /
|
decoder.timestamp += (double)nbytes /
|
||||||
dc.out_audio_format.GetTimeToSize();
|
dc.out_audio_format.GetTimeToSize();
|
||||||
|
|
||||||
if (dc.end_ms > 0 &&
|
if (dc.end_ms > 0 &&
|
||||||
decoder->timestamp >= dc.end_ms / 1000.0)
|
decoder.timestamp >= dc.end_ms / 1000.0)
|
||||||
/* the end of this range has been reached:
|
/* the end of this range has been reached:
|
||||||
stop decoding */
|
stop decoding */
|
||||||
return DecoderCommand::STOP;
|
return DecoderCommand::STOP;
|
||||||
@ -463,10 +462,10 @@ decoder_data(struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_tag(gcc_unused struct decoder *decoder, struct input_stream *is,
|
decoder_tag(Decoder &decoder, struct input_stream *is,
|
||||||
Tag &&tag)
|
Tag &&tag)
|
||||||
{
|
{
|
||||||
gcc_unused const decoder_control &dc = decoder->dc;
|
gcc_unused const decoder_control &dc = decoder.dc;
|
||||||
DecoderCommand cmd;
|
DecoderCommand cmd;
|
||||||
|
|
||||||
assert(dc.state == DecoderState::DECODE);
|
assert(dc.state == DecoderState::DECODE);
|
||||||
@ -474,8 +473,8 @@ decoder_tag(gcc_unused struct decoder *decoder, struct input_stream *is,
|
|||||||
|
|
||||||
/* save the tag */
|
/* save the tag */
|
||||||
|
|
||||||
delete decoder->decoder_tag;
|
delete decoder.decoder_tag;
|
||||||
decoder->decoder_tag = new Tag(tag);
|
decoder.decoder_tag = new Tag(tag);
|
||||||
|
|
||||||
/* check for a new stream tag */
|
/* check for a new stream tag */
|
||||||
|
|
||||||
@ -491,27 +490,25 @@ decoder_tag(gcc_unused struct decoder *decoder, struct input_stream *is,
|
|||||||
|
|
||||||
/* send tag to music pipe */
|
/* send tag to music pipe */
|
||||||
|
|
||||||
if (decoder->stream_tag != nullptr) {
|
if (decoder.stream_tag != nullptr) {
|
||||||
/* merge with tag from input stream */
|
/* merge with tag from input stream */
|
||||||
Tag *merged;
|
Tag *merged;
|
||||||
|
|
||||||
merged = Tag::Merge(*decoder->stream_tag,
|
merged = Tag::Merge(*decoder.stream_tag,
|
||||||
*decoder->decoder_tag);
|
*decoder.decoder_tag);
|
||||||
cmd = do_send_tag(decoder, *merged);
|
cmd = do_send_tag(decoder, *merged);
|
||||||
delete merged;
|
delete merged;
|
||||||
} else
|
} else
|
||||||
/* send only the decoder tag */
|
/* send only the decoder tag */
|
||||||
cmd = do_send_tag(decoder, *decoder->decoder_tag);
|
cmd = do_send_tag(decoder, *decoder.decoder_tag);
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_replay_gain(struct decoder *decoder,
|
decoder_replay_gain(Decoder &decoder,
|
||||||
const struct replay_gain_info *replay_gain_info)
|
const struct replay_gain_info *replay_gain_info)
|
||||||
{
|
{
|
||||||
assert(decoder != nullptr);
|
|
||||||
|
|
||||||
if (replay_gain_info != nullptr) {
|
if (replay_gain_info != nullptr) {
|
||||||
static unsigned serial;
|
static unsigned serial;
|
||||||
if (++serial == 0)
|
if (++serial == 0)
|
||||||
@ -522,33 +519,32 @@ decoder_replay_gain(struct decoder *decoder,
|
|||||||
if (rgm != REPLAY_GAIN_ALBUM)
|
if (rgm != REPLAY_GAIN_ALBUM)
|
||||||
rgm = REPLAY_GAIN_TRACK;
|
rgm = REPLAY_GAIN_TRACK;
|
||||||
|
|
||||||
decoder->dc.replay_gain_db = 20.0 * log10f(
|
decoder.dc.replay_gain_db = 20.0 * log10f(
|
||||||
replay_gain_tuple_scale(
|
replay_gain_tuple_scale(
|
||||||
&replay_gain_info->tuples[rgm],
|
&replay_gain_info->tuples[rgm],
|
||||||
replay_gain_preamp, replay_gain_missing_preamp,
|
replay_gain_preamp, replay_gain_missing_preamp,
|
||||||
replay_gain_limit));
|
replay_gain_limit));
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->replay_gain_info = *replay_gain_info;
|
decoder.replay_gain_info = *replay_gain_info;
|
||||||
decoder->replay_gain_serial = serial;
|
decoder.replay_gain_serial = serial;
|
||||||
|
|
||||||
if (decoder->chunk != nullptr) {
|
if (decoder.chunk != nullptr) {
|
||||||
/* flush the current chunk because the new
|
/* flush the current chunk because the new
|
||||||
replay gain values affect the following
|
replay gain values affect the following
|
||||||
samples */
|
samples */
|
||||||
decoder_flush_chunk(decoder);
|
decoder_flush_chunk(decoder);
|
||||||
decoder->dc.client_cond.signal();
|
decoder.dc.client_cond.signal();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
decoder->replay_gain_serial = 0;
|
decoder.replay_gain_serial = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_mixramp(struct decoder *decoder,
|
decoder_mixramp(Decoder &decoder,
|
||||||
char *mixramp_start, char *mixramp_end)
|
char *mixramp_start, char *mixramp_end)
|
||||||
{
|
{
|
||||||
assert(decoder != nullptr);
|
decoder_control &dc = decoder.dc;
|
||||||
decoder_control &dc = decoder->dc;
|
|
||||||
|
|
||||||
dc.MixRampStart(mixramp_start);
|
dc.MixRampStart(mixramp_start);
|
||||||
dc.MixRampEnd(mixramp_end);
|
dc.MixRampEnd(mixramp_end);
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
* @param total_time the total number of seconds in this song; -1 if unknown
|
* @param total_time the total number of seconds in this song; -1 if unknown
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_initialized(struct decoder *decoder,
|
decoder_initialized(Decoder &decoder,
|
||||||
AudioFormat audio_format,
|
AudioFormat audio_format,
|
||||||
bool seekable, float total_time);
|
bool seekable, float total_time);
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ decoder_initialized(struct decoder *decoder,
|
|||||||
* command pending
|
* command pending
|
||||||
*/
|
*/
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_get_command(struct decoder *decoder);
|
decoder_get_command(Decoder &decoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the decoder when it has performed the requested command
|
* Called by the decoder when it has performed the requested command
|
||||||
@ -68,7 +68,7 @@ decoder_get_command(struct decoder *decoder);
|
|||||||
* @param decoder the decoder object
|
* @param decoder the decoder object
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_command_finished(struct decoder *decoder);
|
decoder_command_finished(Decoder &decoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this when you have received the DecoderCommand::SEEK command.
|
* Call this when you have received the DecoderCommand::SEEK command.
|
||||||
@ -77,7 +77,7 @@ decoder_command_finished(struct decoder *decoder);
|
|||||||
* @return the destination position for the week
|
* @return the destination position for the week
|
||||||
*/
|
*/
|
||||||
double
|
double
|
||||||
decoder_seek_where(struct decoder *decoder);
|
decoder_seek_where(Decoder &decoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this instead of decoder_command_finished() when seeking has
|
* Call this instead of decoder_command_finished() when seeking has
|
||||||
@ -86,7 +86,7 @@ decoder_seek_where(struct decoder *decoder);
|
|||||||
* @param decoder the decoder object
|
* @param decoder the decoder object
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_seek_error(struct decoder *decoder);
|
decoder_seek_error(Decoder &decoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocking read from the input stream.
|
* Blocking read from the input stream.
|
||||||
@ -99,9 +99,16 @@ decoder_seek_error(struct decoder *decoder);
|
|||||||
* occurs: end of file; error; command (like SEEK or STOP).
|
* occurs: end of file; error; command (like SEEK or STOP).
|
||||||
*/
|
*/
|
||||||
size_t
|
size_t
|
||||||
decoder_read(struct decoder *decoder, struct input_stream *is,
|
decoder_read(Decoder *decoder, struct input_stream *is,
|
||||||
void *buffer, size_t length);
|
void *buffer, size_t length);
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
decoder_read(Decoder &decoder, input_stream *is,
|
||||||
|
void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
return decoder_read(&decoder, is, buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the time stamp for the next data chunk [seconds]. The MPD
|
* Sets the time stamp for the next data chunk [seconds]. The MPD
|
||||||
* core automatically counts it up, and a decoder plugin only needs to
|
* core automatically counts it up, and a decoder plugin only needs to
|
||||||
@ -109,7 +116,7 @@ decoder_read(struct decoder *decoder, struct input_stream *is,
|
|||||||
* on the buffer size won't work.
|
* on the buffer size won't work.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_timestamp(struct decoder *decoder, double t);
|
decoder_timestamp(Decoder &decoder, double t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is called by the decoder plugin when it has
|
* This function is called by the decoder plugin when it has
|
||||||
@ -124,7 +131,7 @@ decoder_timestamp(struct decoder *decoder, double t);
|
|||||||
* command pending
|
* command pending
|
||||||
*/
|
*/
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_data(struct decoder *decoder, struct input_stream *is,
|
decoder_data(Decoder &decoder, struct input_stream *is,
|
||||||
const void *data, size_t length,
|
const void *data, size_t length,
|
||||||
uint16_t kbit_rate);
|
uint16_t kbit_rate);
|
||||||
|
|
||||||
@ -140,7 +147,7 @@ decoder_data(struct decoder *decoder, struct input_stream *is,
|
|||||||
* command pending
|
* command pending
|
||||||
*/
|
*/
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_tag(struct decoder *decoder, struct input_stream *is, Tag &&tag);
|
decoder_tag(Decoder &decoder, struct input_stream *is, Tag &&tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set replay gain values for the following chunks.
|
* Set replay gain values for the following chunks.
|
||||||
@ -150,7 +157,7 @@ decoder_tag(struct decoder *decoder, struct input_stream *is, Tag &&tag);
|
|||||||
* the previous replay gain values
|
* the previous replay gain values
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_replay_gain(struct decoder *decoder,
|
decoder_replay_gain(Decoder &decoder,
|
||||||
const struct replay_gain_info *replay_gain_info);
|
const struct replay_gain_info *replay_gain_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,7 +168,7 @@ decoder_replay_gain(struct decoder *decoder,
|
|||||||
* @param mixramp_end the mixramp_end tag; may be nullptr to invalidate
|
* @param mixramp_end the mixramp_end tag; may be nullptr to invalidate
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_mixramp(struct decoder *decoder,
|
decoder_mixramp(Decoder &decoder,
|
||||||
char *mixramp_start, char *mixramp_end);
|
char *mixramp_start, char *mixramp_end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct DecoderBuffer {
|
struct DecoderBuffer {
|
||||||
struct decoder *decoder;
|
Decoder *decoder;
|
||||||
struct input_stream *is;
|
struct input_stream *is;
|
||||||
|
|
||||||
/** the allocated size of the buffer */
|
/** the allocated size of the buffer */
|
||||||
@ -45,7 +45,7 @@ struct DecoderBuffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DecoderBuffer *
|
DecoderBuffer *
|
||||||
decoder_buffer_new(struct decoder *decoder, struct input_stream *is,
|
decoder_buffer_new(Decoder *decoder, struct input_stream *is,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
DecoderBuffer *buffer = (DecoderBuffer *)
|
DecoderBuffer *buffer = (DecoderBuffer *)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
struct DecoderBuffer;
|
struct DecoderBuffer;
|
||||||
|
|
||||||
struct decoder;
|
struct Decoder;
|
||||||
struct input_stream;
|
struct input_stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +41,7 @@ struct input_stream;
|
|||||||
* @return the new decoder_buffer object
|
* @return the new decoder_buffer object
|
||||||
*/
|
*/
|
||||||
DecoderBuffer *
|
DecoderBuffer *
|
||||||
decoder_buffer_new(struct decoder *decoder, struct input_stream *is,
|
decoder_buffer_new(Decoder *decoder, struct input_stream *is,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
decoder::~decoder()
|
Decoder::~Decoder()
|
||||||
{
|
{
|
||||||
/* caller must flush the chunk */
|
/* caller must flush the chunk */
|
||||||
assert(chunk == nullptr);
|
assert(chunk == nullptr);
|
||||||
@ -59,26 +59,24 @@ need_chunks(decoder_control &dc, bool do_wait)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct music_chunk *
|
struct music_chunk *
|
||||||
decoder_get_chunk(struct decoder *decoder)
|
decoder_get_chunk(Decoder &decoder)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
DecoderCommand cmd;
|
DecoderCommand cmd;
|
||||||
|
|
||||||
assert(decoder != nullptr);
|
if (decoder.chunk != nullptr)
|
||||||
|
return decoder.chunk;
|
||||||
if (decoder->chunk != nullptr)
|
|
||||||
return decoder->chunk;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
decoder->chunk = dc.buffer->Allocate();
|
decoder.chunk = dc.buffer->Allocate();
|
||||||
if (decoder->chunk != nullptr) {
|
if (decoder.chunk != nullptr) {
|
||||||
decoder->chunk->replay_gain_serial =
|
decoder.chunk->replay_gain_serial =
|
||||||
decoder->replay_gain_serial;
|
decoder.replay_gain_serial;
|
||||||
if (decoder->replay_gain_serial != 0)
|
if (decoder.replay_gain_serial != 0)
|
||||||
decoder->chunk->replay_gain_info =
|
decoder.chunk->replay_gain_info =
|
||||||
decoder->replay_gain_info;
|
decoder.replay_gain_info;
|
||||||
|
|
||||||
return decoder->chunk;
|
return decoder.chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc.Lock();
|
dc.Lock();
|
||||||
@ -90,17 +88,16 @@ decoder_get_chunk(struct decoder *decoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_flush_chunk(struct decoder *decoder)
|
decoder_flush_chunk(Decoder &decoder)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
|
|
||||||
assert(decoder != nullptr);
|
assert(decoder.chunk != nullptr);
|
||||||
assert(decoder->chunk != nullptr);
|
|
||||||
|
|
||||||
if (decoder->chunk->IsEmpty())
|
if (decoder.chunk->IsEmpty())
|
||||||
dc.buffer->Return(decoder->chunk);
|
dc.buffer->Return(decoder.chunk);
|
||||||
else
|
else
|
||||||
dc.pipe->Push(decoder->chunk);
|
dc.pipe->Push(decoder.chunk);
|
||||||
|
|
||||||
decoder->chunk = nullptr;
|
decoder.chunk = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ struct decoder_control;
|
|||||||
struct input_stream;
|
struct input_stream;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
|
||||||
struct decoder {
|
struct Decoder {
|
||||||
decoder_control &dc;
|
decoder_control &dc;
|
||||||
|
|
||||||
PcmConvert conv_state;
|
PcmConvert conv_state;
|
||||||
@ -83,7 +83,7 @@ struct decoder {
|
|||||||
*/
|
*/
|
||||||
unsigned replay_gain_serial;
|
unsigned replay_gain_serial;
|
||||||
|
|
||||||
decoder(decoder_control &_dc, bool _initial_seek_pending, Tag *_tag)
|
Decoder(decoder_control &_dc, bool _initial_seek_pending, Tag *_tag)
|
||||||
:dc(_dc),
|
:dc(_dc),
|
||||||
timestamp(0),
|
timestamp(0),
|
||||||
initial_seek_pending(_initial_seek_pending),
|
initial_seek_pending(_initial_seek_pending),
|
||||||
@ -94,7 +94,7 @@ struct decoder {
|
|||||||
replay_gain_serial(0) {
|
replay_gain_serial(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~decoder();
|
~Decoder();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,12 +104,12 @@ struct decoder {
|
|||||||
* @return the chunk, or NULL if we have received a decoder command
|
* @return the chunk, or NULL if we have received a decoder command
|
||||||
*/
|
*/
|
||||||
struct music_chunk *
|
struct music_chunk *
|
||||||
decoder_get_chunk(struct decoder *decoder);
|
decoder_get_chunk(Decoder &decoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes the current chunk.
|
* Flushes the current chunk.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
decoder_flush_chunk(struct decoder *decoder);
|
decoder_flush_chunk(Decoder &decoder);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,7 +31,7 @@ struct tag_handler;
|
|||||||
* Opaque handle which the decoder plugin passes to the functions in
|
* Opaque handle which the decoder plugin passes to the functions in
|
||||||
* this header.
|
* this header.
|
||||||
*/
|
*/
|
||||||
struct decoder;
|
struct Decoder;
|
||||||
|
|
||||||
struct DecoderPlugin {
|
struct DecoderPlugin {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -59,15 +59,14 @@ struct DecoderPlugin {
|
|||||||
* possible, it is recommended to implement this method,
|
* possible, it is recommended to implement this method,
|
||||||
* because it is more versatile.
|
* because it is more versatile.
|
||||||
*/
|
*/
|
||||||
void (*stream_decode)(struct decoder *decoder,
|
void (*stream_decode)(Decoder &decoder, input_stream *is);
|
||||||
struct input_stream *is);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode a local file.
|
* Decode a local file.
|
||||||
*
|
*
|
||||||
* Either implement this method or stream_decode().
|
* Either implement this method or stream_decode().
|
||||||
*/
|
*/
|
||||||
void (*file_decode)(struct decoder *decoder, const char *path_fs);
|
void (*file_decode)(Decoder &decoder, const char *path_fs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan metadata of a file.
|
* Scan metadata of a file.
|
||||||
@ -128,15 +127,15 @@ struct DecoderPlugin {
|
|||||||
/**
|
/**
|
||||||
* Decode a stream.
|
* Decode a stream.
|
||||||
*/
|
*/
|
||||||
void StreamDecode(decoder &decoder, input_stream &is) const {
|
void StreamDecode(Decoder &decoder, input_stream &is) const {
|
||||||
stream_decode(&decoder, &is);
|
stream_decode(decoder, &is);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode a file.
|
* Decode a file.
|
||||||
*/
|
*/
|
||||||
void FileDecode(decoder &decoder, const char *path_fs) const {
|
void FileDecode(Decoder &decoder, const char *path_fs) const {
|
||||||
file_decode(&decoder, path_fs);
|
file_decode(decoder, path_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,64 +112,62 @@ decoder_input_stream_open(decoder_control &dc, const char *uri)
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
decoder_stream_decode(const DecoderPlugin &plugin,
|
decoder_stream_decode(const DecoderPlugin &plugin,
|
||||||
struct decoder *decoder,
|
Decoder &decoder,
|
||||||
struct input_stream *input_stream)
|
struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
assert(plugin.stream_decode != nullptr);
|
assert(plugin.stream_decode != nullptr);
|
||||||
assert(decoder != nullptr);
|
assert(decoder.stream_tag == nullptr);
|
||||||
assert(decoder->stream_tag == nullptr);
|
assert(decoder.decoder_tag == nullptr);
|
||||||
assert(decoder->decoder_tag == nullptr);
|
|
||||||
assert(input_stream != nullptr);
|
assert(input_stream != nullptr);
|
||||||
assert(input_stream->ready);
|
assert(input_stream->ready);
|
||||||
assert(decoder->dc.state == DecoderState::START);
|
assert(decoder.dc.state == DecoderState::START);
|
||||||
|
|
||||||
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
|
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
|
||||||
|
|
||||||
if (decoder->dc.command == DecoderCommand::STOP)
|
if (decoder.dc.command == DecoderCommand::STOP)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* rewind the stream, so each plugin gets a fresh start */
|
/* rewind the stream, so each plugin gets a fresh start */
|
||||||
input_stream->Seek(0, SEEK_SET, IgnoreError());
|
input_stream->Seek(0, SEEK_SET, IgnoreError());
|
||||||
|
|
||||||
decoder->dc.Unlock();
|
decoder.dc.Unlock();
|
||||||
|
|
||||||
plugin.StreamDecode(*decoder, *input_stream);
|
plugin.StreamDecode(decoder, *input_stream);
|
||||||
|
|
||||||
decoder->dc.Lock();
|
decoder.dc.Lock();
|
||||||
|
|
||||||
assert(decoder->dc.state == DecoderState::START ||
|
assert(decoder.dc.state == DecoderState::START ||
|
||||||
decoder->dc.state == DecoderState::DECODE);
|
decoder.dc.state == DecoderState::DECODE);
|
||||||
|
|
||||||
return decoder->dc.state != DecoderState::START;
|
return decoder.dc.state != DecoderState::START;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
decoder_file_decode(const DecoderPlugin &plugin,
|
decoder_file_decode(const DecoderPlugin &plugin,
|
||||||
struct decoder *decoder, const char *path)
|
Decoder &decoder, const char *path)
|
||||||
{
|
{
|
||||||
assert(plugin.file_decode != nullptr);
|
assert(plugin.file_decode != nullptr);
|
||||||
assert(decoder != nullptr);
|
assert(decoder.stream_tag == nullptr);
|
||||||
assert(decoder->stream_tag == nullptr);
|
assert(decoder.decoder_tag == nullptr);
|
||||||
assert(decoder->decoder_tag == nullptr);
|
|
||||||
assert(path != nullptr);
|
assert(path != nullptr);
|
||||||
assert(PathTraits::IsAbsoluteFS(path));
|
assert(PathTraits::IsAbsoluteFS(path));
|
||||||
assert(decoder->dc.state == DecoderState::START);
|
assert(decoder.dc.state == DecoderState::START);
|
||||||
|
|
||||||
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
|
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
|
||||||
|
|
||||||
if (decoder->dc.command == DecoderCommand::STOP)
|
if (decoder.dc.command == DecoderCommand::STOP)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
decoder->dc.Unlock();
|
decoder.dc.Unlock();
|
||||||
|
|
||||||
plugin.FileDecode(*decoder, path);
|
plugin.FileDecode(decoder, path);
|
||||||
|
|
||||||
decoder->dc.Lock();
|
decoder.dc.Lock();
|
||||||
|
|
||||||
assert(decoder->dc.state == DecoderState::START ||
|
assert(decoder.dc.state == DecoderState::START ||
|
||||||
decoder->dc.state == DecoderState::DECODE);
|
decoder.dc.state == DecoderState::DECODE);
|
||||||
|
|
||||||
return decoder->dc.state != DecoderState::START;
|
return decoder.dc.state != DecoderState::START;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,7 +185,7 @@ deconst_plugin(const struct DecoderPlugin *plugin)
|
|||||||
* @param tried_r a list of plugins which were tried
|
* @param tried_r a list of plugins which were tried
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
|
decoder_run_stream_mime_type(Decoder &decoder, struct input_stream *is,
|
||||||
GSList **tried_r)
|
GSList **tried_r)
|
||||||
{
|
{
|
||||||
assert(tried_r != nullptr);
|
assert(tried_r != nullptr);
|
||||||
@ -223,7 +221,7 @@ decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
|
|||||||
* @param tried_r a list of plugins which were tried
|
* @param tried_r a list of plugins which were tried
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
decoder_run_stream_suffix(struct decoder *decoder, struct input_stream *is,
|
decoder_run_stream_suffix(Decoder &decoder, struct input_stream *is,
|
||||||
const char *uri, GSList **tried_r)
|
const char *uri, GSList **tried_r)
|
||||||
{
|
{
|
||||||
assert(tried_r != nullptr);
|
assert(tried_r != nullptr);
|
||||||
@ -255,7 +253,7 @@ decoder_run_stream_suffix(struct decoder *decoder, struct input_stream *is,
|
|||||||
* Try decoding a stream, using the fallback plugin.
|
* Try decoding a stream, using the fallback plugin.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
decoder_run_stream_fallback(struct decoder *decoder, struct input_stream *is)
|
decoder_run_stream_fallback(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
const struct DecoderPlugin *plugin;
|
const struct DecoderPlugin *plugin;
|
||||||
|
|
||||||
@ -268,9 +266,9 @@ decoder_run_stream_fallback(struct decoder *decoder, struct input_stream *is)
|
|||||||
* Try decoding a stream.
|
* Try decoding a stream.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
decoder_run_stream(struct decoder *decoder, const char *uri)
|
decoder_run_stream(Decoder &decoder, const char *uri)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
@ -311,7 +309,7 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
|
|||||||
* decoder_replay_gain().
|
* decoder_replay_gain().
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
decoder_load_replay_gain(struct decoder *decoder, const char *path_fs)
|
decoder_load_replay_gain(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
struct replay_gain_info info;
|
struct replay_gain_info info;
|
||||||
if (replay_gain_ape_read(path_fs, &info))
|
if (replay_gain_ape_read(path_fs, &info))
|
||||||
@ -322,9 +320,9 @@ decoder_load_replay_gain(struct decoder *decoder, const char *path_fs)
|
|||||||
* Try decoding a file.
|
* Try decoding a file.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
decoder_run_file(struct decoder *decoder, const char *path_fs)
|
decoder_run_file(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
decoder_control &dc = decoder->dc;
|
decoder_control &dc = decoder.dc;
|
||||||
const char *suffix = uri_get_suffix(path_fs);
|
const char *suffix = uri_get_suffix(path_fs);
|
||||||
const struct DecoderPlugin *plugin = nullptr;
|
const struct DecoderPlugin *plugin = nullptr;
|
||||||
|
|
||||||
@ -375,7 +373,7 @@ static void
|
|||||||
decoder_run_song(decoder_control &dc,
|
decoder_run_song(decoder_control &dc,
|
||||||
const Song *song, const char *uri)
|
const Song *song, const char *uri)
|
||||||
{
|
{
|
||||||
decoder decoder(dc, dc.start_ms > 0,
|
Decoder decoder(dc, dc.start_ms > 0,
|
||||||
song->tag != nullptr && song->IsFile()
|
song->tag != nullptr && song->IsFile()
|
||||||
? new Tag(*song->tag) : nullptr);
|
? new Tag(*song->tag) : nullptr);
|
||||||
int ret;
|
int ret;
|
||||||
@ -385,15 +383,15 @@ decoder_run_song(decoder_control &dc,
|
|||||||
decoder_command_finished_locked(dc);
|
decoder_command_finished_locked(dc);
|
||||||
|
|
||||||
ret = song->IsFile()
|
ret = song->IsFile()
|
||||||
? decoder_run_file(&decoder, uri)
|
? decoder_run_file(decoder, uri)
|
||||||
: decoder_run_stream(&decoder, uri);
|
: decoder_run_stream(decoder, uri);
|
||||||
|
|
||||||
dc.Unlock();
|
dc.Unlock();
|
||||||
|
|
||||||
/* flush the last chunk */
|
/* flush the last chunk */
|
||||||
|
|
||||||
if (decoder.chunk != nullptr)
|
if (decoder.chunk != nullptr)
|
||||||
decoder_flush_chunk(&decoder);
|
decoder_flush_chunk(decoder);
|
||||||
|
|
||||||
dc.Lock();
|
dc.Lock();
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ adplug_init(const config_param ¶m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
adplug_file_decode(struct decoder *decoder, const char *path_fs)
|
adplug_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
CEmuopl opl(sample_rate, true, true);
|
CEmuopl opl(sample_rate, true, true);
|
||||||
opl.init();
|
opl.init();
|
||||||
|
@ -157,7 +157,7 @@ audiofile_setup_sample_format(AFfilehandle af_fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
|
audiofile_stream_decode(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
AFvirtualfile *vf;
|
AFvirtualfile *vf;
|
||||||
int fs, frame_count;
|
int fs, frame_count;
|
||||||
|
@ -51,7 +51,7 @@ dsdlib_id_equals(const struct dsdlib_id *id, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
dsdlib_read(struct decoder *decoder, struct input_stream *is,
|
dsdlib_read(Decoder *decoder, struct input_stream *is,
|
||||||
void *data, size_t length)
|
void *data, size_t length)
|
||||||
{
|
{
|
||||||
size_t nbytes = decoder_read(decoder, is, data, length);
|
size_t nbytes = decoder_read(decoder, is, data, length);
|
||||||
@ -62,7 +62,7 @@ dsdlib_read(struct decoder *decoder, struct input_stream *is,
|
|||||||
* Skip the #input_stream to the specified offset.
|
* Skip the #input_stream to the specified offset.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
dsdlib_skip_to(struct decoder *decoder, struct input_stream *is,
|
dsdlib_skip_to(Decoder *decoder, struct input_stream *is,
|
||||||
int64_t offset)
|
int64_t offset)
|
||||||
{
|
{
|
||||||
if (is->IsSeekable())
|
if (is->IsSeekable())
|
||||||
@ -90,7 +90,7 @@ dsdlib_skip_to(struct decoder *decoder, struct input_stream *is,
|
|||||||
* Skip some bytes from the #input_stream.
|
* Skip some bytes from the #input_stream.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
dsdlib_skip(struct decoder *decoder, struct input_stream *is,
|
dsdlib_skip(Decoder *decoder, struct input_stream *is,
|
||||||
int64_t delta)
|
int64_t delta)
|
||||||
{
|
{
|
||||||
assert(delta >= 0);
|
assert(delta >= 0);
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct Decoder;
|
||||||
|
|
||||||
struct dsdlib_id {
|
struct dsdlib_id {
|
||||||
char value[4];
|
char value[4];
|
||||||
};
|
};
|
||||||
@ -31,15 +33,15 @@ bool
|
|||||||
dsdlib_id_equals(const struct dsdlib_id *id, const char *s);
|
dsdlib_id_equals(const struct dsdlib_id *id, const char *s);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
dsdlib_read(struct decoder *decoder, struct input_stream *is,
|
dsdlib_read(Decoder *decoder, struct input_stream *is,
|
||||||
void *data, size_t length);
|
void *data, size_t length);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
dsdlib_skip_to(struct decoder *decoder, struct input_stream *is,
|
dsdlib_skip_to(Decoder *decoder, struct input_stream *is,
|
||||||
int64_t offset);
|
int64_t offset);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
dsdlib_skip(struct decoder *decoder, struct input_stream *is,
|
dsdlib_skip(Decoder *decoder, struct input_stream *is,
|
||||||
int64_t delta);
|
int64_t delta);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -91,21 +91,21 @@ dsdiff_init(const config_param ¶m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_id(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_id(Decoder *decoder, struct input_stream *is,
|
||||||
struct dsdlib_id *id)
|
struct dsdlib_id *id)
|
||||||
{
|
{
|
||||||
return dsdlib_read(decoder, is, id, sizeof(*id));
|
return dsdlib_read(decoder, is, id, sizeof(*id));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_chunk_header(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_chunk_header(Decoder *decoder, struct input_stream *is,
|
||||||
DsdiffChunkHeader *header)
|
DsdiffChunkHeader *header)
|
||||||
{
|
{
|
||||||
return dsdlib_read(decoder, is, header, sizeof(*header));
|
return dsdlib_read(decoder, is, header, sizeof(*header));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_payload(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_payload(Decoder *decoder, struct input_stream *is,
|
||||||
const DsdiffChunkHeader *header,
|
const DsdiffChunkHeader *header,
|
||||||
void *data, size_t length)
|
void *data, size_t length)
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ dsdiff_read_payload(struct decoder *decoder, struct input_stream *is,
|
|||||||
* Read and parse a "SND" chunk inside "PROP".
|
* Read and parse a "SND" chunk inside "PROP".
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_prop_snd(Decoder *decoder, struct input_stream *is,
|
||||||
DsdiffMetaData *metadata,
|
DsdiffMetaData *metadata,
|
||||||
input_stream::offset_type end_offset)
|
input_stream::offset_type end_offset)
|
||||||
{
|
{
|
||||||
@ -179,7 +179,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
|
|||||||
* Read and parse a "PROP" chunk.
|
* Read and parse a "PROP" chunk.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_prop(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_prop(Decoder *decoder, struct input_stream *is,
|
||||||
DsdiffMetaData *metadata,
|
DsdiffMetaData *metadata,
|
||||||
const DsdiffChunkHeader *prop_header)
|
const DsdiffChunkHeader *prop_header)
|
||||||
{
|
{
|
||||||
@ -239,7 +239,7 @@ dsdiff_handle_native_tag(struct input_stream *is,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_metadata_extra(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_metadata_extra(Decoder *decoder, struct input_stream *is,
|
||||||
DsdiffMetaData *metadata,
|
DsdiffMetaData *metadata,
|
||||||
DsdiffChunkHeader *chunk_header,
|
DsdiffChunkHeader *chunk_header,
|
||||||
const struct tag_handler *handler,
|
const struct tag_handler *handler,
|
||||||
@ -325,7 +325,7 @@ dsdiff_read_metadata_extra(struct decoder *decoder, struct input_stream *is,
|
|||||||
* "chunk_header" parameter.
|
* "chunk_header" parameter.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dsdiff_read_metadata(struct decoder *decoder, struct input_stream *is,
|
dsdiff_read_metadata(Decoder *decoder, struct input_stream *is,
|
||||||
DsdiffMetaData *metadata,
|
DsdiffMetaData *metadata,
|
||||||
DsdiffChunkHeader *chunk_header)
|
DsdiffChunkHeader *chunk_header)
|
||||||
{
|
{
|
||||||
@ -371,7 +371,7 @@ bit_reverse_buffer(uint8_t *p, uint8_t *end)
|
|||||||
* Decode one "DSD" chunk.
|
* Decode one "DSD" chunk.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dsdiff_decode_chunk(struct decoder *decoder, struct input_stream *is,
|
dsdiff_decode_chunk(Decoder &decoder, struct input_stream *is,
|
||||||
unsigned channels,
|
unsigned channels,
|
||||||
uint64_t chunk_size)
|
uint64_t chunk_size)
|
||||||
{
|
{
|
||||||
@ -418,17 +418,17 @@ dsdiff_decode_chunk(struct decoder *decoder, struct input_stream *is,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dsdlib_skip(decoder, is, chunk_size);
|
return dsdlib_skip(&decoder, is, chunk_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dsdiff_stream_decode(struct decoder *decoder, struct input_stream *is)
|
dsdiff_stream_decode(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
DsdiffMetaData metadata;
|
DsdiffMetaData metadata;
|
||||||
|
|
||||||
DsdiffChunkHeader chunk_header;
|
DsdiffChunkHeader chunk_header;
|
||||||
/* check if it is is a proper DFF file */
|
/* check if it is is a proper DFF file */
|
||||||
if (!dsdiff_read_metadata(decoder, is, &metadata, &chunk_header))
|
if (!dsdiff_read_metadata(&decoder, is, &metadata, &chunk_header))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
@ -461,13 +461,13 @@ dsdiff_stream_decode(struct decoder *decoder, struct input_stream *is)
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* ignore other chunks */
|
/* ignore other chunks */
|
||||||
if (!dsdlib_skip(decoder, is, chunk_size))
|
if (!dsdlib_skip(&decoder, is, chunk_size))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read next chunk header; the first one was read by
|
/* read next chunk header; the first one was read by
|
||||||
dsdiff_read_metadata() */
|
dsdiff_read_metadata() */
|
||||||
if (!dsdiff_read_chunk_header(decoder,
|
if (!dsdiff_read_chunk_header(&decoder,
|
||||||
is, &chunk_header))
|
is, &chunk_header))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ struct DsfDataChunk {
|
|||||||
* Read and parse all needed metadata chunks for DSF files.
|
* Read and parse all needed metadata chunks for DSF files.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
|
dsf_read_metadata(Decoder *decoder, struct input_stream *is,
|
||||||
DsfMetaData *metadata)
|
DsfMetaData *metadata)
|
||||||
{
|
{
|
||||||
uint64_t chunk_size;
|
uint64_t chunk_size;
|
||||||
@ -219,7 +219,7 @@ dsf_to_pcm_order(uint8_t *dest, uint8_t *scratch, size_t nrbytes)
|
|||||||
* Decode one complete DSF 'data' chunk i.e. a complete song
|
* Decode one complete DSF 'data' chunk i.e. a complete song
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dsf_decode_chunk(struct decoder *decoder, struct input_stream *is,
|
dsf_decode_chunk(Decoder &decoder, struct input_stream *is,
|
||||||
unsigned channels,
|
unsigned channels,
|
||||||
uint64_t chunk_size,
|
uint64_t chunk_size,
|
||||||
bool bitreverse)
|
bool bitreverse)
|
||||||
@ -246,7 +246,7 @@ dsf_decode_chunk(struct decoder *decoder, struct input_stream *is,
|
|||||||
now_size = now_frames * frame_size;
|
now_size = now_frames * frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nbytes = decoder_read(decoder, is, buffer, now_size);
|
size_t nbytes = decoder_read(&decoder, is, buffer, now_size);
|
||||||
if (nbytes != now_size)
|
if (nbytes != now_size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -273,15 +273,15 @@ dsf_decode_chunk(struct decoder *decoder, struct input_stream *is,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dsdlib_skip(decoder, is, chunk_size);
|
return dsdlib_skip(&decoder, is, chunk_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dsf_stream_decode(struct decoder *decoder, struct input_stream *is)
|
dsf_stream_decode(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
/* check if it is a proper DSF file */
|
/* check if it is a proper DSF file */
|
||||||
DsfMetaData metadata;
|
DsfMetaData metadata;
|
||||||
if (!dsf_read_metadata(decoder, is, &metadata))
|
if (!dsf_read_metadata(&decoder, is, &metadata))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
|
@ -357,7 +357,7 @@ faad_get_file_time(struct input_stream *is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
faad_stream_decode(Decoder &mpd_decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
float total_time = 0;
|
float total_time = 0;
|
||||||
AudioFormat audio_format;
|
AudioFormat audio_format;
|
||||||
@ -365,7 +365,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
|||||||
uint16_t bit_rate = 0;
|
uint16_t bit_rate = 0;
|
||||||
DecoderBuffer *buffer;
|
DecoderBuffer *buffer;
|
||||||
|
|
||||||
buffer = decoder_buffer_new(mpd_decoder, is,
|
buffer = decoder_buffer_new(&mpd_decoder, is,
|
||||||
FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
|
FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
|
||||||
total_time = faad_song_duration(buffer, is);
|
total_time = faad_song_duration(buffer, is);
|
||||||
|
|
||||||
|
@ -91,14 +91,14 @@ mpd_ffmpeg_log_callback(gcc_unused void *ptr, int level,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct AvioStream {
|
struct AvioStream {
|
||||||
struct decoder *decoder;
|
Decoder *const decoder;
|
||||||
struct input_stream *input;
|
struct input_stream *input;
|
||||||
|
|
||||||
AVIOContext *io;
|
AVIOContext *io;
|
||||||
|
|
||||||
unsigned char buffer[8192];
|
unsigned char buffer[8192];
|
||||||
|
|
||||||
AvioStream(struct decoder *_decoder, input_stream *_input)
|
AvioStream(Decoder *_decoder, input_stream *_input)
|
||||||
:decoder(_decoder), input(_input), io(nullptr) {}
|
:decoder(_decoder), input(_input), io(nullptr) {}
|
||||||
|
|
||||||
~AvioStream() {
|
~AvioStream() {
|
||||||
@ -255,7 +255,7 @@ copy_interleave_frame(const AVCodecContext *codec_context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DecoderCommand
|
static DecoderCommand
|
||||||
ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
|
ffmpeg_send_packet(Decoder &decoder, struct input_stream *is,
|
||||||
const AVPacket *packet,
|
const AVPacket *packet,
|
||||||
AVCodecContext *codec_context,
|
AVCodecContext *codec_context,
|
||||||
const AVRational *time_base,
|
const AVRational *time_base,
|
||||||
@ -341,7 +341,7 @@ ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static AVInputFormat *
|
static AVInputFormat *
|
||||||
ffmpeg_probe(struct decoder *decoder, struct input_stream *is)
|
ffmpeg_probe(Decoder *decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
BUFFER_SIZE = 16384,
|
BUFFER_SIZE = 16384,
|
||||||
@ -370,16 +370,16 @@ ffmpeg_probe(struct decoder *decoder, struct input_stream *is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
ffmpeg_decode(Decoder &decoder, struct input_stream *input)
|
||||||
{
|
{
|
||||||
AVInputFormat *input_format = ffmpeg_probe(decoder, input);
|
AVInputFormat *input_format = ffmpeg_probe(&decoder, input);
|
||||||
if (input_format == nullptr)
|
if (input_format == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FormatDebug(ffmpeg_domain, "detected input format '%s' (%s)",
|
FormatDebug(ffmpeg_domain, "detected input format '%s' (%s)",
|
||||||
input_format->name, input_format->long_name);
|
input_format->name, input_format->long_name);
|
||||||
|
|
||||||
AvioStream stream(decoder, input);
|
AvioStream stream(&decoder, input);
|
||||||
if (!stream.Open()) {
|
if (!stream.Open()) {
|
||||||
LogError(ffmpeg_domain, "Failed to open stream");
|
LogError(ffmpeg_domain, "Failed to open stream");
|
||||||
return;
|
return;
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
flac_data::flac_data(struct decoder *_decoder,
|
flac_data::flac_data(Decoder &_decoder,
|
||||||
struct input_stream *_input_stream)
|
struct input_stream *_input_stream)
|
||||||
:FlacInput(_input_stream, _decoder),
|
:FlacInput(_input_stream, &_decoder),
|
||||||
initialized(false), unsupported(false),
|
initialized(false), unsupported(false),
|
||||||
total_frames(0), first_frame(0), next_frame(0), position(0),
|
total_frames(0), first_frame(0), next_frame(0), position(0),
|
||||||
decoder(_decoder), input_stream(_input_stream)
|
decoder(_decoder), input_stream(_input_stream)
|
||||||
|
@ -75,12 +75,12 @@ struct flac_data : public FlacInput {
|
|||||||
|
|
||||||
FLAC__uint64 position;
|
FLAC__uint64 position;
|
||||||
|
|
||||||
struct decoder *decoder;
|
Decoder &decoder;
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
|
|
||||||
Tag tag;
|
Tag tag;
|
||||||
|
|
||||||
flac_data(struct decoder *decoder, struct input_stream *input_stream);
|
flac_data(Decoder &decoder, struct input_stream *input_stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
||||||
|
@ -173,7 +173,7 @@ static void
|
|||||||
flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec,
|
flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec,
|
||||||
FLAC__uint64 t_start, FLAC__uint64 t_end)
|
FLAC__uint64 t_start, FLAC__uint64 t_end)
|
||||||
{
|
{
|
||||||
struct decoder *decoder = data->decoder;
|
Decoder &decoder = data->decoder;
|
||||||
|
|
||||||
data->first_frame = t_start;
|
data->first_frame = t_start;
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ stream_init(FLAC__StreamDecoder *flac_dec, struct flac_data *data, bool is_ogg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flac_decode_internal(struct decoder * decoder,
|
flac_decode_internal(Decoder &decoder,
|
||||||
struct input_stream *input_stream,
|
struct input_stream *input_stream,
|
||||||
bool is_ogg)
|
bool is_ogg)
|
||||||
{
|
{
|
||||||
@ -289,7 +289,7 @@ flac_decode_internal(struct decoder * decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flac_decode(struct decoder * decoder, struct input_stream *input_stream)
|
flac_decode(Decoder &decoder, struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
flac_decode_internal(decoder, input_stream, false);
|
flac_decode_internal(decoder, input_stream, false);
|
||||||
}
|
}
|
||||||
@ -333,9 +333,9 @@ oggflac_scan_stream(struct input_stream *is,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
oggflac_decode(struct decoder *decoder, struct input_stream *input_stream)
|
oggflac_decode(Decoder &decoder, struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
if (ogg_codec_detect(decoder, input_stream) != OGG_CODEC_FLAC)
|
if (ogg_codec_detect(&decoder, input_stream) != OGG_CODEC_FLAC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* rewind the stream, because ogg_codec_detect() has
|
/* rewind the stream, because ogg_codec_detect() has
|
||||||
|
@ -35,7 +35,7 @@ FlacInput::Read(FLAC__byte buffer[], size_t *bytes)
|
|||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
if (input_stream->LockIsEOF() ||
|
if (input_stream->LockIsEOF() ||
|
||||||
(decoder != nullptr &&
|
(decoder != nullptr &&
|
||||||
decoder_get_command(decoder) != DecoderCommand::NONE))
|
decoder_get_command(*decoder) != DecoderCommand::NONE))
|
||||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||||
else
|
else
|
||||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||||
@ -83,8 +83,8 @@ FLAC__bool
|
|||||||
FlacInput::Eof()
|
FlacInput::Eof()
|
||||||
{
|
{
|
||||||
return (decoder != nullptr &&
|
return (decoder != nullptr &&
|
||||||
decoder_get_command(decoder) != DecoderCommand::NONE &&
|
decoder_get_command(*decoder) != DecoderCommand::NONE &&
|
||||||
decoder_get_command(decoder) != DecoderCommand::SEEK) ||
|
decoder_get_command(*decoder) != DecoderCommand::SEEK) ||
|
||||||
input_stream->LockIsEOF();
|
input_stream->LockIsEOF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ void
|
|||||||
FlacInput::Error(FLAC__StreamDecoderErrorStatus status)
|
FlacInput::Error(FLAC__StreamDecoderErrorStatus status)
|
||||||
{
|
{
|
||||||
if (decoder == nullptr ||
|
if (decoder == nullptr ||
|
||||||
decoder_get_command(decoder) != DecoderCommand::STOP)
|
decoder_get_command(*decoder) != DecoderCommand::STOP)
|
||||||
LogWarning(flac_domain,
|
LogWarning(flac_domain,
|
||||||
FLAC__StreamDecoderErrorStatusString[status]);
|
FLAC__StreamDecoderErrorStatusString[status]);
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,20 @@
|
|||||||
|
|
||||||
#include <FLAC/stream_decoder.h>
|
#include <FLAC/stream_decoder.h>
|
||||||
|
|
||||||
|
struct Decoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class wraps an #input_stream in libFLAC stream decoder
|
* This class wraps an #input_stream in libFLAC stream decoder
|
||||||
* callbacks.
|
* callbacks.
|
||||||
*/
|
*/
|
||||||
class FlacInput {
|
class FlacInput {
|
||||||
struct decoder *decoder;
|
Decoder *const decoder;
|
||||||
|
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FlacInput(struct input_stream *_input_stream,
|
FlacInput(struct input_stream *_input_stream,
|
||||||
struct decoder *_decoder=nullptr)
|
Decoder *_decoder=nullptr)
|
||||||
:decoder(_decoder), input_stream(_input_stream) {}
|
:decoder(_decoder), input_stream(_input_stream) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -92,7 +92,7 @@ fluidsynth_init(const config_param ¶m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
|
fluidsynth_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
char setting_sample_rate[] = "synth.sample-rate";
|
char setting_sample_rate[] = "synth.sample-rate";
|
||||||
/*
|
/*
|
||||||
|
@ -130,7 +130,7 @@ gme_container_scan(const char *path_fs, const unsigned int tnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gme_file_decode(struct decoder *decoder, const char *path_fs)
|
gme_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
char *path_container = get_container_name(path_fs);
|
char *path_container = get_container_name(path_fs);
|
||||||
|
|
||||||
|
@ -139,11 +139,11 @@ struct MadDecoder {
|
|||||||
bool found_first_frame;
|
bool found_first_frame;
|
||||||
bool decoded_first_frame;
|
bool decoded_first_frame;
|
||||||
unsigned long bit_rate;
|
unsigned long bit_rate;
|
||||||
struct decoder *decoder;
|
Decoder *const decoder;
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
enum mad_layer layer;
|
enum mad_layer layer;
|
||||||
|
|
||||||
MadDecoder(struct decoder *decoder, struct input_stream *input_stream);
|
MadDecoder(Decoder *decoder, struct input_stream *input_stream);
|
||||||
~MadDecoder();
|
~MadDecoder();
|
||||||
|
|
||||||
bool Seek(long offset);
|
bool Seek(long offset);
|
||||||
@ -184,7 +184,7 @@ struct MadDecoder {
|
|||||||
bool Read();
|
bool Read();
|
||||||
};
|
};
|
||||||
|
|
||||||
MadDecoder::MadDecoder(struct decoder *_decoder,
|
MadDecoder::MadDecoder(Decoder *_decoder,
|
||||||
struct input_stream *_input_stream)
|
struct input_stream *_input_stream)
|
||||||
:mute_frame(MUTEFRAME_NONE),
|
:mute_frame(MUTEFRAME_NONE),
|
||||||
frame_offsets(nullptr),
|
frame_offsets(nullptr),
|
||||||
@ -397,12 +397,12 @@ MadDecoder::ParseId3(size_t tagsize, Tag **mpd_tag)
|
|||||||
char *mixramp_end;
|
char *mixramp_end;
|
||||||
|
|
||||||
if (parse_id3_replay_gain_info(&rgi, id3_tag)) {
|
if (parse_id3_replay_gain_info(&rgi, id3_tag)) {
|
||||||
decoder_replay_gain(decoder, &rgi);
|
decoder_replay_gain(*decoder, &rgi);
|
||||||
found_replay_gain = true;
|
found_replay_gain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_id3_mixramp(&mixramp_start, &mixramp_end, id3_tag))
|
if (parse_id3_mixramp(&mixramp_start, &mixramp_end, id3_tag))
|
||||||
decoder_mixramp(decoder, mixramp_start, mixramp_end);
|
decoder_mixramp(*decoder, mixramp_start, mixramp_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
id3_tag_delete(id3_tag);
|
id3_tag_delete(id3_tag);
|
||||||
@ -875,7 +875,7 @@ MadDecoder::DecodeFirstFrame(Tag **tag)
|
|||||||
replay_gain_info_init(&rgi);
|
replay_gain_info_init(&rgi);
|
||||||
rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain;
|
rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain;
|
||||||
rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak;
|
rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak;
|
||||||
decoder_replay_gain(decoder, &rgi);
|
decoder_replay_gain(*decoder, &rgi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -979,7 +979,7 @@ MadDecoder::SendPCM(unsigned i, unsigned pcm_length)
|
|||||||
MAD_NCHANNELS(&frame.header));
|
MAD_NCHANNELS(&frame.header));
|
||||||
num_samples *= MAD_NCHANNELS(&frame.header);
|
num_samples *= MAD_NCHANNELS(&frame.header);
|
||||||
|
|
||||||
auto cmd = decoder_data(decoder, input_stream, output_buffer,
|
auto cmd = decoder_data(*decoder, input_stream, output_buffer,
|
||||||
sizeof(output_buffer[0]) * num_samples,
|
sizeof(output_buffer[0]) * num_samples,
|
||||||
bit_rate / 1000);
|
bit_rate / 1000);
|
||||||
if (cmd != DecoderCommand::NONE)
|
if (cmd != DecoderCommand::NONE)
|
||||||
@ -1065,17 +1065,17 @@ MadDecoder::Read()
|
|||||||
|
|
||||||
assert(input_stream->IsSeekable());
|
assert(input_stream->IsSeekable());
|
||||||
|
|
||||||
j = TimeToFrame(decoder_seek_where(decoder));
|
j = TimeToFrame(decoder_seek_where(*decoder));
|
||||||
if (j < highest_frame) {
|
if (j < highest_frame) {
|
||||||
if (Seek(frame_offsets[j])) {
|
if (Seek(frame_offsets[j])) {
|
||||||
current_frame = j;
|
current_frame = j;
|
||||||
decoder_command_finished(decoder);
|
decoder_command_finished(*decoder);
|
||||||
} else
|
} else
|
||||||
decoder_seek_error(decoder);
|
decoder_seek_error(*decoder);
|
||||||
} else {
|
} else {
|
||||||
seek_where = decoder_seek_where(decoder);
|
seek_where = decoder_seek_where(*decoder);
|
||||||
mute_frame = MUTEFRAME_SEEK;
|
mute_frame = MUTEFRAME_SEEK;
|
||||||
decoder_command_finished(decoder);
|
decoder_command_finished(*decoder);
|
||||||
}
|
}
|
||||||
} else if (cmd != DecoderCommand::NONE)
|
} else if (cmd != DecoderCommand::NONE)
|
||||||
return false;
|
return false;
|
||||||
@ -1090,7 +1090,7 @@ MadDecoder::Read()
|
|||||||
ret = DecodeNextFrameHeader(&tag);
|
ret = DecodeNextFrameHeader(&tag);
|
||||||
|
|
||||||
if (tag != nullptr) {
|
if (tag != nullptr) {
|
||||||
decoder_tag(decoder, input_stream,
|
decoder_tag(*decoder, input_stream,
|
||||||
std::move(*tag));
|
std::move(*tag));
|
||||||
delete tag;
|
delete tag;
|
||||||
}
|
}
|
||||||
@ -1116,9 +1116,9 @@ MadDecoder::Read()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
mp3_decode(Decoder &decoder, struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
MadDecoder data(decoder, input_stream);
|
MadDecoder data(&decoder, input_stream);
|
||||||
|
|
||||||
Tag *tag = nullptr;
|
Tag *tag = nullptr;
|
||||||
if (!data.DecodeFirstFrame(&tag)) {
|
if (!data.DecodeFirstFrame(&tag)) {
|
||||||
|
@ -146,7 +146,7 @@ mikmod_decoder_finish(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
|
mikmod_decoder_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
/* deconstify the path because libmikmod wants a non-const
|
/* deconstify the path because libmikmod wants a non-const
|
||||||
string pointer */
|
string pointer */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <libmodplug/modplug.h>
|
#include <libmodplug/modplug.h>
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static constexpr Domain modplug_domain("modplug");
|
static constexpr Domain modplug_domain("modplug");
|
||||||
@ -51,7 +52,7 @@ modplug_decoder_init(const config_param ¶m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static WritableBuffer<uint8_t>
|
static WritableBuffer<uint8_t>
|
||||||
mod_loadfile(struct decoder *decoder, struct input_stream *is)
|
mod_loadfile(Decoder *decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
const input_stream::offset_type size = is->GetSize();
|
const input_stream::offset_type size = is->GetSize();
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ mod_loadfile(struct decoder *decoder, struct input_stream *is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ModPlugFile *
|
static ModPlugFile *
|
||||||
LoadModPlugFile(struct decoder *decoder, struct input_stream *is)
|
LoadModPlugFile(Decoder *decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
const auto buffer = mod_loadfile(decoder, is);
|
const auto buffer = mod_loadfile(decoder, is);
|
||||||
if (buffer.IsNull()) {
|
if (buffer.IsNull()) {
|
||||||
@ -120,7 +121,7 @@ LoadModPlugFile(struct decoder *decoder, struct input_stream *is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mod_decode(struct decoder *decoder, struct input_stream *is)
|
mod_decode(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
ModPlug_Settings settings;
|
ModPlug_Settings settings;
|
||||||
int ret;
|
int ret;
|
||||||
@ -136,7 +137,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
|
|||||||
/* insert more setting changes here */
|
/* insert more setting changes here */
|
||||||
ModPlug_SetSettings(&settings);
|
ModPlug_SetSettings(&settings);
|
||||||
|
|
||||||
ModPlugFile *f = LoadModPlugFile(decoder, is);
|
ModPlugFile *f = LoadModPlugFile(&decoder, is);
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
LogWarning(modplug_domain, "could not decode stream");
|
LogWarning(modplug_domain, "could not decode stream");
|
||||||
return;
|
return;
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
struct mpc_decoder_data {
|
struct mpc_decoder_data {
|
||||||
struct input_stream *is;
|
struct input_stream *is;
|
||||||
struct decoder *decoder;
|
Decoder *decoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr Domain mpcdec_domain("mpcdec");
|
static constexpr Domain mpcdec_domain("mpcdec");
|
||||||
@ -130,13 +130,13 @@ mpc_to_mpd_buffer(int32_t *dest, const MPC_SAMPLE_FORMAT *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
mpcdec_decode(Decoder &mpd_decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
|
MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
|
||||||
|
|
||||||
struct mpc_decoder_data data;
|
struct mpc_decoder_data data;
|
||||||
data.is = is;
|
data.is = is;
|
||||||
data.decoder = mpd_decoder;
|
data.decoder = &mpd_decoder;
|
||||||
|
|
||||||
mpc_reader reader;
|
mpc_reader reader;
|
||||||
reader.read = mpc_read_cb;
|
reader.read = mpc_read_cb;
|
||||||
|
@ -104,7 +104,7 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
|
mpd_mpg123_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
mpg123_handle *handle;
|
mpg123_handle *handle;
|
||||||
int error;
|
int error;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
enum ogg_codec
|
enum ogg_codec
|
||||||
ogg_codec_detect(struct decoder *decoder, struct input_stream *is)
|
ogg_codec_detect(Decoder *decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
/* oggflac detection based on code in ogg123 and this post
|
/* oggflac detection based on code in ogg123 and this post
|
||||||
* http://lists.xiph.org/pipermail/flac/2004-December/000393.html
|
* http://lists.xiph.org/pipermail/flac/2004-December/000393.html
|
||||||
|
@ -34,6 +34,6 @@ enum ogg_codec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum ogg_codec
|
enum ogg_codec
|
||||||
ogg_codec_detect(struct decoder *decoder, struct input_stream *is);
|
ogg_codec_detect(Decoder *decoder, struct input_stream *is);
|
||||||
|
|
||||||
#endif /* _OGG_COMMON_H */
|
#endif /* _OGG_COMMON_H */
|
||||||
|
@ -34,10 +34,10 @@ class OggSyncState {
|
|||||||
ogg_sync_state oy;
|
ogg_sync_state oy;
|
||||||
|
|
||||||
input_stream &is;
|
input_stream &is;
|
||||||
struct decoder *const decoder;
|
Decoder *const decoder;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OggSyncState(input_stream &_is, struct decoder *const _decoder=nullptr)
|
OggSyncState(input_stream &_is, Decoder *const _decoder=nullptr)
|
||||||
:is(_is), decoder(_decoder) {
|
:is(_is), decoder(_decoder) {
|
||||||
ogg_sync_init(&oy);
|
ogg_sync_init(&oy);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "DecoderAPI.hxx"
|
#include "DecoderAPI.hxx"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OggFeed(ogg_sync_state &oy, struct decoder *decoder,
|
OggFeed(ogg_sync_state &oy, Decoder *decoder,
|
||||||
input_stream *input_stream, size_t size)
|
input_stream *input_stream, size_t size)
|
||||||
{
|
{
|
||||||
char *buffer = ogg_sync_buffer(&oy, size);
|
char *buffer = ogg_sync_buffer(&oy, size);
|
||||||
@ -40,7 +40,7 @@ OggFeed(ogg_sync_state &oy, struct decoder *decoder,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
OggExpectPage(ogg_sync_state &oy, ogg_page &page,
|
OggExpectPage(ogg_sync_state &oy, ogg_page &page,
|
||||||
decoder *decoder, input_stream *input_stream)
|
Decoder *decoder, input_stream *input_stream)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
int r = ogg_sync_pageout(&oy, &page);
|
int r = ogg_sync_pageout(&oy, &page);
|
||||||
@ -54,7 +54,7 @@ OggExpectPage(ogg_sync_state &oy, ogg_page &page,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
OggExpectFirstPage(ogg_sync_state &oy, ogg_stream_state &os,
|
OggExpectFirstPage(ogg_sync_state &oy, ogg_stream_state &os,
|
||||||
decoder *decoder, input_stream *is)
|
Decoder *decoder, input_stream *is)
|
||||||
{
|
{
|
||||||
ogg_page page;
|
ogg_page page;
|
||||||
if (!OggExpectPage(oy, page, decoder, is))
|
if (!OggExpectPage(oy, page, decoder, is))
|
||||||
@ -67,7 +67,7 @@ OggExpectFirstPage(ogg_sync_state &oy, ogg_stream_state &os,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
OggExpectPageIn(ogg_sync_state &oy, ogg_stream_state &os,
|
OggExpectPageIn(ogg_sync_state &oy, ogg_stream_state &os,
|
||||||
decoder *decoder, input_stream *is)
|
Decoder *decoder, input_stream *is)
|
||||||
{
|
{
|
||||||
ogg_page page;
|
ogg_page page;
|
||||||
if (!OggExpectPage(oy, page, decoder, is))
|
if (!OggExpectPage(oy, page, decoder, is))
|
||||||
@ -79,7 +79,7 @@ OggExpectPageIn(ogg_sync_state &oy, ogg_stream_state &os,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
|
OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
|
||||||
decoder *decoder, input_stream *input_stream)
|
Decoder *decoder, input_stream *input_stream)
|
||||||
{
|
{
|
||||||
size_t remaining_skipped = 16384;
|
size_t remaining_skipped = 16384;
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
OggExpectPageSeekIn(ogg_sync_state &oy, ogg_stream_state &os,
|
OggExpectPageSeekIn(ogg_sync_state &oy, ogg_stream_state &os,
|
||||||
decoder *decoder, input_stream *is)
|
Decoder *decoder, input_stream *is)
|
||||||
{
|
{
|
||||||
ogg_page page;
|
ogg_page page;
|
||||||
if (!OggExpectPageSeek(oy, page, decoder, is))
|
if (!OggExpectPageSeek(oy, page, decoder, is))
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct input_stream;
|
struct input_stream;
|
||||||
struct decoder;
|
struct Decoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feed data from the #input_stream into the #ogg_sync_state.
|
* Feed data from the #input_stream into the #ogg_sync_state.
|
||||||
@ -35,7 +35,7 @@ struct decoder;
|
|||||||
* @return false on error or end-of-file
|
* @return false on error or end-of-file
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
OggFeed(ogg_sync_state &oy, struct decoder *decoder, input_stream *is,
|
OggFeed(ogg_sync_state &oy, Decoder *decoder, input_stream *is,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +46,7 @@ OggFeed(ogg_sync_state &oy, struct decoder *decoder, input_stream *is,
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
OggExpectPage(ogg_sync_state &oy, ogg_page &page,
|
OggExpectPage(ogg_sync_state &oy, ogg_page &page,
|
||||||
decoder *decoder, input_stream *input_stream);
|
Decoder *decoder, input_stream *input_stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines OggExpectPage(), ogg_stream_init() and
|
* Combines OggExpectPage(), ogg_stream_init() and
|
||||||
@ -57,7 +57,7 @@ OggExpectPage(ogg_sync_state &oy, ogg_page &page,
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
OggExpectFirstPage(ogg_sync_state &oy, ogg_stream_state &os,
|
OggExpectFirstPage(ogg_sync_state &oy, ogg_stream_state &os,
|
||||||
decoder *decoder, input_stream *is);
|
Decoder *decoder, input_stream *is);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines OggExpectPage() and ogg_stream_pagein().
|
* Combines OggExpectPage() and ogg_stream_pagein().
|
||||||
@ -66,14 +66,14 @@ OggExpectFirstPage(ogg_sync_state &oy, ogg_stream_state &os,
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
OggExpectPageIn(ogg_sync_state &oy, ogg_stream_state &os,
|
OggExpectPageIn(ogg_sync_state &oy, ogg_stream_state &os,
|
||||||
decoder *decoder, input_stream *is);
|
Decoder *decoder, input_stream *is);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like OggExpectPage(), but allow skipping garbage (after seeking).
|
* Like OggExpectPage(), but allow skipping garbage (after seeking).
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
|
OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
|
||||||
decoder *decoder, input_stream *input_stream);
|
Decoder *decoder, input_stream *input_stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines OggExpectPageSeek() and ogg_stream_pagein().
|
* Combines OggExpectPageSeek() and ogg_stream_pagein().
|
||||||
@ -82,6 +82,6 @@ OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
OggExpectPageSeekIn(ogg_sync_state &oy, ogg_stream_state &os,
|
OggExpectPageSeekIn(ogg_sync_state &oy, ogg_stream_state &os,
|
||||||
decoder *decoder, input_stream *is);
|
Decoder *decoder, input_stream *is);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,7 +67,7 @@ mpd_opus_init(gcc_unused const config_param ¶m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MPDOpusDecoder {
|
class MPDOpusDecoder {
|
||||||
struct decoder *decoder;
|
Decoder &decoder;
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
|
|
||||||
ogg_stream_state os;
|
ogg_stream_state os;
|
||||||
@ -84,7 +84,7 @@ class MPDOpusDecoder {
|
|||||||
size_t frame_size;
|
size_t frame_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MPDOpusDecoder(struct decoder *_decoder,
|
MPDOpusDecoder(Decoder &_decoder,
|
||||||
struct input_stream *_input_stream)
|
struct input_stream *_input_stream)
|
||||||
:decoder(_decoder), input_stream(_input_stream),
|
:decoder(_decoder), input_stream(_input_stream),
|
||||||
opus_decoder(nullptr),
|
opus_decoder(nullptr),
|
||||||
@ -265,10 +265,10 @@ MPDOpusDecoder::HandleAudio(const ogg_packet &packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mpd_opus_stream_decode(struct decoder *decoder,
|
mpd_opus_stream_decode(Decoder &decoder,
|
||||||
struct input_stream *input_stream)
|
struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
if (ogg_codec_detect(decoder, input_stream) != OGG_CODEC_OPUS)
|
if (ogg_codec_detect(&decoder, input_stream) != OGG_CODEC_OPUS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* rewind the stream, because ogg_codec_detect() has
|
/* rewind the stream, because ogg_codec_detect() has
|
||||||
@ -276,7 +276,7 @@ mpd_opus_stream_decode(struct decoder *decoder,
|
|||||||
input_stream->LockSeek(0, SEEK_SET, IgnoreError());
|
input_stream->LockSeek(0, SEEK_SET, IgnoreError());
|
||||||
|
|
||||||
MPDOpusDecoder d(decoder, input_stream);
|
MPDOpusDecoder d(decoder, input_stream);
|
||||||
OggSyncState oy(*input_stream, decoder);
|
OggSyncState oy(*input_stream, &decoder);
|
||||||
|
|
||||||
if (!d.ReadFirstPage(oy))
|
if (!d.ReadFirstPage(oy))
|
||||||
return;
|
return;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include <stdio.h> /* for SEEK_SET */
|
#include <stdio.h> /* for SEEK_SET */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
|
pcm_stream_decode(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
static constexpr AudioFormat audio_format = {
|
static constexpr AudioFormat audio_format = {
|
||||||
44100,
|
44100,
|
||||||
|
@ -201,7 +201,7 @@ get_song_length(const char *path_fs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sidplay_file_decode(struct decoder *decoder, const char *path_fs)
|
sidplay_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
int channels;
|
int channels;
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ time_to_frame(float t, const AudioFormat *audio_format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
|
sndfile_stream_decode(Decoder &decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
SNDFILE *sf;
|
SNDFILE *sf;
|
||||||
SF_INFO info;
|
SF_INFO info;
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
struct vorbis_input_stream {
|
struct vorbis_input_stream {
|
||||||
struct decoder *decoder;
|
Decoder *decoder;
|
||||||
|
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
bool seekable;
|
bool seekable;
|
||||||
@ -76,7 +76,8 @@ static int ogg_seek_cb(void *data, ogg_int64_t offset, int whence)
|
|||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
return vis->seekable &&
|
return vis->seekable &&
|
||||||
(!vis->decoder || decoder_get_command(vis->decoder) != DecoderCommand::STOP) &&
|
(vis->decoder == nullptr ||
|
||||||
|
decoder_get_command(*vis->decoder) != DecoderCommand::STOP) &&
|
||||||
vis->input_stream->LockSeek(offset, whence, error)
|
vis->input_stream->LockSeek(offset, whence, error)
|
||||||
? 0 : -1;
|
? 0 : -1;
|
||||||
}
|
}
|
||||||
@ -127,7 +128,7 @@ vorbis_strerror(int code)
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
vorbis_is_open(struct vorbis_input_stream *vis, OggVorbis_File *vf,
|
vorbis_is_open(struct vorbis_input_stream *vis, OggVorbis_File *vf,
|
||||||
struct decoder *decoder, struct input_stream *input_stream)
|
Decoder *decoder, struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
vis->decoder = decoder;
|
vis->decoder = decoder;
|
||||||
vis->input_stream = input_stream;
|
vis->input_stream = input_stream;
|
||||||
@ -136,7 +137,7 @@ vorbis_is_open(struct vorbis_input_stream *vis, OggVorbis_File *vf,
|
|||||||
int ret = ov_open_callbacks(vis, vf, NULL, 0, vorbis_is_callbacks);
|
int ret = ov_open_callbacks(vis, vf, NULL, 0, vorbis_is_callbacks);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (decoder == NULL ||
|
if (decoder == NULL ||
|
||||||
decoder_get_command(decoder) == DecoderCommand::NONE)
|
decoder_get_command(*decoder) == DecoderCommand::NONE)
|
||||||
FormatWarning(vorbis_domain,
|
FormatWarning(vorbis_domain,
|
||||||
"Failed to open Ogg Vorbis stream: %s",
|
"Failed to open Ogg Vorbis stream: %s",
|
||||||
vorbis_strerror(ret));
|
vorbis_strerror(ret));
|
||||||
@ -147,7 +148,7 @@ vorbis_is_open(struct vorbis_input_stream *vis, OggVorbis_File *vf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vorbis_send_comments(struct decoder *decoder, struct input_stream *is,
|
vorbis_send_comments(Decoder &decoder, struct input_stream *is,
|
||||||
char **comments)
|
char **comments)
|
||||||
{
|
{
|
||||||
Tag *tag = vorbis_comments_to_tag(comments);
|
Tag *tag = vorbis_comments_to_tag(comments);
|
||||||
@ -175,10 +176,10 @@ vorbis_interleave(float *dest, const float *const*src,
|
|||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
static void
|
static void
|
||||||
vorbis_stream_decode(struct decoder *decoder,
|
vorbis_stream_decode(Decoder &decoder,
|
||||||
struct input_stream *input_stream)
|
struct input_stream *input_stream)
|
||||||
{
|
{
|
||||||
if (ogg_codec_detect(decoder, input_stream) != OGG_CODEC_VORBIS)
|
if (ogg_codec_detect(&decoder, input_stream) != OGG_CODEC_VORBIS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* rewind the stream, because ogg_codec_detect() has
|
/* rewind the stream, because ogg_codec_detect() has
|
||||||
@ -187,7 +188,7 @@ vorbis_stream_decode(struct decoder *decoder,
|
|||||||
|
|
||||||
struct vorbis_input_stream vis;
|
struct vorbis_input_stream vis;
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
if (!vorbis_is_open(&vis, &vf, decoder, input_stream))
|
if (!vorbis_is_open(&vis, &vf, &decoder, input_stream))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const vorbis_info *vi = ov_info(&vf, -1);
|
const vorbis_info *vi = ov_info(&vf, -1);
|
||||||
|
@ -138,7 +138,7 @@ wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample)
|
|||||||
* Requires an already opened WavpackContext.
|
* Requires an already opened WavpackContext.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
|
wavpack_decode(Decoder &decoder, WavpackContext *wpc, bool can_seek)
|
||||||
{
|
{
|
||||||
bool is_float;
|
bool is_float;
|
||||||
SampleFormat sample_format;
|
SampleFormat sample_format;
|
||||||
@ -345,7 +345,7 @@ wavpack_scan_file(const char *fname,
|
|||||||
|
|
||||||
/* This struct is needed for per-stream last_byte storage. */
|
/* This struct is needed for per-stream last_byte storage. */
|
||||||
struct wavpack_input {
|
struct wavpack_input {
|
||||||
struct decoder *decoder;
|
Decoder *decoder;
|
||||||
struct input_stream *is;
|
struct input_stream *is;
|
||||||
/* Needed for push_back_byte() */
|
/* Needed for push_back_byte() */
|
||||||
int last_byte;
|
int last_byte;
|
||||||
@ -449,16 +449,16 @@ static WavpackStreamReader mpd_is_reader = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wavpack_input_init(struct wavpack_input *isp, struct decoder *decoder,
|
wavpack_input_init(struct wavpack_input *isp, Decoder &decoder,
|
||||||
struct input_stream *is)
|
struct input_stream *is)
|
||||||
{
|
{
|
||||||
isp->decoder = decoder;
|
isp->decoder = &decoder;
|
||||||
isp->is = is;
|
isp->is = is;
|
||||||
isp->last_byte = EOF;
|
isp->last_byte = EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct input_stream *
|
static struct input_stream *
|
||||||
wavpack_open_wvc(struct decoder *decoder, const char *uri,
|
wavpack_open_wvc(Decoder &decoder, const char *uri,
|
||||||
Mutex &mutex, Cond &cond,
|
Mutex &mutex, Cond &cond,
|
||||||
struct wavpack_input *wpi)
|
struct wavpack_input *wpi)
|
||||||
{
|
{
|
||||||
@ -504,7 +504,7 @@ wavpack_open_wvc(struct decoder *decoder, const char *uri,
|
|||||||
* Decodes a stream.
|
* Decodes a stream.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
wavpack_streamdecode(struct decoder * decoder, struct input_stream *is)
|
wavpack_streamdecode(Decoder & decoder, struct input_stream *is)
|
||||||
{
|
{
|
||||||
char error[ERRORLEN];
|
char error[ERRORLEN];
|
||||||
WavpackContext *wpc;
|
WavpackContext *wpc;
|
||||||
@ -550,7 +550,7 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is)
|
|||||||
* Decodes a file.
|
* Decodes a file.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
wavpack_filedecode(struct decoder *decoder, const char *fname)
|
wavpack_filedecode(Decoder &decoder, const char *fname)
|
||||||
{
|
{
|
||||||
char error[ERRORLEN];
|
char error[ERRORLEN];
|
||||||
WavpackContext *wpc;
|
WavpackContext *wpc;
|
||||||
|
@ -65,7 +65,7 @@ wildmidi_finish(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
|
wildmidi_file_decode(Decoder &decoder, const char *path_fs)
|
||||||
{
|
{
|
||||||
static constexpr AudioFormat audio_format = {
|
static constexpr AudioFormat audio_format = {
|
||||||
WILDMIDI_SAMPLE_RATE,
|
WILDMIDI_SAMPLE_RATE,
|
||||||
|
@ -54,7 +54,7 @@ my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_initialized(gcc_unused struct decoder *decoder,
|
decoder_initialized(gcc_unused Decoder &decoder,
|
||||||
gcc_unused const AudioFormat audio_format,
|
gcc_unused const AudioFormat audio_format,
|
||||||
gcc_unused bool seekable,
|
gcc_unused bool seekable,
|
||||||
gcc_unused float total_time)
|
gcc_unused float total_time)
|
||||||
@ -62,29 +62,29 @@ decoder_initialized(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_get_command(gcc_unused struct decoder *decoder)
|
decoder_get_command(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
return DecoderCommand::NONE;
|
return DecoderCommand::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_command_finished(gcc_unused struct decoder *decoder)
|
decoder_command_finished(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
decoder_seek_where(gcc_unused struct decoder *decoder)
|
decoder_seek_where(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_seek_error(gcc_unused struct decoder *decoder)
|
decoder_seek_error(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
decoder_read(gcc_unused struct decoder *decoder,
|
decoder_read(gcc_unused Decoder *decoder,
|
||||||
struct input_stream *is,
|
struct input_stream *is,
|
||||||
void *buffer, size_t length)
|
void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
@ -93,13 +93,13 @@ decoder_read(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_timestamp(gcc_unused struct decoder *decoder,
|
decoder_timestamp(gcc_unused Decoder &decoder,
|
||||||
gcc_unused double t)
|
gcc_unused double t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_data(gcc_unused struct decoder *decoder,
|
decoder_data(gcc_unused Decoder &decoder,
|
||||||
gcc_unused struct input_stream *is,
|
gcc_unused struct input_stream *is,
|
||||||
const void *data, size_t datalen,
|
const void *data, size_t datalen,
|
||||||
gcc_unused uint16_t kbit_rate)
|
gcc_unused uint16_t kbit_rate)
|
||||||
@ -109,7 +109,7 @@ decoder_data(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_tag(gcc_unused struct decoder *decoder,
|
decoder_tag(gcc_unused Decoder &decoder,
|
||||||
gcc_unused struct input_stream *is,
|
gcc_unused struct input_stream *is,
|
||||||
gcc_unused Tag &&tag)
|
gcc_unused Tag &&tag)
|
||||||
{
|
{
|
||||||
@ -117,7 +117,7 @@ decoder_tag(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_replay_gain(gcc_unused struct decoder *decoder,
|
decoder_replay_gain(gcc_unused Decoder &decoder,
|
||||||
const struct replay_gain_info *replay_gain_info)
|
const struct replay_gain_info *replay_gain_info)
|
||||||
{
|
{
|
||||||
const struct replay_gain_tuple *tuple =
|
const struct replay_gain_tuple *tuple =
|
||||||
@ -133,7 +133,7 @@ decoder_replay_gain(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_mixramp(gcc_unused struct decoder *decoder,
|
decoder_mixramp(gcc_unused Decoder &decoder,
|
||||||
char *mixramp_start, char *mixramp_end)
|
char *mixramp_start, char *mixramp_end)
|
||||||
{
|
{
|
||||||
g_free(mixramp_start);
|
g_free(mixramp_start);
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_initialized(gcc_unused struct decoder *decoder,
|
decoder_initialized(gcc_unused Decoder &decoder,
|
||||||
gcc_unused const AudioFormat audio_format,
|
gcc_unused const AudioFormat audio_format,
|
||||||
gcc_unused bool seekable,
|
gcc_unused bool seekable,
|
||||||
gcc_unused float total_time)
|
gcc_unused float total_time)
|
||||||
@ -50,26 +50,29 @@ decoder_initialized(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_get_command(gcc_unused struct decoder *decoder)
|
decoder_get_command(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
return DecoderCommand::NONE;
|
return DecoderCommand::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_command_finished(gcc_unused struct decoder *decoder)
|
void
|
||||||
|
decoder_command_finished(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double decoder_seek_where(gcc_unused struct decoder *decoder)
|
double
|
||||||
|
decoder_seek_where(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_seek_error(gcc_unused struct decoder *decoder)
|
void
|
||||||
|
decoder_seek_error(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
decoder_read(gcc_unused struct decoder *decoder,
|
decoder_read(gcc_unused Decoder *decoder,
|
||||||
struct input_stream *is,
|
struct input_stream *is,
|
||||||
void *buffer, size_t length)
|
void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
@ -78,23 +81,23 @@ decoder_read(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_timestamp(gcc_unused struct decoder *decoder,
|
decoder_timestamp(gcc_unused Decoder &decoder,
|
||||||
gcc_unused double t)
|
gcc_unused double t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_data(gcc_unused struct decoder *decoder,
|
decoder_data(gcc_unused Decoder &decoder,
|
||||||
gcc_unused struct input_stream *is,
|
gcc_unused struct input_stream *is,
|
||||||
const void *data, size_t datalen,
|
const void *data, size_t datalen,
|
||||||
gcc_unused uint16_t bit_rate)
|
gcc_unused uint16_t kbit_rate)
|
||||||
{
|
{
|
||||||
gcc_unused ssize_t nbytes = write(1, data, datalen);
|
gcc_unused ssize_t nbytes = write(1, data, datalen);
|
||||||
return DecoderCommand::NONE;
|
return DecoderCommand::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_tag(gcc_unused struct decoder *decoder,
|
decoder_tag(gcc_unused Decoder &decoder,
|
||||||
gcc_unused struct input_stream *is,
|
gcc_unused struct input_stream *is,
|
||||||
gcc_unused Tag &&tag)
|
gcc_unused Tag &&tag)
|
||||||
{
|
{
|
||||||
@ -102,13 +105,13 @@ decoder_tag(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_replay_gain(gcc_unused struct decoder *decoder,
|
decoder_replay_gain(gcc_unused Decoder &decoder,
|
||||||
gcc_unused const struct replay_gain_info *replay_gain_info)
|
gcc_unused const struct replay_gain_info *replay_gain_info)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_mixramp(gcc_unused struct decoder *decoder,
|
decoder_mixramp(gcc_unused Decoder &decoder,
|
||||||
char *mixramp_start, char *mixramp_end)
|
char *mixramp_start, char *mixramp_end)
|
||||||
{
|
{
|
||||||
g_free(mixramp_start);
|
g_free(mixramp_start);
|
||||||
|
@ -45,7 +45,7 @@ my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level,
|
|||||||
g_printerr("%s\n", message);
|
g_printerr("%s\n", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct decoder {
|
struct Decoder {
|
||||||
const char *uri;
|
const char *uri;
|
||||||
|
|
||||||
const struct DecoderPlugin *plugin;
|
const struct DecoderPlugin *plugin;
|
||||||
@ -54,43 +54,46 @@ struct decoder {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_initialized(struct decoder *decoder,
|
decoder_initialized(Decoder &decoder,
|
||||||
const AudioFormat audio_format,
|
const AudioFormat audio_format,
|
||||||
gcc_unused bool seekable,
|
gcc_unused bool seekable,
|
||||||
gcc_unused float total_time)
|
gcc_unused float total_time)
|
||||||
{
|
{
|
||||||
struct audio_format_string af_string;
|
struct audio_format_string af_string;
|
||||||
|
|
||||||
assert(!decoder->initialized);
|
assert(!decoder.initialized);
|
||||||
assert(audio_format.IsValid());
|
assert(audio_format.IsValid());
|
||||||
|
|
||||||
g_printerr("audio_format=%s\n",
|
g_printerr("audio_format=%s\n",
|
||||||
audio_format_to_string(audio_format, &af_string));
|
audio_format_to_string(audio_format, &af_string));
|
||||||
|
|
||||||
decoder->initialized = true;
|
decoder.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_get_command(gcc_unused struct decoder *decoder)
|
decoder_get_command(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
return DecoderCommand::NONE;
|
return DecoderCommand::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_command_finished(gcc_unused struct decoder *decoder)
|
void
|
||||||
|
decoder_command_finished(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double decoder_seek_where(gcc_unused struct decoder *decoder)
|
double
|
||||||
|
decoder_seek_where(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decoder_seek_error(gcc_unused struct decoder *decoder)
|
void
|
||||||
|
decoder_seek_error(gcc_unused Decoder &decoder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
decoder_read(gcc_unused struct decoder *decoder,
|
decoder_read(gcc_unused Decoder *decoder,
|
||||||
struct input_stream *is,
|
struct input_stream *is,
|
||||||
void *buffer, size_t length)
|
void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
@ -98,13 +101,13 @@ decoder_read(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_timestamp(gcc_unused struct decoder *decoder,
|
decoder_timestamp(gcc_unused Decoder &decoder,
|
||||||
gcc_unused double t)
|
gcc_unused double t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_data(gcc_unused struct decoder *decoder,
|
decoder_data(gcc_unused Decoder &decoder,
|
||||||
gcc_unused struct input_stream *is,
|
gcc_unused struct input_stream *is,
|
||||||
const void *data, size_t datalen,
|
const void *data, size_t datalen,
|
||||||
gcc_unused uint16_t kbit_rate)
|
gcc_unused uint16_t kbit_rate)
|
||||||
@ -114,7 +117,7 @@ decoder_data(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderCommand
|
DecoderCommand
|
||||||
decoder_tag(gcc_unused struct decoder *decoder,
|
decoder_tag(gcc_unused Decoder &decoder,
|
||||||
gcc_unused struct input_stream *is,
|
gcc_unused struct input_stream *is,
|
||||||
gcc_unused Tag &&tag)
|
gcc_unused Tag &&tag)
|
||||||
{
|
{
|
||||||
@ -122,7 +125,7 @@ decoder_tag(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_replay_gain(gcc_unused struct decoder *decoder,
|
decoder_replay_gain(gcc_unused Decoder &decoder,
|
||||||
const struct replay_gain_info *replay_gain_info)
|
const struct replay_gain_info *replay_gain_info)
|
||||||
{
|
{
|
||||||
const struct replay_gain_tuple *tuple =
|
const struct replay_gain_tuple *tuple =
|
||||||
@ -138,7 +141,7 @@ decoder_replay_gain(gcc_unused struct decoder *decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_mixramp(gcc_unused struct decoder *decoder,
|
decoder_mixramp(gcc_unused Decoder &decoder,
|
||||||
char *mixramp_start, char *mixramp_end)
|
char *mixramp_start, char *mixramp_end)
|
||||||
{
|
{
|
||||||
g_free(mixramp_start);
|
g_free(mixramp_start);
|
||||||
@ -148,13 +151,13 @@ decoder_mixramp(gcc_unused struct decoder *decoder,
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *decoder_name;
|
const char *decoder_name;
|
||||||
struct decoder decoder;
|
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
g_printerr("Usage: run_decoder DECODER URI >OUT\n");
|
g_printerr("Usage: run_decoder DECODER URI >OUT\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Decoder decoder;
|
||||||
decoder_name = argv[1];
|
decoder_name = argv[1];
|
||||||
decoder.uri = argv[2];
|
decoder.uri = argv[2];
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user