diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/audio_dec/xine_faad_decoder.c | 2 | ||||
-rw-r--r-- | src/combined/ffmpeg/ff_audio_decoder.c | 212 | ||||
-rw-r--r-- | src/demuxers/demux_mng.c | 4 | ||||
-rw-r--r-- | src/demuxers/demux_ts.c | 38 | ||||
-rw-r--r-- | src/spu_dec/spudvb_decoder.c | 4 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 13 |
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 ) { |