Lines 23-28
Link Here
|
23 |
#include <X11/extensions/Xvlib.h> |
23 |
#include <X11/extensions/Xvlib.h> |
24 |
#include <X11/extensions/XvMClib.h> |
24 |
#include <X11/extensions/XvMClib.h> |
25 |
|
25 |
|
|
|
26 |
#ifdef HAVE_XVMC_VLD |
27 |
#include <X11/extensions/vldXvMC.h> |
28 |
extern int has_xvmc_vld; |
29 |
#endif |
30 |
|
26 |
#include "x11_common.h" |
31 |
#include "x11_common.h" |
27 |
#include "xvmc_render.h" |
32 |
#include "xvmc_render.h" |
28 |
|
33 |
|
Lines 45-50
Link Here
|
45 |
|
50 |
|
46 |
|
51 |
|
47 |
#define UNUSED(x) ((void)(x)) |
52 |
#define UNUSED(x) ((void)(x)) |
|
|
53 |
extern unsigned int video_format; |
48 |
|
54 |
|
49 |
#include "libavcodec/avcodec.h" |
55 |
#include "libavcodec/avcodec.h" |
50 |
#if LIBAVCODEC_BUILD < ((51<<16)+(40<<8)+2) |
56 |
#if LIBAVCODEC_BUILD < ((51<<16)+(40<<8)+2) |
Lines 59-64
Link Here
|
59 |
static int xv_port_request = 0; |
65 |
static int xv_port_request = 0; |
60 |
static int bob_deinterlace; |
66 |
static int bob_deinterlace; |
61 |
static int top_field_first; |
67 |
static int top_field_first; |
|
|
68 |
static int use_deint_one; |
69 |
static int use_tv_clip; |
62 |
|
70 |
|
63 |
static int image_width,image_height; |
71 |
static int image_width,image_height; |
64 |
static int image_format; |
72 |
static int image_format; |
Lines 123-129
Link Here
|
123 |
"XVideo Motion Compensation", |
131 |
"XVideo Motion Compensation", |
124 |
"xvmc", |
132 |
"xvmc", |
125 |
"Ivan Kalvachev <iive@users.sf.net>", |
133 |
"Ivan Kalvachev <iive@users.sf.net>", |
126 |
"" |
134 |
"Ivor Hewitt <ivor@ivor.org> - VIA VLD support" |
127 |
}; |
135 |
}; |
128 |
|
136 |
|
129 |
LIBVO_EXTERN(xvmc); |
137 |
LIBVO_EXTERN(xvmc); |
Lines 196-202
Link Here
|
196 |
} |
204 |
} |
197 |
//end of vo_xv shm/xvimage code |
205 |
//end of vo_xv shm/xvimage code |
198 |
|
206 |
|
|
|
207 |
int hasVLDAcceleration() |
208 |
{ |
209 |
#ifdef HAVE_XVMC_VLD |
210 |
return XVMC_VLD == (surface_info.mc_type & XVMC_VLD); |
211 |
#else |
212 |
return 0; |
213 |
#endif |
214 |
} |
215 |
|
199 |
static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){ |
216 |
static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){ |
|
|
217 |
#ifdef HAVE_XVMC_VLD |
218 |
if (format == IMGFMT_XVMC_VLD_MPEG2 ){ |
219 |
if( surf_info->mc_type != (XVMC_VLD|XVMC_MPEG_2) ) return -1; |
220 |
if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; |
221 |
return 0; |
222 |
} |
223 |
#endif |
200 |
if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ |
224 |
if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ |
201 |
if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1; |
225 |
if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1; |
202 |
if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; |
226 |
if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; |
Lines 361-366
Link Here
|
361 |
return VO_TRUE; |
385 |
return VO_TRUE; |
362 |
} |
386 |
} |
363 |
|
387 |
|
|
|
388 |
|
389 |
static int |
390 |
check_xvmc_vld() |
391 |
{ |
392 |
int rez; |
393 |
XvAdaptorInfo* ai; |
394 |
XvMCSurfaceInfo* surf_info; |
395 |
int max_adaptor; |
396 |
int max_surf; |
397 |
int i; |
398 |
unsigned long p; |
399 |
int s; |
400 |
|
401 |
rez = XvQueryAdaptors(mDisplay, DefaultRootWindow(mDisplay), |
402 |
&max_adaptor,&ai); |
403 |
if (rez != Success) return; |
404 |
|
405 |
if (mp_msg_test(MSGT_VO, MSGL_DBG3)) |
406 |
printf("vo_xvmc: Querying %d adaptors for VLD\n", max_adaptor); |
407 |
|
408 |
for (i = 0; i < max_adaptor; i++) |
409 |
{ |
410 |
if (mp_msg_test(MSGT_VO,MSGL_DBG3)) |
411 |
printf("vo_xvmc: Quering adaptor #%d for VLD\n", i); |
412 |
if (ai[i].type == 0) continue; |
413 |
|
414 |
// Probing every XV port |
415 |
for (p = ai[i].base_id; p < ai[i].base_id + ai[i].num_ports; p++) |
416 |
{ |
417 |
// Respect the users wish |
418 |
if ((xv_port_request != 0) && (xv_port_request != p)) continue; |
419 |
if (mp_msg_test(MSGT_VO,MSGL_DBG3)) |
420 |
printf("vo_xvmc: Probing port #%ld for VLD\n", p); |
421 |
surf_info = XvMCListSurfaceTypes(mDisplay, p, &max_surf); |
422 |
if (surf_info == NULL || max_surf == 0) continue; |
423 |
|
424 |
// We have XvMC list! |
425 |
for(s = 0; s < max_surf; s++) |
426 |
{ |
427 |
// We have match! |
428 |
if (XVMC_VLD == (surf_info[s].mc_type & XVMC_VLD)) |
429 |
has_xvmc_vld = 1; |
430 |
} |
431 |
XFree(surf_info); |
432 |
} |
433 |
} |
434 |
XvFreeAdaptorInfo(ai); |
435 |
|
436 |
if (mp_msg_test(MSGT_VO,MSGL_DBG3) && has_xvmc_vld) |
437 |
printf("vo_xvmc: Found VLD support in XvMC\n"); |
438 |
} |
439 |
|
440 |
|
364 |
static int preinit(const char *arg){ |
441 |
static int preinit(const char *arg){ |
365 |
int xv_version,xv_release,xv_request_base,xv_event_base,xv_error_base; |
442 |
int xv_version,xv_release,xv_request_base,xv_event_base,xv_error_base; |
366 |
int mc_eventBase,mc_errorBase; |
443 |
int mc_eventBase,mc_errorBase; |
Lines 377-385
Link Here
|
377 |
{ "sleep", OPT_ARG_BOOL, &use_sleep, NULL }, |
454 |
{ "sleep", OPT_ARG_BOOL, &use_sleep, NULL }, |
378 |
{ "queue", OPT_ARG_BOOL, &use_queue, NULL }, |
455 |
{ "queue", OPT_ARG_BOOL, &use_queue, NULL }, |
379 |
{ "bobdeint", OPT_ARG_BOOL, &bob_deinterlace, NULL }, |
456 |
{ "bobdeint", OPT_ARG_BOOL, &bob_deinterlace, NULL }, |
|
|
457 |
{ "onedeint", OPT_ARG_BOOL, &use_deint_one, NULL }, |
458 |
{ "tv-clip", OPT_ARG_BOOL, &use_tv_clip, NULL }, |
380 |
{ NULL } |
459 |
{ NULL } |
381 |
}; |
460 |
}; |
382 |
|
461 |
|
|
|
462 |
// If the video is not MPEG1 or MPEG2, we can't decode it, so |
463 |
// fail cleanly to allow mplayer to fallback to another vo system |
464 |
if (video_format != 0x10000001 && video_format != 0x10000002) return -1; |
465 |
|
466 |
|
383 |
//Obtain display handler |
467 |
//Obtain display handler |
384 |
if (!vo_init()) return -1;//vo_xv |
468 |
if (!vo_init()) return -1;//vo_xv |
385 |
|
469 |
|
Lines 415-420
Link Here
|
415 |
use_sleep = 0; |
499 |
use_sleep = 0; |
416 |
use_queue = 0; |
500 |
use_queue = 0; |
417 |
bob_deinterlace = 0; |
501 |
bob_deinterlace = 0; |
|
|
502 |
use_deint_one = 0; |
503 |
use_tv_clip = 0; |
418 |
|
504 |
|
419 |
/* parse suboptions */ |
505 |
/* parse suboptions */ |
420 |
if ( subopt_parse( arg, subopts ) != 0 ) |
506 |
if ( subopt_parse( arg, subopts ) != 0 ) |
Lines 424-429
Link Here
|
424 |
|
510 |
|
425 |
xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); |
511 |
xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); |
426 |
|
512 |
|
|
|
513 |
// Check whether XvMC supports VLD |
514 |
check_xvmc_vld(); |
515 |
|
427 |
return 0; |
516 |
return 0; |
428 |
} |
517 |
} |
429 |
|
518 |
|
Lines 505-510
Link Here
|
505 |
if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444) |
594 |
if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444) |
506 |
blocks_per_macroblock = 12; |
595 |
blocks_per_macroblock = 12; |
507 |
|
596 |
|
|
|
597 |
if (!hasVLDAcceleration()) |
598 |
{ |
508 |
rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks); |
599 |
rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks); |
509 |
if( rez != Success ){ |
600 |
if( rez != Success ){ |
510 |
XvMCDestroyContext(mDisplay,&ctx); |
601 |
XvMCDestroyContext(mDisplay,&ctx); |
Lines 520-525
Link Here
|
520 |
} |
611 |
} |
521 |
printf("vo_xvmc: mv_blocks allocated\n"); |
612 |
printf("vo_xvmc: mv_blocks allocated\n"); |
522 |
|
613 |
|
|
|
614 |
} |
615 |
|
523 |
if(surface_render==NULL) |
616 |
if(surface_render==NULL) |
524 |
surface_render=malloc(MAX_SURFACES*sizeof(xvmc_render_state_t));//easy mem debug |
617 |
surface_render=malloc(MAX_SURFACES*sizeof(xvmc_render_state_t));//easy mem debug |
525 |
memset(surface_render,0,MAX_SURFACES*sizeof(xvmc_render_state_t)); |
618 |
memset(surface_render,0,MAX_SURFACES*sizeof(xvmc_render_state_t)); |
Lines 538-543
Link Here
|
538 |
surface_render[i].chroma_format = surface_info.chroma_format; |
631 |
surface_render[i].chroma_format = surface_info.chroma_format; |
539 |
surface_render[i].unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED; |
632 |
surface_render[i].unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED; |
540 |
surface_render[i].p_surface = &surface_array[i]; |
633 |
surface_render[i].p_surface = &surface_array[i]; |
|
|
634 |
|
635 |
surface_render[i].state = 0; |
636 |
surface_render[i].disp = mDisplay; |
637 |
surface_render[i].ctx = &ctx; |
638 |
|
541 |
if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
639 |
if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) |
542 |
printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]); |
640 |
printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]); |
543 |
} |
641 |
} |
Lines 993-998
Link Here
|
993 |
int rez; |
1091 |
int rez; |
994 |
int clipX,clipY,clipW,clipH; |
1092 |
int clipX,clipY,clipW,clipH; |
995 |
int i; |
1093 |
int i; |
|
|
1094 |
int srcY=0, srcH=image_height; |
1095 |
int fieldnobob; |
996 |
|
1096 |
|
997 |
if(p_render_surface == NULL) |
1097 |
if(p_render_surface == NULL) |
998 |
return; |
1098 |
return; |
Lines 1002-1023
Link Here
|
1002 |
clipW = vo_dwidth+vo_panscan_x; |
1102 |
clipW = vo_dwidth+vo_panscan_x; |
1003 |
clipH = vo_dheight+vo_panscan_y; |
1103 |
clipH = vo_dheight+vo_panscan_y; |
1004 |
|
1104 |
|
|
|
1105 |
if (use_tv_clip) { |
1106 |
/* |
1107 |
* Clip top few lines off to get rid of annoying flicker |
1108 |
* when using bob de-interlacing on TV sourced video. |
1109 |
*/ |
1110 |
srcY+=4; |
1111 |
srcH-=4; |
1112 |
} |
1113 |
|
1005 |
if(draw_ck) |
1114 |
if(draw_ck) |
1006 |
vo_xv_draw_colorkey(clipX,clipY,clipW,clipH); |
1115 |
vo_xv_draw_colorkey(clipX,clipY,clipW,clipH); |
1007 |
|
1116 |
|
1008 |
if(benchmark) |
1117 |
if(benchmark) |
1009 |
return; |
1118 |
return; |
1010 |
|
1119 |
|
|
|
1120 |
fieldnobob = XVMC_FRAME_PICTURE; |
1121 |
|
1122 |
if (use_deint_one) |
1123 |
fieldnobob = (top_field_first) ? XVMC_TOP_FIELD : XVMC_BOTTOM_FIELD; |
1124 |
|
1011 |
for (i = 1; i <= bob_deinterlace + 1; i++) { |
1125 |
for (i = 1; i <= bob_deinterlace + 1; i++) { |
1012 |
int field = top_field_first ? i : i ^ 3; |
1126 |
int field = top_field_first ? i : i ^ XVMC_FRAME_PICTURE; |
1013 |
rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface, |
1127 |
rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface, |
1014 |
vo_window, |
1128 |
vo_window, |
1015 |
0, 0, image_width, image_height, |
1129 |
0, srcY, image_width, srcH, |
1016 |
clipX, clipY, clipW, clipH, |
1130 |
clipX, clipY, clipW, clipH, |
1017 |
bob_deinterlace ? field : 3); |
1131 |
bob_deinterlace ? field : fieldnobob); |
1018 |
//p_render_surface_to_show->display_flags); |
1132 |
if (i == 1 && bob_deinterlace) { |
|
|
1133 |
usleep(10*1000); |
1134 |
} |
1019 |
if(rez != Success){ |
1135 |
if(rez != Success){ |
1020 |
printf("vo_xvmc: PutSurface failer, critical error %d!\n",rez); |
1136 |
printf("vo_xvmc: PutSurface failure, critical error %d!\n",rez); |
1021 |
assert(0); |
1137 |
assert(0); |
1022 |
} |
1138 |
} |
1023 |
} |
1139 |
} |
Lines 1109-1117
Link Here
|
1109 |
|
1225 |
|
1110 |
if( number_of_surfaces ){ |
1226 |
if( number_of_surfaces ){ |
1111 |
|
1227 |
|
|
|
1228 |
if (!hasVLDAcceleration()) |
1229 |
{ |
1112 |
XvMCDestroyMacroBlocks(mDisplay,&mv_blocks); |
1230 |
XvMCDestroyMacroBlocks(mDisplay,&mv_blocks); |
1113 |
XvMCDestroyBlocks(mDisplay,&data_blocks); |
1231 |
XvMCDestroyBlocks(mDisplay,&data_blocks); |
1114 |
|
1232 |
} |
1115 |
for(i=0; i<number_of_surfaces; i++) |
1233 |
for(i=0; i<number_of_surfaces; i++) |
1116 |
{ |
1234 |
{ |
1117 |
XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope |
1235 |
XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope |
Lines 1189-1194
Link Here
|
1189 |
assert( rndr != NULL ); |
1307 |
assert( rndr != NULL ); |
1190 |
assert( rndr->magic == MP_XVMC_RENDER_MAGIC ); |
1308 |
assert( rndr->magic == MP_XVMC_RENDER_MAGIC ); |
1191 |
|
1309 |
|
|
|
1310 |
if (hasVLDAcceleration()) |
1311 |
{ |
1312 |
rez = XvMCPutSlice2(mDisplay,&ctx,(char*)rndr->slice_data, |
1313 |
rndr->slice_datalen, |
1314 |
rndr->slice_code); |
1315 |
if (rez) |
1316 |
printf("vo_xxmc::slice Error %d\n",rez); |
1317 |
|
1318 |
} |
1319 |
else |
1320 |
{ |
1192 |
rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure, |
1321 |
rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure, |
1193 |
rndr->p_surface, |
1322 |
rndr->p_surface, |
1194 |
rndr->p_past_surface, |
1323 |
rndr->p_past_surface, |
Lines 1200-1206
Link Here
|
1200 |
if(rez != Success) |
1329 |
if(rez != Success) |
1201 |
{ |
1330 |
{ |
1202 |
int i; |
1331 |
int i; |
1203 |
printf("vo_xvmc::slice: RenderSirface returned %d\n",rez); |
1332 |
printf("vo_xvmc::slice: RenderSurface returned %d\n",rez); |
1204 |
|
1333 |
|
1205 |
printf("vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n", |
1334 |
printf("vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n", |
1206 |
rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num, |
1335 |
rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num, |
Lines 1228-1233
Link Here
|
1228 |
rez = XvMCFlushSurface(mDisplay, rndr->p_surface); |
1357 |
rez = XvMCFlushSurface(mDisplay, rndr->p_surface); |
1229 |
assert(rez==Success); |
1358 |
assert(rez==Success); |
1230 |
|
1359 |
|
|
|
1360 |
} |
1231 |
// rndr->start_mv_blocks_num += rndr->filled_mv_blocks_num; |
1361 |
// rndr->start_mv_blocks_num += rndr->filled_mv_blocks_num; |
1232 |
rndr->start_mv_blocks_num = 0; |
1362 |
rndr->start_mv_blocks_num = 0; |
1233 |
rndr->filled_mv_blocks_num = 0; |
1363 |
rndr->filled_mv_blocks_num = 0; |
Lines 1337-1344
Link Here
|
1337 |
|
1467 |
|
1338 |
// these are shared!! so watch out |
1468 |
// these are shared!! so watch out |
1339 |
// do call RenderSurface before overwriting |
1469 |
// do call RenderSurface before overwriting |
|
|
1470 |
if (!hasVLDAcceleration()) |
1471 |
{ |
1340 |
mpi->planes[0] = (char*)data_blocks.blocks; |
1472 |
mpi->planes[0] = (char*)data_blocks.blocks; |
1341 |
mpi->planes[1] = (char*)mv_blocks.macro_blocks; |
1473 |
mpi->planes[1] = (char*)mv_blocks.macro_blocks; |
|
|
1474 |
} |
1475 |
else |
1476 |
{ |
1477 |
mpi->planes[0] = 1; |
1478 |
mpi->planes[1] = 0; |
1479 |
} |
1342 |
mpi->priv = |
1480 |
mpi->priv = |
1343 |
mpi->planes[2] = (char*)rndr; |
1481 |
mpi->planes[2] = (char*)rndr; |
1344 |
|
1482 |
|