diff --git a/NEWS b/NEWS
index 364832cf5..ed3cd97c3 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
 	}