decoder/Client: add virtual method Ready()

Replaces decoder_initialized().
This commit is contained in:
Max Kellermann 2016-11-18 07:59:01 +01:00
parent fd77acc217
commit 66fb352cca
28 changed files with 73 additions and 79 deletions

View File

@ -21,11 +21,27 @@
#define MPD_DECODER_CLIENT_HXX
#include "check.h"
#include "Chrono.hxx"
struct AudioFormat;
/**
* An interface between the decoder plugin and the MPD core.
*/
class DecoderClient {
public:
/**
* Notify the client that it has finished initialization and
* that it has read the song's meta data.
*
* @param audio_format the audio format which is going to be
* sent to SubmitData()
* @param seekable true if the song is seekable
* @param duration the total duration of this song; negative if
* unknown
*/
virtual void Ready(AudioFormat audio_format,
bool seekable, SignedSongTime duration) = 0;
};
#endif

View File

@ -38,21 +38,18 @@
#include <math.h>
void
decoder_initialized(DecoderClient &client,
const AudioFormat audio_format,
bool seekable, SignedSongTime duration)
Decoder::Ready(const AudioFormat audio_format,
bool seekable, SignedSongTime duration)
{
auto &decoder = (Decoder &)client;
DecoderControl &dc = decoder.dc;
struct audio_format_string af_string;
assert(dc.state == DecoderState::START);
assert(dc.pipe != nullptr);
assert(dc.pipe->IsEmpty());
assert(decoder.convert == nullptr);
assert(decoder.stream_tag == nullptr);
assert(decoder.decoder_tag == nullptr);
assert(!decoder.seeking);
assert(convert == nullptr);
assert(stream_tag == nullptr);
assert(decoder_tag == nullptr);
assert(!seeking);
assert(audio_format.IsDefined());
assert(audio_format.IsValid());
@ -71,13 +68,13 @@ decoder_initialized(DecoderClient &client,
audio_format_to_string(dc.out_audio_format,
&af_string));
decoder.convert = new PcmConvert();
convert = new PcmConvert();
try {
decoder.convert->Open(dc.in_audio_format,
convert->Open(dc.in_audio_format,
dc.out_audio_format);
} catch (...) {
decoder.error = std::current_exception();
error = std::current_exception();
}
}

View File

@ -30,6 +30,7 @@
// IWYU pragma: begin_exports
#include "check.h"
#include "Client.hxx"
#include "input/Ptr.hxx"
#include "DecoderCommand.hxx"
#include "DecoderPlugin.hxx"
@ -53,22 +54,6 @@ class DecoderClient;
*/
class StopDecoder {};
/**
* Notify the player thread that it has finished initialization and
* that it has read the song's meta data.
*
* @param decoder the decoder object
* @param audio_format the audio format which is going to be sent to
* decoder_data()
* @param seekable true if the song is seekable
* @param duration the total duration of this song; negative if
* unknown
*/
void
decoder_initialized(DecoderClient &decoder,
AudioFormat audio_format,
bool seekable, SignedSongTime duration);
/**
* Determines the pending decoder command.
*

View File

@ -116,6 +116,10 @@ struct Decoder final : DecoderClient {
* Caller must not lock the #DecoderControl object.
*/
void FlushChunk();
/* virtual methods from DecoderClient */
void Ready(AudioFormat audio_format,
bool seekable, SignedSongTime duration) override;
};
#endif

View File

@ -61,8 +61,8 @@ adplug_file_decode(DecoderClient &client, Path path_fs)
const AudioFormat audio_format(sample_rate, SampleFormat::S16, 2);
assert(audio_format.IsValid());
decoder_initialized(client, audio_format, false,
SongTime::FromMS(player->songlength()));
client.Ready(audio_format, false,
SongTime::FromMS(player->songlength()));
DecoderCommand cmd;

View File

@ -210,7 +210,7 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is)
const unsigned frame_size = (unsigned)
afGetVirtualFrameSize(fh, AF_DEFAULT_TRACK, true);
decoder_initialized(client, audio_format, true, total_time);
client.Ready(audio_format, true, total_time);
DecoderCommand cmd;
do {

View File

@ -437,7 +437,7 @@ dsdiff_stream_decode(DecoderClient &client, InputStream &is)
audio_format.sample_rate);
/* success: file was recognized */
decoder_initialized(client, audio_format, is.IsSeekable(), songtime);
client.Ready(audio_format, is.IsSeekable(), songtime);
/* every iteration of the following loop decodes one "DSD"
chunk from a DFF file */

View File

@ -316,7 +316,7 @@ dsf_stream_decode(DecoderClient &client, InputStream &is)
audio_format.sample_rate);
/* success: file was recognized */
decoder_initialized(client, audio_format, is.IsSeekable(), songtime);
client.Ready(audio_format, is.IsSeekable(), songtime);
dsf_decode_chunk(client, is, metadata.channels,
metadata.sample_rate,

View File

@ -339,7 +339,7 @@ faad_stream_decode(DecoderClient &client, InputStream &is,
/* initialize the MPD core */
decoder_initialized(client, audio_format, false, total_time);
client.Ready(audio_format, false, total_time);
/* the decoder loop */

View File

@ -689,8 +689,7 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
const SignedSongTime total_time =
FromFfmpegTimeChecked(av_stream.duration, av_stream.time_base);
decoder_initialized(client, audio_format,
input.IsSeekable(), total_time);
client.Ready(audio_format, input.IsSeekable(), total_time);
FfmpegParseMetaData(client, format_context, audio_stream);

View File

@ -52,9 +52,9 @@ FlacDecoder::Initialize(unsigned sample_rate, unsigned bits_per_sample,
audio_format.sample_rate)
: SignedSongTime::Negative();
decoder_initialized(*GetClient(), audio_format,
GetInputStream().IsSeekable(),
duration);
GetClient()->Ready(audio_format,
GetInputStream().IsSeekable(),
duration);
initialized = true;
return true;

View File

@ -32,7 +32,7 @@
struct FlacDecoder : public FlacInput {
/**
* Has decoder_initialized() been called yet?
* Has DecoderClient::Ready() been called yet?
*/
bool initialized = false;
@ -55,7 +55,7 @@ struct FlacDecoder : public FlacInput {
:FlacInput(_input_stream, &_client) {}
/**
* Wrapper for decoder_initialized().
* Wrapper for DecoderClient::Ready().
*/
bool Initialize(unsigned sample_rate, unsigned bits_per_sample,
unsigned channels, FLAC__uint64 total_frames);
@ -77,7 +77,7 @@ private:
void OnVorbisComment(const FLAC__StreamMetadata_VorbisComment &vc);
/**
* This function attempts to call decoder_initialized() in case there
* This function attempts to call DecoderClient::Ready() in case there
* was no STREAMINFO block. This is allowed for nonseekable streams,
* where the server sends us only a part of the file, without
* providing the STREAMINFO block from the beginning of the file

View File

@ -160,8 +160,7 @@ fluidsynth_file_decode(DecoderClient &client, Path path_fs)
MPD core */
const AudioFormat audio_format(sample_rate, SampleFormat::S16, 2);
decoder_initialized(client, audio_format, false,
SignedSongTime::Negative());
client.Ready(audio_format, false, SignedSongTime::Negative());
DecoderCommand cmd;
while (fluid_player_get_status(player) == FLUID_PLAYER_PLAYING) {

View File

@ -171,7 +171,7 @@ gme_file_decode(DecoderClient &client, Path path_fs)
SampleFormat::S16,
GME_CHANNELS);
decoder_initialized(client, audio_format, true, song_len);
client.Ready(audio_format, true, song_len);
gme_err = gme_start_track(emu, container.track);
if (gme_err != nullptr)

View File

@ -1050,12 +1050,11 @@ mp3_decode(DecoderClient &client, InputStream &input_stream)
data.AllocateBuffers();
decoder_initialized(client,
CheckAudioFormat(data.frame.header.samplerate,
SampleFormat::S24_P32,
MAD_NCHANNELS(&data.frame.header)),
input_stream.IsSeekable(),
data.total_time);
client.Ready(CheckAudioFormat(data.frame.header.samplerate,
SampleFormat::S24_P32,
MAD_NCHANNELS(&data.frame.header)),
input_stream.IsSeekable(),
data.total_time);
if (tag != nullptr) {
decoder_tag(client, input_stream, std::move(*tag));

View File

@ -170,8 +170,7 @@ mikmod_decoder_file_decode(DecoderClient &client, Path path_fs)
const AudioFormat audio_format(mikmod_sample_rate, SampleFormat::S16, 2);
assert(audio_format.IsValid());
decoder_initialized(client, audio_format, false,
SignedSongTime::Negative());
client.Ready(audio_format, false, SignedSongTime::Negative());
Player_Start(handle);

View File

@ -151,9 +151,8 @@ mod_decode(DecoderClient &client, InputStream &is)
static constexpr AudioFormat audio_format(44100, SampleFormat::S16, 2);
assert(audio_format.IsValid());
decoder_initialized(client, audio_format,
is.IsSeekable(),
SongTime::FromMS(ModPlug_GetLength(f)));
client.Ready(audio_format, is.IsSeekable(),
SongTime::FromMS(ModPlug_GetLength(f)));
DecoderCommand cmd;
do {

View File

@ -174,9 +174,8 @@ mpcdec_decode(DecoderClient &client, InputStream &is)
decoder_replay_gain(client, &rgi);
decoder_initialized(client, audio_format,
is.IsSeekable(),
SongTime::FromS(mpc_streaminfo_get_length(&info)));
client.Ready(audio_format, is.IsSeekable(),
SongTime::FromS(mpc_streaminfo_get_length(&info)));
DecoderCommand cmd = DecoderCommand::NONE;
do {

View File

@ -210,7 +210,7 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs)
SongTime::FromScale<uint64_t>(num_samples,
audio_format.sample_rate);
decoder_initialized(client, audio_format, true, duration);
client.Ready(audio_format, true, duration);
struct mpg123_frameinfo info;
if (mpg123_info(handle, &info) != MPG123_OK) {

View File

@ -93,7 +93,7 @@ public:
~MPDOpusDecoder();
/**
* Has decoder_initialized() been called yet?
* Has DecoderClient::Ready() been called yet?
*/
bool IsInitialized() const {
return previous_channels != 0;
@ -175,8 +175,7 @@ MPDOpusDecoder::OnOggBeginning(const ogg_packet &packet)
previous_channels = channels;
const AudioFormat audio_format(opus_sample_rate,
SampleFormat::S16, channels);
decoder_initialized(client, audio_format,
eos_granulepos > 0, duration);
client.Ready(audio_format, eos_granulepos > 0, duration);
frame_size = audio_format.GetFrameSize();
output_buffer = new opus_int16[opus_output_buffer_frames

View File

@ -143,8 +143,7 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
audio_format.sample_rate)
: SignedSongTime::Negative();
decoder_initialized(client, audio_format,
is.IsSeekable(), total_time);
client.Ready(audio_format, is.IsSeekable(), total_time);
StaticFifoBuffer<uint8_t, 4096> buffer;

View File

@ -337,7 +337,7 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
const AudioFormat audio_format(48000, SampleFormat::S16, channels);
assert(audio_format.IsValid());
decoder_initialized(client, audio_format, true, duration);
client.Ready(audio_format, true, duration);
/* .. and play */

View File

@ -205,8 +205,7 @@ sndfile_stream_decode(DecoderClient &client, InputStream &is)
sndfile_sample_format(info),
info.channels);
decoder_initialized(client, audio_format, info.seekable,
sndfile_duration(info));
client.Ready(audio_format, info.seekable, sndfile_duration(info));
char buffer[16384];

View File

@ -175,8 +175,7 @@ VorbisDecoder::SubmitInit()
audio_format.sample_rate)
: SignedSongTime::Negative();
decoder_initialized(client, audio_format,
eos_granulepos > 0, duration);
client.Ready(audio_format, eos_granulepos > 0, duration);
}
bool

View File

@ -168,7 +168,7 @@ wavpack_decode(DecoderClient &client, WavpackContext *wpc, bool can_seek)
const uint32_t samples_requested = ARRAY_SIZE(chunk) /
audio_format.channels;
decoder_initialized(client, audio_format, can_seek, total_time);
client.Ready(audio_format, can_seek, total_time);
DecoderCommand cmd = decoder_get_command(client);
while (cmd != DecoderCommand::STOP) {

View File

@ -103,7 +103,7 @@ wildmidi_file_decode(DecoderClient &client, Path path_fs)
SongTime::FromScale<uint64_t>(info->approx_total_samples,
WILDMIDI_SAMPLE_RATE);
decoder_initialized(client, audio_format, true, duration);
client.Ready(audio_format, true, duration);
DecoderCommand cmd;
do {

View File

@ -29,22 +29,20 @@
#include <stdio.h>
void
decoder_initialized(DecoderClient &client,
const AudioFormat audio_format,
gcc_unused bool seekable,
SignedSongTime duration)
FakeDecoder::Ready(const AudioFormat audio_format,
gcc_unused bool seekable,
SignedSongTime duration)
{
auto &decoder = (FakeDecoder &)client;
struct audio_format_string af_string;
assert(!decoder.initialized);
assert(!initialized);
assert(audio_format.IsValid());
fprintf(stderr, "audio_format=%s duration=%f\n",
audio_format_to_string(audio_format, &af_string),
duration.ToDoubleS());
decoder.initialized = true;
initialized = true;
}
DecoderCommand

View File

@ -30,6 +30,10 @@ struct FakeDecoder final : DecoderClient {
Cond cond;
bool initialized = false;
/* virtual methods from DecoderClient */
void Ready(AudioFormat audio_format,
bool seekable, SignedSongTime duration) override;
};
#endif