371c629f8b
* The "I'm at Tyneside LUG" release. * Enable PulseAudio, JACK and VDPAU on the Hurd. * Rewrite of VDPAU OSD handling. * sndio plugin is now buildable. * Various bug fixes. - first build of xine-lib-12 for packman OBS-URL: https://build.opensuse.org/package/show/multimedia:xine/xine-lib?expand=0&rev=56
389 lines
12 KiB
Diff
389 lines
12 KiB
Diff
diff -uNr xine-lib-1.2.1.orig/src/combined/ffmpeg/ffmpeg_compat.h xine-lib-1.2.1/src/combined/ffmpeg/ffmpeg_compat.h
|
|
--- xine-lib-1.2.1.orig/src/combined/ffmpeg/ffmpeg_compat.h 2012-02-04 01:41:43.000000000 +0100
|
|
+++ xine-lib-1.2.1/src/combined/ffmpeg/ffmpeg_compat.h 2012-02-09 21:00:25.000000000 +0100
|
|
@@ -91,5 +91,9 @@
|
|
# define AVAUDIO 2
|
|
#endif
|
|
|
|
+/* AVFrame.age */
|
|
+#if !(LIBAVCODEC_VERSION_MAJOR >= 53 && LIBAVCODEC_VERSION_MAJOR >= 28 && LIBAVCODEC_VERSION_MICRO >= 1)
|
|
+# define AVFRAMEAGE 1
|
|
+#endif
|
|
|
|
#endif /* XINE_AVCODEC_COMPAT_H */
|
|
diff -uNr xine-lib-1.2.1.orig/src/combined/ffmpeg/ff_video_decoder.c xine-lib-1.2.1/src/combined/ffmpeg/ff_video_decoder.c
|
|
--- xine-lib-1.2.1.orig/src/combined/ffmpeg/ff_video_decoder.c 2012-02-04 01:41:43.000000000 +0100
|
|
+++ xine-lib-1.2.1/src/combined/ffmpeg/ff_video_decoder.c 2012-05-10 21:50:50.000000000 +0200
|
|
@@ -68,6 +68,7 @@
|
|
int thread_count;
|
|
int8_t skip_loop_filter_enum;
|
|
int8_t choose_speed_over_accuracy;
|
|
+ uint8_t enable_dri;
|
|
|
|
xine_t *xine;
|
|
} ff_video_class_t;
|
|
@@ -92,7 +93,7 @@
|
|
uint8_t is_mpeg12:1;
|
|
uint8_t pp_available:1;
|
|
uint8_t yuv_init:1;
|
|
- uint8_t is_direct_rendering_disabled:1;
|
|
+ uint8_t is_direct_rendering_disabled:1; /* used only to avoid flooding log */
|
|
uint8_t cs_convert_init:1;
|
|
uint8_t assume_bad_field_picture:1;
|
|
|
|
@@ -127,13 +128,45 @@
|
|
|
|
yuv_planes_t yuv;
|
|
|
|
+#ifdef AVPaletteControl
|
|
AVPaletteControl palette_control;
|
|
+#endif
|
|
+
|
|
+ int color_matrix, full2mpeg;
|
|
+ unsigned char ytab[256], ctab[256];
|
|
|
|
#ifdef LOG
|
|
enum PixelFormat debug_fmt;
|
|
#endif
|
|
};
|
|
|
|
+static void ff_check_colorspace (ff_video_decoder_t *this) {
|
|
+ int i, cm;
|
|
+
|
|
+ cm = this->context->colorspace << 1;
|
|
+ /* ffmpeg bug: color_range not set by svq3 decoder */
|
|
+ i = this->context->pix_fmt;
|
|
+ if (cm && ((i == PIX_FMT_YUVJ420P) || (i == PIX_FMT_YUVJ444P) ||
|
|
+ (this->context->color_range == AVCOL_RANGE_JPEG)))
|
|
+ cm |= 1;
|
|
+
|
|
+ /* report changes of colorspyce and/or color range */
|
|
+ if (cm != this->color_matrix) {
|
|
+ this->color_matrix = cm;
|
|
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
|
|
+ "ffmpeg_video_dec: color matrix #%d\n", cm >> 1);
|
|
+
|
|
+ this->full2mpeg = 0;
|
|
+ if (cm & 1) {
|
|
+ /* sigh. fall back to manual conversion */
|
|
+ this->full2mpeg = 1;
|
|
+ for (i = 0; i < 256; i++) {
|
|
+ this->ytab[i] = (219 * i + 127) / 255 + 16;
|
|
+ this->ctab[i] = 112 * (i - 128) / 127 + 128;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
|
|
static void set_stream_info(ff_video_decoder_t *this) {
|
|
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth);
|
|
@@ -149,6 +182,8 @@
|
|
int width = context->width;
|
|
int height = context->height;
|
|
|
|
+ ff_check_colorspace (this);
|
|
+
|
|
if (!this->bih.biWidth || !this->bih.biHeight) {
|
|
this->bih.biWidth = width;
|
|
this->bih.biHeight = height;
|
|
@@ -163,7 +198,8 @@
|
|
|
|
avcodec_align_dimensions(context, &width, &height);
|
|
|
|
- if( this->context->pix_fmt != PIX_FMT_YUV420P && this->context->pix_fmt != PIX_FMT_YUVJ420P ) {
|
|
+ if (this->full2mpeg || (this->context->pix_fmt != PIX_FMT_YUV420P &&
|
|
+ this->context->pix_fmt != PIX_FMT_YUVJ420P)) {
|
|
if (!this->is_direct_rendering_disabled) {
|
|
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
|
|
_("ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n"));
|
|
@@ -195,6 +231,8 @@
|
|
}
|
|
}
|
|
|
|
+ this->is_direct_rendering_disabled = 0;
|
|
+
|
|
img = this->stream->video_out->get_frame (this->stream->video_out,
|
|
width,
|
|
height,
|
|
@@ -215,7 +253,9 @@
|
|
/* We should really keep track of the ages of xine frames (see
|
|
* avcodec_default_get_buffer in libavcodec/utils.c)
|
|
* For the moment tell ffmpeg that every frame is new (age = bignumber) */
|
|
+#ifdef AVFRAMEAGE
|
|
av_frame->age = 256*256*256*64;
|
|
+#endif
|
|
|
|
av_frame->type= FF_BUFFER_TYPE_USER;
|
|
|
|
@@ -309,7 +349,7 @@
|
|
|
|
/* Some codecs (eg rv10) copy flags in init so it's necessary to set
|
|
* this flag here in case we are going to use direct rendering */
|
|
- if(this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264) {
|
|
+ if(this->codec->capabilities & CODEC_CAP_DR1 && this->class->enable_dri) {
|
|
this->context->flags |= CODEC_FLAG_EMU_EDGE;
|
|
}
|
|
|
|
@@ -320,6 +360,13 @@
|
|
if (this->class->choose_speed_over_accuracy)
|
|
this->context->flags2 |= CODEC_FLAG2_FAST;
|
|
|
|
+#ifdef DEPRECATED_AVCODEC_THREAD_INIT
|
|
+ if (this->class->thread_count > 1) {
|
|
+ if (this->codec->id != CODEC_ID_SVQ3)
|
|
+ this->context->thread_count = this->class->thread_count;
|
|
+ }
|
|
+#endif
|
|
+
|
|
pthread_mutex_lock(&ffmpeg_lock);
|
|
if (avcodec_open (this->context, this->codec) < 0) {
|
|
pthread_mutex_unlock(&ffmpeg_lock);
|
|
@@ -347,14 +394,13 @@
|
|
}
|
|
}
|
|
|
|
+#ifndef DEPRECATED_AVCODEC_THREAD_INIT
|
|
if (this->class->thread_count > 1) {
|
|
if (this->codec->id != CODEC_ID_SVQ3
|
|
-#ifndef DEPRECATED_AVCODEC_THREAD_INIT
|
|
- && avcodec_thread_init(this->context, this->class->thread_count) != -1
|
|
-#endif
|
|
- )
|
|
+ && avcodec_thread_init(this->context, this->class->thread_count) != -1)
|
|
this->context->thread_count = this->class->thread_count;
|
|
}
|
|
+#endif
|
|
|
|
this->context->skip_loop_filter = skip_loop_filter_enum_values[this->class->skip_loop_filter_enum];
|
|
|
|
@@ -383,7 +429,7 @@
|
|
/* enable direct rendering by default */
|
|
this->output_format = XINE_IMGFMT_YV12;
|
|
#ifdef ENABLE_DIRECT_RENDERING
|
|
- if( this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264 ) {
|
|
+ if( this->codec->capabilities & CODEC_CAP_DR1 && this->class->enable_dri ) {
|
|
this->context->get_buffer = get_buffer;
|
|
this->context->release_buffer = release_buffer;
|
|
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
|
|
@@ -442,6 +488,12 @@
|
|
class->pp_quality = entry->num_value;
|
|
}
|
|
|
|
+static void dri_cb(void *user_data, xine_cfg_entry_t *entry) {
|
|
+ ff_video_class_t *class = (ff_video_class_t *) user_data;
|
|
+
|
|
+ class->enable_dri = entry->num_value;
|
|
+}
|
|
+
|
|
static void pp_change_quality (ff_video_decoder_t *this) {
|
|
this->pp_quality = this->class->pp_quality;
|
|
|
|
@@ -542,6 +594,8 @@
|
|
printf ("frame format == %08x\n", this->debug_fmt = this->context->pix_fmt);
|
|
#endif
|
|
|
|
+ ff_check_colorspace (this);
|
|
+
|
|
dy = img->base[0];
|
|
du = img->base[1];
|
|
dv = img->base[2];
|
|
@@ -772,54 +826,91 @@
|
|
|
|
} else {
|
|
|
|
- for (y = 0; y < this->bih.biHeight; y++) {
|
|
- xine_fast_memcpy (dy, sy, img->width);
|
|
-
|
|
- dy += img->pitches[0];
|
|
-
|
|
- sy += this->av_frame->linesize[0];
|
|
- }
|
|
-
|
|
- for (y = 0; y < this->bih.biHeight / 2; y++) {
|
|
+ int subsamph = (this->context->pix_fmt == PIX_FMT_YUV444P)
|
|
+ || (this->context->pix_fmt == PIX_FMT_YUVJ444P);
|
|
+ int subsampv = (this->context->pix_fmt != PIX_FMT_YUV420P)
|
|
+ && (this->context->pix_fmt != PIX_FMT_YUVJ420P);
|
|
+
|
|
+ if (this->full2mpeg) {
|
|
+
|
|
+ uint8_t *ytab = this->ytab;
|
|
+ uint8_t *ctab = this->ctab;
|
|
+ uint8_t *p, *q;
|
|
+ int x;
|
|
+
|
|
+ for (y = 0; y < this->bih.biHeight; y++) {
|
|
+ p = sy;
|
|
+ q = dy;
|
|
+ for (x = img->width; x > 0; x--) *q++ = ytab[*p++];
|
|
+ dy += img->pitches[0];
|
|
+ sy += this->av_frame->linesize[0];
|
|
+ }
|
|
|
|
- if (this->context->pix_fmt != PIX_FMT_YUV444P) {
|
|
+ for (y = 0; y < this->bih.biHeight / 2; y++) {
|
|
+ if (!subsamph) {
|
|
+ p = su, q = du;
|
|
+ for (x = img->width / 2; x > 0; x--) *q++ = ctab[*p++];
|
|
+ p = sv, q = dv;
|
|
+ for (x = img->width / 2; x > 0; x--) *q++ = ctab[*p++];
|
|
+ } else {
|
|
+ p = su, q = sv;
|
|
+ for (x = img->width / 2; x > 0; x--) {*q++ = ctab[*p]; p += 2;}
|
|
+ p = sv, q = dv;
|
|
+ for (x = img->width / 2; x > 0; x--) {*q++ = ctab[*p]; p += 2;}
|
|
+ }
|
|
+ du += img->pitches[1];
|
|
+ dv += img->pitches[2];
|
|
+ if (subsampv) {
|
|
+ su += 2 * this->av_frame->linesize[1];
|
|
+ sv += 2 * this->av_frame->linesize[2];
|
|
+ } else {
|
|
+ su += this->av_frame->linesize[1];
|
|
+ sv += this->av_frame->linesize[2];
|
|
+ }
|
|
+ }
|
|
|
|
- xine_fast_memcpy (du, su, img->width/2);
|
|
- xine_fast_memcpy (dv, sv, img->width/2);
|
|
+ } else {
|
|
|
|
- } else {
|
|
+ for (y = 0; y < this->bih.biHeight; y++) {
|
|
+ xine_fast_memcpy (dy, sy, img->width);
|
|
+ dy += img->pitches[0];
|
|
+ sy += this->av_frame->linesize[0];
|
|
+ }
|
|
|
|
- int x;
|
|
- uint8_t *src;
|
|
- uint8_t *dst;
|
|
-
|
|
- /* subsample */
|
|
-
|
|
- src = su; dst = du;
|
|
- for (x=0; x<(img->width/2); x++) {
|
|
- *dst = *src;
|
|
- dst++;
|
|
- src += 2;
|
|
+ for (y = 0; y < this->bih.biHeight / 2; y++) {
|
|
+ if (!subsamph) {
|
|
+ xine_fast_memcpy (du, su, img->width/2);
|
|
+ xine_fast_memcpy (dv, sv, img->width/2);
|
|
+ } else {
|
|
+ int x;
|
|
+ uint8_t *src;
|
|
+ uint8_t *dst;
|
|
+ src = su;
|
|
+ dst = du;
|
|
+ for (x = 0; x < (img->width / 2); x++) {
|
|
+ *dst = *src;
|
|
+ dst++;
|
|
+ src += 2;
|
|
+ }
|
|
+ src = sv;
|
|
+ dst = dv;
|
|
+ for (x = 0; x < (img->width / 2); x++) {
|
|
+ *dst = *src;
|
|
+ dst++;
|
|
+ src += 2;
|
|
+ }
|
|
}
|
|
- src = sv; dst = dv;
|
|
- for (x=0; x<(img->width/2); x++) {
|
|
- *dst = *src;
|
|
- dst++;
|
|
- src += 2;
|
|
+ du += img->pitches[1];
|
|
+ dv += img->pitches[2];
|
|
+ if (subsampv) {
|
|
+ su += 2*this->av_frame->linesize[1];
|
|
+ sv += 2*this->av_frame->linesize[2];
|
|
+ } else {
|
|
+ su += this->av_frame->linesize[1];
|
|
+ sv += this->av_frame->linesize[2];
|
|
}
|
|
-
|
|
}
|
|
|
|
- du += img->pitches[1];
|
|
- dv += img->pitches[2];
|
|
-
|
|
- if (this->context->pix_fmt != PIX_FMT_YUV420P) {
|
|
- su += 2*this->av_frame->linesize[1];
|
|
- sv += 2*this->av_frame->linesize[2];
|
|
- } else {
|
|
- su += this->av_frame->linesize[1];
|
|
- sv += this->av_frame->linesize[2];
|
|
- }
|
|
}
|
|
}
|
|
}
|
|
@@ -1023,7 +1114,9 @@
|
|
memcpy(this->context->extradata, buf->decoder_info_ptr[2],
|
|
buf->decoder_info[2]);
|
|
|
|
- } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) {
|
|
+ }
|
|
+#ifdef AVPaletteControl
|
|
+ else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) {
|
|
unsigned int i;
|
|
|
|
palette_entry_t *demuxer_palette;
|
|
@@ -1042,7 +1135,9 @@
|
|
}
|
|
decoder_palette->palette_changed = 1;
|
|
|
|
- } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) {
|
|
+ }
|
|
+#endif
|
|
+ else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) {
|
|
int i;
|
|
|
|
lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n");
|
|
@@ -1504,8 +1599,8 @@
|
|
img->duration = video_step_to_use;
|
|
|
|
/* additionally crop away the extra pixels due to adjusting frame size above */
|
|
- img->crop_right = this->crop_right + (img->width - this->bih.biWidth);
|
|
- img->crop_bottom = this->crop_bottom + (img->height - this->bih.biHeight);
|
|
+ img->crop_right = img->width - this->bih.biWidth;
|
|
+ img->crop_bottom = img->height - this->bih.biHeight;
|
|
|
|
/* transfer some more frame settings for deinterlacing */
|
|
img->progressive_frame = !this->av_frame->interlaced_frame;
|
|
@@ -1536,8 +1631,8 @@
|
|
img->duration = video_step_to_use;
|
|
|
|
/* additionally crop away the extra pixels due to adjusting frame size above */
|
|
- img->crop_right = ((this->bih.biWidth <= 0) ? 0 : this->crop_right) + (img->width - this->bih.biWidth);
|
|
- img->crop_bottom = ((this->bih.biHeight <= 0) ? 0 : this->crop_bottom) + (img->height - this->bih.biHeight);
|
|
+ img->crop_right = this->bih.biWidth <= 0 ? 0 : (img->width - this->bih.biWidth);
|
|
+ img->crop_bottom = this->bih.biHeight <= 0 ? 0 : (img->height - this->bih.biHeight);
|
|
|
|
img->bad_frame = 1;
|
|
this->skipframes = img->draw(img, this->stream);
|
|
@@ -1758,7 +1853,9 @@
|
|
this->av_frame = avcodec_alloc_frame();
|
|
this->context = avcodec_alloc_context();
|
|
this->context->opaque = this;
|
|
+#ifdef AVPaletteControl
|
|
this->context->palctrl = NULL;
|
|
+#endif
|
|
|
|
this->decoder_ok = 0;
|
|
this->decoder_init_mode = 1;
|
|
@@ -1839,6 +1936,12 @@
|
|
"A change of this setting will take effect with playing the next stream."),
|
|
10, choose_speed_over_accuracy_cb, this);
|
|
|
|
+ this->enable_dri = xine->config->register_bool(config, "video.processing.ffmpeg_direct_rendering", 1,
|
|
+ _("Enable direct rendering"),
|
|
+ _("Disable direct rendering if you are experiencing lock-ups with\n"
|
|
+ "streams with lot of reference frames."),
|
|
+ 10, dri_cb, this);
|
|
+
|
|
return this;
|
|
}
|
|
|