summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_dec/xine_faad_decoder.c2
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c212
-rw-r--r--src/demuxers/demux_mng.c4
-rw-r--r--src/demuxers/demux_ts.c38
-rw-r--r--src/spu_dec/spudvb_decoder.c4
-rw-r--r--src/xine-engine/video_decoder.c13
6 files changed, 181 insertions, 92 deletions
diff --git a/src/audio_dec/xine_faad_decoder.c b/src/audio_dec/xine_faad_decoder.c
index cd58771e7..be495ee8f 100644
--- a/src/audio_dec/xine_faad_decoder.c
+++ b/src/audio_dec/xine_faad_decoder.c
@@ -71,7 +71,7 @@ typedef struct faad_decoder_s {
int size;
int rec_audio_src_size;
int max_audio_src_size;
- int pts;
+ int64_t pts;
unsigned char *dec_config;
int dec_config_size;
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index 7c293c100..8d7cc1574 100644
--- a/src/combined/ffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -75,6 +75,8 @@ typedef struct ff_audio_decoder_s {
char *decode_buffer;
int decoder_ok;
+ AVCodecParserContext *parser_context;
+
} ff_audio_decoder_t;
@@ -164,6 +166,24 @@ static void ff_audio_init_codec(ff_audio_decoder_t *this, unsigned int codec_typ
this->context->codec_id = this->codec->id;
this->context->codec_type = this->codec->type;
this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC);
+
+ /* Use parser for AAC LATM and MPEG.
+ * Fixes:
+ * - DVB streams where multiple AAC LATM frames are packed to single PES
+ * - DVB streams where MPEG audio frames do not follow PES packet boundaries
+ */
+ if (codec_type == BUF_AUDIO_AAC_LATM ||
+ codec_type == BUF_AUDIO_MPEG) {
+
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: using parser\n");
+
+ this->parser_context = av_parser_init(this->codec->id);
+ if (!this->parser_context) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: couldn't init parser\n");
+ }
+ }
}
static int ff_audio_open_codec(ff_audio_decoder_t *this, unsigned int codec_type) {
@@ -310,6 +330,83 @@ static void ff_handle_header_buffer(ff_audio_decoder_t *this, buf_element_t *buf
this->size = 0;
}
+static void ff_audio_reset_parser(ff_audio_decoder_t *this)
+{
+ /* reset parser */
+ if (this->parser_context) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: resetting parser\n");
+
+ pthread_mutex_lock (&ffmpeg_lock);
+ av_parser_close(this->parser_context);
+ this->parser_context = av_parser_init(this->codec->id);
+ pthread_mutex_unlock (&ffmpeg_lock);
+ }
+}
+
+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)
+{
+ int consumed;
+ int parser_consumed = 0;
+
+ if (parser_ctx) {
+ uint8_t *outbuf;
+ int outsize;
+
+ do {
+ int ret = av_parser_parse2(parser_ctx, ctx,
+ &outbuf, &outsize,
+ buf, size,
+ 0, 0, 0);
+ parser_consumed += ret;
+ buf += ret;
+ size -= ret;
+ } while (size > 0 && outsize <= 0);
+
+ /* nothing to decode ? */
+ if (outsize <= 0) {
+ *decode_buffer_size = 0;
+ xprintf (xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: not enough data to decode\n");
+ return parser_consumed;
+ }
+
+ /* decode next packet */
+ buf = outbuf;
+ size = outsize;
+ }
+
+#if AVAUDIO > 2
+ AVPacket avpkt;
+ av_init_packet (&avpkt);
+ avpkt.data = buf;
+ avpkt.size = size;
+ avpkt.flags = AV_PKT_FLAG_KEY;
+ consumed = avcodec_decode_audio3 (ctx,
+ decode_buffer, decode_buffer_size,
+ &avpkt);
+#else
+ consumed = avcodec_decode_audio2 (ctx,
+ decode_buffer, decode_buffer_size,
+ buf, size);
+#endif
+
+ if (consumed < 0) {
+ xprintf (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,
+ "ffmpeg_audio_dec: decoder didn't consume all data\n");
+ }
+
+ return parser_consumed ? parser_consumed : consumed;
+}
+
static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen;
@@ -332,10 +429,6 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
} else {
-#if AVAUDIO > 2
- AVPacket avpkt;
-#endif
-
if( !this->decoder_ok ) {
if (ff_audio_open_codec(this, codec_type) < 0) {
return;
@@ -349,49 +442,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
this->size += buf->size;
- 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;
- ret = avcodec_decode_audio3 (this->context,
- (int16_t *)this->decode_buffer,
- &decode_buffer_size, &avpkt);
-#else
- 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) {
- 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,
- _x_ao_channels2mode(this->audio_channels));
- }
-
- /* if the audio still isn't open, bail */
- if (!this->output_open)
- return;
-
- if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */
+ if (this->parser_context || buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */
offset = 0;
@@ -400,24 +451,14 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
while (this->size>0) {
decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-#if AVAUDIO > 2
- av_init_packet (&avpkt);
- avpkt.data = (uint8_t *)&this->buf[offset];
- avpkt.size = this->size;
- avpkt.flags = AV_PKT_FLAG_KEY;
- bytes_consumed = avcodec_decode_audio3 (this->context,
- (int16_t *)this->decode_buffer,
- &decode_buffer_size, &avpkt);
-#else
- bytes_consumed = avcodec_decode_audio2 (this->context,
- (int16_t *)this->decode_buffer,
- &decode_buffer_size,
- &this->buf[offset],
- this->size);
-#endif
+
+ bytes_consumed =
+ ff_audio_decode(this->stream->xine, this->context,
+ this->parser_context,
+ (int16_t *)this->decode_buffer, &decode_buffer_size,
+ &this->buf[offset], this->size);
+
if (bytes_consumed<0) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "ffmpeg_audio_dec: error decompressing audio frame\n");
this->size=0;
return;
} else if (bytes_consumed == 0 && decode_buffer_size == 0) {
@@ -426,6 +467,33 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
return;
}
+ if (!this->output_open) {
+ if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) {
+ 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) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _("ffmpeg_audio_dec: cannot read codec parameters from packet\n"));
+ /* try to decode next packet. */
+ /* there shouldn't be any output yet */
+ decode_buffer_size = 0;
+ /* pts applies only to first audio packet */
+ buf->pts = 0;
+ } else {
+ this->output_open = (this->stream->audio_out->open) (this->stream->audio_out,
+ this->stream, this->audio_bits, this->audio_sample_rate,
+ _x_ao_channels2mode(this->audio_channels));
+ if (!this->output_open) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: error opening audio output\n");
+ this->size = 0;
+ return;
+ }
+ }
+ }
+
/* dispatch the decoded audio */
out = 0;
while (out < decode_buffer_size) {
@@ -478,6 +546,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels;
audio_buffer->vpts = buf->pts;
+
buf->pts = 0; /* only first buffer gets the real pts */
this->stream->audio_out->put_buffer (this->stream->audio_out,
audio_buffer, this->stream);
@@ -506,15 +575,30 @@ static void ff_audio_reset (audio_decoder_t *this_gen) {
this->decoder_ok = 0;
pthread_mutex_unlock (&ffmpeg_lock);
}
+
+ ff_audio_reset_parser(this);
}
static void ff_audio_discontinuity (audio_decoder_t *this_gen) {
+
+ ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen;
+
+ this->size = 0;
+
+ ff_audio_reset_parser(this);
}
static void ff_audio_dispose (audio_decoder_t *this_gen) {
ff_audio_decoder_t *this = (ff_audio_decoder_t *) this_gen;
+ if (this->parser_context) {
+ pthread_mutex_lock (&ffmpeg_lock);
+ av_parser_close(this->parser_context);
+ this->parser_context = NULL;
+ pthread_mutex_unlock (&ffmpeg_lock);
+ }
+
if( this->context && this->decoder_ok ) {
pthread_mutex_lock (&ffmpeg_lock);
avcodec_close (this->context);
diff --git a/src/demuxers/demux_mng.c b/src/demuxers/demux_mng.c
index c20d3d051..b2bb819d8 100644
--- a/src/demuxers/demux_mng.c
+++ b/src/demuxers/demux_mng.c
@@ -38,8 +38,6 @@
#undef HAVE_STDLIB_H
#endif
-#include <libmng.h>
-
#define LOG_MODULE "demux_mng"
#define LOG_VERBOSE
/*
@@ -50,6 +48,8 @@
#include <xine/xineutils.h>
#include <xine/demux.h>
+#include <libmng.h>
+
typedef struct {
demux_plugin_t demux_plugin;
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index c37a6c488..2b20fef7a 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -292,7 +292,6 @@
typedef struct {
unsigned int pid;
fifo_buffer_t *fifo;
- uint8_t *content;
uint32_t size;
uint32_t type;
int64_t pts;
@@ -874,7 +873,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
packet_len -= header_len + 9;
if (m->descriptor_tag == STREAM_VIDEO_VC1) {
- m->content = p;
m->size = packet_len;
m->type = BUF_VIDEO_VC1;
return 1;
@@ -883,7 +881,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
if (m->descriptor_tag == HDMV_SPU_BITMAP) {
long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
- m->content = p;
m->size = packet_len;
m->type |= BUF_SPU_HDMV;
m->buf->decoder_info[2] = payload_len;
@@ -905,27 +902,23 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
* For audio streams, m->type already contains the stream no.
*/
if(m->descriptor_tag == HDMV_AUDIO_84_EAC3) {
- m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_EAC3;
return 1;
} else if(m->descriptor_tag == STREAM_AUDIO_AC3) { /* ac3 - raw */
- m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_A52;
return 1;
} else if (m->descriptor_tag == HDMV_AUDIO_83_TRUEHD) {
/* TODO: separate AC3 and TrueHD streams ... */
- m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_A52;
return 1;
} else if (m->descriptor_tag == HDMV_AUDIO_82_DTS ||
m->descriptor_tag == HDMV_AUDIO_86_DTS_HD_MA ) {
- m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_DTS;
return 1;
@@ -939,7 +932,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0;
}
- m->content = p + 4;
m->size = packet_len - 4;
m->type |= BUF_AUDIO_LPCM_BE;
@@ -954,14 +946,12 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
/* DVBSUB */
long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
- m->content = p;
m->size = packet_len;
m->type |= BUF_SPU_DVB;
m->buf->decoder_info[2] = payload_len;
return 1;
} else if (p[0] == 0x0B && p[1] == 0x77) { /* ac3 - syncword */
- m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_A52;
return 1;
@@ -969,7 +959,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
} else if ((p[0] & 0xE0) == 0x20) {
spu_id = (p[0] & 0x1f);
- m->content = p+1;
m->size = packet_len-1;
m->type = BUF_SPU_DVD + spu_id;
return 1;
@@ -979,7 +968,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0;
}
- m->content = p+4;
m->size = packet_len - 4;
m->type |= BUF_AUDIO_A52;
return 1;
@@ -1001,7 +989,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0;
}
- m->content = p+pcm_offset;
m->size = packet_len-pcm_offset;
m->type |= BUF_AUDIO_LPCM_BE;
return 1;
@@ -1010,7 +997,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
} else if ((stream_id & 0xf0) == 0xe0) {
- m->content = p;
m->size = packet_len;
switch (m->descriptor_tag) {
case ISO_11172_VIDEO:
@@ -1036,7 +1022,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
} else if ((stream_id & 0xe0) == 0xc0) {
- m->content = p;
m->size = packet_len;
switch (m->descriptor_tag) {
case ISO_11172_AUDIO:
@@ -1068,6 +1053,20 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0 ;
}
+static void update_extra_info(demux_ts_t *this, demux_ts_media *m)
+{
+ off_t length = this->input->get_length (this->input);
+
+ /* cache frame position */
+
+ if (length > 0) {
+ m->input_normpos = (double)this->frame_pos * 65535.0 / length;
+ }
+ if (this->rate) {
+ m->input_time = this->frame_pos * 1000 / this->rate;
+ }
+}
+
/*
* buffer arriving pes data
*/
@@ -1117,14 +1116,7 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
memcpy(m->buf->mem, ts+len-m->size, m->size);
m->buf->size = m->size;
- /* cache frame position */
- off_t length = this->input->get_length (this->input);
- if (length > 0) {
- m->input_normpos = (double)this->frame_pos * 65535.0 / length;
- }
- if (this->rate) {
- m->input_time = this->frame_pos * 1000 / this->rate;
- }
+ update_extra_info(this, m);
/* rate estimation */
if ((this->tbre_pid == INVALID_PID) && (this->audio_fifo == m->fifo))
diff --git a/src/spu_dec/spudvb_decoder.c b/src/spu_dec/spudvb_decoder.c
index b6720acdf..860d7cc35 100644
--- a/src/spu_dec/spudvb_decoder.c
+++ b/src/spu_dec/spudvb_decoder.c
@@ -32,8 +32,8 @@
#include <xine/osd.h>
#define MAX_REGIONS 7
-#define SPU_MAX_WIDTH 720
-#define SPU_MAX_HEIGHT 576
+#define SPU_MAX_WIDTH 1920
+#define SPU_MAX_HEIGHT 1080
/*#define LOG*/
#define LOG_MODULE "spudvb"
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 564eacb5d..7b0ac72c1 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.c
@@ -366,6 +366,19 @@ static void *video_decoder_loop (void *stream_gen) {
case BUF_CONTROL_NOP:
break;
+ case BUF_CONTROL_RESET_TRACK_MAP:
+ if (stream->spu_track_map_entries)
+ {
+ xine_event_t ui_event;
+
+ stream->spu_track_map_entries = 0;
+
+ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED;
+ ui_event.data_length = 0;
+ xine_event_send(stream, &ui_event);
+ }
+ break;
+
default:
if ( (buf->type & 0xFF000000) == BUF_VIDEO_BASE ) {