Пример #1
0
    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;
    }
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
  }
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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];
	}
}
Пример #14
0
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);
        }
    }
}
Пример #16
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;
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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
}