Ejemplo n.º 1
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);
            }

        }
Ejemplo n.º 2
0
static void
gst_v4l2_xoverlay_open (GstV4l2Object * v4l2object)
{
    struct stat s;
    GstV4l2Xv *v4l2xv;
    const gchar *name = g_getenv ("DISPLAY");
    unsigned int ver, rel, req, ev, err, anum;
    int i, id = 0, first_id = 0, min;
    XvAdaptorInfo *ai;
    Display *dpy;

    /* we need a display, obviously */
    if (!name || !(dpy = XOpenDisplay (name))) {
        GST_WARNING_OBJECT (v4l2object->element,
                            "No $DISPLAY set or failed to open - no overlay");
        return;
    }

    /* First let's check that XVideo extension is available */
    if (!XQueryExtension (dpy, "XVideo", &i, &i, &i)) {
        GST_WARNING_OBJECT (v4l2object->element,
                            "Xv extension not available - no overlay");
        XCloseDisplay (dpy);
        return;
    }

    /* find port that belongs to this device */
    if (XvQueryExtension (dpy, &ver, &rel, &req, &ev, &err) != Success) {
        GST_WARNING_OBJECT (v4l2object->element,
                            "Xv extension not supported - no overlay");
        XCloseDisplay (dpy);
        return;
    }
    if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &anum, &ai) != Success) {
        GST_WARNING_OBJECT (v4l2object->element, "Failed to query Xv adaptors");
        XCloseDisplay (dpy);
        return;
    }
    if (fstat (v4l2object->video_fd, &s) < 0) {
        GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
                           (_("Cannot identify device '%s'."), v4l2object->videodev),
                           GST_ERROR_SYSTEM);
        XCloseDisplay (dpy);
        return;
    }
    min = s.st_rdev & 0xff;
    for (i = 0; i < anum; i++) {
        if (!strcmp (ai[i].name, "video4linux2")) {
            if (first_id == 0)
                first_id = ai[i].base_id;

            /* hmm... */
            if (first_id != 0 && ai[i].base_id == first_id + min)
                id = ai[i].base_id;
        }
    }
    XvFreeAdaptorInfo (ai);

    if (id == 0) {
        GST_WARNING_OBJECT (v4l2object->element,
                            "Did not find XvPortID for device - no overlay");
        XCloseDisplay (dpy);
        return;
    }

    v4l2xv = g_new0 (GstV4l2Xv, 1);
    v4l2xv->dpy = dpy;
    v4l2xv->port = id;
    v4l2xv->mutex = g_mutex_new ();
    v4l2xv->idle_id = 0;
    v4l2object->xv = v4l2xv;

    if (v4l2object->xwindow_id) {
        gst_v4l2_xoverlay_set_xwindow_id (v4l2object, v4l2object->xwindow_id);
    }
}
Ejemplo n.º 3
0
int
xf_video_init(xfInfo * xfi)
{
	unsigned int version;
	unsigned int release;
	unsigned int request_base;
	unsigned int event_base;
	unsigned int error_base;
	unsigned int num_adaptors;
	unsigned int i;
	int ret;
	XvAdaptorInfo * ai;
	XvAttribute * attr;
	XvImageFormatValues * fo;

	xfi->xv_colorkey_atom = None;
	xfi->xv_image_size = 0;

	if (!XShmQueryExtension(xfi->display))
	{
		printf("xf_video_init: no shmem available.\n");
		return 1;
	}

	ret = XvQueryExtension(xfi->display, &version, &release, &request_base, &event_base, &error_base);
	if (ret != Success)
	{
		printf("xf_video_init: XvQueryExtension failed %d.\n", ret);
		return 1;
	}
	printf("xf_video_init:");
	printf(" version %u", version);
	printf(" release %u", release);
	printf("\n");

	ret = XvQueryAdaptors(xfi->display, DefaultRootWindow(xfi->display),
		&num_adaptors, &ai);
	if (ret != Success)
	{
		printf("xf_video_init: XvQueryAdaptors failed %d.\n", ret);
		return 1;
	}

	for (i = 0; i < num_adaptors; i++)
	{
		printf("xf_video_init: adapter port %ld-%ld (%s)\n", ai[i].base_id,
			ai[i].base_id + ai[i].num_ports - 1, ai[i].name);
		if (xfi->xv_port == -1 && i == num_adaptors - 1)
			xfi->xv_port = ai[i].base_id;
	}

	if (num_adaptors > 0)
		XvFreeAdaptorInfo(ai);

	if (xfi->xv_port == -1)
	{
		printf("xf_video_init: no adapter selected, video frames will not be processed.\n");
		return 1;
	}
	printf("xf_video_init: selected %ld\n", xfi->xv_port);

	attr = XvQueryPortAttributes(xfi->display, xfi->xv_port, &ret);
	for (i = 0; i < (unsigned int)ret; i++)
	{
		if (strcmp(attr[i].name, "XV_COLORKEY") == 0)
		{
			xfi->xv_colorkey_atom = XInternAtom(xfi->display, "XV_COLORKEY", False);
			XvSetPortAttribute(xfi->display, xfi->xv_port, xfi->xv_colorkey_atom, attr[i].min_value + 1);
			break;
		}
	}
	XFree(attr);

	printf("xf_video_init: pixel format ");
	fo = XvListImageFormats(xfi->display, xfi->xv_port, &ret);
	if (ret > 0)
	{
		xfi->xv_pixfmts = (uint32 *) malloc((ret + 1) * sizeof(uint32));
		for (i = 0; i < ret; i++)
		{
			xfi->xv_pixfmts[i] = fo[i].id;
			printf("%c%c%c%c ", ((char*)(xfi->xv_pixfmts + i))[0], ((char*)(xfi->xv_pixfmts + i))[1],
				((char*)(xfi->xv_pixfmts + i))[2], ((char*)(xfi->xv_pixfmts + i))[3]);
		}
		xfi->xv_pixfmts[i] = 0;
	}
	printf("\n");

	return 0;
}
Ejemplo n.º 4
0
Archivo: vo_xv.c Proyecto: hroncok/mpv
static void draw_osd(struct vo *vo, struct osd_state *osd)
{
    struct xvctx *ctx = vo->priv;

    struct mp_image img = get_xv_buffer(vo, ctx->current_buf);

    struct mp_osd_res res = {
        .w = ctx->image_width,
        .h = ctx->image_height,
        .display_par = 1.0 / vo->aspdat.par,
    };

    osd_draw_on_image(osd, res, osd->vo_pts, 0, &img);
}

static void wait_for_completion(struct vo *vo, int max_outstanding)
{
#if HAVE_SHM
    struct xvctx *ctx = vo->priv;
    struct vo_x11_state *x11 = vo->x11;
    if (ctx->Shmem_Flag) {
        while (x11->ShmCompletionWaitCount > max_outstanding) {
            if (!ctx->Shm_Warned_Slow) {
                MP_WARN(vo, "X11 can't keep up! Waiting"
                        " for XShm completion events...\n");
                ctx->Shm_Warned_Slow = 1;
            }
            mp_sleep_us(1000);
            vo_x11_check_events(vo);
        }
    }
#endif
}

static void flip_page(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    put_xvimage(vo, ctx->xvimage[ctx->current_buf]);

    /* remember the currently visible buffer */
    ctx->current_buf = (ctx->current_buf + 1) % ctx->num_buffers;

    if (!ctx->Shmem_Flag)
        XSync(vo->x11->display, False);
}

static mp_image_t *get_screenshot(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    if (!ctx->original_image)
        return NULL;

    return mp_image_new_ref(ctx->original_image);
}

// Note: redraw_frame() can call this with NULL.
static void draw_image(struct vo *vo, mp_image_t *mpi)
{
    struct xvctx *ctx = vo->priv;

    wait_for_completion(vo, ctx->num_buffers - 1);

    struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf);
    if (mpi) {
        mp_image_copy(&xv_buffer, mpi);
    } else {
        mp_image_clear(&xv_buffer, 0, 0, xv_buffer.w, xv_buffer.h);
    }

    mp_image_setrefp(&ctx->original_image, mpi);
}

static int redraw_frame(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;

    draw_image(vo, ctx->original_image);
    return true;
}

static int query_format(struct vo *vo, uint32_t format)
{
    struct xvctx *ctx = vo->priv;
    uint32_t i;
    int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;

    int fourcc = find_xv_format(format);
    if (fourcc) {
        for (i = 0; i < ctx->formats; i++) {
            if (ctx->fo[i].id == fourcc)
                return flag;
        }
    }
    return 0;
}

static void uninit(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    int i;

    talloc_free(ctx->original_image);

    if (ctx->ai)
        XvFreeAdaptorInfo(ctx->ai);
    ctx->ai = NULL;
    if (ctx->fo) {
        XFree(ctx->fo);
        ctx->fo = NULL;
    }
    for (i = 0; i < ctx->num_buffers; i++)
        deallocate_xvimage(vo, i);
    // uninit() shouldn't get called unless initialization went past vo_init()
    vo_x11_uninit(vo);
}

static int preinit(struct vo *vo)
{
    XvPortID xv_p;
    int busy_ports = 0;
    unsigned int i;
    struct xvctx *ctx = vo->priv;
    int xv_adaptor = ctx->cfg_xv_adaptor;

    if (!vo_x11_init(vo))
        return -1;

    struct vo_x11_state *x11 = vo->x11;

    /* check for Xvideo extension */
    unsigned int ver, rel, req, ev, err;
    if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
        MP_ERR(vo, "Xv not supported by this X11 version/driver\n");
        goto error;
    }

    /* check for Xvideo support */
    if (Success !=
        XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
                        &ctx->adaptors, &ctx->ai)) {
        MP_ERR(vo, "XvQueryAdaptors failed.\n");
        goto error;
    }

    /* check adaptors */
    if (ctx->xv_port) {
        int port_found;

        for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
            if ((ctx->ai[i].type & XvInputMask)
                && (ctx->ai[i].type & XvImageMask)) {
                for (xv_p = ctx->ai[i].base_id;
                     xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
                     ++xv_p) {
                    if (xv_p == ctx->xv_port) {
                        port_found = 1;
                        break;
                    }
                }
            }
        }
        if (port_found) {
            if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime))
                ctx->xv_port = 0;
        } else {
            MP_WARN(vo, "Invalid port parameter, overriding with port 0.\n");
            ctx->xv_port = 0;
        }
    }

    for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) {
        /* check if adaptor number has been specified */
        if (xv_adaptor != -1 && xv_adaptor != i)
            continue;

        if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
            for (xv_p = ctx->ai[i].base_id;
                 xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
                if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
                    ctx->xv_port = xv_p;
                    MP_VERBOSE(vo, "Using Xv Adapter #%d (%s)\n",
                               i, ctx->ai[i].name);
                    break;
                } else {
                    MP_WARN(vo, "Could not grab port %i.\n", (int) xv_p);
                    ++busy_ports;
                }
        }
    }
    if (!ctx->xv_port) {
        if (busy_ports)
            MP_ERR(vo,
                   "Could not find free Xvideo port - maybe another process is already\n"\
                   "using it. Close all video applications, and try again. If that does\n"\
                   "not help, see 'mpv -vo help' for other (non-xv) video out drivers.\n");
        else
            MP_ERR(vo,
                   "It seems there is no Xvideo support for your video card available.\n"\
                   "Run 'xvinfo' to verify its Xv support and read\n"\
                   "DOCS/HTML/en/video.html#xv!\n"\
                   "See 'mpv -vo help' for other (non-xv) video out drivers.\n"\
                   "Try -vo x11.\n");
        goto error;
    }

    if (!xv_init_colorkey(vo)) {
        goto error;             // bail out, colorkey setup failed
    }
    xv_enable_vsync(vo);
    xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);

    ctx->fo = XvListImageFormats(x11->display, ctx->xv_port,
                                 (int *) &ctx->formats);

    return 0;

  error:
    uninit(vo);                 // free resources
    return -1;
}
Ejemplo n.º 5
0
static int XVideoGetPort( Display *p_display,
                          int32_t i_chroma,
                          int i_requested_adaptor)      // -1 for autoscan
{
    XvAdaptorInfo *p_adaptor;
    unsigned int i;
    unsigned int i_adaptor, i_num_adaptors;
    int i_selected_port;

    switch( XvQueryExtension( p_display, &i, &i, &i, &i, &i ) )
    {
        case Success:
            break;

        case XvBadExtension:
            ml_log_error("XvBadExtension\n" );
            return -1;

        case XvBadAlloc:
            ml_log_error("XvBadAlloc\n" );
            return -1;

        default:
            ml_log_error("XvQueryExtension failed\n" );
            return -1;
    }

    switch( XvQueryAdaptors( p_display,
                             DefaultRootWindow( p_display ),
                             &i_num_adaptors, &p_adaptor ) )
    {
        case Success:
            break;

        case XvBadExtension:
            ml_log_error("XvBadExtension for XvQueryAdaptors\n" );
            return -1;

        case XvBadAlloc:
            ml_log_error("XvBadAlloc for XvQueryAdaptors\n" );
            return -1;

        default:
            ml_log_error("XvQueryAdaptors failed\n" );
            return -1;
    }

    i_selected_port = -1;

    for( i_adaptor = 0; i_adaptor < i_num_adaptors; ++i_adaptor )
    {
        XvImageFormatValues *p_formats;
        int i_format, i_num_formats;
        int i_port;

        /* If we requested an adaptor and it's not this one, we aren't
         * interested */
        if( i_requested_adaptor != -1 && i_adaptor != (unsigned int)i_requested_adaptor )
        {
            continue;
        }

        /* If the adaptor doesn't have the required properties, skip it */
        if( !( p_adaptor[ i_adaptor ].type & XvInputMask ) ||
            !( p_adaptor[ i_adaptor ].type & XvImageMask ) )
        {
            continue;
        }

        /* Check that adaptor supports our requested format... */
        p_formats = XvListImageFormats( p_display,
                                        p_adaptor[i_adaptor].base_id,
                                        &i_num_formats );

        for( i_format = 0;
             i_format < i_num_formats && ( i_selected_port == -1 );
             i_format++ )
        {
            XvAttribute     *p_attr;
            int             i_attr, i_num_attributes;

            /* Matching chroma? */
            if( p_formats[ i_format ].id != i_chroma )
            {
                continue;
            }

            /* Look for the first available port supporting this format */
            for( i_port = p_adaptor[i_adaptor].base_id;
                 ( i_port < (int)(p_adaptor[i_adaptor].base_id
                                   + p_adaptor[i_adaptor].num_ports) )
                   && ( i_selected_port == -1 );
                 i_port++ )
            {
                if( XvGrabPort( p_display, i_port, CurrentTime )
                     == Success )
                {
                    i_selected_port = i_port;
                }
            }

            /* If no free port was found, forget it */
            if( i_selected_port == -1 )
            {
                continue;
            }

            /* If we found a port, print information about it */
            ml_log_info("X11 display adaptor %i, port %i, format 0x%x (%4.4s) %s\n",
                     i_adaptor, i_selected_port, p_formats[ i_format ].id,
                     (char *)&p_formats[ i_format ].id,
                     ( p_formats[ i_format ].format == XvPacked ) ?
                         "packed" : "planar" );

            /* Make sure XV_AUTOPAINT_COLORKEY is set */
            p_attr = XvQueryPortAttributes( p_display,
                                            i_selected_port,
                                            &i_num_attributes );

            for( i_attr = 0; i_attr < i_num_attributes; i_attr++ )
            {
                if( !strcmp( p_attr[i_attr].name, "XV_AUTOPAINT_COLORKEY" ) )
                {
                    const Atom autopaint =
                        XInternAtom( p_display,
                                     "XV_AUTOPAINT_COLORKEY", False );
                    XvSetPortAttribute( p_display,
                                        i_selected_port, autopaint, 1 );
                    break;
                }
            }

            if( p_attr != NULL )
            {
                XFree( p_attr );
            }
        }

        if( p_formats != NULL )
        {
            XFree( p_formats );
        }

    }

    if( i_num_adaptors > 0 )
    {
        XvFreeAdaptorInfo( p_adaptor );
    }

    if( i_selected_port == -1 )
    {
        int i_chroma_tmp = X112VLC_FOURCC( i_chroma );
        if( i_requested_adaptor == -1 )
        {
            ml_log_error("no free XVideo port found for format: "
                      "0x%.8x (%4.4s)\n", i_chroma_tmp, (char*)&i_chroma_tmp );
        }
        else
        {
            ml_log_error("XVideo adaptor %i does not have a free: "
                      "XVideo port for format 0x%.8x (%4.4s)\n",
                      i_requested_adaptor, i_chroma_tmp, (char*)&i_chroma_tmp );
        }
    }

    return i_selected_port;
}
/** The initialization function
  * This function opens the frame buffer device and allocates memory for display
  * also it finds the frame buffer supported display formats
  */
OMX_ERRORTYPE omx_xvideo_sink_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) {
  omx_xvideo_sink_component_PrivateType* omx_xvideo_sink_component_Private = openmaxStandComp->pComponentPrivate;
  omx_xvideo_sink_component_PortType* pPort = (omx_xvideo_sink_component_PortType *) omx_xvideo_sink_component_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX];
  int yuv_width  = pPort->sPortParam.format.video.nFrameWidth;
  int yuv_height = pPort->sPortParam.format.video.nFrameHeight;
  unsigned int err,i;

  omx_xvideo_sink_component_Private->dpy = XOpenDisplay(NULL);
  omx_xvideo_sink_component_Private->screen = DefaultScreen(omx_xvideo_sink_component_Private->dpy);

  XGetWindowAttributes(omx_xvideo_sink_component_Private->dpy,
    DefaultRootWindow(omx_xvideo_sink_component_Private->dpy),
    &omx_xvideo_sink_component_Private->attribs);

  XMatchVisualInfo(omx_xvideo_sink_component_Private->dpy,
    omx_xvideo_sink_component_Private->screen,
    omx_xvideo_sink_component_Private->attribs.depth, TrueColor, &
    omx_xvideo_sink_component_Private->vinfo);

  omx_xvideo_sink_component_Private->wmDeleteWindow = XInternAtom(omx_xvideo_sink_component_Private->dpy, "WM_DELETE_WINDOW", False);

  omx_xvideo_sink_component_Private->hint.x = 1;
  omx_xvideo_sink_component_Private->hint.y = 1;
  omx_xvideo_sink_component_Private->hint.width = yuv_width;
  omx_xvideo_sink_component_Private->hint.height = yuv_height;
  omx_xvideo_sink_component_Private->hint.flags = PPosition | PSize;

  omx_xvideo_sink_component_Private->xswa.colormap = XCreateColormap(omx_xvideo_sink_component_Private->dpy,
                                                                     DefaultRootWindow(omx_xvideo_sink_component_Private->dpy),
                                                                     omx_xvideo_sink_component_Private->vinfo.visual, AllocNone);
  omx_xvideo_sink_component_Private->xswa.event_mask = StructureNotifyMask | ExposureMask;
  omx_xvideo_sink_component_Private->xswa.background_pixel = 0;
  omx_xvideo_sink_component_Private->xswa.border_pixel = 0;

  omx_xvideo_sink_component_Private->window =
                        XCreateWindow(omx_xvideo_sink_component_Private->dpy,
                                      DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), 0, 0, yuv_width,
                                      yuv_height, 0, omx_xvideo_sink_component_Private->vinfo.depth, InputOutput,
                                      omx_xvideo_sink_component_Private->vinfo.visual,
                                      CWBackPixel | CWBorderPixel | CWColormap |
                                      CWEventMask, &omx_xvideo_sink_component_Private->xswa);

  XSelectInput(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, StructureNotifyMask);
  XSetStandardProperties(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, "xvcam", "xvcam", None, NULL, 0,
                        &omx_xvideo_sink_component_Private->hint);

  XSetWMProtocols(omx_xvideo_sink_component_Private->dpy,
                  omx_xvideo_sink_component_Private->window,
                  &omx_xvideo_sink_component_Private->wmDeleteWindow, 1);
  XMapWindow(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window);

  if (XShmQueryExtension(omx_xvideo_sink_component_Private->dpy))
    omx_xvideo_sink_component_Private->CompletionType = XShmGetEventBase(omx_xvideo_sink_component_Private->dpy) + ShmCompletion;
  else
    return OMX_ErrorUndefined;

  if (Success !=
     XvQueryExtension(omx_xvideo_sink_component_Private->dpy,
                      &omx_xvideo_sink_component_Private->ver,
                      &omx_xvideo_sink_component_Private->rel,
                      &omx_xvideo_sink_component_Private->req,
                      &omx_xvideo_sink_component_Private->ev, &err))
    fprintf(stderr, "Couldn't do Xv stuff\n");

  if (Success !=
     XvQueryAdaptors(omx_xvideo_sink_component_Private->dpy,
                     DefaultRootWindow(omx_xvideo_sink_component_Private->dpy),
                     &omx_xvideo_sink_component_Private->adapt,
                     &omx_xvideo_sink_component_Private->ai))
    fprintf(stderr, "Couldn't do Xv stuff\n");

  for (i = 0; i < (int) omx_xvideo_sink_component_Private->adapt; i++) {
    omx_xvideo_sink_component_Private->xv_port = omx_xvideo_sink_component_Private->ai[i].base_id;
  }

  if (omx_xvideo_sink_component_Private->adapt > 0)
    XvFreeAdaptorInfo(omx_xvideo_sink_component_Private->ai);

  omx_xvideo_sink_component_Private->gc = XCreateGC(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, 0, 0);

  omx_xvideo_sink_component_Private->yuv_image = XvShmCreateImage(omx_xvideo_sink_component_Private->dpy,
                                                                  omx_xvideo_sink_component_Private->xv_port,
                                                                  GUID_I420_PLANAR, 0, yuv_width,
                                                                  yuv_height, &omx_xvideo_sink_component_Private->yuv_shminfo);

  omx_xvideo_sink_component_Private->yuv_shminfo.shmid    = shmget(IPC_PRIVATE, omx_xvideo_sink_component_Private->yuv_image->data_size, IPC_CREAT | 0777);
  omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr  = (char *) shmat(omx_xvideo_sink_component_Private->yuv_shminfo.shmid, 0, 0);
  omx_xvideo_sink_component_Private->yuv_image->data      = omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr;
  omx_xvideo_sink_component_Private->yuv_shminfo.readOnly = False;

  if (!XShmAttach(omx_xvideo_sink_component_Private->dpy, &omx_xvideo_sink_component_Private->yuv_shminfo)) {
    printf("XShmAttach go boom boom!\n");
    return OMX_ErrorUndefined;
  }

  omx_xvideo_sink_component_Private->old_time = 0;
  omx_xvideo_sink_component_Private->new_time = 0;

  omx_xvideo_sink_component_Private->bIsXVideoInit = OMX_TRUE;
  /*Signal XVideo Initialized*/
  tsem_up(omx_xvideo_sink_component_Private->xvideoSyncSem);

  return OMX_ErrorNone;
}
Ejemplo n.º 7
0
Archivo: vo_xv.c Proyecto: DZW314/mpv
static int preinit(struct vo *vo)
{
    XvPortID xv_p;
    int busy_ports = 0;
    unsigned int i;
    struct xvctx *ctx = vo->priv;
    int xv_adaptor = ctx->cfg_xv_adaptor;

    if (!vo_x11_init(vo))
        return -1;

    if (!vo_x11_create_vo_window(vo, NULL, "xv"))
        goto error;

    struct vo_x11_state *x11 = vo->x11;

    /* check for Xvideo extension */
    unsigned int ver, rel, req, ev, err;
    if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
        MP_ERR(vo, "Xv not supported by this X11 version/driver\n");
        goto error;
    }

    /* check for Xvideo support */
    if (Success !=
        XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
                        &ctx->adaptors, &ctx->ai)) {
        MP_ERR(vo, "XvQueryAdaptors failed.\n");
        goto error;
    }

    /* check adaptors */
    if (ctx->xv_port) {
        int port_found;

        for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
            if ((ctx->ai[i].type & XvInputMask)
                && (ctx->ai[i].type & XvImageMask)) {
                for (xv_p = ctx->ai[i].base_id;
                     xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
                     ++xv_p) {
                    if (xv_p == ctx->xv_port) {
                        port_found = 1;
                        break;
                    }
                }
            }
        }
        if (port_found) {
            if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime))
                ctx->xv_port = 0;
        } else {
            MP_WARN(vo, "Invalid port parameter, overriding with port 0.\n");
            ctx->xv_port = 0;
        }
    }

    for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) {
        /* check if adaptor number has been specified */
        if (xv_adaptor != -1 && xv_adaptor != i)
            continue;

        if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
            for (xv_p = ctx->ai[i].base_id;
                 xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
                if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
                    ctx->xv_port = xv_p;
                    MP_VERBOSE(vo, "Using Xv Adapter #%d (%s)\n",
                               i, ctx->ai[i].name);
                    break;
                } else {
                    MP_WARN(vo, "Could not grab port %i.\n", (int) xv_p);
                    ++busy_ports;
                }
        }
    }
    if (!ctx->xv_port) {
        if (busy_ports)
            MP_ERR(vo, "Xvideo ports busy.\n");
        else
            MP_ERR(vo, "No Xvideo support found.\n");
        goto error;
    }

    if (!xv_init_colorkey(vo)) {
        goto error;             // bail out, colorkey setup failed
    }
    xv_enable_vsync(vo);
    xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);

    ctx->fo = XvListImageFormats(x11->display, ctx->xv_port,
                                 (int *) &ctx->formats);

    MP_WARN(vo, "Warning: this legacy VO has bad quality and performance, "
                "and will in particular result in blurry OSD and subtitles. "
                "You should fix your graphic drivers, or not force the xv VO.\n");
    return 0;

  error:
    uninit(vo);                 // free resources
    return -1;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
static int xv_check_extension( void )
{
    unsigned int version;
    unsigned int release;
    unsigned int dummy;
    unsigned int adaptors;
    unsigned int i;
    unsigned long j;
    int has_yuy2 = 0;
    XvAdaptorInfo *adaptorInfo;

    if( ( XvQueryExtension( display, &version, &release,
                            &dummy, &dummy, &dummy) != Success ) ||
         ( version < 2 ) || ( ( version == 2 ) && ( release < 2 ) ) ) {

        fprintf( stderr, "xvoutput: XVIDEO extension not found: X too old? didn't load extmod?\n" );
        return 0;
    }

    XvQueryAdaptors( display, output_window, &adaptors, &adaptorInfo );

    for( i = 0; i < adaptors; i++ ) {
        if( adaptorInfo[ i ].type & XvImageMask ) {
            for( j = 0; j < adaptorInfo[ i ].num_ports; j++ ) {
                if( xv_port_has_yuy2( adaptorInfo[ i ].base_id + j ) ) {
                    if( XvGrabPort( display, adaptorInfo[ i ].base_id + j, 0 ) == Success ) {
                        xv_port = adaptorInfo[ i ].base_id + j;
                        if( xvoutput_verbose ) {
                            fprintf( stderr, "xvoutput: Using XVIDEO adaptor %lu: %s.\n",
                                     adaptorInfo[ i ].base_id + j, adaptorInfo[ i ].name );
                        }
                        XvFreeAdaptorInfo( adaptorInfo );
                        return 1;
                    }
                    has_yuy2 = 1;
                }
            }
        }
    }

    XvFreeAdaptorInfo( adaptorInfo );

    if( has_yuy2 ) {
        fprintf( stderr, "xvoutput: No YUY2 XVIDEO port available.\n" );

        fprintf( stderr, "\n*** tvtime requires a hardware YUY2 overlay.  One is supported\n"
                           "*** by your driver, but we could not grab it.  It is likely\n"
                           "*** being used by another application, either another tvtime\n"
                           "*** instance or a media player.  Please shut down this other\n"
                           "*** application and try tvtime again.\n\n" );
    } else {
        fprintf( stderr, "xvoutput: No XVIDEO port found which supports YUY2 images.\n" );

        fprintf( stderr, "\n*** tvtime requires hardware YUY2 overlay support from your video card\n"
                           "*** driver.  If you are using an older NVIDIA card (TNT2), then\n"
                           "*** this capability is only available with their binary drivers.\n"
                           "*** For some ATI cards, this feature may be found in the experimental\n"
                           "*** GATOS drivers: http://gatos.sourceforge.net/\n"
                           "*** If unsure, please check with your distribution to see if your\n"
                           "*** X driver supports hardware overlay surfaces.\n\n" );
    }
    return 0;
}
Ejemplo n.º 10
0
Archivo: vo_xv.c Proyecto: kax4/mpv
static int preinit(struct vo *vo, const char *arg)
{
    XvPortID xv_p;
    int busy_ports = 0;
    unsigned int i;
    strarg_t ck_src_arg = { 0, NULL };
    strarg_t ck_method_arg = { 0, NULL };
    struct xvctx *ctx = talloc_zero(vo, struct xvctx);
    vo->priv = ctx;
    int xv_adaptor = -1;

    if (!vo_init(vo))
        return -1;

    struct vo_x11_state *x11 = vo->x11;

    const opt_t subopts[] =
    {
      /* name         arg type     arg var         test */
      {  "port",      OPT_ARG_INT, &x11->xv_port,  int_pos },
      {  "adaptor",   OPT_ARG_INT, &xv_adaptor,    int_non_neg },
      {  "ck",        OPT_ARG_STR, &ck_src_arg,    xv_test_ck },
      {  "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm },
      {  NULL }
    };

    x11->xv_port = 0;

    /* parse suboptions */
    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }

    /* modify colorkey settings according to the given options */
    xv_setup_colorkeyhandling(vo, ck_method_arg.str, ck_src_arg.str);

    /* check for Xvideo extension */
    unsigned int ver, rel, req, ev, err;
    if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
        mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] Sorry, Xv not supported by this X11 version/driver\n[VO_XV] ******** Try with  -vo x11 *********\n");
        goto error;
    }

    /* check for Xvideo support */
    if (Success !=
        XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
                        &ctx->adaptors, &ctx->ai)) {
        mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] XvQueryAdaptors failed.\n");
        goto error;
    }

    /* check adaptors */
    if (x11->xv_port) {
        int port_found;

        for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
            if ((ctx->ai[i].type & XvInputMask)
                && (ctx->ai[i].type & XvImageMask)) {
                for (xv_p = ctx->ai[i].base_id;
                     xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
                     ++xv_p) {
                    if (xv_p == x11->xv_port) {
                        port_found = 1;
                        break;
                    }
                }
            }
        }
        if (port_found) {
            if (XvGrabPort(x11->display, x11->xv_port, CurrentTime))
                x11->xv_port = 0;
        } else {
            mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Invalid port parameter, overriding with port 0.\n");
            x11->xv_port = 0;
        }
    }

    for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++) {
        /* check if adaptor number has been specified */
        if (xv_adaptor != -1 && xv_adaptor != i)
            continue;

        if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
            for (xv_p = ctx->ai[i].base_id;
                 xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
                if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
                    x11->xv_port = xv_p;
                    mp_msg(MSGT_VO, MSGL_V,
                           "[VO_XV] Using Xv Adapter #%d (%s)\n",
                           i, ctx->ai[i].name);
                    break;
                } else {
                    mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Could not grab port %i.\n",
                           (int) xv_p);
                    ++busy_ports;
                }
        }
    }
    if (!x11->xv_port) {
        if (busy_ports)
            mp_tmsg(MSGT_VO, MSGL_ERR,
                "[VO_XV] Could not find free Xvideo port - maybe another process is already\n"\
                "[VO_XV] using it. Close all video applications, and try again. If that does\n"\
                "[VO_XV] not help, see 'mpv -vo help' for other (non-xv) video out drivers.\n");
        else
            mp_tmsg(MSGT_VO, MSGL_ERR,
                "[VO_XV] It seems there is no Xvideo support for your video card available.\n"\
                "[VO_XV] Run 'xvinfo' to verify its Xv support and read\n"\
                "[VO_XV] DOCS/HTML/en/video.html#xv!\n"\
                "[VO_XV] See 'mpv -vo help' for other (non-xv) video out drivers.\n"\
                "[VO_XV] Try -vo x11.\n");
        goto error;
    }

    if (!vo_xv_init_colorkey(vo)) {
        goto error;             // bail out, colorkey setup failed
    }
    vo_xv_enable_vsync(vo);
    vo_xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);

    ctx->fo = XvListImageFormats(x11->display, x11->xv_port,
                                 (int *) &ctx->formats);

    ctx->osd_backup = talloc_steal(ctx, mp_draw_sub_backup_new());

    return 0;

  error:
    uninit(vo);                 // free resources
    return -1;
}
Ejemplo n.º 11
0
static void
gst_v4l_xoverlay_open (GstV4lElement * v4lelement)
{
  struct stat s;
  GstV4lXv *v4lxv;
  const gchar *name = g_getenv ("DISPLAY");
  unsigned int ver, rel, req, ev, err, anum;
  int i, id = 0, first_id = 0, min;
  XvAdaptorInfo *ai;
  Display *dpy;

  /* we need a display, obviously */
  if (!name || !(dpy = XOpenDisplay (name))) {
    GST_WARNING ("No $DISPLAY set or failed to open - no overlay");
    return;
  }

  /* First let's check that XVideo extension is available */
  if (!XQueryExtension (dpy, "XVideo", &i, &i, &i)) {
    GST_WARNING ("Xv extension not available - no overlay");
    XCloseDisplay (dpy);
    return;
  }

  /* find port that belongs to this device */
  if (XvQueryExtension (dpy, &ver, &rel, &req, &ev, &err) != Success) {
    GST_WARNING ("Xv extension not supported - no overlay");
    XCloseDisplay (dpy);
    return;
  }
  if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &anum, &ai) != Success) {
    GST_WARNING ("Failed to query Xv adaptors");
    XCloseDisplay (dpy);
    return;
  }
  if (fstat (v4lelement->video_fd, &s) < 0) {
    GST_ERROR ("Failed to stat() file descriptor: %s", g_strerror (errno));
    XCloseDisplay (dpy);
    return;
  }
  min = s.st_rdev & 0xff;
  for (i = 0; i < anum; i++) {
    if (!strcmp (ai[i].name, "video4linux")) {
      if (first_id == 0)
        first_id = ai[i].base_id;

      /* hmm... */
      if (first_id != 0 && ai[i].base_id == first_id + min)
        id = ai[i].base_id;
    }
  }
  XvFreeAdaptorInfo (ai);

  if (id == 0) {
    GST_WARNING ("Did not find XvPortID for device - no overlay");
    XCloseDisplay (dpy);
    return;
  }

  v4lxv = g_new0 (GstV4lXv, 1);
  v4lxv->dpy = dpy;
  v4lxv->port = id;
  v4lxv->mutex = g_mutex_new ();
  v4lxv->idle_id = 0;
  v4lelement->xv = v4lxv;

  if (v4lelement->xwindow_id) {
    gst_v4l_xoverlay_set_window_handle (GST_X_OVERLAY (v4lelement),
        v4lelement->xwindow_id);
  }
}
Ejemplo n.º 12
0
static int preinit(struct vo *vo)
{
    XvPortID xv_p;
    int busy_ports = 0;
    unsigned int i;
    struct xvctx *ctx = vo->priv;
    int xv_adaptor = ctx->cfg_xv_adaptor;

    if (!vo_x11_init(vo))
        return -1;

    struct vo_x11_state *x11 = vo->x11;

    /* check for Xvideo extension */
    unsigned int ver, rel, req, ev, err;
    if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
        MP_ERR(vo, "Xv not supported by this X11 version/driver\n");
        goto error;
    }

    /* check for Xvideo support */
    if (Success !=
        XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
                        &ctx->adaptors, &ctx->ai)) {
        MP_ERR(vo, "XvQueryAdaptors failed.\n");
        goto error;
    }

    /* check adaptors */
    if (ctx->xv_port) {
        int port_found;

        for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
            if ((ctx->ai[i].type & XvInputMask)
                && (ctx->ai[i].type & XvImageMask)) {
                for (xv_p = ctx->ai[i].base_id;
                     xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
                     ++xv_p) {
                    if (xv_p == ctx->xv_port) {
                        port_found = 1;
                        break;
                    }
                }
            }
        }
        if (port_found) {
            if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime))
                ctx->xv_port = 0;
        } else {
            MP_WARN(vo, "Invalid port parameter, overriding with port 0.\n");
            ctx->xv_port = 0;
        }
    }

    for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) {
        /* check if adaptor number has been specified */
        if (xv_adaptor != -1 && xv_adaptor != i)
            continue;

        if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
            for (xv_p = ctx->ai[i].base_id;
                 xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
                if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
                    ctx->xv_port = xv_p;
                    MP_VERBOSE(vo, "Using Xv Adapter #%d (%s)\n",
                               i, ctx->ai[i].name);
                    break;
                } else {
                    MP_WARN(vo, "Could not grab port %i.\n", (int) xv_p);
                    ++busy_ports;
                }
        }
    }
    if (!ctx->xv_port) {
        if (busy_ports)
            MP_ERR(vo,
                   "Could not find free Xvideo port - maybe another process is already\n"\
                   "using it. Close all video applications, and try again. If that does\n"\
                   "not help, see 'mpv -vo help' for other (non-xv) video out drivers.\n");
        else
            MP_ERR(vo,
                   "It seems there is no Xvideo support for your video card available.\n"\
                   "Run 'xvinfo' to verify its Xv support and read\n"\
                   "DOCS/HTML/en/video.html#xv!\n"\
                   "See 'mpv -vo help' for other (non-xv) video out drivers.\n"\
                   "Try -vo x11.\n");
        goto error;
    }

    if (!xv_init_colorkey(vo)) {
        goto error;             // bail out, colorkey setup failed
    }
    xv_enable_vsync(vo);
    xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);

    ctx->fo = XvListImageFormats(x11->display, ctx->xv_port,
                                 (int *) &ctx->formats);

    return 0;

  error:
    uninit(vo);                 // free resources
    return -1;
}
Ejemplo n.º 13
0
int xv_test_fourcc( Display *dpy, __u32 fourcc )
{
	unsigned int version, release;
	unsigned int request_base, event_base, error_base;
	
	int i;

	int num_adaptors;
	XvAdaptorInfo *p_adaptor_info;

	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 ), &num_adaptors, &p_adaptor_info ) != Success )
	{
#ifdef DEBUG
		fprintf( stderr, "XvQueryAdaptors failed\n" );
#endif
		return -1;
	}

	if( num_adaptors == 0 )
	{
		return -2;
	}
	

	for( i = 0; i < num_adaptors; i++ )
	{
		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
		if( XvQueryEncodings( dpy, p_adaptor_info[i].base_id, &num_encodings, &p_encoding_info ) != Success )
		{
			fprintf( stderr, "XvQueryEncodings failed\n" );
		}
#endif


		xvimage_formats = XvListImageFormats( dpy, p_adaptor_info[i].base_id, &num_xvimage_formats );
		for( format = 0; format < num_xvimage_formats; format++ )
		{
			if( xvimage_formats[format].id == fourcc )
			{
				return 1;
			}
		}

		return 0;
	}

	return 0;
}
Ejemplo n.º 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;
}
Ejemplo n.º 15
0
//------------------------------------
//
//------------------------------------
uint8_t GUI_XvInit(GUI_WindowInfo * window, uint32_t w, uint32_t h)
{


    unsigned int ver, rel, req, ev, err;
    unsigned int port, adaptors;
    static XvAdaptorInfo *ai;
    static XvAdaptorInfo *curai;
    
#if 0
    win = gtk_widget_get_parent_window(window);
    xv_display = GDK_WINDOW_XDISPLAY(win);
//      xv_win= RootWindow(xv_display,0);
    xv_win = GDK_WINDOW_XWINDOW(GTK_WIDGET(window)->window);
#endif    

    xv_display=(Display *)window->display;
    xv_win=window->window;
    
    
#define WDN xv_display
    xv_port = 0;

    if (Success != XvQueryExtension(WDN, &ver, &rel, &req, &ev, &err))
      {
	  printf("\n Query Extension failed\n");
	  goto failed;
      }
    /* check for Xvideo support */
    if (Success != XvQueryAdaptors(WDN,
				   DefaultRootWindow(WDN), &adaptors, &ai))
      {
	  printf("\n Query Adaptor failed\n");
	  goto failed;
      }
    curai = ai;
    XvFormat *formats;
    // Dump infos
    port = 0;
    for (uint16_t i = 0; (!port) && (i < adaptors); i++)
      {
/*
XvPortID base_id;
unsigned long num_ports;
char type;
char *name;
unsigned long num_formats;
XvFormat *formats;
unsigned long num_adaptors;
*/
#ifdef VERBOSE_XV
	  printf("\n_______________________________\n");
	  printf("\n Adaptor 		: %d", i);
	  printf("\n Base ID		: %ld", curai->base_id);
	  printf("\n Nb Port	 	: %lu", curai->num_ports);
	  printf("\n Type			 	: %d,",
		 curai->type);
#define CHECK(x) if(curai->type & x) printf("|"#x);
	  CHECK(XvInputMask);
	  CHECK(XvOutputMask);
	  CHECK(XvVideoMask);
	  CHECK(XvStillMask);
	  CHECK(XvImageMask);

	  printf("\n Name			 	: %s",
		 curai->name);
	  printf("\n Num Adap	 	: %lu", curai->num_adaptors);
	  printf("\n Num fmt	 	: %lu", curai->num_formats);
#endif	  
	  formats = curai->formats;

	  //
	  uint16_t k;

	  for (k = 0; (k < curai->num_ports) && !port; k++)
	    {
		if (GUI_XvList(WDN, k + curai->base_id, &xv_format))
		    port = k + curai->base_id;
	    }


	  curai++;
      }
    //
    if (!port)
      {
	  printf("\n no port found");
	  goto failed;
      }
#ifdef 	COLORSPACE_YV12
    printf("\n Xv YV12 found at port :%d, format : %ld", port, xv_format);
#else
    printf("\n Xv YUY2 found at port :%d, format : %ld", port, xv_format);
#endif

    if (Success != XvGrabPort(WDN, port, 0))
	goto failed;
    {
	
	xv_port = port;
/*
   Display *display,
   XvPortID port,
   int id,
   char* data,
   int width,
   int height,
   XShmSegmentInfo *shminfo

*/
        
        XSetWindowAttributes xswa;
        XWindowAttributes attribs;
        static Atom xv_atom;
        unsigned long xswamask;
        int erCode;

        /* check if colorkeying is needed */
        xv_atom = getAtom( "XV_AUTOPAINT_COLORKEY" );
        if(xv_atom!=None)
        {
                XvSetPortAttribute( xv_display, xv_port, xv_atom, 1 );
        }
        else printf("No autopaint \n");

        /* if we have to deal with colorkeying ... */
        
	xvimage = XvShmCreateImage(WDN, xv_port,
				   xv_format, 0, w, h, &Shminfo);

	Shminfo.shmid = shmget(IPC_PRIVATE, xvimage->data_size,
			       IPC_CREAT | 0777);
        if(Shminfo.shmid<=0)
        {
                printf("shmget failed\n");
        }
	Shminfo.shmaddr = (char *) shmat(Shminfo.shmid, 0, 0);
	Shminfo.readOnly = False;
        if(Shminfo.shmaddr==(char *)-1)
        {
                printf("Shmat failed\n");
        }
	xvimage->data = Shminfo.shmaddr;
	XShmAttach(WDN, &Shminfo);
	XSync(WDN, False);
	erCode=shmctl(Shminfo.shmid, IPC_RMID, 0);
        if(erCode)
        {
                printf("Shmctl failed :%d\n",erCode);
        }
	memset(xvimage->data, 0, xvimage->data_size);

	xv_xgc.graphics_exposures = False;

	xv_gc = XCreateGC(xv_display, xv_win, 0L, &xv_xgc);
	
	//ADM_assert(BadWindow!=XSelectInput(xv_display, xv_win, ExposureMask | VisibilityChangeMask));

    }
    printf("\n Xv init succeedeed\n");

    return 1;
  failed:
    printf("\n Xv init failed..\n");
    return 0;
}
Ejemplo n.º 16
0
void xf_tsmf_init(xfInfo* xfi, long xv_port)
{
	int ret;
	unsigned int i;
	unsigned int version;
	unsigned int release;
	unsigned int event_base;
	unsigned int error_base;
	unsigned int request_base;
	unsigned int num_adaptors;
	xfXvContext* xv;
	XvAdaptorInfo* ai;
	XvAttribute* attr;
	XvImageFormatValues* fo;

	xv = (xfXvContext*) malloc(sizeof(xfXvContext));
	ZeroMemory(xv, sizeof(xfXvContext));

	xfi->xv_context = xv;

	xv->xv_colorkey_atom = None;
	xv->xv_image_size = 0;
	xv->xv_port = xv_port;

	if (!XShmQueryExtension(xfi->display))
	{
		DEBUG_XV("no shmem available.");
		return;
	}

	ret = XvQueryExtension(xfi->display, &version, &release, &request_base, &event_base, &error_base);
	if (ret != Success)
	{
		DEBUG_XV("XvQueryExtension failed %d.", ret);
		return;
	}
	DEBUG_XV("version %u release %u", version, release);

	ret = XvQueryAdaptors(xfi->display, DefaultRootWindow(xfi->display),
		&num_adaptors, &ai);
	if (ret != Success)
	{
		DEBUG_XV("XvQueryAdaptors failed %d.", ret);
		return;
	}

	for (i = 0; i < num_adaptors; i++)
	{
		DEBUG_XV("adapter port %ld-%ld (%s)", ai[i].base_id,
			ai[i].base_id + ai[i].num_ports - 1, ai[i].name);
		if (xv->xv_port == 0 && i == num_adaptors - 1)
			xv->xv_port = ai[i].base_id;
	}

	if (num_adaptors > 0)
		XvFreeAdaptorInfo(ai);

	if (xv->xv_port == 0)
	{
		DEBUG_XV("no adapter selected, video frames will not be processed.");
		return;
	}
	DEBUG_XV("selected %ld", xv->xv_port);

	attr = XvQueryPortAttributes(xfi->display, xv->xv_port, &ret);
	for (i = 0; i < (unsigned int)ret; i++)
	{
		if (strcmp(attr[i].name, "XV_COLORKEY") == 0)
		{
			xv->xv_colorkey_atom = XInternAtom(xfi->display, "XV_COLORKEY", FALSE);
			XvSetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, attr[i].min_value + 1);
			break;
		}
	}
	XFree(attr);

#ifdef WITH_DEBUG_XV
	fprintf(stderr, "xf_tsmf_init: pixel format ");
#endif
	fo = XvListImageFormats(xfi->display, xv->xv_port, &ret);
	if (ret > 0)
	{
		xv->xv_pixfmts = (UINT32*) malloc((ret + 1) * sizeof(UINT32));
		ZeroMemory(xv->xv_pixfmts, (ret + 1) * sizeof(UINT32));

		for (i = 0; i < ret; i++)
		{
			xv->xv_pixfmts[i] = fo[i].id;
#ifdef WITH_DEBUG_XV
			fprintf(stderr, "%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1],
				((char*)(xv->xv_pixfmts + i))[2], ((char*)(xv->xv_pixfmts + i))[3]);
#endif
		}
		xv->xv_pixfmts[i] = 0;
	}
	XFree(fo);
#ifdef WITH_DEBUG_XV
	fprintf(stderr, "\n");
#endif
}
Ejemplo n.º 17
0
int find_yuv_port(Display* display, XvPortID* port, fourcc_t* format)
{
  int i, j, k;

  /* XvQueryExtension */
  unsigned int version, release, request_base, event_base, error_base;

  /* XvQueryAdaptors */
  unsigned int num_adaptors;
  XvAdaptorInfo* adaptor_info = NULL;
  XvPortID port_id;

  /* XvListImageFormats */
  int num_formats;
  XvImageFormatValues* format_list = NULL;

  switch (XvQueryExtension(display, &version, &release,
			   &request_base, &event_base, &error_base))
  {
  case Success:
    break;
  case XvBadExtension:
    printf("XvQueryExtension returned XvBadExtension.\n");
    return 0;
  case XvBadAlloc:
    printf("XvQueryExtension returned XvBadAlloc.\n");
    return 0;
  default:
    printf("XvQueryExtension returned unknown error.\n");
    return 0;
  }

  switch (XvQueryAdaptors(display, DefaultRootWindow(display),
			  &num_adaptors, &adaptor_info))
  {
  case Success:
    break;
  case XvBadExtension:
    printf("XvQueryAdaptors returned XvBadExtension.\n");
    return 0;
  case XvBadAlloc:
    printf("XvQueryAdaptors returned XvBadAlloc.\n");
    return 0;
  default:
    printf("XvQueryAdaptors returned unknown error.\n");
    return 0;
  }

  /* Find YUV capable adaptor. */
  for (i = 0; i < (int)num_adaptors; i++) {
    if (!(adaptor_info[i].type & XvInputMask
	  && adaptor_info[i].type & XvImageMask))
    {
      continue;
    }

    format_list = XvListImageFormats(display, adaptor_info[i].base_id,
				     &num_formats);

    for (j = 0; j < (int)(sizeof(fourcc_list) / sizeof(*fourcc_list)); j++) {
      if (format->id && fourcc_list[j].id != format->id) {
	continue;
      }
      for (k = 0; k < num_formats; k++) {
	if (format_list[k].id != fourcc_list[j].id) {
	  continue;
	}

	for (port_id = adaptor_info[i].base_id;
	     port_id < adaptor_info[i].base_id + adaptor_info[i].num_ports;
	     port_id++)
	  {
	    if (XvGrabPort(display, port_id, CurrentTime) != Success) {
	      continue;
	    }
	    *port = port_id;
	    *format = fourcc_list[j];
	    XFree(format_list);
	    XvFreeAdaptorInfo(adaptor_info);
	    return 1;
	  }
      }
    }

    XFree(format_list);
  }

  XvFreeAdaptorInfo(adaptor_info);
  printf("No suitable Xv YUV adaptor/port available.\n");
  return 0;
}
Ejemplo n.º 18
0
int find_yuv_port(Display* display, XvPortID* port, fourcc_t* format, int *overlay)
{
    int i, j, k, found_one = 0, is_overlay;

    /* XvQueryExtension */
    unsigned int version, release, request_base, event_base, error_base;

    /* XvQueryAdaptors */
    unsigned int num_adaptors;
    XvAdaptorInfo* adaptor_info = NULL;
    XvPortID port_id;

    /* XvListImageFormats */
    int num_formats;
    XvImageFormatValues* format_list = NULL;

    switch (XvQueryExtension(display, &version, &release, &request_base, &event_base, &error_base)) {
        case Success:
            break;
        case XvBadExtension:
            printf("XvQueryExtension returned XvBadExtension.\n");
            return 0;
        case XvBadAlloc:
            printf("XvQueryExtension returned XvBadAlloc.\n");
            return 0;
        default:
            printf("XvQueryExtension returned unknown error.\n");
            return 0;
    }

    switch (XvQueryAdaptors(display, DefaultRootWindow(display), &num_adaptors, &adaptor_info)) {
        case Success:
            break;
        case XvBadExtension:
            printf("XvQueryAdaptors returned XvBadExtension.\n");
            return 0;
        case XvBadAlloc:
            printf("XvQueryAdaptors returned XvBadAlloc.\n");
            return 0;
        default:
            printf("XvQueryAdaptors returned unknown error.\n");
            return 0;
    }

    /* Find YUV capable adaptor. */
    for (i = 0; i < (int)num_adaptors; i++) {
        if (!(adaptor_info[i].type & XvInputMask && adaptor_info[i].type & XvImageMask)) {
            continue;
        }
        /* Textured video is not an overlay */
        is_overlay = !strstr(adaptor_info[i].name, "Textured");

        format_list = XvListImageFormats(display, adaptor_info[i].base_id, &num_formats);

        for (j = 0; j < (int)(sizeof(fourcc_list) / sizeof(*fourcc_list)); j++) {
            if (format->id && fourcc_list[j].id != format->id) {
                continue;
            }
            for (k = 0; k < num_formats; k++) {
                if (format_list[k].id != fourcc_list[j].id) {
                    continue;
                }

                for (port_id = adaptor_info[i].base_id; port_id < adaptor_info[i].base_id + adaptor_info[i].num_ports; port_id++) {
                    if (XvGrabPort(display, port_id, CurrentTime) != Success) {
                        continue;
                    }
                    if (found_one) {
                        if (!*overlay && is_overlay) {
                            XvUngrabPort(display, port_id, CurrentTime);
                            continue; /* Prefer non-overlay as that one can handle more than one windows */
                        }
                        XvUngrabPort(display, *port, CurrentTime);
                    }
                    *port = port_id;
                    *format = fourcc_list[j];
                    *overlay = is_overlay;
                    found_one = 1;
                }
            }
        }
        XFree(format_list);
    }
    XvFreeAdaptorInfo(adaptor_info);
    if (!found_one) {
        printf("No suitable Xv YUV adaptor/port available.\n");
    }
    return found_one;
}
Ejemplo n.º 19
0
int main (int argc, char* argv[]) {
  int		yuv_width = 1024;
  int		yuv_height = 768;
  
  int		xv_port = -1;
  int		adaptor, encodings, attributes, formats;
  int		i, j, ret, p, _d, _w, _h;
  long		secsb, secsa, frames;
  
  XvAdaptorInfo		*ai;
  XvEncodingInfo	*ei;
  XvAttribute		*at;
  XvImageFormatValues	*fo;

  XvImage		*yuv_image;

#define GUID_YUV12_PLANAR 0x32315659

  unsigned int		p_version, p_release,
  			p_request_base, p_event_base, p_error_base;
  int			p_num_adaptors;
   	
  Display		*dpy;
  Window		window, _dw;
  XSizeHints		hint;
  XSetWindowAttributes	xswa;
  XVisualInfo		vinfo;
  int			screen;
  unsigned long		mask;
  XEvent		event;
  GC			gc;

  /** for shm */
  int 			shmem_flag = 0;
  XShmSegmentInfo	yuv_shminfo;
  int			CompletionType;


  printf("starting up video testapp...\n\n");
  
  adaptor = -1;
	
  dpy = XOpenDisplay(NULL);
  if (dpy == NULL) {
    printf("Cannot open Display.\n");
    exit (-1);
  }
  
  screen = DefaultScreen(dpy);
  
  /** find best display */
  if (XMatchVisualInfo(dpy, screen, 24, TrueColor, &vinfo)) {
    printf(" found 24bit TrueColor\n");
  } else
    if (XMatchVisualInfo(dpy, screen, 16, TrueColor, &vinfo)) {
      printf(" found 16bit TrueColor\n");
    } else
      if (XMatchVisualInfo(dpy, screen, 15, TrueColor, &vinfo)) {
	printf(" found 15bit TrueColor\n");
      } else
  	if (XMatchVisualInfo(dpy, screen, 8, PseudoColor, &vinfo)) {
	  printf(" found 8bit PseudoColor\n");
  	} else
	  if (XMatchVisualInfo(dpy, screen, 8, GrayScale, &vinfo)) {
	    printf(" found 8bit GrayScale\n");
	  } else
	    if (XMatchVisualInfo(dpy, screen, 8, StaticGray, &vinfo)) {
	      printf(" found 8bit StaticGray\n");
	    } else
	      if (XMatchVisualInfo(dpy, screen, 1, StaticGray, &vinfo)) {
  		printf(" found 1bit StaticGray\n");
	      } else {
  		printf("requires 16 bit display\n");
  		exit (-1);
	      }
  
  CompletionType = -1;	
  
  hint.x = 1;
  hint.y = 1;
  hint.width = yuv_width;
  hint.height = yuv_height;
  hint.flags = PPosition | PSize;
  
  xswa.colormap =  XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual, AllocNone);
  xswa.event_mask = StructureNotifyMask | ExposureMask;
  xswa.background_pixel = 0;
  xswa.border_pixel = 0;
  
  mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  
  window = XCreateWindow(dpy, DefaultRootWindow(dpy),
			 0, 0,
			 yuv_width,
			 yuv_height,
			 0, vinfo.depth,
			 InputOutput,
			 vinfo.visual,
			 mask, &xswa);
  
  XStoreName(dpy, window, "XV");
  XSetIconName(dpy, window, "XV");
  
  XSelectInput(dpy, window, StructureNotifyMask);
  
  /** Map window */
  XMapWindow(dpy, window);
  
  /** Wait for map. */
  do {
    XNextEvent(dpy, &event);
  }
  while (event.type != MapNotify || event.xmap.event != window);
  
  if (XShmQueryExtension(dpy)) shmem_flag = 1;
  if (!shmem_flag) {
    printf("no shmem available.\n");
    exit (-1);
  }
  
  if (shmem_flag==1) CompletionType = XShmGetEventBase(dpy) + ShmCompletion;
  
  
  /**--------------------------------- XV ------------------------------------*/
  printf("beginning to parse the Xvideo extension...\n\n");
  
  /** query and print Xvideo properties */
  ret = XvQueryExtension(dpy, &p_version, &p_release, &p_request_base,
			 &p_event_base, &p_error_base);
  if (ret != Success) {
    if (ret == XvBadExtension)
      printf("XvBadExtension returned at XvQueryExtension.\n");
    else
      if (ret == XvBadAlloc)
	printf("XvBadAlloc returned at XvQueryExtension.\n");
      else
	printf("other error happened at XvQueryExtension.\n");
  }
  printf("========================================\n");
  printf("XvQueryExtension returned the following:\n");
  printf("p_version      : %u\n", p_version);
  printf("p_release      : %u\n", p_release);
  printf("p_request_base : %u\n", p_request_base);
  printf("p_event_base   : %u\n", p_event_base);
  printf("p_error_base   : %u\n", p_error_base);
  printf("========================================\n");
  
  ret = XvQueryAdaptors(dpy, DefaultRootWindow(dpy),
			&p_num_adaptors, &ai);
  
  if (ret != Success) {
    if (ret == XvBadExtension)
      printf("XvBadExtension returned at XvQueryExtension.\n");
    else
      if (ret == XvBadAlloc)
	printf("XvBadAlloc returned at XvQueryExtension.\n");
      else
	printf("other error happaned at XvQueryAdaptors.\n");
  }
  printf("=======================================\n");
  printf("XvQueryAdaptors returned the following:\n");
  printf("%d adaptors available.\n", p_num_adaptors);
  for (i = 0; i < p_num_adaptors; i++) {
    printf(" name:        %s\n"
	   " type:        %s%s%s%s%s\n"
	   " ports:       %ld\n"
	   " first port:  %ld\n",
	   ai[i].name,
	   (ai[i].type & XvInputMask)	? "input | "	: "",
	   (ai[i].type & XvOutputMask)	? "output | "	: "",
	   (ai[i].type & XvVideoMask)	? "video | "	: "",
	   (ai[i].type & XvStillMask)	? "still | "	: "",
	   (ai[i].type & XvImageMask)	? "image | "	: "",
	   ai[i].num_ports,
	   ai[i].base_id);
    xv_port = ai[i].base_id;
    
    printf("adaptor %d ; format list:\n", i);
    for (j = 0; j < ai[i].num_formats; j++) {
      printf(" depth=%d, visual=%ld\n",
	     ai[i].formats[j].depth,
	     ai[i].formats[j].visual_id);
    }
    for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
      
      printf(" encoding list for port %d\n", p);
      if (XvQueryEncodings(dpy, p, &encodings, &ei) != Success) {
	printf("XvQueryEncodings failed.\n");
	continue;
      }
      for (j = 0; j < encodings; j++) {
	printf("  id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n",
	       ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
	       ei[j].rate.numerator, ei[j].rate.denominator);
      }
      XvFreeEncodingInfo(ei);
      
      printf(" attribute list for port %d\n", p);
      at = XvQueryPortAttributes(dpy, p, &attributes);
      for (j = 0; j < attributes; j++) {
	printf("  name:       %s\n"
	       "  flags:     %s%s\n"
	       "  min_color:  %i\n"
	       "  max_color:  %i\n",
	       at[j].name,
	       (at[j].flags & XvGettable) ? " get" : "",
	       (at[j].flags & XvSettable) ? " set" : "",						
	       at[j].min_value, at[j].max_value);
      }
      if (at)
	XFree(at);
      
      printf(" image format list for port %d\n", p);
      fo = XvListImageFormats(dpy, p, &formats);
      for (j = 0; j < formats; j++) {
	printf("  0x%x (%4.4s) %s\n",
	       fo[j].id,
	       (char *)&fo[j].id,
	       (fo[j].format == XvPacked) ? "packed" : "planar");
      }
      if (fo)
	XFree(fo);
    }
    printf("\n");
  }
  if (p_num_adaptors > 0)
    XvFreeAdaptorInfo(ai);
  if (xv_port == -1)
    exit (0);
  
  gc = XCreateGC(dpy, window, 0, 0);		
  
  yuv_image = XvShmCreateImage(dpy, xv_port, GUID_YUV12_PLANAR, 0, yuv_width, yuv_height, &yuv_shminfo);
  yuv_shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777);
  yuv_shminfo.shmaddr = yuv_image->data = shmat(yuv_shminfo.shmid, 0, 0);
  yuv_shminfo.readOnly = False;
  
  if (!XShmAttach(dpy, &yuv_shminfo)) {
    printf("XShmAttach failed !\n");
    exit (-1);
  }
  
  for (i = 0; i < yuv_image->height; i++) {
    for (j = 0; j < yuv_image->width; j++) {
      yuv_image->data[yuv_image->width*i + j] = i*j;
    }
  }
  
  printf("%d\n", yuv_image->data_size);
  int joe = 0;
  while (1) {
    frames = secsa = secsb = 0;
    time(&secsa);
    while (frames < 200) {	
        XGetGeometry(dpy, window, &_dw, &_d, &_d, &_w, &_h, &_d, &_d);
        for (i = 0; i < yuv_image->height * 1.5; i++) {
            for (j = 0; j < yuv_image->width; j++) {
                yuv_image->data[yuv_image->width*i + j] = (i + j + joe / 5);
            }
        }
   
      XvShmPutImage(dpy, xv_port, window, gc, yuv_image,
		    0, 0, yuv_image->width, yuv_image->height,
		    0, 0, _w, _h, True);
      
      /* XFlush(dpy); */
      joe++;
      frames++;
    }
    time(&secsb);
    printf("%ld frames in %ld seconds; %.4f fps\n", frames, secsb-secsa, (double) frames/(secsb-secsa));
  }
  
  return 0;
}
Ejemplo n.º 20
0
static void x11video_prepare(MSFilter *f){
	X11Video *s=(X11Video*)f->data;
	unsigned int n;
	unsigned int nadaptors;
	int i;
	XvAdaptorInfo *xai=NULL;
	XvPortID port=-1;
	int imgfmt_id=0;
	XShmSegmentInfo *shminfo=&s->shminfo;
	XWindowAttributes wa = {0};

	if (s->display==NULL) return;
	if (s->window_id==0){
		if(s->auto_window) {
			s->window_id=createX11Window(s);
		}
		if (s->window_id==0) return;
		s->own_window=TRUE;
	}

	/* Make sure X11 window is ready to use*/
	XSync(s->display, False);

	if (s->own_window==FALSE){
		/*we need to register for resize events*/
		XSelectInput(s->display,s->window_id,StructureNotifyMask);
	}
	XGetWindowAttributes(s->display,s->window_id,&wa);
	XClearWindow(s->display,s->window_id);
	ms_message("x11video_prepare(): Window has size %ix%i, received video is %ix%i",wa.width,wa.height,s->vsize.width,s->vsize.height);

	if (wa.width<MS_LAYOUT_MIN_SIZE || wa.height<MS_LAYOUT_MIN_SIZE){
		return;
	}

	s->wsize.width=wa.width;
	s->wsize.height=wa.height;
	s->fbuf.w=s->vsize.width;
	s->fbuf.h=s->vsize.height;

	s->port=-1;
	if (XvQueryExtension(s->display, &n, &n, &n, &n, &n)!=0){
		ms_error("Fail to query xv extension");
		return;
	}

	if (XShmQueryExtension(s->display)==0){
		ms_error("Fail to query xshm extension");
		return;
	}

	if (XvQueryAdaptors(s->display,DefaultRootWindow(s->display),
	                                 &nadaptors, &xai)!=0){
		ms_error("XvQueryAdaptors failed.");
		return;
	}

	for (n=0;n<nadaptors && port==-1;++n){
		XvAdaptorInfo *ai=&xai[n];
		XvImageFormatValues *imgfmt;
		int nimgfmt=0;

		ms_message("Found output adaptor; name=%s num_ports=%i, with %i formats:",
		           ai->name,(int)ai->num_ports,(int)ai->num_formats);
		imgfmt=XvListImageFormats(s->display,ai->base_id,&nimgfmt);
		for(i=0;i<nimgfmt;++i){
			char fcc[5]={0};
			memcpy(fcc,&imgfmt[i].id,4);
			ms_message("type=%s/%s id=%s",
			           imgfmt[i].type == XvYUV ? "YUV" : "RGB",
			            imgfmt[i].format==XvPlanar ? "Planar" : "Packed",fcc);
			if (port==-1 && imgfmt[i].format==XvPlanar && strcasecmp(fcc,"YV12")==0){
				int k;
				/*we found a format interesting to us*/
				for(k=0;k<ai->num_ports;++k){
					if (XvGrabPort(s->display,ai->base_id+k,CurrentTime)==0){
						ms_message("Grabbed port %i",(int)ai->base_id+k);
						port=ai->base_id+k;
						imgfmt_id=imgfmt[i].id;
						break;
					}
				}
			}
		}
		if (imgfmt) XFree(imgfmt);
	}
	XvFreeAdaptorInfo(xai);
	if (port==-1){
		ms_error("Could not find suitable format or Xv port to work with.");
		return;
	}
	s->port=port;

	/*create the shared memory XvImage*/
	memset(shminfo,0,sizeof(*shminfo));
	s->xv_image=XvShmCreateImage(s->display,s->port,imgfmt_id,NULL,s->fbuf.w,s->fbuf.h,shminfo);
	if (s->xv_image==NULL){
		ms_error("XvShmCreateImage failed.");
		x11video_unprepare(f);
		return;
	}
	/*allocate some shared memory to receive the pixel data */
	shminfo->shmid=shmget(IPC_PRIVATE, s->xv_image->data_size,IPC_CREAT | 0777);
	if (shminfo->shmid==-1){
		ms_error("Could not allocate %i bytes of shared memory: %s",
		         s->xv_image->data_size,
		         strerror(errno));
		x11video_unprepare(f);
		return;
	}
	shminfo->shmaddr=shmat(shminfo->shmid,NULL,0);
	if (shminfo->shmaddr==(void*)-1){
		ms_error("shmat() failed: %s",strerror(errno));
		shminfo->shmaddr=NULL;
		x11video_unprepare(f);
		return;
	}
	/*ask the x-server to attach this shared memory segment*/
	x11_error=FALSE;
	if (!XShmAttach(s->display,shminfo)){
		ms_error("XShmAttach failed !");
		x11video_unprepare(f);
		return ;
	}
	s->xv_image->data=s->shminfo.shmaddr;
	s->fbuf.planes[0]=(void*)s->xv_image->data;
	s->fbuf.planes[2]=s->fbuf.planes[0]+(s->xv_image->height*s->xv_image->pitches[0]);
	s->fbuf.planes[1]=s->fbuf.planes[2]+((s->xv_image->height/2)*s->xv_image->pitches[1]);
	s->fbuf.strides[0]=s->xv_image->pitches[0];
	s->fbuf.strides[2]=s->xv_image->pitches[1];
	s->fbuf.strides[1]=s->xv_image->pitches[2];

	/* set picture black */
	x11video_fill_background(f);

	/*Create a GC*/
	s->gc=XCreateGC(s->display,s->window_id,0,NULL);
	if (s->gc==NULL){
		ms_error("XCreateGC() failed.");
		x11video_unprepare(f);
		return ;
	}

	s->ready=TRUE;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
int XVWindow::init(Display* dp, Window rootWindow, 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 i;
	unsigned int ver, rel, req, ev, err, adapt;
	XSetWindowAttributes xswattributes;
	XWindowAttributes xwattributes;
	XVisualInfo xvinfo;
	XvAdaptorInfo *xvainfo;
	unsigned int candidateXVPort=0;
	unsigned int busyPorts=0;

	_display=dp;
	_rootWindow=rootWindow;
	_state.origLayer=0;

	// initialize atoms
	WM_DELETE_WINDOW = XInternAtom(_display, "WM_DELETE_WINDOW", False);
	XA_WIN_PROTOCOLS = XInternAtom(_display, "_WIN_PROTOCOLS", False);
	XA_NET_SUPPORTED = XInternAtom(_display, "_NET_SUPPORTED", False);
	XA_NET_WM_STATE = XInternAtom(_display, "_NET_WM_STATE", False);
	XA_NET_WM_STATE_FULLSCREEN = XInternAtom(_display, "_NET_WM_STATE_FULLSCREEN", False);
	XA_NET_WM_STATE_ABOVE = XInternAtom(_display, "_NET_WM_STATE_ABOVE", False);
	XA_NET_WM_STATE_STAYS_ON_TOP = XInternAtom(_display, "_NET_WM_STATE_STAYS_ON_TOP", False);
	XA_NET_WM_STATE_BELOW = XInternAtom(_display, "_NET_WM_STATE_BELOW", False);

	XGetWindowAttributes(_display, _rootWindow, &xwattributes);
	XMatchVisualInfo(_display, DefaultScreen(_display), xwattributes.depth, TrueColor, &xvinfo);

	// define window properties and create the window
	xswattributes.colormap = XCreateColormap(_display, _rootWindow, xvinfo.visual, AllocNone);
	xswattributes.event_mask = StructureNotifyMask | ExposureMask;
	xswattributes.background_pixel = 0;
	xswattributes.border_pixel = 0;
	_XVWindow = XCreateWindow(_display, _rootWindow, x, y, windowWidth, windowHeight, 0, xvinfo.depth,
	 	InputOutput, xvinfo.visual, CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &xswattributes);

	// define inputs events
	XSelectInput(_display, _XVWindow, StructureNotifyMask | KeyPressMask | ButtonPressMask);

	setSizeHints(DEFAULT_X,DEFAULT_Y, imageWidth, imageHeight, windowWidth, windowHeight);

	// map the window
	XMapWindow(_display, _XVWindow);

	XSetWMProtocols(_display, _XVWindow, &WM_DELETE_WINDOW,1);

	// check if SHM XV window is possible
	if (Success != XvQueryExtension(_display, &ver, &rel, &req, &ev, &err)) {
		LOG_DEBUG("[x11] XQueryExtension failed");
		return 0;
	}
	if (!XShmQueryExtension(_display)) {
		LOG_DEBUG("[x11] XQueryShmExtension failed");
		return 0;
	}
	if (Success != XvQueryAdaptors(_display, _rootWindow, &adapt, &xvainfo)) {
		LOG_DEBUG("[x11] XQueryAdaptor failed"); XFree(xvainfo);
		return 0;
	}

	// look for a usable XV port
	for (i = 0; i < adapt && _XVPort == 0; i++) {
		if ((xvainfo[i].type & XvInputMask) && (xvainfo[i].type & XvImageMask)) {
			for (candidateXVPort = xvainfo[i].base_id; candidateXVPort < xvainfo[i].base_id + xvainfo[i].num_ports; ++candidateXVPort)
				if (!XvGrabPort(_display, candidateXVPort, CurrentTime)) {
					_XVPort = candidateXVPort;
					break;
				} else {
					LOG_DEBUG("[x11] Could not grab port: " + String::fromNumber(candidateXVPort));
					++busyPorts;
				}
		}
	}
	XvFreeAdaptorInfo(xvainfo);

	if (!_XVPort) {
		if (busyPorts) {
			LOG_WARN("[x11] Could not find free Xvideo port - maybe another process is already using it.");
		} else {
			LOG_WARN("[x11] It seems there is no Xvideo support for your video card available.");
		}
		return 0;
	} else {
		LOG_WARN("[x11] Use XVideo port: " + String::fromNumber(_XVPort));
	}

	_gc = XCreateGC(_display, _XVWindow, 0, 0);

	// create the shared memory portion
	_XVImage = XvShmCreateImage(_display, _XVPort, GUID_I420_PLANAR, 0, imageWidth, imageHeight, &_XShmInfo);

	_XShmInfo.shmid = shmget(IPC_PRIVATE, _XVImage->data_size, IPC_CREAT | 0777);
	_XShmInfo.shmaddr = (char *) shmat(_XShmInfo.shmid, 0, 0);
	_XVImage->data = _XShmInfo.shmaddr;
	_XShmInfo.readOnly = False;
	if (!XShmAttach(_display, &_XShmInfo)) {
		LOG_WARN("[x11] XShmAttach failed");
		return 0;
	} else {
		_isInitialized = true;
	}

	// detect the window manager type
	_wmType=getWMType();

	return 1;
}
// setup x or xvideo
void ffmpegWidget::xvSetup() {
    XvAdaptorInfo * ainfo;
    XvEncodingInfo *encodings;
    unsigned int adaptors, nencode;
    unsigned int ver, rel, extmaj, extev, exterr;
    // get display number
    this->dpy = x11Info().display();
    // Grab the window id and setup a graphics context
    this->w = this->winId();
    this->gc = XCreateGC(this->dpy, this->w, 0, 0);
    // Now try and setup xv
    // return version and release of extension
    if (XvQueryExtension(this->dpy, &ver, &rel, &extmaj, &extev, &exterr) != Success) {
        printf("XvQueryExtension failed, using QImage fallback mode\n");
        return;
    }
    //printf("Ver: %d, Rel: %d, ExtMajor: %d, ExtEvent: %d, ExtError: %d\n", ver, rel, extmaj, extev, exterr);
    //Ver: 2, Rel: 2, ExtMajor: 140, ExtEvent: 75, ExtError: 150
    // return adaptor information for the screen
    if (XvQueryAdaptors(this->dpy, QX11Info::appRootWindow(),
            &adaptors, &ainfo) != Success) {
        printf("XvQueryAdaptors failed, using QImage fallback mode\n");
        return;
    }
    // see if we have any adapters
    if (adaptors <= 0) {
        printf("No xv adaptors found, using QImage fallback mode\n");
        return;
    }
    // grab the port from the first adaptor
    int gotPort = 0;
    for(int p = 0; p < (int) ainfo[0].num_ports; p++) {
        if(XvGrabPort(this->dpy, ainfo[0].base_id + p, CurrentTime) == Success) {
            this->xv_port = ainfo[0].base_id + p;
            gotPort = 1;
            break;
        }
    }
    // if we didn't find a port
    if (!gotPort) {
        printf("No xv ports free, using QImage fallback mode\n");
        return;
    }
    // get max XV Image size
    int gotEncodings = 0;
    XvQueryEncodings(this->dpy, ainfo[0].base_id, &nencode, &encodings);
    if (encodings && nencode && (ainfo[0].type & XvImageMask)) {
        for(unsigned int n = 0; n < nencode; n++) {
            if(!strcmp(encodings[n].name, "XV_IMAGE")) {
                this->maxW = encodings[n].width;
                this->maxH = encodings[n].height;
                gotEncodings = 1;
                break;
            }
        }
    }
    // if we didn't find a list of encodings
    if (!gotEncodings) {
        printf("No encodings information, using QImage fallback mode\n");
        return;
    }
    // only support I420 mode for now
    int num_formats = 0;
    XvImageFormatValues * vals = XvListImageFormats(this->dpy,
        this->xv_port, &num_formats);
    for (int i=0; i<num_formats; i++) {
        if (strcmp(vals->guid, "I420") == 0) {
            this->xv_format = vals->id;
            this->ff_fmt = PIX_FMT_YUVJ420P;
            // Widget is responsible for painting all its pixels with an opaque color
            setAttribute(Qt::WA_OpaquePaintEvent);
            setAttribute(Qt::WA_PaintOnScreen);
            return;
        }
        vals++;
    }
    printf("Display doesn't support I420 mode, using QImage fallback mode\n");
    return;
}
Ejemplo n.º 24
0
SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
{
	SDL_Overlay *overlay;
	struct private_yuvhwdata *hwdata;
	int xv_port;
	int i, j;
	int adaptors;
	XvAdaptorInfo *ainfo;
	XShmSegmentInfo *yuvshm;

	xv_port = -1;
	if ( (Success == XvQueryExtension(GFX_Display, &j, &j, &j, &j, &j)) &&
	     (Success == XvQueryAdaptors(GFX_Display,
	                                 RootWindow(GFX_Display, SDL_Screen),
	                                 &adaptors, &ainfo)) ) {
		for ( i=0; (i<adaptors) && (xv_port == -1); ++i ) {
			if ( (ainfo[i].type & XvInputMask) &&
			     (ainfo[i].type & XvImageMask) ) {
				int num_formats;
				XvImageFormatValues *formats;
				formats = XvListImageFormats(GFX_Display,
				              ainfo[i].base_id, &num_formats);
				for ( j=0; j<num_formats; ++j ) {
					if ( (Uint32)formats[j].id == format ) {
						xv_port = ainfo[i].base_id;
						break;
					}
				}
			}
		}
	}
	if ( xv_port == -1 ) {
		SDL_SetError("No available video ports for requested format");
		return(NULL);
	}

	/* Create the overlay structure */
	overlay = (SDL_Overlay *)malloc(sizeof *overlay);
	if ( overlay == NULL ) {
		SDL_OutOfMemory();
		return(NULL);
	}
	memset(overlay, 0, (sizeof *overlay));

	/* Fill in the basic members */
	overlay->format = format;
	overlay->w = width;
	overlay->h = height;

	/* Set up the YUV surface function structure */
	overlay->hwfuncs = &x11_yuvfuncs;

	/* Create the pixel data and lookup tables */
	hwdata = (struct private_yuvhwdata *)malloc(sizeof *hwdata);
	overlay->hwdata = hwdata;
	if ( hwdata == NULL ) {
		SDL_OutOfMemory();
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	yuvshm = &hwdata->yuvshm;
	memset(yuvshm, 0, sizeof(*yuvshm));
	hwdata->port = xv_port;
	hwdata->image = XvShmCreateImage(GFX_Display, xv_port, format,
	                                 0, width, height, yuvshm);
	if ( hwdata->image == NULL ) {
		SDL_OutOfMemory();
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
	                       IPC_CREAT | 0777);
	if ( yuvshm->shmid < 0 ) {
		SDL_SetError("Unable to get %d bytes shared memory",
		             hwdata->image->data_size);
		SDL_FreeYUVOverlay(overlay);
		return(NULL);
	}
	yuvshm->shmaddr  = (caddr_t) shmat(yuvshm->shmid, 0, 0);
	yuvshm->readOnly = False;
	hwdata->image->data = yuvshm->shmaddr;

	XShmAttach(GFX_Display, yuvshm);
	XSync(GFX_Display, False);
	shmctl(yuvshm->shmid, IPC_RMID, 0);

	/* We're all done.. */
	return(overlay);
}