From 5306a37c61291161102d4834491b16211d8c6b28 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Sun, 14 Aug 2011 14:51:04 +0300 Subject: Fixed multithreaded decoding with lavc >= 52.112.0. avcodec_thread_init() was deprecated in lavc 52.112.0 (2011-02-09) --- src/combined/ffmpeg/ff_video_decoder.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index a9c383c48..d1c2fcb5b 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -66,6 +66,10 @@ # define pp_mode pp_mode_t #endif +#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 112) +# define DEPRECATED_AVCODEC_THREAD_INIT 1 +#endif + /* reordered_opaque appeared in libavcodec 51.68.0 */ #define AVCODEC_HAS_REORDERED_OPAQUE #if LIBAVCODEC_VERSION_INT < 0x334400 @@ -365,7 +369,10 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) if (this->class->thread_count > 1) { if (this->codec->id != CODEC_ID_SVQ3 - && avcodec_thread_init(this->context, this->class->thread_count) != -1) +#ifndef DEPRECATED_AVCODEC_THREAD_INIT + && avcodec_thread_init(this->context, this->class->thread_count) != -1 +#endif + ) this->context->thread_count = this->class->thread_count; } -- cgit v1.2.3 From 7512f3a88f47b32e196f75920480a2d733c9ae61 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 9 Aug 2011 16:05:27 +0300 Subject: ffmpeg VC-1: scan for extradata (sequence header) from preview buffers --- src/combined/ffmpeg/ff_video_decoder.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index d1c2fcb5b..2c2a08cc1 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -878,6 +878,10 @@ static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *b } if (this->decoder_init_mode && !this->is_mpeg12) { + + if (!ff_check_extradata(this, codec_type, buf)) + return; + init_video_codec(this, codec_type); init_postprocess(this); this->decoder_init_mode = 0; -- cgit v1.2.3 From d211575f64577027568ff85497eb357f878401fb Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 9 Aug 2011 16:04:31 +0300 Subject: Cosmetics: reordered functions --- src/combined/ffmpeg/ff_video_decoder.c | 86 +++++++++++++++++----------------- 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 2c2a08cc1..92fee481f 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -862,6 +862,49 @@ static void ff_check_bufsize (ff_video_decoder_t *this, int size) { } } +static int ff_vc1_find_header(ff_video_decoder_t *this, buf_element_t *buf) +{ + uint8_t *p = buf->content; + + if (!p[0] && !p[1] && p[2] == 1 && p[3] == 0x0f) { + int i; + + this->context->extradata = calloc(1, buf->size); + this->context->extradata_size = 0; + + for (i = 0; i < buf->size && i < 128; i++) { + if (!p[i] && !p[i+1] && p[i+2]) { + lprintf("00 00 01 %02x at %d\n", p[i+3], i); + if (p[i+3] != 0x0e && p[i+3] != 0x0f) + break; + } + this->context->extradata[i] = p[i]; + this->context->extradata_size++; + } + + lprintf("ff_video_decoder: found VC1 sequence header\n"); + return 1; + } + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_video_dec: VC1 extradata missing !\n"); + return 0; +} + +static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, buf_element_t *buf) +{ + if (this->context && this->context->extradata) + return 1; + + switch (codec_type) { + case BUF_VIDEO_VC1: + return ff_vc1_find_header(this, buf); + default:; + } + + return 1; +} + static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int codec_type; @@ -1223,49 +1266,6 @@ static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts) } #endif /* AVCODEC_HAS_REORDERED_OPAQUE */ -static int ff_vc1_find_header(ff_video_decoder_t *this, buf_element_t *buf) -{ - uint8_t *p = buf->content; - - if (!p[0] && !p[1] && p[2] == 1 && p[3] == 0x0f) { - int i; - - this->context->extradata = calloc(1, buf->size); - this->context->extradata_size = 0; - - for (i = 0; i < buf->size && i < 128; i++) { - if (!p[i] && !p[i+1] && p[i+2]) { - lprintf("00 00 01 %02x at %d\n", p[i+3], i); - if (p[i+3] != 0x0e && p[i+3] != 0x0f) - break; - } - this->context->extradata[i] = p[i]; - this->context->extradata_size++; - } - - lprintf("ff_video_decoder: found VC1 sequence header\n"); - return 1; - } - - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_video_dec: VC1 extradata missing !\n"); - return 0; -} - -static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, buf_element_t *buf) -{ - if (this->context && this->context->extradata) - return 1; - - switch (codec_type) { - case BUF_VIDEO_VC1: - return ff_vc1_find_header(this, buf); - default:; - } - - return 1; -} - static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { uint8_t *chunk_buf = this->buf; AVRational avr00 = {0, 1}; -- cgit v1.2.3 From 80cbcb6136ca8a4b93c8dd652e8349c7f9ac9dd4 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 29 Aug 2011 09:33:16 +0100 Subject: Add AAC LATM support from FFmpeg 0.7+ I've now tested this patch on Fedora 15 (FFmpeg 0.7) and Fedora 14 (FFmpeg 0.6), and am happy to report that it works fine on F15 and doesn't break xine-lib on F14. On F14, it also has the happy side effect of no longer trying to decode an LATM AAC stream with the xineplug_decode_faad.so plugin. (Which was something which never ended well anyway.) --- src/combined/ffmpeg/xine_audio.list | 1 + 1 file changed, 1 insertion(+) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/xine_audio.list b/src/combined/ffmpeg/xine_audio.list index 5daa4d8b0..0ebbfbda6 100644 --- a/src/combined/ffmpeg/xine_audio.list +++ b/src/combined/ffmpeg/xine_audio.list @@ -42,6 +42,7 @@ WAVPACK WAVPACK WavPack AMR_NB AMR_NB AMR narrow band AMR_WB AMR_WB AMR wide band EAC3 EAC3 E-AC-3 +AAC_LATM AAC_LATM AAC LATM # disabled codecs (ref. configure.ac) ! AAC -- cgit v1.2.3 From ebfebb80c45a283ebaeb09a1ac136810307c5e34 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:07:08 +0100 Subject: Tidy up flags usage. --- src/combined/ffmpeg/ff_video_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 92fee481f..df57fd5f2 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -1274,7 +1274,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { if (!this->decoder_ok) { if (this->decoder_init_mode) { - int codec_type = buf->type & 0xFFFF0000; + int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); if (!ff_check_extradata(this, codec_type, buf)) return; -- cgit v1.2.3 From 965ea6e948e8648433c507b11f2fa36d20758ee1 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:10:54 +0100 Subject: Optimise flags usage. --- src/combined/ffmpeg/ff_audio_decoder.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 14a908d2f..5ff0ce70e 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -128,10 +128,9 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) int out; audio_buffer_t *audio_buffer; int bytes_to_send; - unsigned int codec_type = buf->type & 0xFFFF0000; + unsigned int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_SPECIAL) ) { + if ( (buf->decoder_flags & (BUF_FLAG_HEADER | BUF_FLAG_SPECIAL)) == BUF_FLAG_HEADER ) { /* accumulate init data */ ff_audio_ensure_buffer_size(this, this->size + buf->size); -- cgit v1.2.3 From 72d45226cc4b327d61c620cf3c5c8c22e23c9e1f Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:11:41 +0100 Subject: Use xine's fast memcpy function instead of standard library one. --- src/combined/ffmpeg/ff_audio_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 5ff0ce70e..68380c124 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -134,7 +134,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) /* accumulate init data */ ff_audio_ensure_buffer_size(this, this->size + buf->size); - memcpy(this->buf + this->size, buf->content, buf->size); + xine_fast_memcpy(this->buf + this->size, buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { -- cgit v1.2.3 From 7f5d3fdfb80831aad2949e8975f70d35b4c0752e Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:13:57 +0100 Subject: Pad end of audio data buffer with zeros, as instructed by the API documentation. --- src/combined/ffmpeg/ff_audio_decoder.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 68380c124..321d0e8f4 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -115,7 +115,7 @@ static void *realloc16 (void *m, size_t s) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), this->bufsize); - this->buf = realloc16 (this->buf, this->bufsize); + this->buf = realloc16 (this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); } } @@ -355,6 +355,10 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ offset = 0; + + /* pad input data */ + memset(&this->buf[this->size], 0, FF_INPUT_BUFFER_PADDING_SIZE); + while (this->size>0) { decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; #if AVAUDIO > 2 -- cgit v1.2.3 From de65e355ef7f33091ae14854120574b5509941db Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:21:52 +0100 Subject: Not every audio packet can be used to determine the sample rate and number of audio channels. So we must keep discarding packets that cannot be used to initialise the codec until we receive one that can be. --- src/combined/ffmpeg/ff_audio_decoder.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 321d0e8f4..7fd5af865 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -321,27 +321,36 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) if (!this->output_open) { if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) { + int ret; + decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; #if AVAUDIO > 2 av_init_packet (&avpkt); avpkt.data = (uint8_t *)&this->buf[0]; avpkt.size = this->size; avpkt.flags = AV_PKT_FLAG_KEY; - avcodec_decode_audio3 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, &avpkt); + ret = avcodec_decode_audio3 (this->context, + (int16_t *)this->decode_buffer, + &decode_buffer_size, &avpkt); #else - avcodec_decode_audio2 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, - &this->buf[0], - this->size); + ret = avcodec_decode_audio2 (this->context, + (int16_t *)this->decode_buffer, + &decode_buffer_size, + &this->buf[0], + this->size); #endif this->audio_bits = this->context->bits_per_sample; this->audio_sample_rate = this->context->sample_rate; this->audio_channels = this->context->channels; - if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) + if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: cannot read codec parameters from packet (error=%d)\n"), ret); + + /* We can't use this packet, so we must discard it + * and wait for another one. */ + this->size = 0; return; + } } this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, this->audio_bits, this->audio_sample_rate, -- cgit v1.2.3 From bccc0e0c620bea3e1a6ed502c7d53799ac35c180 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 16 Sep 2011 10:57:05 +0300 Subject: Splitted ff_init_mpeg12_mode() from ff_handle_preview_buffer() --- src/combined/ffmpeg/ff_video_decoder.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index df57fd5f2..eff673822 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -905,6 +905,16 @@ static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, return 1; } +static void ff_init_mpeg12_mode(ff_video_decoder_t *this) +{ + this->is_mpeg12 = 1; + if ( this->mpeg_parser == NULL ) { + this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); + mpeg_parser_init(this->mpeg_parser); + this->decoder_init_mode = 0; + } +} + static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int codec_type; @@ -912,12 +922,7 @@ static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *b codec_type = buf->type & 0xFFFF0000; if (codec_type == BUF_VIDEO_MPEG) { - this->is_mpeg12 = 1; - if ( this->mpeg_parser == NULL ) { - this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); - mpeg_parser_init(this->mpeg_parser); - this->decoder_init_mode = 0; - } + ff_init_mpeg12_mode(this); } if (this->decoder_init_mode && !this->is_mpeg12) { -- cgit v1.2.3 From 752c9d69932238731394c2b86c458b3213d85b97 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 16 Sep 2011 10:59:02 +0300 Subject: ffmpeg video: do not require preview buffers for mpeg1/2 --- src/combined/ffmpeg/ff_video_decoder.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/combined') diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index eff673822..f9822723c 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -1095,6 +1095,11 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu lprintf("handle_mpeg12_buffer\n"); + if (!this->is_mpeg12) { + /* initialize mpeg parser */ + ff_init_mpeg12_mode(this); + } + while ((size > 0) || (flush == 1)) { uint8_t *current; @@ -1617,7 +1622,7 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { if (buf->pts) this->pts = buf->pts; - if (this->is_mpeg12) { + if ((buf->type & 0xFFFF0000) == BUF_VIDEO_MPEG) { ff_handle_mpeg12_buffer(this, buf); } else { ff_handle_buffer(this, buf); -- cgit v1.2.3