summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
Diffstat (limited to 'libvo')
-rw-r--r--libvo/aclib.c15
-rw-r--r--libvo/geometry.c23
-rw-r--r--libvo/osd.c25
-rw-r--r--libvo/spuenc.c2
-rw-r--r--libvo/spuenc.h2
-rw-r--r--libvo/vo_aa.c18
-rw-r--r--libvo/vo_gif89a.c6
-rw-r--r--libvo/vo_gl.c3
-rw-r--r--libvo/vo_jpeg.c20
-rw-r--r--libvo/vo_kva.c10
-rw-r--r--libvo/vo_md5sum.c4
-rw-r--r--libvo/vo_png.c2
-rw-r--r--libvo/vo_pnm.c18
-rw-r--r--libvo/vo_sdl.c8
-rw-r--r--libvo/vo_vdpau.c207
-rw-r--r--libvo/vo_vesa.c8
-rw-r--r--libvo/vo_x11.c6
-rw-r--r--libvo/vo_xvmc.c4
-rw-r--r--libvo/vo_zr2.c8
-rw-r--r--libvo/w32_common.c2
20 files changed, 238 insertions, 153 deletions
diff --git a/libvo/aclib.c b/libvo/aclib.c
index cae86dd3d4..47c9dead6b 100644
--- a/libvo/aclib.c
+++ b/libvo/aclib.c
@@ -33,9 +33,6 @@
//Feel free to fine-tune the above 2, it might be possible to get some speedup with them :)
//#define STATISTICS
-#if ARCH_X86
-#define CAN_COMPILE_X86_ASM
-#endif
//Note: we have MMX, MMX2, 3DNOW version there is no 3DNOW+MMX2 one
//Plain C versions
@@ -43,7 +40,7 @@
//#define COMPILE_C
//#endif
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
#if (HAVE_MMX && !HAVE_AMD3DNOW && !HAVE_MMX2) || defined (RUNTIME_CPUDETECT)
#define COMPILE_MMX
@@ -155,14 +152,14 @@
#include "aclib_template.c"
#endif
-#endif // CAN_COMPILE_X86_ASM
+#endif /* ARCH_X86 */
#undef fast_memcpy
void * fast_memcpy(void * to, const void * from, size_t len)
{
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered per speed fasterst first
if(gCpuCaps.hasSSE2)
fast_memcpy_SSE(to, from, len);
@@ -173,7 +170,7 @@ void * fast_memcpy(void * to, const void * from, size_t len)
else if(gCpuCaps.hasMMX)
fast_memcpy_MMX(to, from, len);
else
-#endif //CAN_COMPILE_X86_ASM
+#endif
memcpy(to, from, len); // prior to mmx we use the standart memcpy
#else
#if HAVE_SSE2
@@ -196,7 +193,7 @@ void * fast_memcpy(void * to, const void * from, size_t len)
void * mem2agpcpy(void * to, const void * from, size_t len)
{
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered per speed fasterst first
if(gCpuCaps.hasSSE2)
mem2agpcpy_SSE(to, from, len);
@@ -207,7 +204,7 @@ void * mem2agpcpy(void * to, const void * from, size_t len)
else if(gCpuCaps.hasMMX)
mem2agpcpy_MMX(to, from, len);
else
-#endif //CAN_COMPILE_X86_ASM
+#endif
memcpy(to, from, len); // prior to mmx we use the standart memcpy
#else
#if HAVE_SSE2
diff --git a/libvo/geometry.c b/libvo/geometry.c
index a805c147f9..7c6dc54087 100644
--- a/libvo/geometry.c
+++ b/libvo/geometry.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <string.h>
+#include <limits.h>
#include "geometry.h"
#include "mp_msg.h"
@@ -38,7 +39,7 @@ int geometry(int *xpos, int *ypos, int *widw, int *widh, int scrw, int scrh)
{
int width, height, xoff, yoff, xper, yper;
- width = height = xoff = yoff = xper = yper = -1;
+ width = height = xoff = yoff = xper = yper = INT_MIN;
if(vo_geometry != NULL) {
if(sscanf(vo_geometry, "%ix%i+%i+%i", &width, &height, &xoff, &yoff) != 4 )
@@ -90,22 +91,14 @@ int geometry(int *xpos, int *ypos, int *widw, int *widh, int scrw, int scrh)
mp_msg(MSGT_VO, MSGL_V,"geometry window parameter: widw: %i,"
" widh: %i, scrw: %i, scrh: %i\n",*widw, *widh, scrw, scrh);
- /* FIXME: better checking of bounds... */
- if( width != -1 && (width < 0 || width > scrw))
- width = (scrw < *widw) ? scrw : *widw;
- if( height != -1 && (height < 0 || height > scrh))
- height = (scrh < *widh) ? scrh : *widh;
- if(xoff != -1 && (xoff < 0 || xoff + width > scrw)) xoff = 0;
- if(yoff != -1 && (yoff < 0 || yoff + height > scrh)) yoff = 0;
+ if (xoff != INT_MIN && xpos) *xpos = xoff;
+ if (yoff != INT_MIN && ypos) *ypos = yoff;
+ if (width > 0 && widw) *widw = width;
+ if (height > 0 && widh) *widh = height;
- if(xoff != -1 && xpos) *xpos = xoff;
- if(yoff != -1 && ypos) *ypos = yoff;
- if(width != -1 && widw) *widw = width;
- if(height != -1 && widh) *widh = height;
-
- if( width != -1 || height != -1)
+ if (width > 0 || height > 0)
geometry_wh_changed = 1;
- if( xoff != -1 || yoff != -1)
+ if (xoff != INT_MIN || yoff != INT_MIN)
geometry_xy_changed = 1;
}
return 1;
diff --git a/libvo/osd.c b/libvo/osd.c
index 6660500ecd..42dd4fcc69 100644
--- a/libvo/osd.c
+++ b/libvo/osd.c
@@ -30,10 +30,6 @@
#include "cpudetect.h"
#if ARCH_X86
-#define CAN_COMPILE_X86_ASM
-#endif
-
-#ifdef CAN_COMPILE_X86_ASM
static const uint64_t bFF __attribute__((aligned(8))) = 0xFFFFFFFFFFFFFFFFULL;
static const unsigned long long mask24lh __attribute__((aligned(8))) = 0xFFFF000000000000ULL;
static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FFFFFFFFFFFFULL;
@@ -45,7 +41,7 @@ static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FF
#define COMPILE_C
#endif
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
#if (HAVE_MMX && !HAVE_AMD3DNOW && !HAVE_MMX2) || defined (RUNTIME_CPUDETECT)
#define COMPILE_MMX
@@ -58,7 +54,8 @@ static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FF
#if (HAVE_AMD3DNOW && !HAVE_MMX2) || defined (RUNTIME_CPUDETECT)
#define COMPILE_3DNOW
#endif
-#endif //CAN_COMPILE_X86_ASM
+
+#endif /* ARCH_X86 */
#undef HAVE_MMX
#undef HAVE_MMX2
@@ -67,7 +64,7 @@ static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FF
#define HAVE_MMX2 0
#define HAVE_AMD3DNOW 0
-#ifndef CAN_COMPILE_X86_ASM
+#if ! ARCH_X86
#ifdef COMPILE_C
#undef HAVE_MMX
@@ -134,11 +131,11 @@ static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FF
#include "osd_template.c"
#endif
-#endif //CAN_COMPILE_X86_ASM
+#endif /* ARCH_X86 */
void vo_draw_alpha_yv12(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered by speed / fastest first
if(gCpuCaps.hasMMX2)
vo_draw_alpha_yv12_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
@@ -168,7 +165,7 @@ void vo_draw_alpha_yv12(int w,int h, unsigned char* src, unsigned char *srca, in
void vo_draw_alpha_yuy2(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered by speed / fastest first
if(gCpuCaps.hasMMX2)
vo_draw_alpha_yuy2_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
@@ -198,7 +195,7 @@ void vo_draw_alpha_yuy2(int w,int h, unsigned char* src, unsigned char *srca, in
void vo_draw_alpha_uyvy(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered by speed / fastest first
if(gCpuCaps.hasMMX2)
vo_draw_alpha_uyvy_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
@@ -228,7 +225,7 @@ void vo_draw_alpha_uyvy(int w,int h, unsigned char* src, unsigned char *srca, in
void vo_draw_alpha_rgb24(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered by speed / fastest first
if(gCpuCaps.hasMMX2)
vo_draw_alpha_rgb24_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
@@ -258,7 +255,7 @@ void vo_draw_alpha_rgb24(int w,int h, unsigned char* src, unsigned char *srca, i
void vo_draw_alpha_rgb32(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered by speed / fastest first
if(gCpuCaps.hasMMX2)
vo_draw_alpha_rgb32_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
@@ -303,7 +300,7 @@ void vo_draw_alpha_init(void){
if( mp_msg_test(MSGT_OSD,MSGL_V) )
{
#ifdef RUNTIME_CPUDETECT
-#ifdef CAN_COMPILE_X86_ASM
+#if ARCH_X86
// ordered per speed fasterst first
if(gCpuCaps.hasMMX2)
mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit MMX2) Optimized OnScreenDisplay\n");
diff --git a/libvo/spuenc.c b/libvo/spuenc.c
index a1e457c282..f03c0d9be9 100644
--- a/libvo/spuenc.c
+++ b/libvo/spuenc.c
@@ -1,5 +1,5 @@
/*
- * subpic_encode.c - encodes a pixmap with RLE
+ * encode a pixmap with RLE
*
* Copyright (C) 2000 Alejandro J. Cura <alecu@protocultura.net>
*
diff --git a/libvo/spuenc.h b/libvo/spuenc.h
index d19732a98f..7f4590b4ac 100644
--- a/libvo/spuenc.h
+++ b/libvo/spuenc.h
@@ -1,5 +1,5 @@
/*
- * subpic_encode.c - encodes a pixmap with RLE
+ * encode a pixmap with RLE
*
* Copyright (C) 2000 Alejandro J. Cura <alecu@protocultura.net>
*
diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c
index 48b9f2f2ad..140c251355 100644
--- a/libvo/vo_aa.c
+++ b/libvo/vo_aa.c
@@ -68,8 +68,8 @@ aa_context *c;
aa_renderparams *p;
static int fast =0;
/* used for the sws */
-static uint8_t * image[3];
-static int image_stride[3];
+static uint8_t * image[MP_MAX_PLANES];
+static int image_stride[MP_MAX_PLANES];
/* image infos */
static int image_format;
@@ -125,13 +125,11 @@ resize(void){
sws = sws_getContextFromCmdLine(src_width,src_height,image_format,
image_width,image_height,IMGFMT_Y8);
+ memset(image, 0, sizeof(image));
image[0] = aa_image(c) + image_y * aa_imgwidth(c) + image_x;
- image[1] = NULL;
- image[2] = NULL;
+ memset(image_stride, 0, sizeof(image_stride));
image_stride[0] = aa_imgwidth(c);
- image_stride[1] = 0;
- image_stride[2] = 0;
showosdmessage=0;
@@ -336,7 +334,7 @@ query_format(uint32_t format) {
static int
draw_frame(uint8_t *src[]) {
- int stride[3] = { 0 , 0 , 0 };
+ int stride[MP_MAX_PLANES] = {0};
switch(image_format) {
case IMGFMT_BGR15:
@@ -576,9 +574,9 @@ static int parse_suboptions(const char *arg) {
*helpmsg = NULL;
int pseudoargc, displayhelp = 0, *booleans;
const opt_t extra_opts[] = {
- {"osdcolor", OPT_ARG_MSTRZ, &osdcolor, NULL, 0},
- {"subcolor", OPT_ARG_MSTRZ, &subcolor, NULL, 0},
- {"help", OPT_ARG_BOOL, &displayhelp, NULL, 0} };
+ {"osdcolor", OPT_ARG_MSTRZ, &osdcolor, NULL},
+ {"subcolor", OPT_ARG_MSTRZ, &subcolor, NULL},
+ {"help", OPT_ARG_BOOL, &displayhelp, NULL} };
opt_t *subopts = NULL, *p;
char * const strings_list[] = {"-driver", "-kbddriver", "-mousedriver", "-font",
"-width", "-height", "-minwidth", "-minheight", "-maxwidth",
diff --git a/libvo/vo_gif89a.c b/libvo/vo_gif89a.c
index 78dd5249fd..5da23cd8cb 100644
--- a/libvo/vo_gif89a.c
+++ b/libvo/vo_gif89a.c
@@ -105,9 +105,9 @@ static char *gif_filename = NULL;
#define DEFAULT_FILE "out.gif"
static const opt_t subopts[] = {
- {"output", OPT_ARG_MSTRZ, &gif_filename, NULL, 0},
- {"fps", OPT_ARG_FLOAT, &target_fps, NULL, 0},
- {NULL, 0, NULL, NULL, 0}
+ {"output", OPT_ARG_MSTRZ, &gif_filename, NULL},
+ {"fps", OPT_ARG_FLOAT, &target_fps, NULL},
+ {NULL, 0, NULL, NULL}
};
static int preinit(const char *arg)
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 2a0edaab6d..93064cfe5e 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -765,6 +765,9 @@ static uint32_t get_image(mp_image_t *mpi) {
return VO_FALSE;
}
if (mpi->flags & MP_IMGFLAG_READABLE) return VO_FALSE;
+ if (mpi->type != MP_IMGTYPE_STATIC && mpi->type != MP_IMGTYPE_TEMP &&
+ (mpi->type != MP_IMGTYPE_NUMBERED || mpi->number))
+ return VO_FALSE;
if (mesa_buffer) mpi->width = texture_width;
else if (ati_hack) {
mpi->width = texture_width;
diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c
index cd6a83a938..d29d7b0cd5 100644
--- a/libvo/vo_jpeg.c
+++ b/libvo/vo_jpeg.c
@@ -340,19 +340,19 @@ static int int_zero_hundred(int *val)
static int preinit(const char *arg)
{
const opt_t subopts[] = {
- {"progressive", OPT_ARG_BOOL, &jpeg_progressive_mode, NULL, 0},
- {"baseline", OPT_ARG_BOOL, &jpeg_baseline, NULL, 0},
+ {"progressive", OPT_ARG_BOOL, &jpeg_progressive_mode, NULL},
+ {"baseline", OPT_ARG_BOOL, &jpeg_baseline, NULL},
{"optimize", OPT_ARG_INT, &jpeg_optimize,
- (opt_test_f)int_zero_hundred, 0},
+ (opt_test_f)int_zero_hundred},
{"smooth", OPT_ARG_INT, &jpeg_smooth,
- (opt_test_f)int_zero_hundred, 0},
+ (opt_test_f)int_zero_hundred},
{"quality", OPT_ARG_INT, &jpeg_quality,
- (opt_test_f)int_zero_hundred, 0},
- {"dpi", OPT_ARG_INT, &jpeg_dpi, NULL, 0},
- {"outdir", OPT_ARG_MSTRZ, &jpeg_outdir, NULL, 0},
- {"subdirs", OPT_ARG_MSTRZ, &jpeg_subdirs, NULL, 0},
- {"maxfiles", OPT_ARG_INT, &jpeg_maxfiles, (opt_test_f)int_pos, 0},
- {NULL, 0, NULL, NULL, 0}
+ (opt_test_f)int_zero_hundred},
+ {"dpi", OPT_ARG_INT, &jpeg_dpi, NULL},
+ {"outdir", OPT_ARG_MSTRZ, &jpeg_outdir, NULL},
+ {"subdirs", OPT_ARG_MSTRZ, &jpeg_subdirs, NULL},
+ {"maxfiles", OPT_ARG_INT, &jpeg_maxfiles, (opt_test_f)int_pos},
+ {NULL, 0, NULL, NULL}
};
const char *info_message = NULL;
diff --git a/libvo/vo_kva.c b/libvo/vo_kva.c
index 6b126ed592..fbd670e790 100644
--- a/libvo/vo_kva.c
+++ b/libvo/vo_kva.c
@@ -131,8 +131,8 @@ struct {
PBYTE pbImage;
BOOL fFixT23;
PFNWP pfnwpOldFrame;
- uint8_t *planes[3]; // y = 0, u = 1, v = 2
- int stride[3];
+ uint8_t *planes[MP_MAX_PLANES]; // y = 0, u = 1, v = 2
+ int stride[MP_MAX_PLANES];
BOOL fHWAccel;
RECTL rclParent;
struct SwsContext *sws;
@@ -230,6 +230,8 @@ static void imgCreate(void)
m_int.pbImage = malloc(size);
+ memset(m_int.planes, 0, sizeof(m_int.planes));
+ memset(m_int.stride, 0, sizeof(m_int.stride));
m_int.planes[0] = m_int.pbImage;
m_int.stride[0] = m_int.lStride;
@@ -257,8 +259,8 @@ static void imgDisplay(void)
ULONG ulBPL;
if (!kvaLockBuffer(&pBuffer, &ulBPL)) {
- uint8_t *dst[3];
- int dstStride[3];
+ uint8_t *dst[MP_MAX_PLANES] = {NULL};
+ int dstStride[MP_MAX_PLANES] = {0};
// Get packed or Y
dst[0] = pBuffer;
diff --git a/libvo/vo_md5sum.c b/libvo/vo_md5sum.c
index c0996354e5..58fab4e1fd 100644
--- a/libvo/vo_md5sum.c
+++ b/libvo/vo_md5sum.c
@@ -108,8 +108,8 @@ static void md5sum_write_error(void) {
static int preinit(const char *arg)
{
const opt_t subopts[] = {
- {"outfile", OPT_ARG_MSTRZ, &md5sum_outfile, NULL, 0},
- {NULL, 0, NULL, NULL, 0}
+ {"outfile", OPT_ARG_MSTRZ, &md5sum_outfile, NULL},
+ {NULL, 0, NULL, NULL}
};
mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
diff --git a/libvo/vo_png.c b/libvo/vo_png.c
index 608a9a63c0..3163059b52 100644
--- a/libvo/vo_png.c
+++ b/libvo/vo_png.c
@@ -230,7 +230,7 @@ static int int_zero_to_nine(int *sh)
}
static const opt_t subopts[] = {
- {"alpha", OPT_ARG_BOOL, &use_alpha, NULL, 0},
+ {"alpha", OPT_ARG_BOOL, &use_alpha, NULL},
{"z", OPT_ARG_INT, &z_compression, (opt_test_f)int_zero_to_nine},
{NULL}
};
diff --git a/libvo/vo_pnm.c b/libvo/vo_pnm.c
index 2defb37ba5..9fe387608e 100644
--- a/libvo/vo_pnm.c
+++ b/libvo/vo_pnm.c
@@ -121,15 +121,15 @@ static int preinit(const char *arg)
int ppm_type = 0, pgm_type = 0, pgmyuv_type = 0,
raw_mode = 0, ascii_mode = 0;
const opt_t subopts[] = {
- {"ppm", OPT_ARG_BOOL, &ppm_type, NULL, 0},
- {"pgm", OPT_ARG_BOOL, &pgm_type, NULL, 0},
- {"pgmyuv", OPT_ARG_BOOL, &pgmyuv_type, NULL, 0},
- {"raw", OPT_ARG_BOOL, &raw_mode, NULL, 0},
- {"ascii", OPT_ARG_BOOL, &ascii_mode, NULL, 0},
- {"outdir", OPT_ARG_MSTRZ, &pnm_outdir, NULL, 0},
- {"subdirs", OPT_ARG_MSTRZ, &pnm_subdirs, NULL, 0},
- {"maxfiles", OPT_ARG_INT, &pnm_maxfiles, (opt_test_f)int_pos, 0},
- {NULL, 0, NULL, NULL, 0}
+ {"ppm", OPT_ARG_BOOL, &ppm_type, NULL},
+ {"pgm", OPT_ARG_BOOL, &pgm_type, NULL},
+ {"pgmyuv", OPT_ARG_BOOL, &pgmyuv_type, NULL},
+ {"raw", OPT_ARG_BOOL, &raw_mode, NULL},
+ {"ascii", OPT_ARG_BOOL, &ascii_mode, NULL},
+ {"outdir", OPT_ARG_MSTRZ, &pnm_outdir, NULL},
+ {"subdirs", OPT_ARG_MSTRZ, &pnm_subdirs, NULL},
+ {"maxfiles", OPT_ARG_INT, &pnm_maxfiles, (opt_test_f)int_pos},
+ {NULL, 0, NULL, NULL}
};
const char *info_message = NULL;
diff --git a/libvo/vo_sdl.c b/libvo/vo_sdl.c
index d4c0e75041..9096350632 100644
--- a/libvo/vo_sdl.c
+++ b/libvo/vo_sdl.c
@@ -1527,10 +1527,10 @@ static int preinit(const char *arg)
int sdl_hwaccel;
int sdl_forcexv;
const opt_t subopts[] = {
- {"forcexv", OPT_ARG_BOOL, &sdl_forcexv, NULL, 0},
- {"hwaccel", OPT_ARG_BOOL, &sdl_hwaccel, NULL, 0},
- {"driver", OPT_ARG_MSTRZ, &sdl_driver, NULL, 0},
- {NULL, 0, NULL, NULL, 0}
+ {"forcexv", OPT_ARG_BOOL, &sdl_forcexv, NULL},
+ {"hwaccel", OPT_ARG_BOOL, &sdl_hwaccel, NULL},
+ {"driver", OPT_ARG_MSTRZ, &sdl_driver, NULL},
+ {NULL, 0, NULL, NULL}
};
sdl_forcexv = 1;
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index 085dfb4156..5d38306efb 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -147,14 +147,19 @@ static void *vdpau_lib_handle;
/* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */
#define osd_surface output_surfaces[NUM_OUTPUT_SURFACES]
static VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1];
+static VdpVideoSurface deint_surfaces[3];
+static mp_image_t *deint_mpi[2];
static int output_surface_width, output_surface_height;
static VdpVideoMixer video_mixer;
static int deint;
static int deint_type;
+static int deint_counter;
+static int deint_buffer_past_frames;
static int pullup;
static float denoise;
static float sharpen;
+static int chroma_deint;
static int top_field_first;
static VdpDecoder decoder;
@@ -169,7 +174,8 @@ static int surface_num;
static int vid_surface_num;
static uint32_t vid_width, vid_height;
static uint32_t image_format;
-static const VdpChromaType vdp_chroma_type = VDP_CHROMA_TYPE_420;
+static VdpChromaType vdp_chroma_type;
+static VdpYCbCrFormat vdp_pixel_format;
/* draw_osd */
static unsigned char *index_data;
@@ -207,6 +213,13 @@ static int int_pause;
static void draw_eosd(void);
+static void push_deint_surface(VdpVideoSurface surface)
+{
+ deint_surfaces[2] = deint_surfaces[1];
+ deint_surfaces[1] = deint_surfaces[0];
+ deint_surfaces[0] = surface;
+}
+
static void video_to_output_surface(void)
{
VdpTime dummy;
@@ -215,8 +228,9 @@ static void video_to_output_surface(void)
if (vid_surface_num < 0)
return;
- // we would need to provide 2 past and 1 future frames to allow advanced
- // deinterlacing, which is not really possible currently.
+ if (deint < 2 || deint_surfaces[0] == VDP_INVALID_HANDLE)
+ push_deint_surface(surface_render[vid_surface_num].surface);
+
for (i = 0; i <= !!(deint > 1); i++) {
int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
VdpOutputSurface output_surface;
@@ -226,7 +240,7 @@ static void video_to_output_surface(void)
flip_page();
}
if (deint)
- field = top_field_first == i ?
+ field = (top_field_first == i) ^ (deint > 1) ?
VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD:
VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
output_surface = output_surfaces[surface_num];
@@ -236,12 +250,14 @@ static void video_to_output_surface(void)
CHECK_ST_WARNING("Error when calling vdp_presentation_queue_block_until_surface_idle")
vdp_st = vdp_video_mixer_render(video_mixer, VDP_INVALID_HANDLE, 0,
- field, 0, NULL,
- surface_render[vid_surface_num].surface,
- 0, NULL, &src_rect_vid,
+ field, 2, deint_surfaces + 1,
+ deint_surfaces[0],
+ 1, &surface_render[vid_surface_num].surface,
+ &src_rect_vid,
output_surface,
NULL, &out_rect_vid, 0, NULL);
CHECK_ST_WARNING("Error when calling vdp_video_mixer_render")
+ push_deint_surface(surface_render[vid_surface_num].surface);
}
}
@@ -359,6 +375,7 @@ static int win_x11_init_vdpau_procs(void)
return -1;
}
+ vdp_get_error_string = NULL;
for (dsc = vdp_func; dsc->pointer; dsc++) {
vdp_st = vdp_get_proc_address(vdp_device, dsc->id, dsc->pointer);
if (vdp_st != VDP_STATUS_OK) {
@@ -397,6 +414,9 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) {
const void * const denoise_value[] = {&denoise};
static const VdpVideoMixerAttribute sharpen_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL};
const void * const sharpen_value[] = {&sharpen};
+ static const VdpVideoMixerAttribute skip_chroma_attrib[] = {VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE};
+ const uint8_t skip_chroma_value = 1;
+ const void * const skip_chroma_value_ptr[] = {&skip_chroma_value};
static const VdpVideoMixerParameter parameters[VDP_NUM_MIXER_PARAMETER] = {
VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
@@ -407,8 +427,7 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) {
&vid_height,
&vdp_chroma_type
};
- if (deint == 3)
- features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL;
+ features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL;
if (deint == 4)
features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL;
if (pullup)
@@ -425,12 +444,16 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) {
CHECK_ST_ERROR("Error when calling vdp_video_mixer_create")
for (i = 0; i < feature_count; i++) feature_enables[i] = VDP_TRUE;
+ if (deint < 3)
+ feature_enables[0] = VDP_FALSE;
if (feature_count)
vdp_video_mixer_set_feature_enables(video_mixer, feature_count, features, feature_enables);
if (denoise)
vdp_video_mixer_set_attribute_values(video_mixer, 1, denoise_attrib, denoise_value);
if (sharpen)
vdp_video_mixer_set_attribute_values(video_mixer, 1, sharpen_attrib, sharpen_value);
+ if (!chroma_deint)
+ vdp_video_mixer_set_attribute_values(video_mixer, 1, skip_chroma_attrib, skip_chroma_value_ptr);
return 0;
}
@@ -445,6 +468,15 @@ static void free_video_specific(void) {
decoder = VDP_INVALID_HANDLE;
decoder_max_refs = -1;
+ for (i = 0; i < 3; i++)
+ deint_surfaces[i] = VDP_INVALID_HANDLE;
+
+ for (i = 0; i < 2; i++)
+ if (deint_mpi[i]) {
+ deint_mpi[i]->usage_count--;
+ deint_mpi[i] = NULL;
+ }
+
for (i = 0; i < MAX_VIDEO_SURFACES; i++) {
if (surface_render[i].surface != VDP_INVALID_HANDLE) {
vdp_st = vdp_video_surface_destroy(surface_render[i].surface);
@@ -460,6 +492,42 @@ static void free_video_specific(void) {
video_mixer = VDP_INVALID_HANDLE;
}
+static int create_vdp_decoder(int max_refs)
+{
+ VdpStatus vdp_st;
+ VdpDecoderProfile vdp_decoder_profile;
+ if (decoder != VDP_INVALID_HANDLE)
+ vdp_decoder_destroy(decoder);
+ switch (image_format) {
+ case IMGFMT_VDPAU_MPEG1:
+ vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG1;
+ break;
+ case IMGFMT_VDPAU_MPEG2:
+ vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
+ break;
+ case IMGFMT_VDPAU_H264:
+ vdp_decoder_profile = VDP_DECODER_PROFILE_H264_HIGH;
+ mp_msg(MSGT_VO, MSGL_V, "[vdpau] Creating H264 hardware decoder for %d reference frames.\n", max_refs);
+ break;
+ case IMGFMT_VDPAU_WMV3:
+ vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_MAIN;
+ break;
+ case IMGFMT_VDPAU_VC1:
+ vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED;
+ break;
+ }
+ vdp_st = vdp_decoder_create(vdp_device, vdp_decoder_profile,
+ vid_width, vid_height, max_refs, &decoder);
+ CHECK_ST_WARNING("Failed creating VDPAU decoder");
+ if (vdp_st != VDP_STATUS_OK) {
+ decoder = VDP_INVALID_HANDLE;
+ decoder_max_refs = 0;
+ return 0;
+ }
+ decoder_max_refs = max_refs;
+ return 1;
+}
+
/*
* connect to X server, create and map window, initialize all
* VDPAU objects, create different surfaces etc.
@@ -479,6 +547,11 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
#endif
image_format = format;
+ vid_width = width;
+ vid_height = height;
+ free_video_specific();
+ if (IMGFMT_IS_VDPAU(image_format) && !create_vdp_decoder(2))
+ return -1;
int_pause = 0;
visible_buf = 0;
@@ -524,16 +597,27 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
vo_fs = 1;
/* -----VDPAU related code here -------- */
-
- free_video_specific();
-
if (vdp_flip_queue == VDP_INVALID_HANDLE && win_x11_init_vdpau_flip_queue())
return -1;
- // video width and height
- vid_width = width;
- vid_height = height;
-
+ vdp_chroma_type = VDP_CHROMA_TYPE_420;
+ switch (image_format) {
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ vdp_pixel_format = VDP_YCBCR_FORMAT_YV12;
+ break;
+ case IMGFMT_NV12:
+ vdp_pixel_format = VDP_YCBCR_FORMAT_NV12;
+ break;
+ case IMGFMT_YUY2:
+ vdp_pixel_format = VDP_YCBCR_FORMAT_YUYV;
+ vdp_chroma_type = VDP_CHROMA_TYPE_422;
+ break;
+ case IMGFMT_UYVY:
+ vdp_pixel_format = VDP_YCBCR_FORMAT_UYVY;
+ vdp_chroma_type = VDP_CHROMA_TYPE_422;
+ }
if (create_vdp_mixer(vdp_chroma_type))
return -1;
@@ -772,38 +856,10 @@ static int draw_slice(uint8_t *image[], int stride[], int w, int h,
int max_refs = image_format == IMGFMT_VDPAU_H264 ? rndr->info.h264.num_ref_frames : 2;
if (!IMGFMT_IS_VDPAU(image_format))
return VO_FALSE;
- if (decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs) {
- VdpDecoderProfile vdp_decoder_profile;
- if (decoder != VDP_INVALID_HANDLE)
- vdp_decoder_destroy(decoder);
- decoder = VDP_INVALID_HANDLE;
- switch (image_format) {
- case IMGFMT_VDPAU_MPEG1:
- vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG1;
- break;
- case IMGFMT_VDPAU_MPEG2:
- vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
- break;
- case IMGFMT_VDPAU_H264:
- vdp_decoder_profile = VDP_DECODER_PROFILE_H264_HIGH;
- mp_msg(MSGT_VO, MSGL_V, "[vdpau] Creating H264 hardware decoder for %d reference frames.\n", max_refs);
- break;
- case IMGFMT_VDPAU_WMV3:
- vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_MAIN;
- break;
- case IMGFMT_VDPAU_VC1:
- vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED;
- break;
- }
- vdp_st = vdp_decoder_create(vdp_device, vdp_decoder_profile, vid_width, vid_height, max_refs, &decoder);
- CHECK_ST_WARNING("Failed creating VDPAU decoder");
- if (vdp_st != VDP_STATUS_OK) {
- decoder = VDP_INVALID_HANDLE;
- decoder_max_refs = 0;
- return VO_FALSE;
- }
- decoder_max_refs = max_refs;
- }
+ if ((decoder == VDP_INVALID_HANDLE || decoder_max_refs < max_refs)
+ && !create_vdp_decoder(max_refs))
+ return VO_FALSE;
+
vdp_st = vdp_decoder_render(decoder, rndr->surface, (void *)&rndr->info, rndr->bitstream_buffers_used, rndr->bitstream_buffers);
CHECK_ST_WARNING("Failed VDPAU decoder rendering");
return VO_TRUE;
@@ -837,18 +893,31 @@ static uint32_t draw_image(mp_image_t *mpi)
if (IMGFMT_IS_VDPAU(image_format)) {
struct vdpau_render_state *rndr = mpi->priv;
vid_surface_num = rndr - surface_render;
+ if (deint_buffer_past_frames) {
+ mpi->usage_count++;
+ if (deint_mpi[1])
+ deint_mpi[1]->usage_count--;
+ deint_mpi[1] = deint_mpi[0];
+ deint_mpi[0] = mpi;
+ }
} else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) {
VdpStatus vdp_st;
void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
- struct vdpau_render_state *rndr = get_surface(0);
+ struct vdpau_render_state *rndr = get_surface(deint_counter);
+ deint_counter = (deint_counter + 1) % 3;
vid_surface_num = rndr - surface_render;
+ if (image_format == IMGFMT_NV12)
+ destdata[1] = destdata[2];
vdp_st = vdp_video_surface_put_bits_y_cb_cr(rndr->surface,
- VDP_YCBCR_FORMAT_YV12,
+ vdp_pixel_format,
(const void *const*)destdata,
mpi->stride); // pitch
CHECK_ST_ERROR("Error when calling vdp_video_surface_put_bits_y_cb_cr")
}
- top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
+ if (mpi->fields & MP_IMGFIELD_ORDERED)
+ top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
+ else
+ top_field_first = 1;
video_to_output_surface();
return VO_TRUE;
@@ -883,6 +952,11 @@ static int query_format(uint32_t format)
int default_flags = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_EOSD | VFCAP_EOSD_UNSCALED;
switch (format) {
case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ case IMGFMT_NV12:
+ case IMGFMT_YUY2:
+ case IMGFMT_UYVY:
return default_flags | VOCAP_NOSLICES;
case IMGFMT_VDPAU_MPEG1:
case IMGFMT_VDPAU_MPEG2:
@@ -952,6 +1026,7 @@ static void uninit(void)
static const opt_t subopts[] = {
{"deint", OPT_ARG_INT, &deint, (opt_test_f)int_non_neg},
+ {"chroma-deint", OPT_ARG_BOOL, &chroma_deint, NULL},