diff --git a/multimedia/xine-lib/Makefile b/multimedia/xine-lib/Makefile index 940f5f6b3a2..dee051f8536 100644 --- a/multimedia/xine-lib/Makefile +++ b/multimedia/xine-lib/Makefile @@ -1,11 +1,11 @@ -# $OpenBSD: Makefile,v 1.80 2011/09/16 10:31:24 espie Exp $ +# $OpenBSD: Makefile,v 1.81 2011/10/09 20:45:07 sthen Exp $ SHARED_ONLY= Yes COMMENT= multimedia decoding library DISTNAME= xine-lib-1.1.19 -REVISION= 10 +REVISION= 11 CATEGORIES= multimedia MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=xine/} EXTRACT_SUFX= .tar.bz2 diff --git a/multimedia/xine-lib/patches/patch-configure_ac b/multimedia/xine-lib/patches/patch-configure_ac index 9dd92219f5e..ba544984e24 100644 --- a/multimedia/xine-lib/patches/patch-configure_ac +++ b/multimedia/xine-lib/patches/patch-configure_ac @@ -1,6 +1,15 @@ -$OpenBSD: patch-configure_ac,v 1.7 2010/09/13 20:12:16 sthen Exp $ +$OpenBSD: patch-configure_ac,v 1.8 2011/10/09 20:45:07 sthen Exp $ --- configure.ac.orig Sun Jul 25 10:37:30 2010 -+++ configure.ac Wed Aug 25 11:21:06 2010 ++++ configure.ac Wed Sep 28 03:18:47 2011 +@@ -412,7 +412,7 @@ for ucname in $ffmpeg_uncommon_codecs; do + done + + dnl popular ffmpeg codecs +-ffmpeg_popular_codecs="CINEPAK FLASHSV H261 H263 H263I H264 INDEO2 INDEO3 MJPEG MJPEGB MPEG1VIDEO MPEG2VIDEO MPEG4 MPEGVIDEO MSMPEG4V1 MSMPEG4V2 MSMPEG4V3 MSRLE MSVIDEO1 QTRLE RV10 RV20 SVQ1 SVQ3 VC1 VP3 VP5 VP6 VP6F WMV1 WMV2 WMV3 COOK DTS EAC3 FLAC MP2 MP3 QDM2 RA_144 RA_288 WAVPACK WMAV1 WMAV2 WMAPRO ADPCM_SWF" ++ffmpeg_popular_codecs="CINEPAK FLASHSV H261 H263 H263I H264 INDEO2 INDEO3 MJPEG MJPEGB MPEG1VIDEO MPEG2VIDEO MPEG4 MPEGVIDEO MSMPEG4V1 MSMPEG4V2 MSMPEG4V3 MSRLE MSVIDEO1 QTRLE RV10 RV20 RV30 RV40 SVQ1 SVQ3 VC1 VP3 VP5 VP6 VP6F VP8 WMV1 WMV2 WMV3 COOK DTS EAC3 FLAC MP2 MP3 QDM2 RA_144 RA_288 WAVPACK WMAV1 WMAV2 WMAPRO ADPCM_SWF" + + for ucname in $ffmpeg_popular_codecs; do + config_name="CONFIG_${ucname}_DECODER" @@ -565,9 +565,9 @@ t q b :q diff --git a/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_audio_decoder_c b/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_audio_decoder_c index 2b01e9a7b08..b690bc55b72 100644 --- a/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_audio_decoder_c +++ b/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_audio_decoder_c @@ -1,9 +1,14 @@ -$OpenBSD: patch-src_combined_ffmpeg_ff_audio_decoder_c,v 1.1 2011/06/13 08:10:01 dcoppa Exp $ +$OpenBSD: patch-src_combined_ffmpeg_ff_audio_decoder_c,v 1.2 2011/10/09 20:45:07 sthen Exp $ -Eliminate use of old FFmpeg APIs. +- Eliminate use of old FFmpeg APIs. +- Fix audio crash (SSE2 alignment). +- Use xine's fast memcpy. +- Pad end of audio data buffer with zeros. +- Not every audio packet can be used to determine the sample rate and number of + audio channels. --- src/combined/ffmpeg/ff_audio_decoder.c.orig Tue Mar 23 11:41:49 2010 -+++ src/combined/ffmpeg/ff_audio_decoder.c Mon May 16 20:42:58 2011 ++++ src/combined/ffmpeg/ff_audio_decoder.c Sun Oct 2 15:45:17 2011 @@ -46,6 +46,12 @@ #define AUDIOBUFSIZE (64 * 1024) @@ -17,7 +22,77 @@ Eliminate use of old FFmpeg APIs. typedef struct { audio_decoder_class_t decoder_class; } ff_audio_class_t; -@@ -255,6 +261,9 @@ static void ff_audio_decode_data (audio_decoder_t *thi +@@ -75,13 +81,41 @@ typedef struct ff_audio_decoder_s { + + #include "ff_audio_list.h" + ++#define malloc16(s) realloc16(NULL,s) ++#define free16(p) realloc16(p,0) ++ ++static void *realloc16 (void *m, size_t s) { ++ unsigned long diff, diff2; ++ unsigned char *p = m, *q; ++ if (p) { ++ diff = p[-1]; ++ if (s == 0) { ++ free (p - diff); ++ return (NULL); ++ } ++ q = realloc (p - diff, s + 16); ++ if (!q) return (q); ++ diff2 = 16 - ((unsigned long)q & 15); ++ if (diff2 != diff) memmove (q + diff2, q + diff, s); ++ } else { ++ if (s == 0) return (NULL); ++ q = malloc (s + 16); ++ if (!q) return (q); ++ diff2 = 16 - ((unsigned long)q & 15); ++ } ++ q += diff2; ++ q[-1] = diff2; ++ return (q); ++} ++ ++ + static void ff_audio_ensure_buffer_size(ff_audio_decoder_t *this, int size) { + if (size > this->bufsize) { + this->bufsize = size + size / 2; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), + this->bufsize); +- this->buf = realloc( this->buf, this->bufsize ); ++ this->buf = realloc16 (this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); + } + } + +@@ -94,14 +128,13 @@ static void ff_audio_decode_data (audio_decoder_t *thi + 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) { +@@ -241,7 +274,7 @@ static void ff_audio_decode_data (audio_decoder_t *thi + + this->size = 0; + +- this->decode_buffer = calloc(1, AVCODEC_MAX_AUDIO_FRAME_SIZE); ++ this->decode_buffer = malloc16 (AVCODEC_MAX_AUDIO_FRAME_SIZE); + + return; + } +@@ -255,6 +288,9 @@ static void ff_audio_decode_data (audio_decoder_t *thi buf->decoder_info[2]); } else if (!(buf->decoder_flags & BUF_FLAG_SPECIAL)) { @@ -27,30 +102,57 @@ Eliminate use of old FFmpeg APIs. if( !this->decoder_ok ) { if ( ! this->context || ! this->codec ) { -@@ -286,11 +295,21 @@ static void ff_audio_decode_data (audio_decoder_t *thi +@@ -285,17 +321,36 @@ static void ff_audio_decode_data (audio_decoder_t *thi + 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; +- avcodec_decode_audio2 (this->context, +- (int16_t *)this->decode_buffer, +- &decode_buffer_size, +- &this->buf[0], +- this->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; -@@ -311,12 +330,21 @@ static void ff_audio_decode_data (audio_decoder_t *thi +- 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, +@@ -309,14 +364,27 @@ static void ff_audio_decode_data (audio_decoder_t *thi + 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 @@ -72,3 +174,14 @@ Eliminate use of old FFmpeg APIs. if (bytes_consumed<0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: error decompressing audio frame\n"); +@@ -427,8 +495,8 @@ static void ff_audio_dispose (audio_decoder_t *this_ge + this->stream->audio_out->close (this->stream->audio_out, this->stream); + this->output_open = 0; + +- free(this->buf); +- free(this->decode_buffer); ++ free16 (this->buf); ++ free16 (this->decode_buffer); + + if(this->context && this->context->extradata) + free(this->context->extradata); diff --git a/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_video_decoder_c b/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_video_decoder_c index 8d38e15d887..44a0cd218ef 100644 --- a/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_video_decoder_c +++ b/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_ff_video_decoder_c @@ -1,10 +1,14 @@ -$OpenBSD: patch-src_combined_ffmpeg_ff_video_decoder_c,v 1.5 2011/06/13 08:10:01 dcoppa Exp $ +$OpenBSD: patch-src_combined_ffmpeg_ff_video_decoder_c,v 1.6 2011/10/09 20:45:07 sthen Exp $ -Eliminate use of old FFmpeg APIs. +- Eliminate use of old FFmpeg APIs. +- RV30 & RV40 support. +- Fixed multithreaded decoding with lavc >= 52.112.0. +- VC-1: scan for extradata (sequence header) from preview buffers. +- Do not require preview buffers for MPEG1/2. --- src/combined/ffmpeg/ff_video_decoder.c.orig Wed Mar 10 14:07:15 2010 -+++ src/combined/ffmpeg/ff_video_decoder.c Mon May 16 20:42:58 2011 -@@ -58,6 +58,14 @@ ++++ src/combined/ffmpeg/ff_video_decoder.c Sun Oct 2 15:47:43 2011 +@@ -58,6 +58,18 @@ #define ENABLE_DIRECT_RENDERING @@ -15,11 +19,15 @@ Eliminate use of old FFmpeg APIs. +# define pp_context pp_context_t +# 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 + /* reordered_opaque appeared in libavcodec 51.68.0 */ #define AVCODEC_HAS_REORDERED_OPAQUE #if LIBAVCODEC_VERSION_INT < 0x334400 -@@ -116,8 +124,8 @@ struct ff_video_decoder_s { +@@ -116,8 +128,8 @@ struct ff_video_decoder_s { int pp_quality; int pp_flags; @@ -30,7 +38,30 @@ Eliminate use of old FFmpeg APIs. /* mpeg-es parsing */ mpeg_parser_t *mpeg_parser; -@@ -444,23 +452,23 @@ static void pp_change_quality (ff_video_decoder_t *thi +@@ -321,6 +333,10 @@ static void init_video_codec (ff_video_decoder_t *this + this->context->flags |= CODEC_FLAG_EMU_EDGE; + } + ++ /* TJ. without this, it wont work at all on my machine */ ++ this->context->codec_id = this->codec->id; ++ this->context->codec_type = this->codec->type; ++ + if (this->class->choose_speed_over_accuracy) + this->context->flags2 |= CODEC_FLAG2_FAST; + +@@ -353,7 +369,10 @@ static void init_video_codec (ff_video_decoder_t *this + + 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; + } + +@@ -444,23 +463,23 @@ static void pp_change_quality (ff_video_decoder_t *thi this->pp_quality = this->class->pp_quality; if(this->pp_available && this->pp_quality) { @@ -65,7 +96,135 @@ Eliminate use of old FFmpeg APIs. } } } -@@ -1055,12 +1063,26 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_ +@@ -502,17 +521,6 @@ static void init_postprocess (ff_video_decoder_t *this + + static int ff_handle_mpeg_sequence(ff_video_decoder_t *this, mpeg_parser_t *parser) { + +- /* +- * init codec +- */ +- if (this->decoder_init_mode) { +- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, +- "mpeg-1 (ffmpeg)"); +- +- init_video_codec (this, BUF_VIDEO_MPEG); +- this->decoder_init_mode = 0; +- } +- + /* frame format change */ + if ((parser->width != this->bih.biWidth) || + (parser->height != this->bih.biHeight) || +@@ -843,6 +851,67 @@ static void ff_check_bufsize (ff_video_decoder_t *this + } + } + ++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->decoder_init_mode) { ++ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, ++ "mpeg-1 (ffmpeg)"); ++ ++ init_video_codec (this, BUF_VIDEO_MPEG); ++ this->decoder_init_mode = 0; ++ } ++ ++ if ( this->mpeg_parser == NULL ) { ++ this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); ++ mpeg_parser_init(this->mpeg_parser); ++ } ++} ++ + static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { + int codec_type; + +@@ -850,15 +919,14 @@ static void ff_handle_preview_buffer (ff_video_decoder + + 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); +- this->decoder_init_mode = 0; +- } ++ 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; +@@ -902,6 +970,8 @@ static void ff_handle_header_buffer (ff_video_decoder_ + switch (codec_type) { + case BUF_VIDEO_RV10: + case BUF_VIDEO_RV20: ++ case BUF_VIDEO_RV30: ++ case BUF_VIDEO_RV40: + this->bih.biWidth = _X_BE_16(&this->buf[12]); + this->bih.biHeight = _X_BE_16(&this->buf[14]); + +@@ -1022,6 +1092,11 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_ + + 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; +@@ -1055,12 +1130,26 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_ } /* skip decoding b frames if too late */ @@ -92,7 +251,7 @@ Eliminate use of old FFmpeg APIs. lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n", len, got_picture); len = current - buf->content - offset; -@@ -1112,7 +1134,13 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_ +@@ -1112,7 +1201,13 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_ } else { @@ -107,7 +266,66 @@ Eliminate use of old FFmpeg APIs. /* skipped frame, output a bad frame */ img = this->stream->video_out->get_frame (this->stream->video_out, this->bih.biWidth, -@@ -1304,13 +1332,25 @@ static void ff_handle_buffer (ff_video_decoder_t *this +@@ -1178,49 +1273,6 @@ static void ff_check_pts_tagging(ff_video_decoder_t *t + } + #endif /* AVCODEC_HAS_REORDERED_OPAQUE */ + +-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}; +@@ -1229,7 +1281,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this + + 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; +@@ -1304,13 +1356,25 @@ static void ff_handle_buffer (ff_video_decoder_t *this got_picture = 0; } else { /* skip decoding b frames if too late */ @@ -135,7 +353,7 @@ Eliminate use of old FFmpeg APIs. #ifdef AVCODEC_HAS_REORDERED_OPAQUE /* reset consumed pts value */ this->context->reordered_opaque = ff_tag_pts(this, 0); -@@ -1432,7 +1472,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this +@@ -1432,7 +1496,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this img->base, img->pitches, img->width, img->height, this->av_frame->qscale_table, this->av_frame->qstride, @@ -144,7 +362,16 @@ Eliminate use of old FFmpeg APIs. this->av_frame->pict_type); } else if (!this->av_frame->opaque) { -@@ -1676,11 +1716,11 @@ static void ff_dispose (video_decoder_t *this_gen) { +@@ -1555,7 +1619,7 @@ static void ff_decode_data (video_decoder_t *this_gen, + 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); +@@ -1676,11 +1740,11 @@ static void ff_dispose (video_decoder_t *this_gen) { free(this->buf); this->buf = NULL; @@ -160,7 +387,7 @@ Eliminate use of old FFmpeg APIs. mpeg_parser_dispose(this->mpeg_parser); -@@ -1721,8 +1761,8 @@ static video_decoder_t *ff_video_open_plugin (video_de +@@ -1721,8 +1785,8 @@ static video_decoder_t *ff_video_open_plugin (video_de this->aspect_ratio = 0; this->pp_quality = 0; diff --git a/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_xine_video_list b/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_xine_video_list new file mode 100644 index 00000000000..b49dd1d94d2 --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_combined_ffmpeg_xine_video_list @@ -0,0 +1,20 @@ +$OpenBSD: patch-src_combined_ffmpeg_xine_video_list,v 1.1 2011/10/09 20:45:07 sthen Exp $ +--- src/combined/ffmpeg/xine_video.list.orig Wed Sep 28 01:30:30 2011 ++++ src/combined/ffmpeg/xine_video.list Wed Sep 28 01:36:42 2011 +@@ -24,6 +24,8 @@ I263 H263I ITU H.263 + H263 H263 H.263 + RV10 RV10 Real Video 1.0 + RV20 RV20 Real Video 2.0 ++RV30 RV30 Real Video 3.0 ++RV40 RV40 Real Video 4.0 + IV31 INDEO3 Indeo Video 3.1 + IV32 INDEO3 Indeo Video 3.2 + SORENSON_V1 SVQ1 Sorenson Video 1 +@@ -34,6 +36,7 @@ VP31 VP3 On2 VP3.1 + VP5 VP5 On2 VP5 + VP6 VP6 On2 VP6 + VP6F VP6F On2 VP6 ++VP8 VP8 On2 VP8 + 4XM 4XM 4X Video + CINEPAK CINEPAK Cinepak + MSVC MSVIDEO1 Microsoft Video 1 diff --git a/multimedia/xine-lib/patches/patch-src_demuxers_demux_matroska_c b/multimedia/xine-lib/patches/patch-src_demuxers_demux_matroska_c new file mode 100644 index 00000000000..14fbd20bc2e --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_demuxers_demux_matroska_c @@ -0,0 +1,36 @@ +$OpenBSD: patch-src_demuxers_demux_matroska_c,v 1.5 2011/10/09 20:45:07 sthen Exp $ + +VP8 support. + +--- src/demuxers/demux_matroska.c.orig Wed Sep 28 01:31:40 2011 ++++ src/demuxers/demux_matroska.c Wed Sep 28 01:32:48 2011 +@@ -1327,6 +1327,29 @@ static int parse_track_entry(demux_matroska_t *this, m + lprintf("MATROSKA_CODEC_ID_V_MPEG2\n"); + track->buf_type = BUF_VIDEO_MPEG; + init_codec = init_codec_video; ++ } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VP8)) { ++ xine_bmiheader *bih; ++ ++ lprintf("MATROSKA_CODEC_ID_V_VP8\n"); ++ if (track->codec_private_len > 0x7fffffff - sizeof(xine_bmiheader)) ++ track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader); ++ ++ /* create a bitmap info header struct for vp8 */ ++ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len); ++ bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len; ++ bih->biCompression = ME_FOURCC('v', 'p', '8', '0'); ++ bih->biWidth = track->video_track->pixel_width; ++ bih->biHeight = track->video_track->pixel_height; ++ _x_bmiheader_le2me(bih); ++ ++ /* add bih extra data */ ++ memcpy(bih + 1, track->codec_private, track->codec_private_len); ++ free(track->codec_private); ++ track->codec_private = (uint8_t *)bih; ++ track->codec_private_len = bih->biSize; ++ track->buf_type = BUF_VIDEO_VP8; ++ ++ init_codec = init_codec_video; + } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV10)) { + } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV20)) { + } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV30)) { diff --git a/multimedia/xine-lib/patches/patch-src_demuxers_demux_qt_c b/multimedia/xine-lib/patches/patch-src_demuxers_demux_qt_c index 26ad4ac242b..0c6fa637e9f 100644 --- a/multimedia/xine-lib/patches/patch-src_demuxers_demux_qt_c +++ b/multimedia/xine-lib/patches/patch-src_demuxers_demux_qt_c @@ -1,10 +1,84 @@ -$OpenBSD: patch-src_demuxers_demux_qt_c,v 1.13 2011/05/11 09:05:54 dcoppa Exp $ +$OpenBSD: patch-src_demuxers_demux_qt_c,v 1.14 2011/10/09 20:45:07 sthen Exp $ -Add f4v/f4a file extensions to the Qt demuxer. +- Add f4v/f4a file extensions to the Qt demuxer. +- Better support for 24-bit LPCM. --- src/demuxers/demux_qt.c.orig Sat Jul 24 18:21:31 2010 -+++ src/demuxers/demux_qt.c Fri Apr 15 17:46:25 2011 -@@ -3255,7 +3255,7 @@ static const char *get_identifier (demux_class_t *this ++++ src/demuxers/demux_qt.c Wed Sep 28 04:09:22 2011 +@@ -90,6 +90,7 @@ typedef unsigned int qt_atom; + #define WAVE_ATOM QT_ATOM('w', 'a', 'v', 'e') + #define FRMA_ATOM QT_ATOM('f', 'r', 'm', 'a') + #define AVCC_ATOM QT_ATOM('a', 'v', 'c', 'C') ++#define ENDA_ATOM QT_ATOM('e', 'n', 'd', 'a') + + #define IMA4_FOURCC ME_FOURCC('i', 'm', 'a', '4') + #define MAC3_FOURCC ME_FOURCC('M', 'A', 'C', '3') +@@ -103,6 +104,8 @@ typedef unsigned int qt_atom; + #define TWOS_FOURCC ME_FOURCC('t', 'w', 'o', 's') + #define SOWT_FOURCC ME_FOURCC('s', 'o', 'w', 't') + #define RAW_FOURCC ME_FOURCC('r', 'a', 'w', ' ') ++#define IN24_FOURCC ME_FOURCC('i', 'n', '2', '4') ++#define NI42_FOURCC ME_FOURCC('4', '2', 'n', 'i') + #define AVC1_FOURCC ME_FOURCC('a', 'v', 'c', '1') + + #define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a') +@@ -1250,6 +1253,13 @@ static qt_error parse_trak_atom (qt_trak *trak, + trak->stsd_atoms[k].audio.channels = trak_atom[atom_pos + 0x15]; + trak->stsd_atoms[k].audio.bits = trak_atom[atom_pos + 0x17]; + ++ /* 24-bit audio doesn't always declare itself properly, and can be big- or little-endian */ ++ if (trak->stsd_atoms[k].audio.codec_fourcc == IN24_FOURCC) { ++ trak->stsd_atoms[k].audio.bits = 24; ++ if (_X_BE_32(&trak_atom[atom_pos + 0x48]) == ENDA_ATOM && trak_atom[atom_pos + 0x4D]) ++ trak->stsd_atoms[k].audio.codec_fourcc = NI42_FOURCC; ++ } ++ + /* assume uncompressed audio parameters */ + trak->stsd_atoms[k].audio.bytes_per_sample = + trak->stsd_atoms[k].audio.bits / 8; +@@ -1312,11 +1322,13 @@ static qt_error parse_trak_atom (qt_trak *trak, + * appears to be a handler for uncompressed data; if there are an + * extra 0x10 bytes, there are some more useful decoding params; + * further, do not do load these parameters if the audio is just +- * PCM ('raw ', 'twos', or 'sowt') */ ++ * PCM ('raw ', 'twos', 'sowt' or 'in24') */ + if ((current_stsd_atom_size > 0x24) && + (trak->stsd_atoms[k].audio.codec_fourcc != TWOS_FOURCC) && + (trak->stsd_atoms[k].audio.codec_fourcc != SOWT_FOURCC) && +- (trak->stsd_atoms[k].audio.codec_fourcc != RAW_FOURCC)) { ++ (trak->stsd_atoms[k].audio.codec_fourcc != RAW_FOURCC) && ++ (trak->stsd_atoms[k].audio.codec_fourcc != IN24_FOURCC) && ++ (trak->stsd_atoms[k].audio.codec_fourcc != NI42_FOURCC)) { + + if (_X_BE_32(&trak_atom[atom_pos + 0x20])) + trak->stsd_atoms[k].audio.samples_per_packet = +@@ -2400,6 +2412,7 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge + buf_element_t *buf = NULL; + unsigned int i, j; + unsigned int remaining_sample_bytes; ++ unsigned int frame_aligned_buf_size; + int frame_duration; + int first_buf; + qt_trak *video_trak = NULL; +@@ -2655,9 +2668,15 @@ static int demux_qt_send_chunk(demux_plugin_t *this_ge + buf->pts = audio_trak->frames[i].pts; + } + +- if (remaining_sample_bytes > buf->max_size) +- buf->size = buf->max_size; ++ /* 24-bit audio doesn't fit evenly into the default 8192-byte buffers */ ++ if (audio_trak->properties->audio.bits == 24) ++ frame_aligned_buf_size = 8184; + else ++ frame_aligned_buf_size = buf->max_size; ++ ++ if (remaining_sample_bytes > frame_aligned_buf_size) ++ buf->size = frame_aligned_buf_size; ++ else + buf->size = remaining_sample_bytes; + remaining_sample_bytes -= buf->size; + +@@ -3255,7 +3274,7 @@ static const char *get_identifier (demux_class_t *this } static const char *get_extensions (demux_class_t *this_gen) { @@ -13,7 +87,7 @@ Add f4v/f4a file extensions to the Qt demuxer. } static const char *get_mimetypes (demux_class_t *this_gen) { -@@ -3263,8 +3263,8 @@ static const char *get_mimetypes (demux_class_t *this_ +@@ -3263,8 +3282,8 @@ static const char *get_mimetypes (demux_class_t *this_ "video/x-quicktime: mov,qt: Quicktime animation;" "audio/x-m4a: m4a,m4b: MPEG-4 audio;" "application/x-quicktimeplayer: qtl: Quicktime list;" diff --git a/multimedia/xine-lib/patches/patch-src_demuxers_demux_ts_c b/multimedia/xine-lib/patches/patch-src_demuxers_demux_ts_c index 7de814b3398..bc954261520 100644 --- a/multimedia/xine-lib/patches/patch-src_demuxers_demux_ts_c +++ b/multimedia/xine-lib/patches/patch-src_demuxers_demux_ts_c @@ -1,9 +1,19 @@ -$OpenBSD: patch-src_demuxers_demux_ts_c,v 1.1 2011/05/11 09:05:54 dcoppa Exp $ +$OpenBSD: patch-src_demuxers_demux_ts_c,v 1.2 2011/10/09 20:45:07 sthen Exp $ -Check boundaries during MPEG TS stream detection. +- Check boundaries during MPEG TS stream detection. +- Logic error with AC3 demuxer. ---- src/demuxers/demux_ts.c.orig Mon May 9 20:47:00 2011 -+++ src/demuxers/demux_ts.c Mon May 9 20:49:06 2011 +--- src/demuxers/demux_ts.c.orig Fri Apr 9 17:08:08 2010 ++++ src/demuxers/demux_ts.c Wed Sep 28 01:47:17 2011 +@@ -1438,7 +1438,7 @@ printf("Program Number is %i, looking for %i\n",progra + if (((stream[i] == 0x6a) || (stream[i] == 0x7a)) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { + int j, found = 0; + for(j = 0; j < this->audio_tracks_count; j++) { +- if(this->audio_tracks[i].pid == pid) { ++ if(this->audio_tracks[j].pid == pid) { + found = 1; + break; + } @@ -2360,18 +2360,20 @@ static demux_plugin_t *open_plugin (demux_class_t *cla demux_ts_t *this; int i; diff --git a/multimedia/xine-lib/patches/patch-src_demuxers_matroska_h b/multimedia/xine-lib/patches/patch-src_demuxers_matroska_h new file mode 100644 index 00000000000..d5f0348b0be --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_demuxers_matroska_h @@ -0,0 +1,11 @@ +$OpenBSD: patch-src_demuxers_matroska_h,v 1.3 2011/10/09 20:45:07 sthen Exp $ +--- src/demuxers/matroska.h.orig Wed Sep 28 01:32:54 2011 ++++ src/demuxers/matroska.h Wed Sep 28 01:33:12 2011 +@@ -312,6 +312,7 @@ struct matroska_track_s { + #define MATROSKA_CODEC_ID_V_REAL_RV40 "V_REAL/RV40" + #define MATROSKA_CODEC_ID_V_MJPEG "V_MJPEG" + #define MATROSKA_CODEC_ID_V_THEORA "V_THEORA" ++#define MATROSKA_CODEC_ID_V_VP8 "V_VP8" + + #define MATROSKA_CODEC_ID_A_MPEG1_L1 "A_MPEG/L1" + #define MATROSKA_CODEC_ID_A_MPEG1_L2 "A_MPEG/L2" diff --git a/multimedia/xine-lib/patches/patch-src_libxineadec_xine_lpcm_decoder_c b/multimedia/xine-lib/patches/patch-src_libxineadec_xine_lpcm_decoder_c new file mode 100644 index 00000000000..18d5a4dfd0c --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_libxineadec_xine_lpcm_decoder_c @@ -0,0 +1,115 @@ +$OpenBSD: patch-src_libxineadec_xine_lpcm_decoder_c,v 1.1 2011/10/09 20:45:07 sthen Exp $ + +- Better support for 24-bit LPCM. +- Fixed 20-bit BluRay PCM audio. + +--- src/libxineadec/xine_lpcm_decoder.c.orig Tue Mar 9 17:17:05 2010 ++++ src/libxineadec/xine_lpcm_decoder.c Wed Sep 28 01:22:20 2011 +@@ -94,6 +94,7 @@ static void lpcm_decode_data (audio_decoder_t *this_ge + int stream_be; + audio_buffer_t *audio_buffer; + int format_changed = 0; ++ int special_dvd_audio = 0; + + /* Drop preview data */ + if (buf->decoder_flags & BUF_FLAG_PREVIEW) +@@ -115,7 +116,11 @@ static void lpcm_decode_data (audio_decoder_t *this_ge + num_channels = channels[(buf->decoder_info[2] >> (16+4)) & 0x0f]; + switch ((buf->decoder_info[2] >> (24+6)) & 0x03) { + case 1: bits_per_sample = 16; break; +- case 2: bits_per_sample = 20; break; ++ case 2: /*bits_per_sample = 20; break;*/ ++ /* fall thru. Samples are 0-padded to 24 bits, and ++ * converted later to 16 bits by dropping 8 lowest bits. ++ * this needs to be changed if audio out some day accepts 24bit samples. ++ */ + case 3: bits_per_sample = 24; break; + default: bits_per_sample = 0; break; + } +@@ -152,7 +157,7 @@ static void lpcm_decode_data (audio_decoder_t *this_ge + switch ((buf->decoder_info[2]>>6) & 3) { + case 0: bits_per_sample = 16; break; + case 1: bits_per_sample = 20; break; +- case 2: bits_per_sample = 24; break; ++ case 2: bits_per_sample = 24; special_dvd_audio = 1; break; + } + } + +@@ -270,35 +275,58 @@ static void lpcm_decode_data (audio_decoder_t *this_ge + int n = buf_size; + + if ( stream_be ) { +- while (n >= 12) { ++ if (special_dvd_audio) ++ while (n >= 12) { ++ if ( stream_be == this->cpu_be ) { ++ *d++ = s[0]; ++ *d++ = s[1]; ++ *d++ = s[2]; ++ *d++ = s[3]; ++ *d++ = s[4]; ++ *d++ = s[5]; ++ *d++ = s[6]; ++ *d++ = s[7]; ++ } else { ++ *d++ = s[1]; ++ *d++ = s[0]; ++ *d++ = s[3]; ++ *d++ = s[2]; ++ *d++ = s[5]; ++ *d++ = s[4]; ++ *d++ = s[7]; ++ *d++ = s[6]; ++ } ++ s += 12; ++ n -= 12; ++ } ++ else ++ while (n >= 3) { ++ if ( stream_be == this->cpu_be ) { ++ *d++ = s[0]; ++ *d++ = s[1]; ++ } else { ++ *d++ = s[1]; ++ *d++ = s[0]; ++ } ++ s += 3; ++ n -= 3; ++ } ++ } else { ++ while (n >= 3) { + if ( stream_be == this->cpu_be ) { +- *d++ = s[0]; + *d++ = s[1]; + *d++ = s[2]; +- *d++ = s[3]; +- *d++ = s[4]; +- *d++ = s[5]; +- *d++ = s[6]; +- *d++ = s[7]; + } else { +- *d++ = s[1]; +- *d++ = s[0]; +- *d++ = s[3]; + *d++ = s[2]; +- *d++ = s[5]; +- *d++ = s[4]; +- *d++ = s[7]; +- *d++ = s[6]; ++ *d++ = s[1]; + } +- s += 12; +- n -= 12; ++ s += 3; ++ n -= 3; + } +- } else { +- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: I don't know what should decode lpcm 24bit little endian byte stream"); + } + + if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf_size ) +- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem))/2*3); ++ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes of %i in the buffer\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem)/2*3), buf_size); + + } else { + memcpy (audio_buffer->mem, sample_buffer, buf_size); diff --git a/multimedia/xine-lib/patches/patch-src_xine-engine_audio_decoder_c b/multimedia/xine-lib/patches/patch-src_xine-engine_audio_decoder_c new file mode 100644 index 00000000000..4613fb96641 --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_xine-engine_audio_decoder_c @@ -0,0 +1,16 @@ +$OpenBSD: patch-src_xine-engine_audio_decoder_c,v 1.11 2011/10/09 20:45:07 sthen Exp $ + +Fix audio crash. + +--- src/xine-engine/audio_decoder.c.orig Wed Sep 28 01:38:57 2011 ++++ src/xine-engine/audio_decoder.c Wed Sep 28 01:39:29 2011 +@@ -283,6 +283,9 @@ static void *audio_decoder_loop (void *stream_gen) { + } + stream->audio_track_map[i] = buf->type; + stream->audio_track_map_entries++; ++ /* implicit channel change - reopen decoder below */ ++ if ((i == 0) && (audio_channel_user == -1) && (stream->audio_channel_auto < 0)) ++ stream->audio_decoder_streamtype = -1; + + ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; + ui_event.data_length = 0; diff --git a/multimedia/xine-lib/patches/patch-src_xine-engine_buffer_h b/multimedia/xine-lib/patches/patch-src_xine-engine_buffer_h new file mode 100644 index 00000000000..13693219f15 --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_xine-engine_buffer_h @@ -0,0 +1,11 @@ +$OpenBSD: patch-src_xine-engine_buffer_h,v 1.3 2011/10/09 20:45:07 sthen Exp $ +--- src/xine-engine/buffer.h.orig Wed Sep 28 01:33:37 2011 ++++ src/xine-engine/buffer.h Wed Sep 28 01:34:02 2011 +@@ -189,6 +189,7 @@ extern "C" { + #define BUF_VIDEO_VC1 0x02650000 + #define BUF_VIDEO_VMNC 0x02660000 + #define BUF_VIDEO_SNOW 0x02670000 ++#define BUF_VIDEO_VP8 0x02680000 + + /* audio buffer types: (please keep in sync with buffer_types.c) */ + diff --git a/multimedia/xine-lib/patches/patch-src_xine-engine_buffer_types_c b/multimedia/xine-lib/patches/patch-src_xine-engine_buffer_types_c new file mode 100644 index 00000000000..a9b7e9e5b0e --- /dev/null +++ b/multimedia/xine-lib/patches/patch-src_xine-engine_buffer_types_c @@ -0,0 +1,26 @@ +$OpenBSD: patch-src_xine-engine_buffer_types_c,v 1.1 2011/10/09 20:45:07 sthen Exp $ +--- src/xine-engine/buffer_types.c.orig Tue Mar 23 11:46:03 2010 ++++ src/xine-engine/buffer_types.c Wed Sep 28 04:09:58 2011 +@@ -789,6 +789,14 @@ static const video_db_t video_db[] = { + BUF_VIDEO_SNOW, + "Snow" + }, ++{ ++ { ++ ME_FOURCC('V','P','8','0'), ++ 0 ++ }, ++ BUF_VIDEO_VP8, ++ "On2 VP8" ++}, + { { 0 }, 0, "last entry" } + }; + +@@ -826,6 +834,7 @@ static const audio_db_t audio_db[] = { + { + ME_FOURCC('t','w','o','s'), + ME_FOURCC('i','n','2','4'), ++ ME_FOURCC('4','2','n','i'), + 0 + }, + BUF_AUDIO_LPCM_BE, diff --git a/multimedia/xine-lib/patches/patch-src_xine-engine_video_out_c b/multimedia/xine-lib/patches/patch-src_xine-engine_video_out_c index a060e090e84..f76f049dad8 100644 --- a/multimedia/xine-lib/patches/patch-src_xine-engine_video_out_c +++ b/multimedia/xine-lib/patches/patch-src_xine-engine_video_out_c @@ -1,12 +1,14 @@ -$OpenBSD: patch-src_xine-engine_video_out_c,v 1.10 2011/05/11 09:05:55 dcoppa Exp $ +$OpenBSD: patch-src_xine-engine_video_out_c,v 1.11 2011/10/09 20:45:07 sthen Exp $ - Disable decoder flush from video out to avoid decoding errors. - Fixes two issues of video out standard cropping feature. Resulting left and right cropping parameters should be multiple of 2. Left cropping offset calculation to YUY2 frames fixed. +- Fix UI freeze. +- Fix video deadlock. ---- src/xine-engine/video_out.c.orig Mon May 9 21:02:46 2011 -+++ src/xine-engine/video_out.c Mon May 9 21:10:23 2011 +--- src/xine-engine/video_out.c.orig Wed Jul 21 13:43:52 2010 ++++ src/xine-engine/video_out.c Wed Sep 28 01:45:14 2011 @@ -533,8 +533,8 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream xine_list_iterator_t ite; @@ -18,7 +20,95 @@ $OpenBSD: patch-src_xine-engine_video_out_c,v 1.10 2011/05/11 09:05:55 dcoppa Ex img->crop_top += this->crop_top; img->crop_bottom += this->crop_bottom; -@@ -1124,6 +1124,11 @@ static void paused_loop( vos_t *this, int64_t vpts ) +@@ -571,25 +571,28 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream + * check for first frame after seek and mark it + */ + img->is_first = 0; +- pthread_mutex_lock(&this->streams_lock); +- for (ite = xine_list_front(this->streams); ite; +- ite = xine_list_next(this->streams, ite)) { +- stream = xine_list_get_value(this->streams, ite); +- if (stream == XINE_ANON_STREAM) continue; +- pthread_mutex_lock (&stream->first_frame_lock); +- if (stream->first_frame_flag == 2) { +- if (this->grab_only) { +- stream->first_frame_flag = 0; +- pthread_cond_broadcast(&stream->first_frame_reached); +- } else +- stream->first_frame_flag = 1; +- img->is_first = FIRST_FRAME_MAX_POLL; ++ /* avoid a complex deadlock situation caused by net_buf_control */ ++ if (!pthread_mutex_trylock(&this->streams_lock)) { ++ for (ite = xine_list_front(this->streams); ite; ++ ite = xine_list_next(this->streams, ite)) { ++ stream = xine_list_get_value(this->streams, ite); ++ if (stream == XINE_ANON_STREAM) continue; ++ pthread_mutex_lock (&stream->first_frame_lock); ++ if (stream->first_frame_flag == 2) { ++ if (this->grab_only) { ++ stream->first_frame_flag = 0; ++ pthread_cond_broadcast(&stream->first_frame_reached); ++ } else { ++ stream->first_frame_flag = 1; ++ } ++ img->is_first = FIRST_FRAME_MAX_POLL; + +- lprintf ("get_next_video_frame first_frame_reached\n"); ++ lprintf ("get_next_video_frame first_frame_reached\n"); ++ } ++ pthread_mutex_unlock (&stream->first_frame_lock); + } +- pthread_mutex_unlock (&stream->first_frame_lock); ++ pthread_mutex_unlock(&this->streams_lock); + } +- pthread_mutex_unlock(&this->streams_lock); + + if (!img_already_locked) + vo_frame_inc_lock( img ); +@@ -801,7 +804,7 @@ static void expire_frames (vos_t *this, int64_t cur_vp + + while (img) { + +- if (img->is_first) { ++ if (img->is_first > 0) { + lprintf("expire_frames: first_frame !\n"); + + /* +@@ -818,6 +821,8 @@ static void expire_frames (vos_t *this, int64_t cur_vp + img->vpts = cur_vpts + FIRST_FRAME_POLL_DELAY; + } + img->is_first--; ++ /* make sure to wake up xine_play even if this first frame gets discarded */ ++ if (img->is_first == 0) img->is_first = -1; + break; + } + +@@ -847,6 +852,24 @@ static void expire_frames (vos_t *this, int64_t cur_vp + pthread_mutex_lock( &img->stream->current_extra_info_lock ); + _x_extra_info_merge( img->stream->current_extra_info, img->extra_info ); + pthread_mutex_unlock( &img->stream->current_extra_info_lock ); ++ /* wake up xine_play now if we just discarded first frame */ ++ if (img->is_first != 0) { ++ xine_list_iterator_t ite; ++ pthread_mutex_lock (&this->streams_lock); ++ for (ite = xine_list_front(this->streams); ite; ++ ite = xine_list_next(this->streams, ite)) { ++ xine_stream_t *stream = xine_list_get_value (this->streams, ite); ++ if (stream == XINE_ANON_STREAM) continue; ++ pthread_mutex_lock (&stream->first_frame_lock); ++ if (stream->first_frame_flag) { ++ stream->first_frame_flag = 0; ++ pthread_cond_broadcast (&stream->first_frame_reached); ++ } ++ pthread_mutex_unlock (&stream->first_frame_lock); ++ } ++ pthread_mutex_unlock(&this->streams_lock); ++ xine_log (this->xine, XINE_LOG_MSG, _("video_out: just discarded first frame after seek\n")); ++ } + } + + /* when flushing frames, keep the first one as backup */ +@@ -1124,6 +1147,11 @@ static void paused_loop( vos_t *this, int64_t vpts ) pthread_mutex_unlock( &this->free_img_buf_queue->mutex ); } @@ -30,7 +120,7 @@ $OpenBSD: patch-src_xine-engine_video_out_c,v 1.10 2011/05/11 09:05:55 dcoppa Ex static void *video_out_loop (void *this_gen) { int64_t vpts, diff; -@@ -1131,6 +1136,7 @@ static void *video_out_loop (void *this_gen) { +@@ -1131,6 +1159,7 @@ static void *video_out_loop (void *this_gen) { vos_t *this = (vos_t *) this_gen; int64_t next_frame_vpts = 0; int64_t usec_to_sleep; @@ -38,7 +128,7 @@ $OpenBSD: patch-src_xine-engine_video_out_c,v 1.10 2011/05/11 09:05:55 dcoppa Ex #ifndef WIN32 /* nice(-value) will fail silently for normal users. -@@ -1141,6 +1147,16 @@ static void *video_out_loop (void *this_gen) { +@@ -1141,6 +1170,16 @@ static void *video_out_loop (void *this_gen) { nice(-2); #endif /* WIN32 */ @@ -55,7 +145,7 @@ $OpenBSD: patch-src_xine-engine_video_out_c,v 1.10 2011/05/11 09:05:55 dcoppa Ex /* * here it is - the heart of xine (or rather: one of the hearts * of xine) : the video output loop -@@ -1191,7 +1207,7 @@ static void *video_out_loop (void *this_gen) { +@@ -1191,7 +1230,7 @@ static void *video_out_loop (void *this_gen) { ite = xine_list_next(this->streams, ite)) { xine_stream_t *stream = xine_list_get_value(this->streams, ite); if (stream == XINE_ANON_STREAM) continue; @@ -64,7 +154,7 @@ $OpenBSD: patch-src_xine-engine_video_out_c,v 1.10 2011/05/11 09:05:55 dcoppa Ex buf_element_t *buf; lprintf ("flushing current video decoder plugin\n"); -@@ -1741,7 +1757,7 @@ static vo_frame_t * crop_frame( xine_video_port_t *thi +@@ -1741,7 +1780,7 @@ static vo_frame_t * crop_frame( xine_video_port_t *thi yuy2_to_yuy2( /* src */ img->base[0] + img->crop_top * img->pitches[0] +