From e23ea1143257ede4cdbbe8ab89222978d43b0344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 31 Dec 2007 00:01:32 +0100 Subject: Provide FFmpeg options skip_loop_filter and choose_speed_over_accuracy. Both options tweak FFmpeg for the sake of decoding speed. The first one skips the loop filter for certain frames while the latter allows FFmpeg to violate the codec's specification. Both options may lead to artefacts. --- src/libffmpeg/ff_video_decoder.c | 59 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index cceb96bf0..784571779 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -65,6 +65,8 @@ typedef struct ff_video_class_s { int pp_quality; int thread_count; + int8_t skip_loop_filter_enum; + int8_t choose_speed_over_accuracy; xine_t *xine; } ff_video_class_t; @@ -316,6 +318,24 @@ static const ff_codec_t ff_video_lookup[] = { {BUF_VIDEO_THEORA_RAW, CODEC_ID_THEORA, "Theora (ffmpeg)"}, }; +static const char *const skip_loop_filter_enum_names[] = { + "default", /* AVDISCARD_DEFAULT */ + "none", /* AVDISCARD_NONE */ + "nonref", /* AVDISCARD_NONREF */ + "bidir", /* AVDISCARD_BIDIR */ + "nonkey", /* AVDISCARD_NONKEY */ + "all", /* AVDISCARD_ALL */ + NULL +}; + +static const int skip_loop_filter_enum_values[] = { + AVDISCARD_DEFAULT, + AVDISCARD_NONE, + AVDISCARD_NONREF, + AVDISCARD_BIDIR, + AVDISCARD_NONKEY, + AVDISCARD_ALL +}; static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) { size_t i; @@ -360,6 +380,9 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) this->context->flags |= CODEC_FLAG_EMU_EDGE; } + if (this->class->choose_speed_over_accuracy) + this->context->flags2 |= CODEC_FLAG2_FAST; + pthread_mutex_lock(&ffmpeg_lock); if (avcodec_open (this->context, this->codec) < 0) { pthread_mutex_unlock(&ffmpeg_lock); @@ -376,6 +399,8 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) this->context->thread_count = this->class->thread_count; } + this->context->skip_loop_filter = skip_loop_filter_enum_values[this->class->skip_loop_filter_enum]; + pthread_mutex_unlock(&ffmpeg_lock); lprintf("lavc decoder opened\n"); @@ -433,6 +458,18 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) } +static void choose_speed_over_accuracy_cb(void *user_data, xine_cfg_entry_t *entry) { + ff_video_class_t *class = (ff_video_class_t *) user_data; + + class->choose_speed_over_accuracy = entry->num_value; +} + +static void skip_loop_filter_enum_cb(void *user_data, xine_cfg_entry_t *entry) { + ff_video_class_t *class = (ff_video_class_t *) user_data; + + class->skip_loop_filter_enum = entry->num_value; +} + static void thread_count_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; @@ -1572,10 +1609,28 @@ void *init_video_plugin (xine_t *xine, void *data) { _("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."), + "decoding thread per logical CPU (typically 1 to 4).\n" + "A change of this setting will take effect with playing the next stream."), 10, thread_count_cb, this); + this->skip_loop_filter_enum = xine->config->register_enum(config, "video.processing.ffmpeg_skip_loop_filter", 0, + (char **)skip_loop_filter_enum_names, + _("Skip loop filter"), + _("You can control for which frames the loop filter shall be skipped after " + "decoding.\n" + "Skipping the loop filter will speedup decoding but may lead to artefacts. " + "The number of frames for which it is skipped increases from 'none' to 'all'. " + "The default value leaves the decision up to the implementation.\n" + "A change of this setting will take effect with playing the next stream."), + 10, skip_loop_filter_enum_cb, this); + + this->choose_speed_over_accuracy = xine->config->register_bool(config, "video.processing.ffmpeg_choose_speed_over_accuracy", 0, + _("Choose speed over specification compliance"), + _("You may want to allow speed cheats which violate codec specification.\n" + "Cheating may speed up decoding but can also lead to decoding artefacts.\n" + "A change of this setting will take effect with playing the next stream."), + 10, choose_speed_over_accuracy_cb, this); + return this; } -- cgit v1.2.3 From 147a5017b476e4cd61aadb8e7420bc20832abfef Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 31 Dec 2007 13:29:40 +0000 Subject: Convert XML parser ABI breakage into ABI extension. Bump the soname accordingly. --- src/xine-utils/xmllexer.c | 12 ++++++++++-- src/xine-utils/xmllexer.h | 3 ++- src/xine-utils/xmlparser.c | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c index a77d6654a..be3bdd248 100644 --- a/src/xine-utils/xmllexer.c +++ b/src/xine-utils/xmllexer.c @@ -123,7 +123,7 @@ void lexer_init(const char * buf, int size) { lprintf("buffer length %d\n", size); } -int lexer_get_token(char ** _tok, int * _tok_size) { +int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) { char *tok = *_tok; int tok_size = *_tok_size; @@ -458,12 +458,14 @@ int lexer_get_token(char ** _tok, int * _tok_size) { /* pb */ if (tok_pos >= tok_size) { + if (fixed) + return T_ERROR; *_tok_size *= 2; *_tok = realloc (*_tok, *_tok_size); lprintf("token buffer is too small\n"); lprintf("increasing buffer size to %d bytes\n", *_tok_size); if (*_tok) { - return lexer_get_token (_tok, _tok_size); + return lexer_get_token_d (_tok, _tok_size, 0); } else { return T_ERROR; } @@ -509,6 +511,12 @@ int lexer_get_token(char ** _tok, int * _tok_size) { return T_ERROR; } +/* for ABI compatibility */ +int lexer_get_token (char *tok, int tok_size) +{ + return lexer_get_token_d (&tok, &tok_size, 1); +} + static struct { char code; unsigned char namelen; diff --git a/src/xine-utils/xmllexer.h b/src/xine-utils/xmllexer.h index bf9948d2d..425d0e70a 100644 --- a/src/xine-utils/xmllexer.h +++ b/src/xine-utils/xmllexer.h @@ -51,7 +51,8 @@ /* public functions */ void lexer_init(const char * buf, int size) XINE_PROTECTED; -int lexer_get_token(char ** tok, int * tok_size) XINE_PROTECTED; +int lexer_get_token_d(char ** tok, int * tok_size, int fixed) XINE_PROTECTED; +int lexer_get_token(char * tok, int tok_size) XINE_PROTECTED; char *lexer_decode_entities (const char *tok) XINE_PROTECTED; #endif diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index cc2bfe462..14ce35c54 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -175,7 +175,7 @@ static int _xml_parser_get_node (char ** token_buffer, int * token_buffer_size, memset (tok, 0, *token_buffer_size); - while ((bypass_get_token) || (res = lexer_get_token(token_buffer, token_buffer_size)) != T_ERROR) { + while ((bypass_get_token) || (res = lexer_get_token_d(token_buffer, token_buffer_size, 0)) != T_ERROR) { tok = *token_buffer; bypass_get_token = 0; lprintf("info: %d - %d : '%s'\n", state, res, tok); -- cgit v1.2.3 From 827f7684690ba127f6477a1d32548dd14d3c79bb Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 31 Dec 2007 13:51:07 +0000 Subject: Build fix: back out the SSA subtitles change from the DirectFB video-out plugin. --- src/video_out/video_out_directfb.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src') diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c index 9786049b4..e6e333a0c 100644 --- a/src/video_out/video_out_directfb.c +++ b/src/video_out/video_out_directfb.c @@ -923,18 +923,6 @@ static int directfb_get_property (vo_driver_t *this_gen, int property) { case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; - case VO_PROP_OUTPUT_WIDTH: - return this->cur_frame->sc.output_width; - - case VO_PROP_OUTPUT_HEIGHT: - return this->cur_frame->sc.output_height; - - case VO_PROP_OUTPUT_XOFFSET: - return this->cur_frame->sc.output_xoffset; - - case VO_PROP_OUTPUT_YOFFSET: - return this->cur_frame->sc.output_yoffset; - case VO_PROP_MAX_NUM_FRAMES: return (this->type & DLTF_VIDEO) ? 8 : 15; -- cgit v1.2.3 From 3a636d2081083046da558174b945c390eeb9341f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Mon, 31 Dec 2007 12:09:01 +0100 Subject: Add a missing initialisation. --- src/libffmpeg/ff_video_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index 784571779..dc1176e78 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -1197,7 +1197,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int got_one_picture = 0; int offset = 0; int codec_type = buf->type & 0xFFFF0000; - int video_step_to_use; + int video_step_to_use = this->video_step; /* pad input data */ /* note: bitstream, alt bitstream reader or something will cause -- cgit v1.2.3 From d3e2c4e2f1dd26f4abb62622a1e3a2869d2f3dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Tue, 1 Jan 2008 00:01:29 +0100 Subject: Use signed data type for pan&scan center offset components. According to specification the center offset components are signed integers. --- src/libmpeg2/header.c | 14 +++++++++++--- src/libmpeg2/mpeg2_internal.h | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libmpeg2/header.c b/src/libmpeg2/header.c index 7f1ef1fc8..c0df02c7f 100644 --- a/src/libmpeg2/header.c +++ b/src/libmpeg2/header.c @@ -101,6 +101,14 @@ static uint32_t get_bits(uint8_t *buffer, uint32_t count, uint32_t *bit_position return result; } +static int32_t get_bits_signed(uint8_t *buffer, uint32_t count, uint32_t *bit_position) { + uint32_t value = get_bits(buffer, count, bit_position); + uint32_t sign_mask = (uint32_t)(-1 << (count - 1)); + if (value & sign_mask) + value |= sign_mask; /* sign-extend value */ + return (int32_t)value; +} + void mpeg2_header_state_init (picture_t * picture) { picture->scan = mpeg2_scan_norm; @@ -291,13 +299,13 @@ static int picture_display_extension (picture_t * picture, uint8_t * buffer) { bit_position = 0; padding = get_bits(buffer, 4, &bit_position); - picture->frame_centre_horizontal_offset = get_bits(buffer, 16, &bit_position); + picture->frame_centre_horizontal_offset = get_bits_signed(buffer, 16, &bit_position); padding = get_bits(buffer, 1, &bit_position); - picture->frame_centre_vertical_offset = get_bits(buffer, 16, &bit_position); + picture->frame_centre_vertical_offset = get_bits_signed(buffer, 16, &bit_position); padding = get_bits(buffer, 1, &bit_position); #ifdef LOG_PAN_SCAN - printf("Pan & Scan centre (x,y) = (%u, %u)\n", + printf("Pan & Scan centre (x,y) = (%d, %d)\n", picture->frame_centre_horizontal_offset, picture->frame_centre_vertical_offset); #endif diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h index c2ffbf909..345e73080 100644 --- a/src/libmpeg2/mpeg2_internal.h +++ b/src/libmpeg2/mpeg2_internal.h @@ -177,8 +177,8 @@ typedef struct picture_s { int progressive_sequence; int repeat_first_field; int progressive_frame; - uint32_t frame_centre_horizontal_offset; - uint32_t frame_centre_vertical_offset; + int32_t frame_centre_horizontal_offset; + int32_t frame_centre_vertical_offset; uint32_t video_format; uint32_t colour_description; uint32_t colour_primatives; -- cgit v1.2.3 From 158c5f2072b8a67a0c9e8d8523908a9d89188b1c Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Tue, 1 Jan 2008 02:29:17 +0000 Subject: Skip deleted keys - should any ever occur! - while saving the config. --- src/xine-engine/configfile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 2f5e6214a..2dc89f0af 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -1060,7 +1060,7 @@ void xine_config_save (xine_t *xine, const char *filename) { if (!entry->key[0]) /* deleted key */ - continue; + goto next; lprintf ("saving key '%s'\n", entry->key); @@ -1130,6 +1130,7 @@ void xine_config_save (xine_t *xine, const char *filename) { break; } + next: entry = entry->next; } pthread_mutex_unlock(&this->config_lock); -- cgit v1.2.3