summaryrefslogtreecommitdiff
path: root/extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch')
-rw-r--r--extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch277
1 files changed, 277 insertions, 0 deletions
diff --git a/extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch b/extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch
new file mode 100644
index 000000000..255f56d0d
--- /dev/null
+++ b/extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch
@@ -0,0 +1,277 @@
+From 679582503c8ba2f91a82e44c4a2938550306fd07 Mon Sep 17 00:00:00 2001
+From: Torsten Jager <t.jager@gmx.de>
+Date: Thu, 21 Feb 2013 22:35:00 +0200
+Subject: [PATCH 3/5] ffmpeg_audio_decoder: support new av_decode_audio4 ()
+
+---
+ src/combined/ffmpeg/ff_audio_decoder.c | 153 +++++++++++++++++++++++++++------
+ src/combined/ffmpeg/ffmpeg_compat.h | 4 +-
+ 2 files changed, 131 insertions(+), 26 deletions(-)
+
+diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
+index 4e64378..34a7a9e 100644
+--- a/src/combined/ffmpeg/ff_audio_decoder.c
++++ b/src/combined/ffmpeg/ff_audio_decoder.c
+@@ -71,7 +71,9 @@ typedef struct ff_audio_decoder_s {
+ int decoder_ok;
+
+ AVCodecParserContext *parser_context;
+-
++#if AVAUDIO > 3
++ AVFrame *av_frame;
++#endif
+ } ff_audio_decoder_t;
+
+
+@@ -150,6 +152,9 @@ static void ff_audio_init_codec(ff_audio_decoder_t *this, unsigned int codec_typ
+ return;
+ }
+
++ /* Try to make the following true */
++ this->context->request_sample_fmt = AV_SAMPLE_FMT_S16;
++
+ /* Current ffmpeg audio decoders usually use 16 bits/sample
+ * buf->decoder_info[2] can't be used as it doesn't refer to the output
+ * bits/sample for some codecs (e.g. MS ADPCM) */
+@@ -358,25 +363,19 @@ static void ff_audio_output_close(ff_audio_decoder_t *this)
+ this->audio_channels = 0;
+ }
+
+-static int ff_audio_decode(xine_t *xine,
+- AVCodecContext *ctx,
+- AVCodecParserContext *parser_ctx,
+- int16_t *decode_buffer, int *decode_buffer_size,
+- uint8_t *buf, int size)
+-{
++static int ff_audio_decode (ff_audio_decoder_t *this,
++ int16_t *decode_buffer, int *decode_buffer_size, uint8_t *buf, int size) {
+ int consumed;
+ int parser_consumed = 0;
+
+ #if AVPARSE > 1
+- if (parser_ctx) {
++ if (this->parser_context) {
+ uint8_t *outbuf;
+ int outsize;
+
+ do {
+- int ret = av_parser_parse2(parser_ctx, ctx,
+- &outbuf, &outsize,
+- buf, size,
+- 0, 0, 0);
++ int ret = av_parser_parse2 (this->parser_context, this->context,
++ &outbuf, &outsize, buf, size, 0, 0, 0);
+ parser_consumed += ret;
+ buf += ret;
+ size -= ret;
+@@ -385,7 +384,7 @@ static int ff_audio_decode(xine_t *xine,
+ /* nothing to decode ? */
+ if (outsize <= 0) {
+ *decode_buffer_size = 0;
+- xprintf (xine, XINE_VERBOSITY_DEBUG,
++ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: not enough data to decode\n");
+ return parser_consumed;
+ }
+@@ -402,21 +401,115 @@ static int ff_audio_decode(xine_t *xine,
+ avpkt.data = buf;
+ avpkt.size = size;
+ avpkt.flags = AV_PKT_FLAG_KEY;
+- consumed = avcodec_decode_audio3 (ctx,
+- decode_buffer, decode_buffer_size,
+- &avpkt);
++# if AVAUDIO > 3
++ int got_frame;
++ if (!this->av_frame)
++ this->av_frame = avcodec_alloc_frame ();
++
++ consumed = avcodec_decode_audio4 (this->context, this->av_frame, &got_frame, &avpkt);
++ if ((consumed >= 0) && got_frame) {
++ int16_t *q = decode_buffer;
++ int samples = this->av_frame->nb_samples;
++ int channels = this->context->channels;
++ int bytes, i, j;
++ /* limit buffer */
++ if (channels > 12)
++ channels = 12;
++ if (*decode_buffer_size < samples * channels * 2)
++ samples = *decode_buffer_size / (channels * 2);
++ bytes = samples * channels * 2;
++ *decode_buffer_size = bytes;
++ /* convert to packed int16_t. I guess there is something
++ in libavfilter but also another dependency... */
++ switch (this->context->sample_fmt) {
++ case AV_SAMPLE_FMT_U8P:
++ if (channels > 1) {
++ uint8_t *p[12];
++ for (i = 0; i < channels; i++)
++ p[i] = (uint8_t *)this->av_frame->extended_data[i];
++ for (i = samples; i; i--) {
++ for (j = 0; j < channels; j++)
++ *q++ = ((uint16_t)(*p[j]++) << 8) ^ 0x8000;
++ }
++ break;
++ }
++ case AV_SAMPLE_FMT_U8:
++ {
++ uint8_t *p = (uint8_t *)this->av_frame->extended_data[0];
++ for (i = samples * channels; i; i--)
++ *q++ = ((uint16_t)(*p++) << 8) ^ 0x8000;
++ }
++ break;
++ case AV_SAMPLE_FMT_S16P:
++ if (channels > 1) {
++ int16_t *p[12];
++ for (i = 0; i < channels; i++)
++ p[i] = (int16_t *)this->av_frame->extended_data[i];
++ for (i = samples; i; i--) {
++ for (j = 0; j < channels; j++)
++ *q++ = *p[j]++;
++ }
++ break;
++ }
++ case AV_SAMPLE_FMT_S16:
++ xine_fast_memcpy (q, this->av_frame->extended_data[0], bytes);
++ break;
++ case AV_SAMPLE_FMT_S32P:
++ if (channels > 1) {
++ int32_t *p[12];
++ for (i = 0; i < channels; i++)
++ p[i] = (int32_t *)this->av_frame->extended_data[i];
++ for (i = samples; i; i--) {
++ for (j = 0; j < channels; j++)
++ *q++ = *p[j]++ >> 16;
++ }
++ break;
++ }
++ case AV_SAMPLE_FMT_S32:
++ {
++ int32_t *p = (int32_t *)this->av_frame->extended_data[0];
++ for (i = samples * channels; i; i--)
++ *q++ = *p++ >> 16;
++ }
++ break;
++ case AV_SAMPLE_FMT_FLTP: /* the most popular one */
++ if (channels > 1) {
++ float *p[12];
++ for (i = 0; i < channels; i++)
++ p[i] = (float *)this->av_frame->extended_data[i];
++ for (i = samples; i; i--) {
++ for (j = 0; j < channels; j++) {
++ int v = *p[j]++ * (float)0x7fff;
++ *q++ = (v + 0x8000) & ~0xffff ? (v >> 31) ^ 0x7fff : v;
++ }
++ }
++ break;
++ }
++ case AV_SAMPLE_FMT_FLT:
++ {
++ float *p = (float *)this->av_frame->extended_data[0];
++ for (i = samples * channels; i; i--) {
++ int v = *p++ * (float)0x7fff;
++ *q++ = (v + 0x8000) & ~0xffff ? (v >> 31) ^ 0x7fff : v;
++ }
++ }
++ break;
++ default: ;
++ }
++ } else *decode_buffer_size = 0;
++# else
++ consumed = avcodec_decode_audio3 (this->context, decode_buffer, decode_buffer_size, &avpkt);
++# endif
+ #else
+- consumed = avcodec_decode_audio2 (ctx,
+- decode_buffer, decode_buffer_size,
+- buf, size);
++ consumed = avcodec_decode_audio2 (this->context, decode_buffer, decode_buffer_size, buf, size);
+ #endif
+
+ if (consumed < 0) {
+- xprintf (xine, XINE_VERBOSITY_DEBUG,
++ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: error decompressing audio frame (%d)\n", consumed);
+ } else if (parser_consumed && consumed != size) {
+
+- xprintf (xine, XINE_VERBOSITY_DEBUG,
++ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: decoder didn't consume all data\n");
+ }
+
+@@ -469,8 +562,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
+ decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+
+ bytes_consumed =
+- ff_audio_decode(this->stream->xine, this->context,
+- this->parser_context,
++ ff_audio_decode(this,
+ (int16_t *)this->decode_buffer, &decode_buffer_size,
+ &this->buf[offset], this->size);
+
+@@ -539,6 +631,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
+ }
+
+ /* fill up this buffer */
++#if AVAUDIO < 4
+ if (codec_type == BUF_AUDIO_WMAPRO) {
+ /* the above codecs output float samples, not 16-bit integers */
+ int bytes_per_sample = sizeof(float);
+@@ -558,7 +651,9 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
+ bytes_to_send = bytes_to_send * 2 / bytes_per_sample;
+ xine_fast_memcpy(audio_buffer->mem, int_buffer, bytes_to_send);
+ free(int_buffer);
+- } else {
++ } else
++#endif
++ {
+ if ((decode_buffer_size - out) > audio_buffer->mem_size)
+ bytes_to_send = audio_buffer->mem_size;
+ else
+@@ -595,6 +690,9 @@ static void ff_audio_reset (audio_decoder_t *this_gen) {
+
+ /* try to reset the wma decoder */
+ if( this->decoder_ok ) {
++#if AVAUDIO > 3
++ avcodec_free_frame (&this->av_frame);
++#endif
+ pthread_mutex_lock (&ffmpeg_lock);
+ avcodec_close (this->context);
+ if (avcodec_open (this->context, this->codec) < 0)
+@@ -626,6 +724,9 @@ static void ff_audio_dispose (audio_decoder_t *this_gen) {
+ }
+
+ if( this->context && this->decoder_ok ) {
++#if AVAUDIO > 3
++ avcodec_free_frame (&this->av_frame);
++#endif
+ pthread_mutex_lock (&ffmpeg_lock);
+ avcodec_close (this->context);
+ pthread_mutex_unlock (&ffmpeg_lock);
+@@ -668,7 +769,9 @@ static audio_decoder_t *ff_audio_open_plugin (audio_decoder_class_t *class_gen,
+
+ this->context = avcodec_alloc_context();
+ this->decode_buffer = malloc16 (AVCODEC_MAX_AUDIO_FRAME_SIZE);
+-
++#if AVAUDIO > 3
++ this->av_frame = NULL;
++#endif
+ return &this->audio_decoder;
+ }
+
+diff --git a/src/combined/ffmpeg/ffmpeg_compat.h b/src/combined/ffmpeg/ffmpeg_compat.h
+index 0acead8..b567dc1 100644
+--- a/src/combined/ffmpeg/ffmpeg_compat.h
++++ b/src/combined/ffmpeg/ffmpeg_compat.h
+@@ -94,7 +94,9 @@
+ #endif
+
+ /* avcodec_decode_audio() */
+-#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 32)
++#if LIBAVCODEC_VERSION_MAJOR >= 54
++# define AVAUDIO 4
++#elif LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 32)
+ # define AVAUDIO 3
+ #else
+ # define AVAUDIO 2
+--
+1.8.1.5
+