mirror of
https://github.com/archlinuxarm/PKGBUILDs.git
synced 2024-11-08 22:45:43 +00:00
277 lines
9.8 KiB
Diff
277 lines
9.8 KiB
Diff
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
|
|
|