Backport support to xine-lib for VP8 (WebM) and RealVideo 3/4, improved

24-bit LPCM support and various bug fixes. From Brad.
This commit is contained in:
sthen 2011-10-09 20:45:07 +00:00
parent 2132e022a6
commit 192008d487
14 changed files with 805 additions and 47 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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)) {

View File

@ -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;"

View File

@ -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;

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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) */

View File

@ -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,

View File

@ -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] +