bool prepareImage(int w, int h) { if (xv_image_width == w && xv_image_height == h && xv_image) return true; xv_image_width = w; xv_image_height = h; #ifdef _XSHM_H_ if (use_shm) { xv_image = XvShmCreateImage(display, xv_port, format_id, 0, xv_image_width, xv_image_height, &shm); shm.shmid = shmget(IPC_PRIVATE, xv_image->data_size, IPC_CREAT | 0777); if (shm.shmid < 0) { qCritical("get shm failed. try to use none shm"); use_shm = false; } else { shm.shmaddr = (char *)shmat(shm.shmid, 0, 0); xv_image->data = shm.shmaddr; shm.readOnly = 0; if (XShmAttach(display, &shm)) { XSync(display, false); shmctl(shm.shmid, IPC_RMID, 0); } else { qCritical("Attach to shm failed! try to use none shm"); use_shm = false; } } } #endif //_XSHM_H_ if (!use_shm) { xv_image = XvCreateImage(display, xv_port, format_id, 0, xv_image_width, xv_image_height); // malloc if use copy (e.g. shm) xv_image->data = (char*)malloc(xv_image->data_size); } return true; }
static GF_Err X11_InitOverlay(GF_VideoOutput *vout, u32 VideoWidth, u32 VideoHeight) { XWindow *xwin = (XWindow *)vout->opaque; if (xwin->overlay && (VideoWidth<=xwin->overlay->width) && (VideoHeight<=xwin->overlay->height)) { return GF_OK; } X11_DestroyOverlay(xwin); xwin->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0); if (xwin->xvport<0) xwin->xvport = X11_GetXVideoPort(vout, GF_PIXEL_YUY2, 0); if (xwin->xvport<0) { return GF_NOT_SUPPORTED; } /* Create overlay image */ xwin->overlay = XvCreateImage(xwin->display, xwin->xvport, xwin->xv_pf_format, NULL, VideoWidth, VideoHeight); if (!xwin->overlay) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Xv Overlay Creation Failure\n")); return GF_IO_ERR; } GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Overlay init %d x %d - pixel format %s - XV port %d\n", VideoWidth, VideoHeight, gf_4cc_to_str(vout->yuv_pixel_format), xwin->xvport )); return GF_OK; }
void display_frame() { if (!freeze && adaptor >= 0) { // copy into frame buffer for display for (int i = 0; i < numCameras; i++) { if (sync_display && i==0) { rgb2yuy2((unsigned char *) async_display_image->imageData, frame_buffer + (i * frame_length), (device_width * device_height)); } else { rgb2yuy2((unsigned char *) iplImages[i]->imageData, frame_buffer + (i * frame_length), (device_width * device_height)); } } xv_image = XvCreateImage(display, info[adaptor].base_id, format, (char*) frame_buffer, device_width, device_height * numCameras); XvPutImage(display, info[adaptor].base_id, window, gc, xv_image, 0, 0, device_width, device_height * numCameras, 0, 0, width, height); xv_image = NULL; } XFlush(display); }
static int xv_alloc_frame( void ) { int size; uint8_t *alloc; size = input_width * input_height * 2; if( use_shm ) { alloc = create_shm( size ); } else { alloc = malloc( input_width * input_height * 2 ); } if( alloc ) { /* Initialize the input image to black. */ blit_colour_packed422_scanline( alloc, input_width * input_height, 16, 128, 128 ); if( use_shm ) { image = XvShmCreateImage( display, xv_port, FOURCC_YUY2, (char *) alloc, input_width, input_height, &shminfo ); } else { image = XvCreateImage( display, xv_port, FOURCC_YUY2, (char *) alloc, input_width, input_height ); } image_data = alloc; return 1; } return 0; }
/* * Function: XvMCCreateSurface */ _X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context, XvMCSurface * surface) { Status ret; int priv_count; CARD32 *priv_data; intel_xvmc_surface_ptr intel_surf = NULL; struct intel_xvmc_context *intel_ctx; if (!display || !context) return XvMCBadContext; if (!surface) return XvMCBadSurface; intel_ctx = context->privData; if ((ret = _xvmc_create_surface(display, context, surface, &priv_count, &priv_data))) { XVMC_ERR("Unable to create XvMCSurface."); return ret; } XFree(priv_data); surface->privData = calloc(1, sizeof(struct intel_xvmc_surface)); if (!(intel_surf = surface->privData)) { PPTHREAD_MUTEX_UNLOCK(); return BadAlloc; } intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface", intel_ctx->surface_bo_size, GTT_PAGE_SIZE); if (!intel_surf->bo) { free(intel_surf); return BadAlloc; } drm_intel_bo_disable_reuse(intel_surf->bo); intel_surf = surface->privData; intel_surf->context = context; intel_surf->image = XvCreateImage(display, context->port, FOURCC_XVMC, (char *) &intel_surf->gem_handle, surface->width, surface->height); if (!intel_surf->image) { XVMC_ERR("Can't create XvImage for surface\n"); free(intel_surf); _xvmc_destroy_surface(display, surface); return BadAlloc; } return Success; }
GF_Err X11_Blit(struct _video_out *vout, GF_VideoSurface *video_src, GF_Window *src, GF_Window *dest, u32 overlay_type) { XvImage *overlay; int xvport; Drawable dst_dr; GF_Err e; Window cur_wnd; XWindow *xwin = (XWindow *)vout->opaque; if (!video_src) { if (overlay_type && xwin->xvport) { } return GF_OK; } if (video_src->pixel_format != GF_PIXEL_YV12) return GF_NOT_SUPPORTED; cur_wnd = xwin->fullscreen ? xwin->full_wnd : xwin->wnd; /*init if needed*/ if ((xwin->xvport<0) || !xwin->overlay) { e = X11_InitOverlay(vout, video_src->width, video_src->height); if (e) return e; } /*different size, recreate an image*/ if ((xwin->overlay->width != video_src->width) || (xwin->overlay->height != video_src->height)) { if (xwin->overlay) XFree(xwin->overlay); xwin->overlay = XvCreateImage(xwin->display, xwin->xvport, xwin->xv_pf_format, NULL, video_src->width, video_src->height); if (!xwin->overlay) return GF_IO_ERR; } GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[X11] Blit surface to dest %d x %d - overlay type %s\n", dest->w, dest->h, (overlay_type==0)? "none" : ((overlay_type==1) ? "Top-Level" : "ColorKey") )); overlay = xwin->overlay; xvport = xwin->xvport; overlay->data = video_src->video_buffer; overlay->num_planes = 3; overlay->pitches[0] = video_src->width; overlay->pitches[1] = xwin->overlay->pitches[2] = video_src->width/2; overlay->offsets[0] = 0; overlay->offsets[1] = video_src->width*video_src->height; overlay->offsets[2] = 5*video_src->width*video_src->height/4; dst_dr = cur_wnd; if (!overlay_type) { if (!xwin->pixmap) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Back buffer not configured for Blt\n")); return GF_BAD_PARAM; } dst_dr = xwin->pixmap; } XvPutImage(xwin->display, xvport, dst_dr, xwin->the_gc, overlay, src->x, src->y, src->w, src->h, dest->x, dest->y, dest->w, dest->h); return GF_OK; }
XvImage* create_yuv_image(Display* display, XvPortID port, fourcc_t format, int width, int height, XShmSegmentInfo* shminfo) { XvImage* image; if (shminfo) { if (!(image = XvShmCreateImage(display, port, format.id, NULL, width, height, shminfo))) { printf("Unable to create shm XvImage\n"); return NULL; } if ((shminfo->shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777)) == -1) { printf("Unable to allocate shared memory\n"); XFree(image); return NULL; } if (!(shminfo->shmaddr = shmat(shminfo->shmid, 0, 0))) { printf("Unable to attach shared memory\n"); XFree(image); shmctl(shminfo->shmid, IPC_RMID, 0); return NULL; } shminfo->readOnly = False; image->data = shminfo->shmaddr; if (!XShmAttach(display, shminfo)) { printf("XShmAttach failed\n"); XFree(image); shmctl(shminfo->shmid, IPC_RMID, 0); shmdt(shminfo->shmaddr); return NULL; } /* Send image to X server. This instruction is required, since having * built a Shm XImage and not using it causes an error on XCloseDisplay. */ XSync(display, False); /* Mark the segment to be automatically removed when the last attachment is broken (i.e. on shmdt or process exit). */ shmctl(shminfo->shmid, IPC_RMID, 0); } else { if (!(image = XvCreateImage(display, port, format.id, NULL, width, height))) { printf("Unable to create XvImage\n"); return NULL; } image->data = malloc(image->data_size); } return image; }
static bool allocate_xvimage(struct vo *vo, int foo) { struct xvctx *ctx = vo->priv; struct vo_x11_state *x11 = vo->x11; // align it for faster OSD rendering (draw_bmp.c swscale usage) int aligned_w = FFALIGN(ctx->image_width, 32); #if HAVE_SHM if (x11->display_is_local && XShmQueryExtension(x11->display)) { ctx->Shmem_Flag = 1; x11->ShmCompletionEvent = XShmGetEventBase(x11->display) + ShmCompletion; } else { ctx->Shmem_Flag = 0; MP_INFO(vo, "Shared memory not supported\nReverting to normal Xv.\n"); } if (ctx->Shmem_Flag) { ctx->xvimage[foo] = (XvImage *) XvShmCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height, &ctx->Shminfo[foo]); if (!ctx->xvimage[foo]) return false; ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE, ctx->xvimage[foo]->data_size, IPC_CREAT | 0777); ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, 0); if (ctx->Shminfo[foo].shmaddr == (void *)-1) return false; ctx->Shminfo[foo].readOnly = False; ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; XShmAttach(x11->display, &ctx->Shminfo[foo]); XSync(x11->display, False); shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { ctx->xvimage[foo] = (XvImage *) XvCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height); if (!ctx->xvimage[foo]) return false; ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size); if (!ctx->xvimage[foo]->data) return false; XSync(x11->display, False); } struct mp_image img = get_xv_buffer(vo, foo); img.w = aligned_w; mp_image_clear(&img, 0, 0, img.w, img.h); return true; }
void display_frames() { uint32_t i; if(!freeze && adaptor>=0){ for (i = 0; i < numCameras; i++) { if (!frames[i]) continue; switch (res) { case DC1394_VIDEO_MODE_640x480_YUV411: iyu12yuy2( frames[i]->image, (unsigned char *)(frame_buffer + (i * frame_length)), (device_width*device_height) ); break; case DC1394_VIDEO_MODE_320x240_YUV422: case DC1394_VIDEO_MODE_640x480_YUV422: memcpy( frame_buffer + (i * frame_length), frames[i]->image, device_width*device_height*2); break; case DC1394_VIDEO_MODE_640x480_RGB8: rgb2yuy2( frames[i]->image, (unsigned char *) (frame_buffer + (i * frame_length)), (device_width*device_height) ); break; } } xv_image=XvCreateImage(display,info[adaptor].base_id,format,frame_buffer, device_width,device_height* numCameras); //xv_image=XvCreateImage(display,info[adaptor].base_id,format,frame_buffer, // device_width, device_height* numCameras); XvPutImage(display,info[adaptor].base_id,window,gc,xv_image, 0,0,device_width ,device_height * numCameras, 0,0,width,height); /* XvPutImage(display,info[adaptor].base_id,window,gc,xv_image, 0,0,device_width * numCameras, device_height , 0,0,width, height);*/ /*XvPutImage(display,info[adaptor].base_id,window,gc,xv_image, 0,0,device_width , device_height * numCameras, 0,0,width, height);*/ xv_image=NULL; } }
bool QX11VideoSurface::start(const QVideoSurfaceFormat &format) { if (m_image) XFree(m_image); int xvFormatId = 0; for (int i = 0; i < m_supportedPixelFormats.count(); ++i) { if (m_supportedPixelFormats.at(i) == format.pixelFormat()) { xvFormatId = m_formatIds.at(i); break; } } if (xvFormatId == 0) { setError(UnsupportedFormatError); } else { XvImage *image = XvCreateImage( QX11Info::display(), m_portId, xvFormatId, 0, format.frameWidth(), format.frameHeight()); if (!image) { setError(ResourceError); } else { m_viewport = format.viewport(); m_image = image; QVideoSurfaceFormat newFormat = format; newFormat.setProperty("portId", QVariant(quint64(m_portId))); newFormat.setProperty("xvFormatId", xvFormatId); newFormat.setProperty("dataSize", image->data_size); return QAbstractVideoSurface::start(newFormat); } } if (m_image) { m_image = 0; QAbstractVideoSurface::stop(); } return false; }
bool X11Renderer::InitVideoXv() { XvAdaptorInfo *ai; uint32_t adaptors; XvPortID xvP; int ret; ret = XvQueryAdaptors(m_pDisplay, DefaultRootWindow(m_pDisplay), &adaptors, &ai); if (ret != Success) { ERROR("XvQueryAdaptors failed"); return false; } REND_DBG("adaptors: %d", adaptors); m_Port = 0; for (unsigned int i = 0; i < adaptors; i++) { REND_DBG("adaptor %d", adaptors); if ((ai[i].type & ( XvInputMask | XvImageMask)) == (XvInputMask | XvImageMask)) { for (xvP = ai[i].base_id; xvP<ai[i].base_id+ai[i].num_ports; xvP++ ) { REND_DBG("Port %d", xvP); if (XvGrabPort( m_pDisplay, xvP, CurrentTime ) == Success) { m_Port = xvP; REND_DBG("Got port %d\n", m_Port); break; } } if ( m_Port != 0 ) break; } } XvFreeAdaptorInfo(ai); if (!m_Port) { ERROR("Failed to grab port"); return false; } m_pXvImage = XvCreateImage(m_pDisplay, m_Port, GUID_I420_PLANAR, NULL, m_VPar.width, m_VPar.height); if (!m_pXvImage) { ERROR("XvCreateImage failed"); return false; } REND_DBG("Image data: 0x%x, size: %d", m_pXvImage->data, m_pXvImage->data_size); return true; }
XvImage * XvShmCreateImage ( Display *dpy, XvPortID port, int id, char *data, int width, int height, XShmSegmentInfo *shminfo ){ XvImage *ret; ret = XvCreateImage(dpy, port, id, data, width, height); if(ret) ret->obdata = (XPointer)shminfo; return ret; }
BC_XvImage::BC_XvImage(BC_Bitmap *bitmap, int index, int w, int h, int color_model) : BC_BitmapImage(bitmap, index) { Display *display = top_level->display; int id = BC_CModels::bc_to_x(color_model); xv_image = XvCreateImage(display, bitmap->xv_portid, id, 0, w, h); dataSize = xv_image->data_size; data = new unsigned char[dataSize + 8]; xv_image->data = (char *) data; w = xv_image->width; h = xv_image->height; if( color_model == BC_YUV422 ) { int bytesPerLine = w*2; row_data = new unsigned char*[h]; for( int i=0; i<h; ++i ) row_data[i] = &data[i*bytesPerLine]; } }
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; }
void ffmpegWidget::updateScalefactor() { /* Width or height of window has changed, so update scale */ this->widgetW = width(); this->widgetH = height(); /* Work out which is the minimum ratio to scale by */ double wratio = this->widgetW / (double) _imW; double hratio = this->widgetH / (double) _imH; double sf = pow(10, (double) (_zoom)/ 20) * qMin(wratio, hratio); /* Now work out the scaled dimensions */ _scImW = (int) (_imW*sf + 0.5); emit scImWChanged(_scImW); _scImH = (int) (_imH*sf + 0.5); emit scImHChanged(_scImH); _scVisW = qMin(_scImW, this->widgetW); emit scVisWChanged(_scVisW); _scVisH = qMin(_scImH, this->widgetH); emit scVisHChanged(_scVisH); /* Now work out how much of the original image is visible */ if (_scVisW < this->widgetW) { _visW = _imW; } else { _visW = qMin((int) (this->widgetW / sf + 0.5), _imW); } emit visWChanged(_visW); emit visWChanged(QString("%1").arg(_visW)); if (_scVisH < this->widgetH) { _visH = _imH; } else { _visH = qMin((int) (this->widgetH / sf + 0.5), _imH); } emit visHChanged(_visH); emit visHChanged(QString("%1").arg(_visH)); /* Now work out our real scale factors */ this->sfx = _scVisW / (double) _visW; this->sfy = _scVisH / (double) _visH; /* Now work out max x and y */; int maxX = qMax(_imW - _visW, 0); int maxY = qMax(_imH - _visH, 0); disableUpdates = true; if (_maxX != maxX) { _maxX = maxX; emit maxXChanged(_maxX); setX(qMin(_x, _maxX)); } if (_maxY != maxY) { _maxY = maxY; emit maxYChanged(_maxY); setY(qMin(_y, _maxY)); } disableUpdates = false; /* Now make an image */ if (this->xv_format >= 0) { // xvideo supported if (this->xv_image) XFree(this->xv_image); this->xv_image = XvCreateImage(this->dpy, this->xv_port, this->xv_format, 0, _imW, _imH); assert(this->xv_image); /* Clear area not filled by image */ if (_scVisW < this->widgetW) { XClearArea(dpy, w, _scVisW, 0, this->widgetW-_scVisW, this->widgetH, 0); } if (_scVisH < this->widgetH) { XClearArea(dpy, w, 0, _scVisH, this->widgetW, this->widgetH-_scVisH, 0); } } }
int XVWindow::Init (Display* dp, Window rootWindow, GC gc, int x, int y, int windowWidth, int windowHeight, int imageWidth, int imageHeight) { // local variables needed for creation of window // and initialization of XV extension unsigned int ver = 0; unsigned int rel = 0; unsigned int req = 0; unsigned int ev = 0; unsigned int err = 0; int ret = 0; unsigned int i = 0; _display = dp; _rootWindow = rootWindow; _imageWidth = imageWidth; _imageHeight = imageHeight; PTRACE(4, "XVideo\tInitializing XV window with " << windowWidth << "x" << windowHeight << " at " << x << "," << y); XLockDisplay (_display); // check if SHM XV window is possible ret = XvQueryExtension (_display, &ver, &rel, &req, &ev, &err); PTRACE(4, "XVideo\tXvQueryExtension: Version: " << ver << " Release: " << rel << " Request Base: " << req << " Event Base: " << ev << " Error Base: " << err ); if (Success != ret) { if (ret == XvBadExtension) PTRACE(1, "XVideo\tXvQueryExtension failed - XvBadExtension"); else if (ret == XvBadAlloc) PTRACE(1, "XVideo\tXvQueryExtension failed - XvBadAlloc"); else PTRACE(1, "XVideo\tXQueryExtension failed"); XUnlockDisplay (_display); return 0; } // Find XV port _XVPort = FindXVPort (); if (!_XVPort) { PTRACE(1, "XVideo\tFindXVPort failed"); XUnlockDisplay(_display); return 0; } PTRACE(4, "XVideo\tUsing XVideo port: " << _XVPort); if (!CreateAtomsAndWindow(gc, x, y, windowWidth, windowHeight)) { XUnlockDisplay(_display); return 0; } XV_SYNC_TO_VBLANK = GetXVAtom("XV_SYNC_TO_VBLANK"); XV_COLORKEY = GetXVAtom( "XV_COLORKEY" ); XV_AUTOPAINT_COLORKEY = GetXVAtom( "XV_AUTOPAINT_COLORKEY" ); if ( !InitColorkey() ) { PTRACE(1, "XVideo\tColorkey initialization failed"); XUnlockDisplay(_display); return 0; } if (XV_SYNC_TO_VBLANK != None) if (XvSetPortAttribute(_display, _XVPort, XV_SYNC_TO_VBLANK, 1) == Success) PTRACE(4, "XVideo\tVertical sync successfully activated" ); else PTRACE(4, "XVideo\tFailure when trying to activate vertical sync" ); else PTRACE(4, "XVideo\tVertical sync not supported"); if (!checkMaxSize (imageWidth, imageHeight)) { PTRACE(1, "XVideo\tCheck of image size failed"); XUnlockDisplay(_display); return 0; } #ifdef HAVE_SHM if (XShmQueryExtension (_display)) { _useShm = true; PTRACE(1, "XVideo\tXQueryShmExtension success"); } else { _useShm = false; PTRACE(1, "XVideo\tXQueryShmExtension failed"); } if (_useShm) ShmAttach(imageWidth, imageHeight); if (!_useShm) { #endif for (i = 0; i < NUM_BUFFERS; i++) { _XVImage[i] = (XvImage *) XvCreateImage( _display, _XVPort, GUID_YV12_PLANAR, 0, imageWidth, imageHeight); if (!_XVImage[i]) { PTRACE(1, "XVideo\tUnable to create XVideo Image"); XUnlockDisplay (_display); return 0; } _XVImage[i]->data = (char*) malloc(_XVImage[i]->data_size); } PTRACE(1, "XVideo\tNot using SHM extension"); #ifdef HAVE_SHM } else { PTRACE(1, "XVideo\tUsing SHM extension"); } #endif XSync(_display, False); _isInitialized = true; XUnlockDisplay (_display); // detect the window manager type _wmType = GetWMType (); CalculateSize (windowWidth, windowHeight, true); return 1; }
static int X11_xv_blit(struct DriverInstance* sh, const uint8_t* fb, int width, int height, struct blit_params* params, int needs_adjust, char* error_text, int text_len) { if (sh->xv_image == 0 || width != sh->image_width || height != sh->image_height) { if (sh->xv_image) XFree(sh->xv_image); sh->xv_image = XvCreateImage(sh->display, sh->xv_port, sh->xv_format_id, 0, width, height); sh->image_width = width; sh->image_height = height; } if (sh->data == 0 || sh->data_size < sh->xv_image->data_size) { if (sh->data) free(sh->data); sh->data = malloc(sh->xv_image->data_size); sh->data_size = sh->xv_image->data_size; if (sh->data == 0) { snprintf(error_text, text_len, "Could not allocate data for XVImage"); return 0; } } assert(sh->data); //TODO: this is a hack for big-endian machines if (big_endian()) convert_endianness(sh->data, sh->width, sh->height); sh->xv_image->data = sh->data; if (sh->vis.depth == 24) cvt_rgb32_to_i420((uint8_t*) sh->data, (uint32_t*) fb, width, height, sh->xv_image->pitches, sh->xv_image->offsets); else if (sh->vis.depth == 16) cvt_rgb16_to_i420((uint8_t*) sh->data, (uint16_t*) fb, width, height, sh->xv_image->pitches, sh->xv_image->offsets); // blit image XvPutImage(sh->display, sh->xv_port, sh->win, sh->gc, sh->xv_image, 0, 0, width, height, 0, 0, sh->width, sh->height); XFlush(sh->display); //XSync(sh->display, False); return 1; }
static void player_av_load (Player *self, Entry *entry) { gint i; PlayerAVPrivate *priv = PLAYER_AV (self)->priv; player_av_close (self); if (av_open_input_file (&priv->fctx, entry_get_location (entry), NULL, 0, NULL) != 0) return; if (av_find_stream_info (priv->fctx) < 0) return; priv->fctx->flags = AVFMT_FLAG_GENPTS; dump_format(priv->fctx, 0, entry_get_location (entry), 0); priv->astream = priv->vstream = -1; for (i = 0; i < priv->fctx->nb_streams; i++) { if (priv->fctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) { priv->vstream = i; } if (priv->fctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { priv->astream = i; } if (priv->vstream != -1 && priv->astream != -1) break; } // Setup Audio Stream if (priv->astream != -1) { priv->actx = priv->fctx->streams[priv->astream]->codec; AVCodec *acodec = avcodec_find_decoder (priv->actx->codec_id); if (acodec && avcodec_open (priv->actx, acodec) < 0) { g_print ("Error opening audio stream\n"); return; } } else { priv->actx = NULL; } // Setup Video Stream if (priv->vstream != -1) { priv->vctx = priv->fctx->streams[priv->vstream]->codec; AVCodec *vcodec = avcodec_find_decoder (priv->vctx->codec_id); if(vcodec && avcodec_open (priv->vctx, vcodec) < 0) { g_print ("Error opening video stream\n"); return; } } else { priv->vctx = NULL; } if (priv->vctx) { priv->vctx->get_buffer = player_av_av_get_buffer; priv->vctx->release_buffer = player_av_av_release_buffer; priv->display = gdk_x11_display_get_xdisplay (gdk_display_get_default ()); priv->root = DefaultRootWindow (priv->display); priv->win = GDK_WINDOW_XID (priv->em_da->window); XSetWindowBackgroundPixmap (priv->display, priv->win, None); int nb_adaptors; XvAdaptorInfo *adaptors; XvQueryAdaptors (priv->display, priv->root, &nb_adaptors, &adaptors); int adaptor_no = 0, j, res; priv->xv_port_id = 0; for (i = 0; i < nb_adaptors && !priv->xv_port_id; i++) { adaptor_no = i; for (j = 0; j < adaptors[adaptor_no].num_ports && !priv->xv_port_id; j++) { res = XvGrabPort (priv->display, adaptors[adaptor_no].base_id + j, 0); if (Success == res) { priv->xv_port_id = adaptors[adaptor_no].base_id + j; } } } XvFreeAdaptorInfo (adaptors); int nb_formats; XvImageFormatValues *formats = XvListImageFormats (priv->display, priv->xv_port_id, &nb_formats); unsigned int vfmt = avcodec_pix_fmt_to_codec_tag (priv->vctx->pix_fmt); for (i = 0; i < nb_formats; i++) { if (vfmt == formats[i].id) { break; } } enum PixelFormat ofmt = PIX_FMT_NONE; priv->vframe = avcodec_alloc_frame (); priv->vframe_xv = avcodec_alloc_frame(); if (i < nb_formats) { ofmt = priv->vctx->pix_fmt; } else { for (i = 0; i < nb_formats; i++) { ofmt = avcodec_codec_tag_to_pix_fmt (formats[i].id); if (ofmt != PIX_FMT_NONE) { break; } } } int num_bytes = avpicture_get_size (ofmt, priv->vctx->width + priv->vctx->width % 4, priv->vctx->height); priv->vbuffer_xv = (uint8_t*) av_malloc (num_bytes * sizeof (uint8_t)); avpicture_fill ((AVPicture*) priv->vframe_xv, priv->vbuffer_xv, ofmt, priv->vctx->width + priv->vctx->width % 4, priv->vctx->height); priv->sws_ctx = sws_getContext ( priv->vctx->width, priv->vctx->height, priv->vctx->pix_fmt, priv->vctx->width, priv->vctx->height, ofmt, SWS_POINT, NULL, NULL, NULL); priv->xvimage = XvCreateImage ( priv->display, priv->xv_port_id, formats[i].id, priv->vbuffer_xv, priv->vctx->width, priv->vctx->height); XFree (formats); priv->xv_gc = XCreateGC (priv->display, priv->win, 0, &priv->values); } priv->entry = entry; g_object_ref (entry); priv->vpos = 0; priv->start_time = -1; priv->stop_time = -1; }
static GstXvImageMeta * gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool) { GstXvImageSink *xvimagesink; int (*handler) (Display *, XErrorEvent *); gboolean success = FALSE; GstXContext *xcontext; GstXvImageMeta *meta; gint width, height, im_format, align = 15, offset; GstXvImageBufferPoolPrivate *priv; priv = xvpool->priv; xvimagesink = xvpool->sink; xcontext = xvimagesink->xcontext; width = priv->padded_width; height = priv->padded_height; im_format = priv->im_format; meta = (GstXvImageMeta *) gst_buffer_add_meta (buffer, GST_XVIMAGE_META_INFO, NULL); #ifdef HAVE_XSHM meta->SHMInfo.shmaddr = ((void *) -1); meta->SHMInfo.shmid = -1; #endif meta->x = priv->align.padding_left; meta->y = priv->align.padding_top; meta->width = priv->info.width; meta->height = priv->info.height; meta->sink = gst_object_ref (xvimagesink); meta->im_format = im_format; GST_DEBUG_OBJECT (xvimagesink, "creating image %p (%dx%d)", buffer, width, height); g_mutex_lock (&xvimagesink->x_lock); /* Setting an error handler to catch failure */ error_caught = FALSE; handler = XSetErrorHandler (gst_xvimagesink_handle_xerror); #ifdef HAVE_XSHM if (xcontext->use_xshm) { int expected_size; meta->xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id, im_format, NULL, width, height, &meta->SHMInfo); if (!meta->xvimage || error_caught) { g_mutex_unlock (&xvimagesink->x_lock); /* Reset error flag */ error_caught = FALSE; /* Push a warning */ GST_ELEMENT_WARNING (xvimagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", width, height), ("could not XShmCreateImage a %dx%d image", width, height)); /* Retry without XShm */ xvimagesink->xcontext->use_xshm = FALSE; /* Hold X mutex again to try without XShm */ g_mutex_lock (&xvimagesink->x_lock); goto no_xshm; } /* we have to use the returned data_size for our shm size */ meta->size = meta->xvimage->data_size; GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT, meta->size); /* calculate the expected size. This is only for sanity checking the * number we get from X. */ switch (im_format) { case GST_MAKE_FOURCC ('I', '4', '2', '0'): case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): { gint pitches[3]; gint offsets[3]; guint plane; offsets[0] = 0; pitches[0] = GST_ROUND_UP_4 (width); offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (height); pitches[1] = GST_ROUND_UP_8 (width) / 2; offsets[2] = offsets[1] + pitches[1] * GST_ROUND_UP_2 (height) / 2; pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2; expected_size = offsets[2] + pitches[2] * GST_ROUND_UP_2 (height) / 2; for (plane = 0; plane < meta->xvimage->num_planes; plane++) { GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a expected pitch of %d bytes, " "offset of %d", plane, pitches[plane], offsets[plane]); } break; } case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): expected_size = height * GST_ROUND_UP_4 (width * 2); break; default: expected_size = 0; break; } if (expected_size != 0 && meta->size != expected_size) { GST_WARNING_OBJECT (xvimagesink, "unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)", meta->size, expected_size); } /* Be verbose about our XvImage stride */ { guint plane; for (plane = 0; plane < meta->xvimage->num_planes; plane++) { GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, " "offset of %d", plane, meta->xvimage->pitches[plane], meta->xvimage->offsets[plane]); } } /* get shared memory */ meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size + align, IPC_CREAT | 0777); if (meta->SHMInfo.shmid == -1) goto shmget_failed; /* attach */ meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, NULL, 0); if (meta->SHMInfo.shmaddr == ((void *) -1)) goto shmat_failed; /* now we can set up the image data */ meta->xvimage->data = meta->SHMInfo.shmaddr; meta->SHMInfo.readOnly = FALSE; if (XShmAttach (xcontext->disp, &meta->SHMInfo) == 0) goto xattach_failed; XSync (xcontext->disp, FALSE); /* Delete the shared memory segment as soon as we everyone is attached. * This way, it will be deleted as soon as we detach later, and not * leaked if we crash. */ shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL); GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx", meta->SHMInfo.shmid, meta->SHMInfo.shmseg); } else no_xshm: #endif /* HAVE_XSHM */ { meta->xvimage = XvCreateImage (xcontext->disp, xcontext->xv_port_id, im_format, NULL, width, height); if (!meta->xvimage || error_caught) goto create_failed; /* we have to use the returned data_size for our image size */ meta->size = meta->xvimage->data_size; meta->xvimage->data = g_malloc (meta->size + align); XSync (xcontext->disp, FALSE); } if ((offset = ((guintptr) meta->xvimage->data & align))) offset = (align + 1) - offset; GST_DEBUG_OBJECT (xvimagesink, "memory %p, align %d, offset %d", meta->xvimage->data, align, offset); /* Reset error handler */ error_caught = FALSE; XSetErrorHandler (handler); gst_buffer_append_memory (buffer, gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, meta->xvimage->data, meta->size + align, offset, meta->size, NULL, NULL)); g_mutex_unlock (&xvimagesink->x_lock); success = TRUE; beach: if (!success) meta = NULL; return meta; /* ERRORS */ create_failed: { g_mutex_unlock (&xvimagesink->x_lock); /* Reset error handler */ error_caught = FALSE; XSetErrorHandler (handler); /* Push an error */ GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", width, height), ("could not XvShmCreateImage a %dx%d image", width, height)); goto beach; } #ifdef HAVE_XSHM shmget_failed: { g_mutex_unlock (&xvimagesink->x_lock); GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", width, height), ("could not get shared memory of %" G_GSIZE_FORMAT " bytes", meta->size)); goto beach; } shmat_failed: { g_mutex_unlock (&xvimagesink->x_lock); GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", width, height), ("Failed to shmat: %s", g_strerror (errno))); /* Clean up the shared memory segment */ shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL); goto beach; } xattach_failed: { /* Clean up the shared memory segment */ shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL); g_mutex_unlock (&xvimagesink->x_lock); GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", width, height), ("Failed to XShmAttach")); goto beach; } #endif }