static int get_colourkey( void ) { Atom atom; XvAttribute *attr; int value; int nattr; attr = XvQueryPortAttributes( display, xv_port, &nattr ); if( attr ) { if( nattr ) { int k; for( k = 0; k < nattr; k++ ) { if( (attr[ k ].flags & XvSettable) && (attr[ k ].flags & XvGettable)) { if( !strcmp( attr[ k ].name, "XV_COLORKEY" ) ) { atom = XInternAtom( display, "XV_COLORKEY", False ); if( atom != None ) { XvGetPortAttribute( display, xv_port, atom, &value ); XvSetPortAttribute( display, xv_port, atom, value ); XvGetPortAttribute( display, xv_port, atom, &value ); XFree( attr ); return value; } } } } } XFree( attr ); } return 0; }
int XvGrabber::getattr(Atom attr) { int v; Display* dpy = Tk_Display(Tcl::instance().tkmain()); XvGetPortAttribute(dpy, grabID_, attr, &v); return(v); }
int XvGrabber::getgrabber() { Tk_Window tk = Tcl::instance().tkmain(); Display* dpy = Tk_Display(tk); int majop, eventbase, errbase; if (XQueryExtension(dpy, "XVideo", &majop, &eventbase, &errbase) == False) return (-1); Window root = DefaultRootWindow(dpy); u_int ngrabbers=0; XvAdaptorInfo* grabbers; if (XvQueryAdaptors(dpy, root, &ngrabbers, &grabbers) != Success) return (-1); if (ngrabbers > 1) fprintf(stderr, "XVgrabber: warning: more than one frame grabber\n"); for (int i=2; i<ngrabbers; i++) { //if ((grabbers[i].type)&XvOutputMask) { if ((grabbers[i].type)&XvInputMask) { fprintf(stderr, "Xv %d grabber: %s\n",i,grabbers[i].name); strncpy(grabber_name, grabbers[i].name, sizeof(grabber_name)); grabID_ = grabbers[i].base_id; } } if (!grabID_) return (-1); XvFreeAdaptorInfo(grabbers); XvQueryEncodings(dpy, grabID_, &nencodings, &encoding); #if 1 printf("Encodings(%d): ", nencodings); for (int i=0; i<nencodings; i++) printf("%s %d %d\n", encoding[i].name, encoding[i].width, encoding[i].height); printf("\n"); #endif XAbrightness = XInternAtom(dpy, "XV_BRIGHTNESS", False); XAcontrast = XInternAtom(dpy, "XV_CONTRAST", False); XAhue = XInternAtom(dpy, "XV_HUE", False); XAsaturation = XInternAtom(dpy, "XV_SATURATION", False); XAencoding = XInternAtom(dpy, "XV_ENCODING", False); XvGetPortAttribute(dpy, grabID_, XAencoding, (int *)&encodingid_); if (!XMatchVisualInfo(dpy, Tk_ScreenNumber(tk), 24, TrueColor, &vinfo_)) return (-1); return (0); }
static int xv_get_eq(struct vo *vo, uint32_t xv_port, const char *name, int *value) { int min, max; int atom = xv_find_atom(vo, xv_port, name, true, &min, &max); if (atom != None) { int port_value = 0; XvGetPortAttribute(vo->x11->display, xv_port, atom, &port_value); *value = (port_value - min) * 200 / (max - min) - 100; MP_VERBOSE(vo, "xv_get_eq called! (%s, %d)\n", name, *value); return VO_TRUE; } return VO_FALSE; }
int QX11VideoSurface::getAttribute(const char *attribute, int minimum, int maximum) const { if (m_portId != 0) { Display *display = QX11Info::display(); Atom atom = XInternAtom(display, attribute, True); int value = 0; XvGetPortAttribute(display, m_portId, atom, &value); return redistribute(value, minimum, maximum, -100, 100); } else { return 0; } }
static void init_xv_settings(video_canvas_t *canvas) { /* Find XVideo color setting limits. */ if (canvas->videoconfig->hwscale && canvas->xv_image) { int i, j; int numattr = 0; Display *dpy = x11ui_get_display_ptr(); XvAttribute *attr = XvQueryPortAttributes(dpy, canvas->xv_port, &numattr); xv_settings[0].value = &(canvas->videoconfig->video_resources.color_saturation); xv_settings[1].value = &(canvas->videoconfig->video_resources.color_contrast); xv_settings[2].value = &(canvas->videoconfig->video_resources.color_brightness); xv_settings[3].value = &(canvas->videoconfig->video_resources.color_gamma); for (i = 0; i < (int)util_arraysize(xv_settings); i++) { xv_settings[i].atom = 0; for (j = 0; j < numattr; j++) { if (!(attr[j].flags & XvSettable)) { continue; /* useless, can't be set */ } if (strcmp(xv_settings[i].name, attr[j].name) == 0) { xv_settings[i].atom = XInternAtom(dpy, xv_settings[i].name, False); xv_settings[i].min = attr[j].min_value; xv_settings[i].max = attr[j].max_value; if ((attr[j].flags & XvGettable) && !xv_settings[i].restore) { xv_settings[i].restore = (XvGetPortAttribute(dpy, canvas->xv_port, xv_settings[i].atom, &xv_settings[i].xv_default) == Success); if (!xv_settings[i].restore) { xv_settings[i].restore = 2; } } break; } } } if (attr) { XFree(attr); } /* Apply color settings to XVideo. */ video_canvas_set_palette(canvas, canvas->palette); } }
bool XVWindow::InitColorkey() { if( XV_COLORKEY != None ) { if ( XvGetPortAttribute(_display,_XVPort, XV_COLORKEY, &_colorKey) == Success ) PTRACE(4, "XVideo\tUsing colorkey " << _colorKey ); else { PTRACE(1, "XVideo\tCould not get colorkey! Maybe the selected Xv port has no overlay." ); return false; } if ( XV_AUTOPAINT_COLORKEY != None ) { if ( XvSetPortAttribute( _display, _XVPort, XV_AUTOPAINT_COLORKEY, 1 ) == Success ) PTRACE(4, "XVideo\tColorkey method: AUTOPAINT"); else { _paintColorKey = true; PTRACE(4, "XVideo\tFailed to set XV_AUTOPAINT_COLORKEY"); PTRACE(4, "XVideo\tColorkey method: MANUAL"); } } else { _paintColorKey = true; PTRACE(4, "XVideo\tXV_AUTOPAINT_COLORKEY not supported"); PTRACE(4, "XVideo\tColorkey method: MANUAL"); } } else { PTRACE(4, "XVideo\tColorkey method: NONE"); } return true; }
int xf_video_process_frame(xfInfo * xfi, RD_VIDEO_FRAME_EVENT * vevent) { XShmSegmentInfo shminfo; XvImage * image; int colorkey = 0; int i; uint32 pixfmt; uint8 * data1; uint8 * data2; if (xfi->xv_port == -1) return 1; /* In case the player is minimized */ if (vevent->x < -2048 || vevent->y < -2048 || vevent->num_visible_rects <= 0) return 0; if (xfi->xv_colorkey_atom != None) { XvGetPortAttribute(xfi->display, xfi->xv_port, xfi->xv_colorkey_atom, &colorkey); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, colorkey); for (i = 0; i < vevent->num_visible_rects; i++) { XFillRectangle(xfi->display, xfi->wnd, xfi->gc, vevent->x + vevent->visible_rects[i].x, vevent->y + vevent->visible_rects[i].y, vevent->visible_rects[i].width, vevent->visible_rects[i].height); } } pixfmt = vevent->frame_pixfmt; image = XvShmCreateImage(xfi->display, xfi->xv_port, pixfmt, 0, vevent->frame_width, vevent->frame_height, &shminfo); if (xfi->xv_image_size != image->data_size) { if (xfi->xv_image_size > 0) { shmdt(xfi->xv_shmaddr); shmctl(xfi->xv_shmid, IPC_RMID, NULL); } xfi->xv_image_size = image->data_size; xfi->xv_shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); xfi->xv_shmaddr = shmat(xfi->xv_shmid, 0, 0); } shminfo.shmid = xfi->xv_shmid; shminfo.shmaddr = image->data = xfi->xv_shmaddr; shminfo.readOnly = False; if (!XShmAttach(xfi->display, &shminfo)) { XFree(image); printf("xf_video_process_frame: XShmAttach failed.\n"); return 1; } /* The video driver may align each line to a different size and we need to convert our original image data. */ switch (pixfmt) { case RD_PIXFMT_I420: case RD_PIXFMT_YV12: if (!xf_video_is_format_supported(xfi, RD_PIXFMT_I420) && !xf_video_is_format_supported(xfi, RD_PIXFMT_YV12)) { printf("xf_video_process_frame: pixel format 0x%X not supported by hardware.\n", pixfmt); break; } /* Y */ if (image->pitches[0] == vevent->frame_width) { memcpy(image->data + image->offsets[0], vevent->frame_data, vevent->frame_width * vevent->frame_height); } else { for (i = 0; i < vevent->frame_height; i++) { memcpy(image->data + image->offsets[0] + i * image->pitches[0], vevent->frame_data + i * vevent->frame_width, vevent->frame_width); } } /* UV */ /* Conversion between I420 and YV12 is to simply swap U and V */ if (xf_video_is_format_supported(xfi, pixfmt)) { data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; } else { data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; image->id = pixfmt == RD_PIXFMT_I420 ? RD_PIXFMT_YV12 : RD_PIXFMT_I420; } if (image->pitches[1] * 2 == vevent->frame_width) { memcpy(image->data + image->offsets[1], data1, vevent->frame_width * vevent->frame_height / 4); memcpy(image->data + image->offsets[2], data2, vevent->frame_width * vevent->frame_height / 4); } else { for (i = 0; i < vevent->frame_height / 2; i++) { memcpy(image->data + image->offsets[1] + i * image->pitches[1], data1 + i * vevent->frame_width / 2, vevent->frame_width / 2); memcpy(image->data + image->offsets[2] + i * image->pitches[2], data2 + i * vevent->frame_width / 2, vevent->frame_width / 2); } } break; default: memcpy(image->data, vevent->frame_data, image->data_size <= vevent->frame_size ? image->data_size : vevent->frame_size); break; } XvShmPutImage(xfi->display, xfi->xv_port, xfi->wnd, xfi->gc_default, image, 0, 0, image->width, image->height, vevent->x, vevent->y, vevent->width, vevent->height, False); XSync(xfi->display, False); XShmDetach(xfi->display, &shminfo); XFree(image); return 0; }
int main(int argc, char **argv) { struct Config config; Display *display; Window root, window; const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; XvPortID port_num; int surface_type_id; unsigned int is_overlay, intra_unsigned; int colorkey; XvMCContext context; XvMCSurface surface; XvMCBlockArray block_array; XvMCMacroBlockArray mb_array; unsigned int mbw, mbh; unsigned int mbx, mby; unsigned int reps; struct timeval start, stop, diff; double diff_secs; ParseArgs(argc, argv, &config); mbw = align(config.input_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH; mbh = align(config.input_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT; display = XOpenDisplay(NULL); if (!GetPort ( display, config.input_width, config.input_height, XVMC_CHROMA_FORMAT_420, mc_types, 2, &port_num, &surface_type_id, &is_overlay, &intra_unsigned )) { XCloseDisplay(display); fprintf(stderr, "Error, unable to find a good port.\n"); exit(1); } if (is_overlay) { Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); } else { colorkey = 0; } root = XDefaultRootWindow(display); window = XCreateSimpleWindow(display, root, 0, 0, config.output_width, config.output_height, 0, 0, colorkey); assert(XvMCCreateContext(display, port_num, surface_type_id, config.input_width, config.input_height, XVMC_DIRECT, &context) == Success); assert(XvMCCreateSurface(display, &context, &surface) == Success); assert(XvMCCreateBlocks(display, &context, mbw * mbh * BLOCKS_PER_MACROBLOCK, &block_array) == Success); assert(XvMCCreateMacroBlocks(display, &context, mbw * mbh, &mb_array) == Success); for (mby = 0; mby < mbh; ++mby) for (mbx = 0; mbx < mbw; ++mbx) { mb_array.macro_blocks[mby * mbw + mbx].x = mbx; mb_array.macro_blocks[mby * mbw + mbx].y = mby; mb_array.macro_blocks[mby * mbw + mbx].macroblock_type = XVMC_MB_TYPE_INTRA; /*mb->motion_type = ;*/ /*mb->motion_vertical_field_select = ;*/ mb_array.macro_blocks[mby * mbw + mbx].dct_type = XVMC_DCT_TYPE_FRAME; /*mb->PMV[0][0][0] = ; mb->PMV[0][0][1] = ; mb->PMV[0][1][0] = ; mb->PMV[0][1][1] = ; mb->PMV[1][0][0] = ; mb->PMV[1][0][1] = ; mb->PMV[1][1][0] = ; mb->PMV[1][1][1] = ;*/ mb_array.macro_blocks[mby * mbw + mbx].index = (mby * mbw + mbx) * BLOCKS_PER_MACROBLOCK; mb_array.macro_blocks[mby * mbw + mbx].coded_block_pattern = 0x3F; } XSelectInput(display, window, ExposureMask | KeyPressMask); XMapWindow(display, window); XSync(display, 0); gettimeofday(&start, NULL); for (reps = 0; reps < config.reps; ++reps) { if (config.pipeline & PIPELINE_STEP_MC) { assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, mbw * mbh, 0, &mb_array, &block_array) == Success); assert(XvMCFlushSurface(display, &surface) == Success); } if (config.pipeline & PIPELINE_STEP_CSC) assert(XvMCPutSurface(display, &surface, window, 0, 0, config.input_width, config.input_height, 0, 0, config.output_width, config.output_height, XVMC_FRAME_PICTURE) == Success); } gettimeofday(&stop, NULL); timeval_subtract(&diff, &stop, &start); diff_secs = (double)diff.tv_sec + (double)diff.tv_usec / 1000000.0; printf("XvMC Benchmark\n"); printf("Input: %u,%u\nOutput: %u,%u\n", config.input_width, config.input_height, config.output_width, config.output_height); printf("Pipeline: "); if (config.pipeline & PIPELINE_STEP_MC) printf("|mc|"); if (config.pipeline & PIPELINE_STEP_CSC) printf("|csc|"); if (config.pipeline & PIPELINE_STEP_SWAP) printf("|swap|"); printf("\n"); printf("Reps: %u\n", config.reps); printf("Total time: %.2lf (%.2lf reps / sec)\n", diff_secs, config.reps / diff_secs); assert(XvMCDestroyBlocks(display, &block_array) == Success); assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success); assert(XvMCDestroySurface(display, &surface) == Success); assert(XvMCDestroyContext(display, &context) == Success); XvUngrabPort(display, port_num, CurrentTime); XDestroyWindow(display, window); XCloseDisplay(display); return 0; }
/* NOTE: If vo.colorkey has bits set after the first 3 low order bytes * we don't draw anything as this means it was forced to off. */ static int xv_init_colorkey(struct vo *vo) { struct xvctx *ctx = vo->priv; Display *display = vo->x11->display; Atom xv_atom; int rez; /* check if colorkeying is needed */ xv_atom = xv_intern_atom_if_exists(vo, "XV_COLORKEY"); if (xv_atom != None && !(ctx->colorkey & 0xFF000000)) { if (ctx->xv_ck_info.source == CK_SRC_CUR) { int colorkey_ret; rez = XvGetPortAttribute(display, ctx->xv_port, xv_atom, &colorkey_ret); if (rez == Success) ctx->xv_colorkey = colorkey_ret; else { MP_FATAL(vo, "Couldn't get colorkey! " "Maybe the selected Xv port has no overlay.\n"); return 0; // error getting colorkey } } else { ctx->xv_colorkey = ctx->colorkey; /* check if we have to set the colorkey too */ if (ctx->xv_ck_info.source == CK_SRC_SET) { xv_atom = XInternAtom(display, "XV_COLORKEY", False); rez = XvSetPortAttribute(display, ctx->xv_port, xv_atom, ctx->colorkey); if (rez != Success) { MP_FATAL(vo, "Couldn't set colorkey!\n"); return 0; // error setting colorkey } } } xv_atom = xv_intern_atom_if_exists(vo, "XV_AUTOPAINT_COLORKEY"); /* should we draw the colorkey ourselves or activate autopainting? */ if (ctx->xv_ck_info.method == CK_METHOD_AUTOPAINT) { rez = !Success; if (xv_atom != None) // autopaint is supported rez = XvSetPortAttribute(display, ctx->xv_port, xv_atom, 1); if (rez != Success) ctx->xv_ck_info.method = CK_METHOD_MANUALFILL; } else { // disable colorkey autopainting if supported if (xv_atom != None) XvSetPortAttribute(display, ctx->xv_port, xv_atom, 0); } } else // do no colorkey drawing at all ctx->xv_ck_info.method = CK_METHOD_NONE; xv_print_ck_info(vo); return 1; }
int xv_init( xv_handle_t handle, Display *dpy, __u32 fourcc, int width, int height, int bpp ) { unsigned int version, release; unsigned int request_base, event_base, error_base; int i; if( XvQueryExtension( dpy, &version, &release, &request_base, &event_base, &error_base ) != Success ) { #ifdef DEBUG fprintf( stderr, "XvQueryExtension failed\n" ); #endif return -1; } if( XvQueryAdaptors( dpy, DefaultRootWindow( dpy ), &handle->num_adaptors, &handle->p_adaptor_info ) != Success ) { #ifdef DEBUG fprintf( stderr, "XvQueryAdaptors failed\n" ); #endif return -1; } /* printf( "%d adaptors found\n", handle->num_adaptors ); */ if( handle->num_adaptors == 0 ) { return -2; } for( i = 0; i < handle->num_adaptors; i++ ) { /* int format; */ unsigned int num_encodings; XvEncodingInfo *p_encoding_info; int encoding; XvAttribute *at; unsigned int num_attributes; int attribute; XvImageFormatValues *xvimage_formats; unsigned int num_xvimage_formats; int format; #ifdef DEBUG printf( "Adaptor: %d\n", i ); printf( "Name: %s\n", handle->p_adaptor_info[i].name ); printf( "Ports: %lu\n", handle->p_adaptor_info[i].num_ports ); printf( "Formats: %lu\n", handle->p_adaptor_info[i].num_formats ); for( format = 0; format < handle->p_adaptor_info[i].num_formats; format++ ) { printf( "+Format: %d\n", format ); printf( " +Depth: %d\n", handle->p_adaptor_info[i].formats[format].depth ); printf( " +VisualID: %lu\n", handle->p_adaptor_info[i].formats[format].visual_id ); } if( XvQueryEncodings( dpy, handle->p_adaptor_info[i].base_id, &num_encodings, &p_encoding_info ) != Success ) { fprintf( stderr, "XvQueryEncodings failed\n" ); } printf( " +num_encodings: %d\n", num_encodings ); for( encoding = 0; encoding < num_encodings; encoding++ ) { printf( " +Encoding: %d\n", encoding ); printf( " +Name: %s\n", p_encoding_info[encoding].name ); printf( " +Resolution: %lu x %lu\n", p_encoding_info[encoding].width, p_encoding_info[encoding].height ); } #endif //DEBUG at = XvQueryPortAttributes( dpy, handle->p_adaptor_info[i].base_id, &num_attributes ); #ifdef DEBUG printf( "num_attributes: %d\n", num_attributes ); #endif for( attribute = 0; attribute < num_attributes; attribute++ ) { int val; Atom atom; if( !strcmp( at[attribute].name, "XV_COLORKEY" ) ) { #ifdef DEBUG printf( "attribute: %d\n", attribute ); printf( "name: %s\n", at[attribute].name ); #endif atom = (Atom)XInternAtom( dpy, at[attribute].name, 0 ); #ifdef DEBUG printf( "atom: %p\n", atom ); #endif XvGetPortAttribute( dpy, handle->p_adaptor_info[i].base_id, atom, &val ); #ifdef DEBUG printf( "Attribute: %d\n", attribute ); printf( "Name: %s\n", at[attribute].name ); printf( "min: %x\n", at[attribute].min_value ); printf( "max: %x\n", at[attribute].max_value ); printf( "value: %x\n", val ); #endif handle->atom_colorkey = XInternAtom( dpy, at[attribute].name, 0 ); } if( !strcmp( at[attribute].name, "XV_BRIGHTNESS" ) ) { handle->atom_brightness = XInternAtom( dpy, at[attribute].name, 0 ); handle->brightness_min = at[attribute].min_value; handle->brightness_max = at[attribute].max_value; } if( !strcmp( at[attribute].name, "XV_HUE" ) ) { handle->atom_hue = XInternAtom( dpy, at[attribute].name, 0 ); handle->hue_min = at[attribute].min_value; handle->hue_max = at[attribute].max_value; } if( !strcmp( at[attribute].name, "XV_CONTRAST" ) ) { handle->atom_contrast = XInternAtom( dpy, at[attribute].name, 0 ); handle->contrast_min = at[attribute].min_value; handle->contrast_max = at[attribute].max_value; } if( !strcmp( at[attribute].name, "XV_DOUBLE_BUFFER" ) ) { Atom _atom; _atom = XInternAtom( dpy, at[attribute].name, 0 ); XvSetPortAttribute( dpy, handle->p_adaptor_info[i].base_id, _atom, 1 ); #ifdef DEBUG printf( "Xv: DOUBLE_BUFFER available\n" ); #endif } } xvimage_formats = XvListImageFormats( dpy, handle->p_adaptor_info[i].base_id, &num_xvimage_formats ); /* printf( "num_xvimage_formats: %d\n", num_xvimage_formats ); */ for( format = 0; format < num_xvimage_formats; format++ ) { char imageName[5] = {0, 0, 0, 0, 0}; memcpy(imageName, &(xvimage_formats[format].id), 4); #ifdef DEBUG fprintf(stdout, " id: 0x%x", xvimage_formats[format].id); #endif if( isprint( imageName[0]) && isprint(imageName[1]) && isprint( imageName[2]) && isprint(imageName[3])) { #ifdef DEBUG fprintf(stdout, " (%s)\n", imageName); #endif if( xvimage_formats[format].id == fourcc ) { handle->xv_mode_id = fourcc; break; } } else { #ifdef DEBUG fprintf(stdout, "\n"); #endif } } if( handle->xv_mode_id != fourcc ) { return -3; } if( XvGrabPort( dpy, handle->p_adaptor_info[i].base_id, CurrentTime ) != Success ) { /* fprintf( stderr, "Failed to grab port!\n" ); */ return -1; } } handle->use_shm = 1; if( handle->use_shm ) { memset( &handle->shminfo, 0, sizeof( XShmSegmentInfo ) ); handle->image = XvShmCreateImage( dpy, handle->p_adaptor_info[0].base_id, handle->xv_mode_id, (char*)NULL, width, height, &handle->shminfo ); if( handle->image ) { handle->shminfo.shmid = shmget( IPC_PRIVATE, handle->image->data_size, IPC_CREAT | 0777 ); if( handle->shminfo.shmid == -1 ) { /* fprintf( stderr, "shmget failed\n" ); */ return -1; } handle->shminfo.shmaddr = handle->image->data = shmat( handle->shminfo.shmid, 0, 0 ); shmctl(handle->shminfo.shmid, IPC_RMID, 0); /* destroy when we terminate, now if shmat failed */ if( handle->shminfo.shmaddr == ( void * ) -1 ) { /* fprintf( stderr, "shmat failed\n" ); */ return -1; } handle->shminfo.readOnly = False; if( !XShmAttach( dpy, &handle->shminfo ) ) { /* fprintf( stderr, "XShmAttach failed\n" ); */ shmdt( handle->shminfo.shmaddr ); XFree( handle->image ); return -1; } } else { /* fprintf( stderr, "XvShmCreateImage failed\n" ); */ return -1; } } else { char * data = (char*) malloc( width*height*(bpp/8)); handle->image = XvCreateImage( dpy, handle->p_adaptor_info[0].base_id, handle->xv_mode_id, data, width, height ); } handle->display = dpy; return 0; }
static int X11_GetXVideoPort(GF_VideoOutput *vout, u32 pixel_format, Bool check_color) { XWindow *xwin = (XWindow *)vout->opaque; Bool has_color_key = 0; XvAdaptorInfo *adaptors; unsigned int i; unsigned int nb_adaptors; int selected_port; if (XvQueryExtension(xwin->display, &i, &i, &i, &i, &i ) != Success) return -1; if (XvQueryAdaptors(xwin->display, DefaultRootWindow(xwin->display), &nb_adaptors, &adaptors) != Success) return -1; selected_port = -1; for (i=0; i < nb_adaptors; i++) { XvImageFormatValues *formats; int j, num_formats, port; if( !( adaptors[i].type & XvInputMask ) || !(adaptors[i].type & XvImageMask ) ) continue; /* Check for our format... */ formats = XvListImageFormats(xwin->display, adaptors[i].base_id, &num_formats); for (j=0; j<num_formats && (selected_port == -1 ); j++) { XvAttribute *attr; int k, nb_attributes; u32 pformat = X11_GetPixelFormat(formats[j].id); if( !is_same_yuv(pformat, pixel_format) ) continue; /* Grab first port supporting this format */ for (port=adaptors[i].base_id; (port < (int)(adaptors[i].base_id + adaptors[i].num_ports) ) && (selected_port == -1); port++) { if (port==xwin->xvport) continue; attr = XvQueryPortAttributes(xwin->display, port, &nb_attributes); for (k=0; k<nb_attributes; k++ ) { if (!strcmp(attr[k].name, "XV_COLORKEY")) { const Atom ckey = XInternAtom(xwin->display, "XV_COLORKEY", False); XvGetPortAttribute(xwin->display, port, ckey, &vout->overlay_color_key); has_color_key = 1; vout->overlay_color_key |= 0xFF000000; } /* else if (!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) { const Atom paint = XInternAtom(xwin->display, "XV_AUTOPAINT_COLORKEY", False); XvSetPortAttribute(xwin->display, port, paint, 1); } */ } if (check_color && !has_color_key) continue; if (XvGrabPort(xwin->display, port, CurrentTime) == Success) { selected_port = port; xwin->xv_pf_format = formats[j].id; } } if (selected_port == -1 ) continue; } if (formats != NULL) XFree(formats); } if (nb_adaptors > 0) XvFreeAdaptorInfo(adaptors); return selected_port; }
int main(int argc, char **argv) { unsigned int output_width; unsigned int output_height; double acceptable_error; int prompt; Display *display; Window root, window; const unsigned int mc_types[] = {XVMC_MOCOMP | XVMC_MPEG_2}; XvPortID port_num; int surface_type_id; unsigned int is_overlay, intra_unsigned; int colorkey; XvMCContext context; XvMCSurface surface; XvMCBlockArray block_array; XvMCMacroBlockArray mb_array; int mbx, mby, bx, by; XvMCMacroBlock *mb; short *blocks; int quit = 0; ParseArgs(argc, argv, &output_width, &output_height, &acceptable_error, &prompt); display = XOpenDisplay(NULL); if (!GetPort ( display, INPUT_WIDTH, INPUT_HEIGHT, XVMC_CHROMA_FORMAT_420, mc_types, sizeof(mc_types)/sizeof(*mc_types), &port_num, &surface_type_id, &is_overlay, &intra_unsigned )) { XCloseDisplay(display); error(1, 0, "Error, unable to find a good port.\n"); } if (is_overlay) { Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); } root = XDefaultRootWindow(display); window = XCreateSimpleWindow(display, root, 0, 0, output_width, output_height, 0, 0, colorkey); assert(XvMCCreateContext(display, port_num, surface_type_id, INPUT_WIDTH, INPUT_HEIGHT, XVMC_DIRECT, &context) == Success); assert(XvMCCreateSurface(display, &context, &surface) == Success); assert(XvMCCreateBlocks(display, &context, NUM_MACROBLOCKS * BLOCKS_PER_MACROBLOCK, &block_array) == Success); assert(XvMCCreateMacroBlocks(display, &context, NUM_MACROBLOCKS, &mb_array) == Success); mb = mb_array.macro_blocks; blocks = block_array.blocks; for (mby = 0; mby < INPUT_HEIGHT_IN_MACROBLOCKS; ++mby) for (mbx = 0; mbx < INPUT_WIDTH_IN_MACROBLOCKS; ++mbx) { mb->x = mbx; mb->y = mby; mb->macroblock_type = XVMC_MB_TYPE_INTRA; /*mb->motion_type = ;*/ /*mb->motion_vertical_field_select = ;*/ mb->dct_type = XVMC_DCT_TYPE_FRAME; /*mb->PMV[0][0][0] = ; mb->PMV[0][0][1] = ; mb->PMV[0][1][0] = ; mb->PMV[0][1][1] = ; mb->PMV[1][0][0] = ; mb->PMV[1][0][1] = ; mb->PMV[1][1][0] = ; mb->PMV[1][1][1] = ;*/ mb->index = (mby * INPUT_WIDTH_IN_MACROBLOCKS + mbx) * BLOCKS_PER_MACROBLOCK; mb->coded_block_pattern = 0x3F; mb++; for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS; ++by) for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS; ++bx) { const int start = 16, stop = 235, range = stop - start; Gradient ( blocks, (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))), (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))), 1, intra_unsigned ); blocks += BLOCK_SIZE; } for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS / 2; ++by) for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS / 2; ++bx) { const int start = 16, stop = 240, range = stop - start; Gradient ( blocks, (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))), (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))), 1, intra_unsigned ); blocks += BLOCK_SIZE; Gradient ( blocks, (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))), (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))), 1, intra_unsigned ); blocks += BLOCK_SIZE; } } XSelectInput(display, window, ExposureMask | KeyPressMask); XMapWindow(display, window); XSync(display, 0); /* Test NULL context */ assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadContext); /* Test NULL surface */ assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadSurface); /* Test bad picture structure */ assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == BadValue); /* Test valid params */ assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == Success); /* Test NULL surface */ assert(XvMCPutSurface(display, NULL, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE) == XvMCBadSurface); /* Test bad window */ /* XXX: X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */ /*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/ if (prompt) { puts("Press any button to quit..."); while (!quit) { if (XPending(display) > 0) { XEvent event; XNextEvent(display, &event); switch (event.type) { case Expose: { /* Test valid params */ assert ( XvMCPutSurface ( display, &surface, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE ) == Success ); break; } case KeyPress: { quit = 1; break; } } } } } assert(XvMCDestroyBlocks(display, &block_array) == Success); assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success); assert(XvMCDestroySurface(display, &surface) == Success); assert(XvMCDestroyContext(display, &context) == Success); XvUngrabPort(display, port_num, CurrentTime); XDestroyWindow(display, window); XCloseDisplay(display); return 0; }
int main(int argc, char **argv) { const unsigned int width = 16, height = 16; const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; const unsigned int subpic_width = 16, subpic_height = 16; Display *display; XvPortID port_num; int surface_type_id; unsigned int is_overlay, intra_unsigned; int colorkey; XvMCContext context; XvImageFormatValues *subpics; int num_subpics; XvMCSubpicture subpicture = {0}; int i; display = XOpenDisplay(NULL); if (!GetPort ( display, width, height, XVMC_CHROMA_FORMAT_420, mc_types, 2, &port_num, &surface_type_id, &is_overlay, &intra_unsigned )) { XCloseDisplay(display); fprintf(stderr, "Error, unable to find a good port.\n"); exit(1); } if (is_overlay) { Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); } assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success); subpics = XvMCListSubpictureTypes(display, port_num, surface_type_id, &num_subpics); assert((subpics && num_subpics) > 0 || (!subpics && num_subpics == 0)); for (i = 0; i < num_subpics; ++i) { printf("Subpicture %d:\n", i); printf("\tid: 0x%08x\n", subpics[i].id); printf("\ttype: %s\n", subpics[i].type == XvRGB ? "XvRGB" : (subpics[i].type == XvYUV ? "XvYUV" : "Unknown")); printf("\tbyte_order: %s\n", subpics[i].byte_order == LSBFirst ? "LSB First" : (subpics[i].byte_order == MSBFirst ? "MSB First" : "Unknown")); PrintGUID(subpics[i].guid); printf("\tbpp: %u\n", subpics[i].bits_per_pixel); printf("\tformat: %s\n", subpics[i].format == XvPacked ? "XvPacked" : (subpics[i].format == XvPlanar ? "XvPlanar" : "Unknown")); printf("\tnum_planes: %u\n", subpics[i].num_planes); if (subpics[i].type == XvRGB) { printf("\tdepth: %u\n", subpics[i].depth); printf("\tred_mask: 0x%08x\n", subpics[i].red_mask); printf("\tgreen_mask: 0x%08x\n", subpics[i].green_mask); printf("\tblue_mask: 0x%08x\n", subpics[i].blue_mask); } else if (subpics[i].type == XvYUV) { printf("\ty_sample_bits: %u\n", subpics[i].y_sample_bits); printf("\tu_sample_bits: %u\n", subpics[i].u_sample_bits); printf("\tv_sample_bits: %u\n", subpics[i].v_sample_bits); printf("\thorz_y_period: %u\n", subpics[i].horz_y_period); printf("\thorz_u_period: %u\n", subpics[i].horz_u_period); printf("\thorz_v_period: %u\n", subpics[i].horz_v_period); printf("\tvert_y_period: %u\n", subpics[i].vert_y_period); printf("\tvert_u_period: %u\n", subpics[i].vert_u_period); printf("\tvert_v_period: %u\n", subpics[i].vert_v_period); } PrintComponentOrder(subpics[i].component_order); printf("\tscanline_order: %s\n", subpics[i].scanline_order == XvTopToBottom ? "XvTopToBottom" : (subpics[i].scanline_order == XvBottomToTop ? "XvBottomToTop" : "Unknown")); } if (num_subpics == 0) { printf("Subpictures not supported, nothing to test.\n"); return 0; } /* Test NULL context */ assert(XvMCCreateSubpicture(display, NULL, &subpicture, subpic_width, subpic_height, subpics[0].id) == XvMCBadContext); /* Test NULL subpicture */ assert(XvMCCreateSubpicture(display, &context, NULL, subpic_width, subpic_height, subpics[0].id) == XvMCBadSubpicture); /* Test invalid subpicture */ assert(XvMCCreateSubpicture(display, &context, &subpicture, subpic_width, subpic_height, -1) == BadMatch); /* Test huge width */ assert(XvMCCreateSubpicture(display, &context, &subpicture, 16384, subpic_height, subpics[0].id) == BadValue); /* Test huge height */ assert(XvMCCreateSubpicture(display, &context, &subpicture, subpic_width, 16384, subpics[0].id) == BadValue); /* Test huge width & height */ assert(XvMCCreateSubpicture(display, &context, &subpicture, 16384, 16384, subpics[0].id) == BadValue); for (i = 0; i < num_subpics; ++i) { /* Test valid params */ assert(XvMCCreateSubpicture(display, &context, &subpicture, subpic_width, subpic_height, subpics[i].id) == Success); /* Test subpicture id assigned */ assert(subpicture.subpicture_id != 0); /* Test context id assigned and correct */ assert(subpicture.context_id == context.context_id); /* Test subpicture type id assigned and correct */ assert(subpicture.xvimage_id == subpics[i].id); /* Test width & height assigned and correct */ assert(subpicture.width == width && subpicture.height == height); if (subpics[i].type == XvRGB) /* Test no palette support */ assert(subpicture.num_palette_entries == 0 && subpicture.entry_bytes == 0); else /* Test palette support */ assert(subpicture.num_palette_entries == 16 && subpicture.entry_bytes == 4); /* Test valid params */ assert(XvMCDestroySubpicture(display, &subpicture) == Success); } /* Test NULL surface */ assert(XvMCDestroySubpicture(display, NULL) == XvMCBadSubpicture); assert(XvMCDestroyContext(display, &context) == Success); free(subpics); XvUngrabPort(display, port_num, CurrentTime); XCloseDisplay(display); return 0; }
int main(int argc, char *argv[]) { Display *dpy; unsigned int ver, rev, eventB, reqB, errorB; int i, j, k, n; unsigned int nencode, nadaptors; int nscreens, nattr, numImages; XvAdaptorInfo *ainfo; XvAttribute *attributes; XvEncodingInfo *encodings; XvFormat *format; XvImageFormatValues *formats; char *disname = NULL; char shortmode = 0; if ((argc > 4)) PrintUsage(); if (argc != 1) { for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-display")) { disname = argv[i + 1]; i++; } else if (!strcmp(argv[i], "-short")) shortmode = 1; else if (!strcmp(argv[i], "-version")) { printf("%s\n", PACKAGE_STRING); exit(0); } else { PrintUsage(); } } } if (!(dpy = XOpenDisplay(disname))) { fprintf(stderr, "xvinfo: Unable to open display %s\n", (disname != NULL) ? disname : XDisplayName(NULL)); exit(-1); } if ((Success != XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB))) { fprintf(stderr, "xvinfo: No X-Video Extension on %s\n", (disname != NULL) ? disname : XDisplayName(NULL)); exit(0); } else { fprintf(stdout, "X-Video Extension version %i.%i\n", ver, rev); } nscreens = ScreenCount(dpy); for (i = 0; i < nscreens; i++) { fprintf(stdout, "screen #%i\n", i); XvQueryAdaptors(dpy, RootWindow(dpy, i), &nadaptors, &ainfo); if (!nadaptors) { fprintf(stdout, " no adaptors present\n"); continue; } for (j = 0; j < nadaptors; j++) { fprintf(stdout, " Adaptor #%i: \"%s\"\n", j, ainfo[j].name); fprintf(stdout, " number of ports: %li\n", ainfo[j].num_ports); fprintf(stdout, " port base: %li\n", ainfo[j].base_id); fprintf(stdout, " operations supported: "); switch (ainfo[j].type & (XvInputMask | XvOutputMask)) { case XvInputMask: if (ainfo[j].type & XvVideoMask) fprintf(stdout, "PutVideo "); if (ainfo[j].type & XvStillMask) fprintf(stdout, "PutStill "); if (ainfo[j].type & XvImageMask) fprintf(stdout, "PutImage "); break; case XvOutputMask: if (ainfo[j].type & XvVideoMask) fprintf(stdout, "GetVideo "); if (ainfo[j].type & XvStillMask) fprintf(stdout, "GetStill "); break; default: fprintf(stdout, "none "); break; } fprintf(stdout, "\n"); format = ainfo[j].formats; if (!shortmode) { fprintf(stdout, " supported visuals:\n"); for (k = 0; k < ainfo[j].num_formats; k++, format++) { fprintf(stdout, " depth %i, visualID 0x%2lx\n", format->depth, format->visual_id); } } attributes = XvQueryPortAttributes(dpy, ainfo[j].base_id, &nattr); if (attributes && nattr) { fprintf(stdout, " number of attributes: %i\n", nattr); for (k = 0; k < nattr; k++) { fprintf(stdout, " \"%s\" (range %i to %i)\n", attributes[k].name, attributes[k].min_value, attributes[k].max_value); if (attributes[k].flags & XvSettable) { if (!shortmode) fprintf(stdout, " client settable attribute\n"); else fprintf(stdout, " settable"); } if (attributes[k].flags & XvGettable) { Atom the_atom; int value; if (!shortmode) fprintf(stdout, " client gettable attribute"); else fprintf(stdout, ", gettable"); the_atom = XInternAtom(dpy, attributes[k].name, True); if (the_atom != None) { if ((Success == XvGetPortAttribute(dpy, ainfo[j].base_id, the_atom, &value))) fprintf(stdout, " (current value is %i)", value); } fprintf(stdout, "\n"); } else if (shortmode) fprintf(stdout, "\n"); } XFree(attributes); } else { fprintf(stdout, " no port attributes defined\n"); } XvQueryEncodings(dpy, ainfo[j].base_id, &nencode, &encodings); if (encodings && nencode) { int ImageEncodings = 0; for (n = 0; n < nencode; n++) { if (!strcmp(encodings[n].name, "XV_IMAGE")) ImageEncodings++; } if (nencode - ImageEncodings) { fprintf(stdout, " number of encodings: %i\n", nencode - ImageEncodings); for (n = 0; n < nencode; n++) { if (strcmp(encodings[n].name, "XV_IMAGE")) { fprintf(stdout, " encoding ID #%li: \"%s\"\n", encodings[n].encoding_id, encodings[n].name); fprintf(stdout, " size: %li x %li\n", encodings[n].width, encodings[n].height); fprintf(stdout, " rate: %f\n", (float) encodings[n].rate.numerator / (float) encodings[n].rate.denominator); } } } if (ImageEncodings && (ainfo[j].type & XvImageMask)) { char imageName[5]; for (n = 0; n < nencode; n++) { if (!strcmp(encodings[n].name, "XV_IMAGE")) { fprintf(stdout, " maximum XvImage size: %li x %li\n", encodings[n].width, encodings[n].height); break; } } formats = XvListImageFormats(dpy, ainfo[j].base_id, &numImages); fprintf(stdout, " Number of image formats: %i\n", numImages); for (n = 0; n < numImages; n++) { sprintf(imageName, "%c%c%c%c", formats[n].id & 0xff, (formats[n].id >> 8) & 0xff, (formats[n].id >> 16) & 0xff, (formats[n].id >> 24) & 0xff); fprintf(stdout, " id: 0x%x", formats[n].id); if (isprint(imageName[0]) && isprint(imageName[1]) && isprint(imageName[2]) && isprint(imageName[3])) { fprintf(stdout, " (%s)\n", imageName); } else { fprintf(stdout, "\n"); } if (!shortmode) { fprintf(stdout, " guid: "); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[0]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[1]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[2]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[3]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[4]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[5]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[6]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[7]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[8]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[9]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[10]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[11]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[12]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[13]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[14]); fprintf(stdout, "%02x\n", (unsigned char) formats[n].guid[15]); fprintf(stdout, " bits per pixel: %i\n", formats[n].bits_per_pixel); fprintf(stdout, " number of planes: %i\n", formats[n].num_planes); fprintf(stdout, " type: %s (%s)\n", (formats[n].type == XvRGB) ? "RGB" : "YUV", (formats[n].format == XvPacked) ? "packed" : "planar"); if (formats[n].type == XvRGB) { fprintf(stdout, " depth: %i\n", formats[n].depth); fprintf(stdout, " red, green, blue masks: " "0x%x, 0x%x, 0x%x\n", formats[n].red_mask, formats[n].green_mask, formats[n].blue_mask); } else { } } } if (formats) XFree(formats); } XvFreeEncodingInfo(encodings); } }
int main(int argc, char **argv) { const unsigned int width = 16, height = 16; const unsigned int min_required_blocks = 1, min_required_macroblocks = 1; const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; Display *display; XvPortID port_num; int surface_type_id; unsigned int is_overlay, intra_unsigned; int colorkey; XvMCContext context; XvMCSurface surface; XvMCBlockArray blocks = {0}; XvMCMacroBlockArray macroblocks = {0}; display = XOpenDisplay(NULL); if (!GetPort ( display, width, height, XVMC_CHROMA_FORMAT_420, mc_types, 2, &port_num, &surface_type_id, &is_overlay, &intra_unsigned )) { XCloseDisplay(display); error(1, 0, "Error, unable to find a good port.\n"); } if (is_overlay) { Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); } assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success); assert(XvMCCreateSurface(display, &context, &surface) == Success); /* Test NULL context */ assert(XvMCCreateBlocks(display, NULL, 1, &blocks) == XvMCBadContext); /* Test 0 blocks */ assert(XvMCCreateBlocks(display, &context, 0, &blocks) == BadValue); /* Test valid params */ assert(XvMCCreateBlocks(display, &context, min_required_blocks, &blocks) == Success); /* Test context id assigned and correct */ assert(blocks.context_id == context.context_id); /* Test number of blocks assigned and correct */ assert(blocks.num_blocks == min_required_blocks); /* Test block pointer valid */ assert(blocks.blocks != NULL); /* Test NULL context */ assert(XvMCCreateMacroBlocks(display, NULL, 1, ¯oblocks) == XvMCBadContext); /* Test 0 macroblocks */ assert(XvMCCreateMacroBlocks(display, &context, 0, ¯oblocks) == BadValue); /* Test valid params */ assert(XvMCCreateMacroBlocks(display, &context, min_required_macroblocks, ¯oblocks) == Success); /* Test context id assigned and correct */ assert(macroblocks.context_id == context.context_id); /* Test macroblock pointer valid */ assert(macroblocks.macro_blocks != NULL); /* Test valid params */ assert(XvMCDestroyMacroBlocks(display, ¯oblocks) == Success); /* Test valid params */ assert(XvMCDestroyBlocks(display, &blocks) == Success); assert(XvMCDestroySurface(display, &surface) == Success); assert(XvMCDestroyContext(display, &context) == Success); XvUngrabPort(display, port_num, CurrentTime); XCloseDisplay(display); return 0; }
static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT* vevent) { int i; BYTE* data1; BYTE* data2; UINT32 pixfmt; UINT32 xvpixfmt; BOOL converti420yv12 = FALSE; XvImage * image; int colorkey = 0; XShmSegmentInfo shminfo; xfXvContext* xv = (xfXvContext*) xfi->xv_context; if (xv->xv_port == 0) return; /* In case the player is minimized */ if (vevent->x < -2048 || vevent->y < -2048 || vevent->num_visible_rects <= 0) return; if (xv->xv_colorkey_atom != None) { XvGetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, &colorkey); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, colorkey); for (i = 0; i < vevent->num_visible_rects; i++) { XFillRectangle(xfi->display, xfi->window->handle, xfi->gc, vevent->x + vevent->visible_rects[i].x, vevent->y + vevent->visible_rects[i].y, vevent->visible_rects[i].width, vevent->visible_rects[i].height); } } else { XSetClipRectangles(xfi->display, xfi->gc, vevent->x, vevent->y, (XRectangle*) vevent->visible_rects, vevent->num_visible_rects, YXBanded); } pixfmt = vevent->frame_pixfmt; if (xf_tsmf_is_format_supported(xv, pixfmt)) { xvpixfmt = pixfmt; } else if (pixfmt == RDP_PIXFMT_I420 && xf_tsmf_is_format_supported(xv, RDP_PIXFMT_YV12)) { xvpixfmt = RDP_PIXFMT_YV12; converti420yv12 = TRUE; } else if (pixfmt == RDP_PIXFMT_YV12 && xf_tsmf_is_format_supported(xv, RDP_PIXFMT_I420)) { xvpixfmt = RDP_PIXFMT_I420; converti420yv12 = TRUE; } else { DEBUG_XV("pixel format 0x%X not supported by hardware.", pixfmt); return; } image = XvShmCreateImage(xfi->display, xv->xv_port, xvpixfmt, 0, vevent->frame_width, vevent->frame_height, &shminfo); if (xv->xv_image_size != image->data_size) { if (xv->xv_image_size > 0) { shmdt(xv->xv_shmaddr); shmctl(xv->xv_shmid, IPC_RMID, NULL); } xv->xv_image_size = image->data_size; xv->xv_shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); xv->xv_shmaddr = shmat(xv->xv_shmid, 0, 0); } shminfo.shmid = xv->xv_shmid; shminfo.shmaddr = image->data = xv->xv_shmaddr; shminfo.readOnly = FALSE; if (!XShmAttach(xfi->display, &shminfo)) { XFree(image); DEBUG_XV("XShmAttach failed."); return; } /* The video driver may align each line to a different size and we need to convert our original image data. */ switch (pixfmt) { case RDP_PIXFMT_I420: case RDP_PIXFMT_YV12: /* Y */ if (image->pitches[0] == vevent->frame_width) { memcpy(image->data + image->offsets[0], vevent->frame_data, vevent->frame_width * vevent->frame_height); } else { for (i = 0; i < vevent->frame_height; i++) { memcpy(image->data + image->offsets[0] + i * image->pitches[0], vevent->frame_data + i * vevent->frame_width, vevent->frame_width); } } /* UV */ /* Conversion between I420 and YV12 is to simply swap U and V */ if (converti420yv12 == FALSE) { data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; } else { data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height; data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height + vevent->frame_width * vevent->frame_height / 4; image->id = pixfmt == RDP_PIXFMT_I420 ? RDP_PIXFMT_YV12 : RDP_PIXFMT_I420; } if (image->pitches[1] * 2 == vevent->frame_width) { memcpy(image->data + image->offsets[1], data1, vevent->frame_width * vevent->frame_height / 4); memcpy(image->data + image->offsets[2], data2, vevent->frame_width * vevent->frame_height / 4); } else { for (i = 0; i < vevent->frame_height / 2; i++) { memcpy(image->data + image->offsets[1] + i * image->pitches[1], data1 + i * vevent->frame_width / 2, vevent->frame_width / 2); memcpy(image->data + image->offsets[2] + i * image->pitches[2], data2 + i * vevent->frame_width / 2, vevent->frame_width / 2); } } break; default: memcpy(image->data, vevent->frame_data, image->data_size <= vevent->frame_size ? image->data_size : vevent->frame_size); break; } XvShmPutImage(xfi->display, xv->xv_port, xfi->window->handle, xfi->gc, image, 0, 0, image->width, image->height, vevent->x, vevent->y, vevent->width, vevent->height, FALSE); if (xv->xv_colorkey_atom == None) XSetClipMask(xfi->display, xfi->gc, None); XSync(xfi->display, FALSE); XShmDetach(xfi->display, &shminfo); XFree(image); }