diff options
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | src/decoder/ffmpeg_decoder_plugin.c | 38 | ||||
-rw-r--r-- | src/input/rewind_input_plugin.c | 4 | ||||
-rw-r--r-- | src/pcm_format.c | 4 |
4 files changed, 44 insertions, 11 deletions
@@ -21,6 +21,15 @@ ver 0.17 (2011/??/??) * cue: show CUE track numbers +ver 0.16.5 (2010/??/??) +* pcm_format: fix 32-to-24 bit conversion (the "silence" bug) +* input: + - rewind: reduce heap usage +* decoder: + - ffmpeg: higher precision timestamps + - ffmpeg: don't require key frame for seeking + + ver 0.16.4 (2011/09/01) * don't abort configure when avahi is not found * auto-detect libmad without pkg-config diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 78e874d9e..b4f1f0b51 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -211,6 +211,24 @@ align16(void *p, size_t *length_p) return (char *)p + add; } +G_GNUC_CONST +static double +time_from_ffmpeg(int64_t t, const AVRational time_base) +{ + assert(t != (int64_t)AV_NOPTS_VALUE); + + return (double)av_rescale_q(t, time_base, (AVRational){1, 1024}) + / (double)1024; +} + +G_GNUC_CONST +static int64_t +time_to_ffmpeg(double t, const AVRational time_base) +{ + return av_rescale_q((int64_t)(t * 1024), (AVRational){1, 1024}, + time_base); +} + static enum decoder_command ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, const AVPacket *packet, @@ -219,8 +237,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, { if (packet->pts != (int64_t)AV_NOPTS_VALUE) decoder_timestamp(decoder, - av_rescale_q(packet->pts, *time_base, - (AVRational){1, 1})); + time_from_ffmpeg(packet->pts, *time_base)); #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) AVPacket packet2 = *packet; @@ -367,8 +384,9 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) return; } - AVCodecContext *codec_context = - format_context->streams[audio_stream]->codec; + AVStream *av_stream = format_context->streams[audio_stream]; + + AVCodecContext *codec_context = av_stream->codec; if (codec_context->codec_name[0] != 0) g_debug("codec '%s'", codec_context->codec_name); @@ -419,7 +437,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) if (packet.stream_index == audio_stream) cmd = ffmpeg_send_packet(decoder, input, &packet, codec_context, - &format_context->streams[audio_stream]->time_base); + &av_stream->time_base); else cmd = decoder_get_command(decoder); @@ -427,12 +445,16 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) if (cmd == DECODE_COMMAND_SEEK) { int64_t where = - decoder_seek_where(decoder) * AV_TIME_BASE; + time_to_ffmpeg(decoder_seek_where(decoder), + av_stream->time_base); - if (av_seek_frame(format_context, -1, where, 0) < 0) + if (av_seek_frame(format_context, audio_stream, where, + AV_TIME_BASE) < 0) decoder_seek_error(decoder); - else + else { + avcodec_flush_buffers(codec_context); decoder_command_finished(decoder); + } } } while (cmd != DECODE_COMMAND_STOP); diff --git a/src/input/rewind_input_plugin.c b/src/input/rewind_input_plugin.c index 9d3255cfe..fa2065d61 100644 --- a/src/input/rewind_input_plugin.c +++ b/src/input/rewind_input_plugin.c @@ -83,12 +83,14 @@ copy_attributes(struct input_rewind *r) assert(dest != src); assert(src->mime == NULL || dest->mime != src->mime); + bool dest_ready = dest->ready; + dest->ready = src->ready; dest->seekable = src->seekable; dest->size = src->size; dest->offset = src->offset; - if (src->mime != NULL) { + if (!dest_ready && src->ready) { g_free(dest->mime); dest->mime = g_strdup(src->mime); } diff --git a/src/pcm_format.c b/src/pcm_format.c index 4ca0b45b3..544b0ccd9 100644 --- a/src/pcm_format.c +++ b/src/pcm_format.c @@ -143,7 +143,7 @@ pcm_convert_16_to_24(int32_t *out, const int16_t *in, } static void -pcm_convert_32_to_24(int32_t *out, const int16_t *in, +pcm_convert_32_to_24(int32_t *out, const int32_t *in, unsigned num_samples) { while (num_samples > 0) { @@ -197,7 +197,7 @@ pcm_convert_to_24(struct pcm_buffer *buffer, *dest_size_r = num_samples * sizeof(*dest); dest = pcm_buffer_get(buffer, *dest_size_r); - pcm_convert_32_to_24(dest, (const int16_t *)src, + pcm_convert_32_to_24(dest, (const int32_t *)src, num_samples); return dest; } |