decoder_api: added function decoder_timestamp()

Remove the data_time parameter from decoder_data().  This patch
eliminates the timestamp counting in most decoder plugins, because the
MPD core will do it automatically by default.
This commit is contained in:
Max Kellermann 2009-12-25 19:47:33 +01:00
parent 870436a592
commit bad350bc18
22 changed files with 73 additions and 83 deletions

View File

@ -161,7 +161,6 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
enum decoder_command cmd; enum decoder_command cmd;
size_t buffer_size = frame->header.blocksize * data->frame_size; size_t buffer_size = frame->header.blocksize * data->frame_size;
void *buffer; void *buffer;
float position;
unsigned bit_rate; unsigned bit_rate;
buffer = pcm_buffer_get(&data->buffer, buffer_size); buffer = pcm_buffer_get(&data->buffer, buffer_size);
@ -170,12 +169,6 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
data->sample_format, buf, data->sample_format, buf,
0, frame->header.blocksize); 0, frame->header.blocksize);
if (data->next_frame >= data->first_frame)
position = (float)(data->next_frame - data->first_frame) /
frame->header.sample_rate;
else
position = 0;
if (nbytes > 0) if (nbytes > 0)
bit_rate = nbytes * 8 * frame->header.sample_rate / bit_rate = nbytes * 8 * frame->header.sample_rate /
(1000 * frame->header.blocksize); (1000 * frame->header.blocksize);
@ -184,7 +177,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
cmd = decoder_data(data->decoder, data->input_stream, cmd = decoder_data(data->decoder, data->input_stream,
buffer, buffer_size, buffer, buffer_size,
position, bit_rate, bit_rate,
data->replay_gain_info); data->replay_gain_info);
data->next_frame += frame->header.blocksize; data->next_frame += frame->header.blocksize;
switch (cmd) { switch (cmd) {

View File

@ -160,7 +160,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
struct audio_format audio_format; struct audio_format audio_format;
float total_time; float total_time;
uint16_t bit_rate; uint16_t bit_rate;
int ret, current = 0; int ret;
char chunk[CHUNK_SIZE]; char chunk[CHUNK_SIZE];
enum decoder_command cmd; enum decoder_command cmd;
@ -204,17 +204,14 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
if (ret <= 0) if (ret <= 0)
break; break;
current += ret;
cmd = decoder_data(decoder, NULL, cmd = decoder_data(decoder, NULL,
chunk, ret * fs, chunk, ret * fs,
(float)current /
(float)audio_format.sample_rate,
bit_rate, NULL); bit_rate, NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
current = decoder_seek_where(decoder) * AFframecount frame = decoder_seek_where(decoder) *
audio_format.sample_rate; audio_format.sample_rate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current); afSeekFrame(af_fp, AF_DEFAULT_TRACK, frame);
decoder_command_finished(decoder); decoder_command_finished(decoder);
cmd = DECODE_COMMAND_NONE; cmd = DECODE_COMMAND_NONE;

View File

@ -383,7 +383,6 @@ static void
faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
{ {
GError *error = NULL; GError *error = NULL;
float file_time;
float total_time = 0; float total_time = 0;
faacDecHandle decoder; faacDecHandle decoder;
struct audio_format audio_format; struct audio_format audio_format;
@ -434,8 +433,6 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
/* the decoder loop */ /* the decoder loop */
file_time = 0.0;
do { do {
size_t frame_size; size_t frame_size;
const void *decoded; const void *decoded;
@ -481,15 +478,12 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
bit_rate = frame_info.bytesconsumed * 8.0 * bit_rate = frame_info.bytesconsumed * 8.0 *
frame_info.channels * audio_format.sample_rate / frame_info.channels * audio_format.sample_rate /
frame_info.samples / 1000 + 0.5; frame_info.samples / 1000 + 0.5;
file_time +=
(float)(frame_info.samples) / frame_info.channels /
audio_format.sample_rate;
} }
/* send PCM samples to MPD */ /* send PCM samples to MPD */
cmd = decoder_data(mpd_decoder, is, decoded, cmd = decoder_data(mpd_decoder, is, decoded,
(size_t)frame_info.samples * 2, file_time, (size_t)frame_info.samples * 2,
bit_rate, NULL); bit_rate, NULL);
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);

View File

@ -232,7 +232,6 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
const AVRational *time_base) const AVRational *time_base)
{ {
enum decoder_command cmd = DECODE_COMMAND_NONE; enum decoder_command cmd = DECODE_COMMAND_NONE;
int position;
uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16]; uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16];
int16_t *aligned_buffer; int16_t *aligned_buffer;
size_t buffer_size; size_t buffer_size;
@ -264,14 +263,13 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
if (audio_size <= 0) if (audio_size <= 0)
continue; continue;
position = packet->pts != (int64_t)AV_NOPTS_VALUE if (packet->pts != (int64_t)AV_NOPTS_VALUE)
? av_rescale_q(packet->pts, *time_base, decoder_timestamp(decoder,
(AVRational){1, 1}) av_rescale_q(packet->pts, *time_base,
: 0; (AVRational){1, 1}));
cmd = decoder_data(decoder, is, cmd = decoder_data(decoder, is,
aligned_buffer, audio_size, aligned_buffer, audio_size,
position,
codec_context->bit_rate / 1000, NULL); codec_context->bit_rate / 1000, NULL);
} }
return cmd; return cmd;

View File

@ -204,7 +204,7 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
break; break;
cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer), cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer),
0, 0, NULL); 0, NULL);
} while (cmd == DECODE_COMMAND_NONE); } while (cmd == DECODE_COMMAND_NONE);
/* clean up */ /* clean up */

View File

@ -1025,7 +1025,6 @@ mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length,
cmd = decoder_data(data->decoder, data->input_stream, cmd = decoder_data(data->decoder, data->input_stream,
data->output_buffer, data->output_buffer,
sizeof(data->output_buffer[0]) * num_samples, sizeof(data->output_buffer[0]) * num_samples,
data->elapsed_time,
data->bit_rate / 1000, data->bit_rate / 1000,
replay_gain_info); replay_gain_info);
if (cmd != DECODE_COMMAND_NONE) if (cmd != DECODE_COMMAND_NONE)

View File

@ -147,7 +147,6 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
struct audio_format audio_format; struct audio_format audio_format;
int ret; int ret;
SBYTE buffer[MIKMOD_FRAME_SIZE]; SBYTE buffer[MIKMOD_FRAME_SIZE];
unsigned frame_size, current_frame = 0;
enum decoder_command cmd = DECODE_COMMAND_NONE; enum decoder_command cmd = DECODE_COMMAND_NONE;
path2 = g_strdup(path_fs); path2 = g_strdup(path_fs);
@ -167,14 +166,10 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
decoder_initialized(decoder, &audio_format, false, 0); decoder_initialized(decoder, &audio_format, false, 0);
frame_size = audio_format_frame_size(&audio_format);
Player_Start(handle); Player_Start(handle);
while (cmd == DECODE_COMMAND_NONE && Player_Active()) { while (cmd == DECODE_COMMAND_NONE && Player_Active()) {
ret = VC_WriteBytes(buffer, sizeof(buffer)); ret = VC_WriteBytes(buffer, sizeof(buffer));
current_frame += ret / frame_size;
cmd = decoder_data(decoder, NULL, buffer, ret, cmd = decoder_data(decoder, NULL, buffer, ret,
(float)current_frame / (float)mikmod_sample_rate,
0, NULL); 0, NULL);
} }

View File

@ -96,7 +96,6 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
struct audio_format audio_format; struct audio_format audio_format;
int ret; int ret;
char audio_buffer[MODPLUG_FRAME_SIZE]; char audio_buffer[MODPLUG_FRAME_SIZE];
unsigned frame_size, current_frame = 0;
enum decoder_command cmd = DECODE_COMMAND_NONE; enum decoder_command cmd = DECODE_COMMAND_NONE;
bdatas = mod_loadfile(decoder, is); bdatas = mod_loadfile(decoder, is);
@ -128,24 +127,19 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
decoder_initialized(decoder, &audio_format, decoder_initialized(decoder, &audio_format,
is->seekable, ModPlug_GetLength(f) / 1000.0); is->seekable, ModPlug_GetLength(f) / 1000.0);
frame_size = audio_format_frame_size(&audio_format);
do { do {
ret = ModPlug_Read(f, audio_buffer, MODPLUG_FRAME_SIZE); ret = ModPlug_Read(f, audio_buffer, MODPLUG_FRAME_SIZE);
if (ret <= 0) if (ret <= 0)
break; break;
current_frame += (unsigned)ret / frame_size;
cmd = decoder_data(decoder, NULL, cmd = decoder_data(decoder, NULL,
audio_buffer, ret, audio_buffer, ret,
(float)current_frame / (float)audio_format.sample_rate,
0, NULL); 0, NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
float where = decoder_seek_where(decoder); float where = decoder_seek_where(decoder);
ModPlug_Seek(f, (int)(where * 1000.0)); ModPlug_Seek(f, (int)(where * 1000.0));
current_frame = (unsigned)(where * audio_format.sample_rate);
decoder_command_finished(decoder); decoder_command_finished(decoder);
} }

View File

@ -262,7 +262,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
dur -= offset; dur -= offset;
file_time += ((float)dur) / scale; file_time += ((float)dur) / scale;
if (seeking && file_time > seek_where) if (seeking && file_time >= seek_where)
seek_position_found = true; seek_position_found = true;
if (seeking && seek_position_found) { if (seeking && seek_position_found) {
@ -328,7 +328,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
cmd = decoder_data(mpd_decoder, input_stream, cmd = decoder_data(mpd_decoder, input_stream,
sample_buffer, sample_buffer_length, sample_buffer, sample_buffer_length,
file_time, bit_rate, NULL); bit_rate, NULL);
} }
g_free(seek_table); g_free(seek_table);

View File

@ -152,10 +152,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
mpc_uint32_t ret; mpc_uint32_t ret;
int32_t chunk[G_N_ELEMENTS(sample_buffer)]; int32_t chunk[G_N_ELEMENTS(sample_buffer)];
long bit_rate = 0; long bit_rate = 0;
unsigned long sample_pos = 0;
mpc_uint32_t vbr_update_acc; mpc_uint32_t vbr_update_acc;
mpc_uint32_t vbr_update_bits; mpc_uint32_t vbr_update_bits;
float total_time;
struct replay_gain_info *replay_gain_info = NULL; struct replay_gain_info *replay_gain_info = NULL;
enum decoder_command cmd = DECODE_COMMAND_NONE; enum decoder_command cmd = DECODE_COMMAND_NONE;
@ -219,16 +217,14 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
do { do {
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
mpc_int64_t where = decoder_seek_where(mpd_decoder) *
audio_format.sample_rate;
bool success; bool success;
sample_pos = decoder_seek_where(mpd_decoder) *
audio_format.sample_rate;
#ifdef MPC_IS_OLD_API #ifdef MPC_IS_OLD_API
success = mpc_decoder_seek_sample(&decoder, success = mpc_decoder_seek_sample(&decoder, where);
sample_pos);
#else #else
success = mpc_demux_seek_sample(demux, sample_pos) success = mpc_demux_seek_sample(demux, where)
== MPC_STATUS_OK; == MPC_STATUS_OK;
#endif #endif
if (success) if (success)
@ -259,19 +255,15 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
ret = frame.samples; ret = frame.samples;
#endif #endif
sample_pos += ret;
ret *= info.channels; ret *= info.channels;
mpc_to_mpd_buffer(chunk, sample_buffer, ret); mpc_to_mpd_buffer(chunk, sample_buffer, ret);
total_time = ((float)sample_pos) / audio_format.sample_rate;
bit_rate = vbr_update_bits * audio_format.sample_rate bit_rate = vbr_update_bits * audio_format.sample_rate
/ 1152 / 1000; / 1152 / 1000;
cmd = decoder_data(mpd_decoder, is, cmd = decoder_data(mpd_decoder, is,
chunk, ret * sizeof(chunk[0]), chunk, ret * sizeof(chunk[0]),
total_time,
bit_rate, replay_gain_info); bit_rate, replay_gain_info);
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);

View File

@ -103,7 +103,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
struct audio_format audio_format; struct audio_format audio_format;
mpg123_handle *handle; mpg123_handle *handle;
int error; int error;
off_t num_samples, position; off_t num_samples;
enum decoder_command cmd; enum decoder_command cmd;
/* open the file */ /* open the file */
@ -134,8 +134,6 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
unsigned char buffer[8192]; unsigned char buffer[8192];
size_t nbytes; size_t nbytes;
position = mpg123_tell(handle);
/* decode */ /* decode */
error = mpg123_read(handle, buffer, sizeof(buffer), &nbytes); error = mpg123_read(handle, buffer, sizeof(buffer), &nbytes);
@ -149,8 +147,6 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
/* send to MPD */ /* send to MPD */
cmd = decoder_data(decoder, NULL, buffer, nbytes, cmd = decoder_data(decoder, NULL, buffer, nbytes,
(float)position /
(float)audio_format.sample_rate,
0, NULL); 0, NULL);
/* seeking not yet implemented */ /* seeking not yet implemented */

View File

@ -284,7 +284,6 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
/* .. and play */ /* .. and play */
unsigned data_time = 0;
const unsigned timebase = player.timebase(); const unsigned timebase = player.timebase();
song_len *= timebase; song_len *= timebase;
@ -297,12 +296,13 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
if (nbytes == 0) if (nbytes == 0)
break; break;
decoder_timestamp(decoder, (double)player.time() / timebase);
cmd = decoder_data(decoder, NULL, buffer, nbytes, cmd = decoder_data(decoder, NULL, buffer, nbytes,
(float)data_time / (float)timebase,
0, NULL); 0, NULL);
data_time = player.time();
if(cmd==DECODE_COMMAND_SEEK) { if(cmd==DECODE_COMMAND_SEEK) {
unsigned data_time = player.time();
unsigned target_time = (unsigned) unsigned target_time = (unsigned)
(decoder_seek_where(decoder) * timebase); (decoder_seek_where(decoder) * timebase);
@ -323,7 +323,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
decoder_command_finished(decoder); decoder_command_finished(decoder);
} }
if (song_len > 0 && data_time >= song_len) if (song_len > 0 && player.time() >= song_len)
break; break;
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);

View File

@ -119,7 +119,7 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
SF_INFO info; SF_INFO info;
struct audio_format audio_format; struct audio_format audio_format;
size_t frame_size; size_t frame_size;
sf_count_t read_frames, num_frames, position = 0; sf_count_t read_frames, num_frames;
int buffer[4096]; int buffer[4096];
enum decoder_command cmd; enum decoder_command cmd;
@ -155,7 +155,6 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
cmd = decoder_data(decoder, is, cmd = decoder_data(decoder, is,
buffer, num_frames * frame_size, buffer, num_frames * frame_size,
frame_to_time(position, &audio_format),
0, NULL); 0, NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
sf_count_t c = sf_count_t c =

View File

@ -377,7 +377,6 @@ vorbis_stream_decode(struct decoder *decoder,
cmd = decoder_data(decoder, input_stream, cmd = decoder_data(decoder, input_stream,
chunk, ret, chunk, ret,
ov_pcm_tell(&vf) / audio_format.sample_rate,
bitRate, replay_gain_info); bitRate, replay_gain_info);
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);

View File

@ -165,9 +165,8 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
format_samples_t format_samples; format_samples_t format_samples;
char chunk[CHUNK_SIZE]; char chunk[CHUNK_SIZE];
int samples_requested, samples_got; int samples_requested, samples_got;
float total_time, current_time; float total_time;
int bytes_per_sample, output_sample_size; int bytes_per_sample, output_sample_size;
int position;
is_float = (WavpackGetMode(wpc) & MODE_FLOAT) != 0; is_float = (WavpackGetMode(wpc) & MODE_FLOAT) != 0;
sample_format = sample_format =
@ -199,8 +198,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
decoder_initialized(decoder, &audio_format, can_seek, total_time); decoder_initialized(decoder, &audio_format, can_seek, total_time);
position = 0;
do { do {
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) { if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
if (can_seek) { if (can_seek) {
@ -209,7 +206,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
where = decoder_seek_where(decoder); where = decoder_seek_where(decoder);
where *= audio_format.sample_rate; where *= audio_format.sample_rate;
if (WavpackSeekSample(wpc, where)) { if (WavpackSeekSample(wpc, where)) {
position = where;
decoder_command_finished(decoder); decoder_command_finished(decoder);
} else { } else {
decoder_seek_error(decoder); decoder_seek_error(decoder);
@ -229,9 +225,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
if (samples_got > 0) { if (samples_got > 0) {
int bitrate = (int)(WavpackGetInstantBitrate(wpc) / int bitrate = (int)(WavpackGetInstantBitrate(wpc) /
1000 + 0.5); 1000 + 0.5);
position += samples_got;
current_time = position;
current_time /= audio_format.sample_rate;
format_samples( format_samples(
bytes_per_sample, chunk, bytes_per_sample, chunk,
@ -241,7 +234,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
decoder_data( decoder_data(
decoder, NULL, chunk, decoder, NULL, chunk,
samples_got * output_sample_size, samples_got * output_sample_size,
current_time, bitrate, bitrate,
replay_gain_info replay_gain_info
); );
} }

View File

@ -92,8 +92,6 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
break; break;
cmd = decoder_data(decoder, NULL, buffer, len, cmd = decoder_data(decoder, NULL, buffer, len,
(float)info->current_sample /
(float)WILDMIDI_SAMPLE_RATE,
0, NULL); 0, NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {

View File

@ -95,7 +95,8 @@ enum decoder_command decoder_get_command(G_GNUC_UNUSED struct decoder * decoder)
return dc->command; return dc->command;
} }
void decoder_command_finished(G_GNUC_UNUSED struct decoder * decoder) void
decoder_command_finished(struct decoder *decoder)
{ {
struct decoder_control *dc = decoder->dc; struct decoder_control *dc = decoder->dc;
@ -115,6 +116,8 @@ void decoder_command_finished(G_GNUC_UNUSED struct decoder * decoder)
} }
music_pipe_clear(dc->pipe, dc->buffer); music_pipe_clear(dc->pipe, dc->buffer);
decoder->timestamp = dc->seek_where;
} }
dc->command = DECODE_COMMAND_NONE; dc->command = DECODE_COMMAND_NONE;
@ -192,6 +195,15 @@ size_t decoder_read(struct decoder *decoder,
} }
} }
void
decoder_timestamp(struct decoder *decoder, double t)
{
assert(decoder != NULL);
assert(t >= 0);
decoder->timestamp = t;
}
/** /**
* Sends a #tag as-is to the music pipe. Flushes the current chunk * Sends a #tag as-is to the music pipe. Flushes the current chunk
* (decoder.chunk) if there is one. * (decoder.chunk) if there is one.
@ -250,7 +262,7 @@ enum decoder_command
decoder_data(struct decoder *decoder, decoder_data(struct decoder *decoder,
struct input_stream *is, struct input_stream *is,
const void *_data, size_t length, const void *_data, size_t length,
float data_time, uint16_t bitRate, uint16_t kbit_rate,
struct replay_gain_info *replay_gain_info) struct replay_gain_info *replay_gain_info)
{ {
struct decoder_control *dc = decoder->dc; struct decoder_control *dc = decoder->dc;
@ -316,7 +328,8 @@ decoder_data(struct decoder *decoder,
} }
dest = music_chunk_write(chunk, &dc->out_audio_format, dest = music_chunk_write(chunk, &dc->out_audio_format,
data_time, bitRate, &nbytes); decoder->timestamp, kbit_rate,
&nbytes);
if (dest == NULL) { if (dest == NULL) {
/* the chunk is full, flush it */ /* the chunk is full, flush it */
decoder_flush_chunk(decoder); decoder_flush_chunk(decoder);
@ -350,6 +363,9 @@ decoder_data(struct decoder *decoder,
data += nbytes; data += nbytes;
length -= nbytes; length -= nbytes;
decoder->timestamp += (double)nbytes /
audio_format_time_to_size(&dc->in_audio_format);
} }
return DECODE_COMMAND_NONE; return DECODE_COMMAND_NONE;

View File

@ -114,6 +114,15 @@ size_t
decoder_read(struct decoder *decoder, struct input_stream *is, decoder_read(struct decoder *decoder, struct input_stream *is,
void *buffer, size_t length); void *buffer, size_t length);
/**
* Sets the time stamp for the next data chunk [seconds]. The MPD
* core automatically counts it up, and a decoder plugin only needs to
* use this function if it thinks that adding to the time stamp based
* on the buffer size won't work.
*/
void
decoder_timestamp(struct 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
* successfully decoded block of input data. * successfully decoded block of input data.
@ -129,7 +138,7 @@ decoder_read(struct decoder *decoder, struct input_stream *is,
enum decoder_command enum decoder_command
decoder_data(struct decoder *decoder, struct input_stream *is, decoder_data(struct decoder *decoder, struct input_stream *is,
const void *data, size_t length, const void *data, size_t length,
float data_time, uint16_t bitRate, uint16_t kbit_rate,
struct replay_gain_info *replay_gain_info); struct replay_gain_info *replay_gain_info);
/** /**

View File

@ -30,6 +30,11 @@ struct decoder {
struct pcm_convert_state conv_state; struct pcm_convert_state conv_state;
/**
* The time stamp of the next data chunk, in seconds.
*/
double timestamp;
bool seeking; bool seeking;
/** /**

View File

@ -303,6 +303,7 @@ decoder_run_song(struct decoder_control *dc,
}; };
int ret; int ret;
decoder.timestamp = 0.0;
decoder.seeking = false; decoder.seeking = false;
decoder.song_tag = song->tag != NULL && song_is_file(song) decoder.song_tag = song->tag != NULL && song_is_file(song)
? tag_dup(song->tag) : NULL; ? tag_dup(song->tag) : NULL;

View File

@ -96,11 +96,17 @@ decoder_read(G_GNUC_UNUSED struct decoder *decoder,
return input_stream_read(is, buffer, length, NULL); return input_stream_read(is, buffer, length, NULL);
} }
void
decoder_timestamp(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED double t)
{
}
enum decoder_command enum decoder_command
decoder_data(G_GNUC_UNUSED struct decoder *decoder, decoder_data(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED struct input_stream *is, G_GNUC_UNUSED struct input_stream *is,
const void *data, size_t datalen, const void *data, size_t datalen,
G_GNUC_UNUSED float data_time, G_GNUC_UNUSED uint16_t bit_rate, G_GNUC_UNUSED uint16_t bit_rate,
G_GNUC_UNUSED struct replay_gain_info *replay_gain_info) G_GNUC_UNUSED struct replay_gain_info *replay_gain_info)
{ {
write(1, data, datalen); write(1, data, datalen);

View File

@ -117,11 +117,17 @@ decoder_read(G_GNUC_UNUSED struct decoder *decoder,
return input_stream_read(is, buffer, length, NULL); return input_stream_read(is, buffer, length, NULL);
} }
void
decoder_timestamp(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED double t)
{
}
enum decoder_command enum decoder_command
decoder_data(G_GNUC_UNUSED struct decoder *decoder, decoder_data(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED struct input_stream *is, G_GNUC_UNUSED struct input_stream *is,
const void *data, size_t datalen, const void *data, size_t datalen,
G_GNUC_UNUSED float data_time, G_GNUC_UNUSED uint16_t bit_rate, G_GNUC_UNUSED uint16_t kbit_rate,
G_GNUC_UNUSED struct replay_gain_info *replay_gain_info) G_GNUC_UNUSED struct replay_gain_info *replay_gain_info)
{ {
write(1, data, datalen); write(1, data, datalen);