diff options
Diffstat (limited to 'src/decoder_api.c')
-rw-r--r-- | src/decoder_api.c | 106 |
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; |