From a14c025e6e7bec4b731366a1703f18604d6c70ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 1 Oct 2007 23:21:23 +0200 Subject: Fix allocation of 0x0 frame when frame size is still unknown. When a stream doesn't start with an IDR frame, then frame size isn't known, but all frames up to an IDR frame are reported as bad frames. In such a case, a frame of size 1x1 will be allocated as xine-lib cannot handle 0x0 frames properly, i. e. many output drivers simply crash. --- src/libffmpeg/ff_video_decoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index 81ee6148e..ccce9c578 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -1294,10 +1294,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { } if (!got_one_picture) { - /* skipped frame, output a bad frame */ + /* skipped frame, output a bad frame (of size 1x1 when size still uninitialized) */ img = this->stream->video_out->get_frame (this->stream->video_out, - this->bih.biWidth, - this->bih.biHeight, + (this->bih.biWidth <= 0) ? 1 : this->bih.biWidth, + (this->bih.biHeight <= 0) ? 1 : this->bih.biHeight, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); -- cgit v1.2.3 From 0c5696d523a43a5161134c354d6bfb21bb29bae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 1 Oct 2007 23:24:58 +0200 Subject: Set PTS even for bad frames to improve syncing of audio and video. When a stream doesn't start with an IDR frame, there will be several seconds of bad frames and not setting PTS on those frames causes an unnecessary delay in syncing audio and video. --- src/libffmpeg/ff_video_decoder.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index ccce9c578..077ff2fad 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -1301,7 +1301,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); - img->pts = 0; + /* set PTS to allow early syncing */ + img->pts = this->pts; + this->pts = 0; + img->duration = this->video_step; img->bad_frame = 1; this->skipframes = img->draw(img, this->stream); -- cgit v1.2.3 From c61244d24f43b13d75f73ff70c4421a14210ac13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 1 Oct 2007 23:28:27 +0200 Subject: Add UI option to configure FFmpeg's video decoder thread count. External FFmpeg has recently gained multithreaded H.264 decoding and to make use of this feature, it is necessary to inform FFmpeg about the maximum number of threads it may use for decoding. --- src/libffmpeg/ff_video_decoder.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index 077ff2fad..9ab4f9daf 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -67,6 +67,7 @@ typedef struct ff_video_class_s { video_decoder_class_t decoder_class; int pp_quality; + int thread_count; xine_t *xine; } ff_video_class_t; @@ -368,6 +369,12 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); return; } + + if (this->class->thread_count > 1) { + avcodec_thread_init(this->context, this->class->thread_count); + this->context->thread_count = this->class->thread_count; + } + pthread_mutex_unlock(&ffmpeg_lock); lprintf("lavc decoder opened\n"); @@ -422,6 +429,12 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) } +static void thread_count_cb(void *user_data, xine_cfg_entry_t *entry) { + ff_video_class_t *class = (ff_video_class_t *) user_data; + + class->thread_count = entry->num_value; +} + static void pp_quality_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; @@ -1530,6 +1543,15 @@ void *init_video_plugin (xine_t *xine, void *data) { "too much."), 10, pp_quality_cb, this); + this->thread_count = xine->config->register_num(config, "video.processing.ffmpeg_thread_count", 1, + _("FFmpeg video decoding thread count"), + _("You can adjust the number of video decoding threads which FFmpeg may use.\n" + "Higher values should speed up decoding but it depends on the codec used " + "whether parallel decoding is supported. A rule of thumb is to have one " + "decoding thread per logical CPU (typically 1 to 4). A change will take " + "effect with playing the next stream."), + 10, thread_count_cb, this); + return this; } -- cgit v1.2.3 From 8f0d2fdb0a1921cc0eee8aa03f4620501ba33a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 1 Oct 2007 23:32:39 +0200 Subject: Revert cheating invalid frame sizes after fixed frame allocation. These cheats where hiding a frame allocation bug in FFmpeg decoder which was previously fixed. --- src/video_out/video_out_xv.c | 5 ----- src/video_out/video_out_xxmc.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 4c3db95a6..b20a28c84 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -257,11 +257,6 @@ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, unsigned int xv_format; XvImage *image = NULL; - if (width <= 0) - width = 1; - if (height <= 0) - height = 1; - if (this->use_pitch_alignment) { lprintf ("use_pitch_alignment old width=%d",width); width = (width + 7) & ~0x7; diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 0ba004127..5dd3cb118 100644 --- a/src/video_out/video_out_xxmc.c +++ b/src/video_out/video_out_xxmc.c @@ -608,11 +608,6 @@ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, unsigned int xv_format; XvImage *image = NULL; - if (width <= 0) - width = 1; - if (height <= 0) - height = 1; - if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } -- cgit v1.2.3 From f4e560ef116a71a8d407b615be19e1f0ddf438c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 1 Oct 2007 23:43:57 +0200 Subject: Fix incorrect H.264 detection on successive MPEG1/2 B frames. Successive MPEG1/2 B frames (each with a slice #9) could incorrectly lead to the assumption of a H.264 stream, as sequence or group start codes were not seen for these frames. So the detection logic interpreted the slice #9 start codes as H.264 access unit delimiters and therefore incorrectly switched to H.264 buffer type instead of MPEG1/2. Extending the detection logic to consider MPEG1/2 picture start codes as well (which do not appear in H.264 streams), prevents false positives. --- src/demuxers/demux_mpeg_pes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c index fbfde4e60..9ef38f97d 100644 --- a/src/demuxers/demux_mpeg_pes.c +++ b/src/demuxers/demux_mpeg_pes.c @@ -1110,7 +1110,7 @@ static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_elemen uint8_t *pp = p + 2, *pp_limit = p + payload_size - 1; while (0 < pp && pp < pp_limit) { if (pp[0] == 0x01 && pp[-1] == 0x00 && pp[-2] == 0x00) { - if (pp[1] >= 0x80) { /* MPEG 1/2 start code */ + if (pp[1] >= 0x80 || !pp[1]) { /* MPEG 1/2 start code */ this->mpeg12_h264_detected = 2; break; } else { -- cgit v1.2.3 From edadcb8edb2b0cff8d7408186d581065ea4fe3a6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Tue, 2 Oct 2007 23:34:15 +0100 Subject: Update changelog. --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index 238f31390..493d85193 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,10 @@ xine-lib (1.1.9) (unreleased) * Fix switching DVB subtitles channels. * DVB sub: switch to dyn mem alloc and allow multiple CLUTs per page. * Check if DVB sub PTS is reliable and show sub immediately if it's not. + * Fix incorrect H.264 detection on successive MPEG1/2 B frames. + * Add UI option to configure FFmpeg's video decoder thread count. + * Improve syncing of audio and video in the presence of bad frames. + * Improve handling of invalid or unknown frame sizes. xine-lib (1.1.8) * Send a channel-changed event to the frontend when receiving the SYNC -- cgit v1.2.3