summaryrefslogtreecommitdiff
path: root/src/combined/ffmpeg
diff options
context:
space:
mode:
Diffstat (limited to 'src/combined/ffmpeg')
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c40
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c124
-rw-r--r--src/combined/ffmpeg/xine_audio.list1
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