aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/ffmpeg_plugin.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-19 19:59:34 +0100
committerMax Kellermann <max@duempel.org>2009-11-19 19:59:34 +0100
commitc33bbd947b6afbb9438dc485c890394be096d0d1 (patch)
treea297c1bd447f7ab44cf010f3bd5b1cbafe149b0b /src/decoder/ffmpeg_plugin.c
parentd37b4bb199cbe5c34ad8bcf36be26cd7c3caa11d (diff)
parent21fdf47b563ab7684dc7022aadf5d63bb011ea52 (diff)
downloadmpd-c33bbd947b6afbb9438dc485c890394be096d0d1.tar.gz
mpd-c33bbd947b6afbb9438dc485c890394be096d0d1.tar.xz
mpd-c33bbd947b6afbb9438dc485c890394be096d0d1.zip
Merged release 0.15.6 from branch 'v0.15.x'
Conflicts: NEWS configure.ac
Diffstat (limited to 'src/decoder/ffmpeg_plugin.c')
-rw-r--r--src/decoder/ffmpeg_plugin.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/decoder/ffmpeg_plugin.c b/src/decoder/ffmpeg_plugin.c
index 3c96848bb..9b025153b 100644
--- a/src/decoder/ffmpeg_plugin.c
+++ b/src/decoder/ffmpeg_plugin.c
@@ -210,6 +210,21 @@ ffmpeg_helper(struct input_stream *input,
return ret;
}
+/**
+ * On some platforms, libavcodec wants the output buffer aligned to 16
+ * bytes (because it uses SSE/Altivec internally). This function
+ * returns the aligned version of the specified buffer, and corrects
+ * the buffer size.
+ */
+static void *
+align16(void *p, size_t *length_p)
+{
+ unsigned add = 16 - (size_t)p % 16;
+
+ *length_p -= add;
+ return (char *)p + add;
+}
+
static enum decoder_command
ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
const AVPacket *packet,
@@ -218,7 +233,9 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
{
enum decoder_command cmd = DECODE_COMMAND_NONE;
int position;
- uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
+ uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16];
+ int16_t *aligned_buffer;
+ size_t buffer_size;
int len, audio_size;
uint8_t *packet_data;
int packet_size;
@@ -226,11 +243,13 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
packet_data = packet->data;
packet_size = packet->size;
+ buffer_size = sizeof(audio_buf);
+ aligned_buffer = align16(audio_buf, &buffer_size);
+
while ((packet_size > 0) && (cmd == DECODE_COMMAND_NONE)) {
- audio_size = sizeof(audio_buf);
+ audio_size = buffer_size;
len = avcodec_decode_audio2(codec_context,
- (int16_t *)audio_buf,
- &audio_size,
+ aligned_buffer, &audio_size,
packet_data, packet_size);
if (len < 0) {
@@ -251,7 +270,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
: 0;
cmd = decoder_data(decoder, is,
- audio_buf, audio_size,
+ aligned_buffer, audio_size,
position,
codec_context->bit_rate / 1000, NULL);
}