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:
parent
870436a592
commit
bad350bc18
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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 =
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user