aboutsummaryrefslogtreecommitdiff
path: root/src/decoder_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder_api.c')
-rw-r--r--src/decoder_api.c106
1 files changed, 24 insertions, 82 deletions
diff --git a/src/decoder_api.c b/src/decoder_api.c
index bcab6010..35683d95 100644
--- a/src/decoder_api.c
+++ b/src/decoder_api.c
@@ -159,7 +159,6 @@ void decoder_command_finished(struct decoder *decoder)
if (decoder->initial_seek_running) {
assert(!decoder->seeking);
- assert(decoder->chunk == NULL);
assert(music_pipe_empty(dc->pipe));
decoder->initial_seek_running = false;
@@ -171,14 +170,7 @@ void decoder_command_finished(struct decoder *decoder)
if (decoder->seeking) {
decoder->seeking = false;
- /* delete frames from the old song position */
-
- if (decoder->chunk != NULL) {
- music_buffer_return(dc->buffer, decoder->chunk);
- decoder->chunk = NULL;
- }
-
- music_pipe_clear(dc->pipe, dc->buffer);
+ music_pipe_clear(dc->pipe);
decoder->timestamp = dc->seek_where;
}
@@ -308,15 +300,6 @@ static enum decoder_command do_send_tag(struct decoder *decoder, const struct ta
{
struct music_chunk *chunk;
- if (decoder->chunk != NULL) {
- /* there is a partial chunk - flush it, we want the
- tag in a new chunk */
- decoder_flush_chunk(decoder);
- g_cond_signal(decoder->dc->client_cond);
- }
-
- assert(decoder->chunk == NULL);
-
chunk = decoder_get_chunk(decoder);
if (chunk == NULL) {
assert(decoder->dc->command != DECODE_COMMAND_NONE);
@@ -356,8 +339,8 @@ enum decoder_command decoder_data(struct decoder *decoder,
{
struct decoder_control *dc = decoder->dc;
enum decoder_command cmd = DECODE_COMMAND_NONE;
- uint8_t *data;
- int length;
+ int nb_samples = frame->nb_samples;
+ struct music_chunk *chunk;
assert(dc->state == DECODE_STATE_DECODE);
assert(dc->pipe != NULL);
@@ -404,69 +387,36 @@ enum decoder_command decoder_data(struct decoder *decoder,
frame = tmp;
}
- length = frame->nb_samples * av_get_bytes_per_sample(frame->format) *
- dc->out_audio_format.channels;
- data = frame->data[0];
- while (length > 0) {
- struct music_chunk *chunk;
- char *dest;
- size_t nbytes;
- bool full;
-
- chunk = decoder_get_chunk(decoder);
- if (chunk == NULL) {
- assert(dc->command != DECODE_COMMAND_NONE);
- cmd = dc->command;
- goto finish;
- }
-
- dest = music_chunk_write(chunk, &dc->out_audio_format,
- decoder->timestamp -
- dc->song->start_ms / 1000.0,
- kbit_rate, &nbytes);
- if (dest == NULL) {
- /* the chunk is full, flush it */
- decoder_flush_chunk(decoder);
- g_cond_signal(dc->client_cond);
- continue;
- }
-
- assert(nbytes > 0);
-
- if (nbytes > length)
- nbytes = length;
-
- /* copy the buffer */
+ // FIXME support planar formats everywhere
+ assert(!av_sample_fmt_is_planar(frame->format));
- memcpy(dest, data, nbytes);
+ chunk = decoder_get_chunk(decoder);
+ if (!chunk) {
+ cmd = (dc->command == DECODE_COMMAND_NONE) ?
+ DECODE_COMMAND_STOP : dc->command;
+ goto finish;
+ }
+ chunk->frame = frame;
+ chunk->bit_rate = kbit_rate;
+ chunk->times = decoder->timestamp - dc->song->start_ms / 1000.0;
- /* expand the music pipe chunk */
+ frame = NULL;
- full = music_chunk_expand(chunk, &dc->out_audio_format, nbytes);
- if (full) {
- /* the chunk is full, flush it */
- decoder_flush_chunk(decoder);
- g_cond_signal(dc->client_cond);
- }
-
- data += nbytes;
- length -= nbytes;
+ music_pipe_push(dc->pipe, chunk);
+ g_cond_signal(dc->client_cond);
- decoder->timestamp += (double)nbytes /
- audio_format_time_to_size(&dc->out_audio_format);
+ decoder->timestamp += (double)nb_samples / dc->in_audio_format.sample_rate;
- if (dc->end_ms > 0 &&
- decoder->timestamp >= dc->end_ms / 1000.0) {
- /* the end of this range has been reached:
- stop decoding */
- cmd = DECODE_COMMAND_STOP;
- break;
- }
+ if (dc->end_ms > 0 &&
+ decoder->timestamp >= dc->end_ms / 1000.0) {
+ /* the end of this range has been reached:
+ stop decoding */
+ cmd = DECODE_COMMAND_STOP;
}
finish:
av_frame_free(&frame);
- return DECODE_COMMAND_NONE;
+ return cmd;
}
enum decoder_command decoder_tag(struct decoder *decoder, struct input_stream *is,
@@ -534,14 +484,6 @@ float decoder_replay_gain(struct decoder *decoder,
decoder->replay_gain_info = *replay_gain_info;
decoder->replay_gain_serial = serial;
-
- if (decoder->chunk != NULL) {
- /* flush the current chunk because the new
- replay gain values affect the following
- samples */
- decoder_flush_chunk(decoder);
- g_cond_signal(decoder->dc->client_cond);
- }
} else
decoder->replay_gain_serial = 0;