diff options
Diffstat (limited to 'src/combined/ffmpeg')
-rw-r--r-- | src/combined/ffmpeg/ff_audio_decoder.c | 40 | ||||
-rw-r--r-- | src/combined/ffmpeg/ff_video_decoder.c | 124 | ||||
-rw-r--r-- | src/combined/ffmpeg/xine_audio.list | 1 |
3 files changed, 100 insertions, 65 deletions
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index db2dc8fa2..f2d1ca93f 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -114,7 +114,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); } } @@ -127,14 +127,13 @@ 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); - 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) { @@ -321,27 +320,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, @@ -355,6 +363,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 diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 5e4967f6c..03a4b8cac 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -65,6 +65,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 + typedef struct ff_video_decoder_s ff_video_decoder_t; typedef struct ff_video_class_s { @@ -354,7 +358,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; } @@ -844,6 +851,59 @@ 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_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; @@ -851,14 +911,14 @@ 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); - } + ff_init_mpeg12_mode(this); } 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; @@ -1024,6 +1084,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; @@ -1198,49 +1263,6 @@ static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts) } } -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}; @@ -1249,7 +1271,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; @@ -1569,7 +1591,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); diff --git a/src/combined/ffmpeg/xine_audio.list b/src/combined/ffmpeg/xine_audio.list index 796917dfe..8a40c29cb 100644 --- a/src/combined/ffmpeg/xine_audio.list +++ b/src/combined/ffmpeg/xine_audio.list @@ -41,6 +41,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 |