diff options
author | root <root@rshg054.dnsready.net> | 2013-03-10 00:51:34 -0800 |
---|---|---|
committer | root <root@rshg054.dnsready.net> | 2013-03-10 00:51:34 -0800 |
commit | 6ee08d6a9217906f2ef84f70923d3d362d4b40ad (patch) | |
tree | dc3d842884f61485a4c01889d37d9432620d5e38 /extra/xine-lib/xine-lib-1.2.2-ffmpeg_audio_decoder-support-new-av_decode_audio4.patch | |
parent | 92eac63df242654434dceb000bac083f6e81a6b9 (diff) |
Sun Mar 10 00:50:57 PST 2013
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.patch | 277 |
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 + |