Пример #1
0
yuv_image decode_frame(const xyuv::frame &frame_in) {

    // Determine the size of each plane.
    bool has_y = !frame_in.format.channel_blocks[channel::Y].samples.empty();
    bool has_u = !frame_in.format.channel_blocks[channel::U].samples.empty();
    bool has_v = !frame_in.format.channel_blocks[channel::V].samples.empty();
    bool has_a = !frame_in.format.channel_blocks[channel::A].samples.empty();

    yuv_image yuva_out = create_yuv_image(
            frame_in.format.image_w,
            frame_in.format.image_h,
            frame_in.format.chroma_siting,
            has_y,
            has_u,
            has_v,
            has_a
    );

    bool has_negative_line_stride = (frame_in.format.origin == image_origin::LOWER_LEFT);

    const uint8_t * raw_data = frame_in.data.get();

    std::unique_ptr<uint8_t> tmp_buffer;
    if (needs_reorder(frame_in.format)) {
        // Todo: If needed optimize this for memory.
        // At some point we will have allocated 2x frame + 1 plane.
        tmp_buffer.reset(new uint8_t[frame_in.format.size]);
        memcpy(tmp_buffer.get(), raw_data, frame_in.format.size);

        // Use the copy instead.
        raw_data = tmp_buffer.get();

        for (auto & plane : frame_in.format.planes) {
            reorder_inverse(tmp_buffer.get(), plane);
        }
    }

    if (has_y)
        decode_channel(
                raw_data,
                frame_in.format.channel_blocks[channel::Y],
                &(yuva_out.y_plane),
                frame_in.format.planes,
                frame_in.format.conversion_matrix.y_packed_range,
                has_negative_line_stride
        );
    if (has_u)
        decode_channel(
                raw_data,
                frame_in.format.channel_blocks[channel::U],
                &(yuva_out.u_plane),
                frame_in.format.planes,
                frame_in.format.conversion_matrix.u_packed_range,
                has_negative_line_stride
        );
    if (has_v)
        decode_channel(
                raw_data,
                frame_in.format.channel_blocks[channel::V],
                &(yuva_out.v_plane),
                frame_in.format.planes,
                frame_in.format.conversion_matrix.v_packed_range,
                has_negative_line_stride
        );
    if (has_a)
        decode_channel(
                raw_data,
                frame_in.format.channel_blocks[channel::A],
                &(yuva_out.a_plane),
                frame_in.format.planes,
                std::make_pair<float, float>(0.0f, 1.0f),
                has_negative_line_stride
        );



    return yuva_out;
}
Пример #2
0
static int video_arch_frame_buffer_alloc(video_canvas_t *canvas, unsigned int width, unsigned int height)
{
    int sizeofpixel = sizeof(BYTE);
    Display *display;
#ifdef USE_MITSHM
    int (*olderrorhandler)(Display *, XErrorEvent *);
#endif

#ifdef USE_MITSHM
    canvas->using_mitshm = use_mitshm;
#endif

    display = x11ui_get_display_ptr();

    /* sizeof(PIXEL) is not always what we are using. I guess this should
       be checked from the XImage but I'm lazy... */
    if (canvas->depth > 8) {
        sizeofpixel *= 2;
    }
    if (canvas->depth > 16) {
        sizeofpixel *= 2;
    }
    canvas->videoconfig->readable = 1; /* it's not direct rendering */

#ifdef HAVE_XVIDEO
    canvas->xv_image = NULL;

    if (canvas->videoconfig->hwscale) {
#if defined(__QNX__) || defined(MINIX_SUPPORT)
        XShmSegmentInfo* shminfo = NULL;
#else
        XShmSegmentInfo* shminfo = canvas->using_mitshm ? &canvas->xshm_info : NULL;
#endif
	for (;;) {
	    canvas->xv_image = create_yuv_image(display, canvas->xv_port, canvas->xv_format, width, height, shminfo);
	    if (canvas->xv_image) {
		break;
	    }

	    if (shminfo) {
#ifndef __QNX__
		canvas->using_mitshm = 0;
#endif
		shminfo = NULL;
		continue;
	    }
	    return -1;
        }
        XSync(display, False);

        /* Copy data for architecture independent rendering. */
        canvas->yuv_image.width = canvas->xv_image->width;
        canvas->yuv_image.height = canvas->xv_image->height;
        canvas->yuv_image.data_size = canvas->xv_image->data_size;
        canvas->yuv_image.num_planes = canvas->xv_image->num_planes;
        canvas->yuv_image.pitches = canvas->xv_image->pitches;
        canvas->yuv_image.offsets = canvas->xv_image->offsets;
        canvas->yuv_image.data = (unsigned char *)canvas->xv_image->data;

        log_message(x11video_log, "Successfully initialized using XVideo (%dx%d %.4s)%s shared memory.",
		width, height, canvas->xv_format.label,
#ifndef __QNX__
		canvas->using_mitshm ? ", using" : " without");
#else
                " without");
#endif

        return 0;
    }
Пример #3
0
static int video_arch_frame_buffer_alloc(video_canvas_t *canvas, unsigned int width, unsigned int height)
{
    int sizeofpixel = sizeof(BYTE);
    Display *display;
#ifdef USE_MITSHM
    int (*olderrorhandler)(Display *, XErrorEvent *);
    int dummy;
#endif

#ifdef USE_MITSHM
    canvas->using_mitshm = use_mitshm;
#endif

    display = x11ui_get_display_ptr();

    /* sizeof(PIXEL) is not always what we are using. I guess this should
       be checked from the XImage but I'm lazy... */
    if (canvas->depth > 8) {
        sizeofpixel *= 2;
    }
    if (canvas->depth > 16) {
        sizeofpixel *= 2;
    }

#ifdef HAVE_XVIDEO
    canvas->xv_image = NULL;

    if (canvas->videoconfig->hwscale) {
#if defined(__QNX__) || defined(MINIX_SUPPORT)
        XShmSegmentInfo* shminfo = NULL;
#else
        XShmSegmentInfo* shminfo = use_mitshm ? &canvas->xshm_info : NULL;
#endif

        canvas->xv_image = create_yuv_image(display, canvas->xv_port, canvas->xv_format, width, height, shminfo);
        if (!(canvas->xv_image)) {
            return -1;
        }

        /* Copy data for architecture independent rendering. */
        canvas->yuv_image.width = canvas->xv_image->width;
        canvas->yuv_image.height = canvas->xv_image->height;
        canvas->yuv_image.data_size = canvas->xv_image->data_size;
        canvas->yuv_image.num_planes = canvas->xv_image->num_planes;
        canvas->yuv_image.pitches = canvas->xv_image->pitches;
        canvas->yuv_image.offsets = canvas->xv_image->offsets;
        canvas->yuv_image.data = (unsigned char *)canvas->xv_image->data;

        log_message(x11video_log, "Successfully initialized using XVideo (%dx%d %.4s).", width, height, canvas->xv_format.label);

        return 0;
    }
#endif /* HAVE_XVIDEO */

    /* Round up to 32-bit boundary (used in XCreateImage). */
    width = (width + 3) & ~0x3;

#ifdef USE_MITSHM
tryagain:
    if (canvas->using_mitshm) {
        DEBUG_MITSHM(("frame_buffer_alloc(): allocating XImage with MITSHM, %d x %d pixels...", width, height));
        canvas->x_image = XShmCreateImage(display, visual, canvas->depth, ZPixmap, NULL, &(canvas->xshm_info), width, height);
        if (!canvas->x_image) {
            log_warning(x11video_log, "Cannot allocate XImage with XShm; falling back to non MITSHM extension mode.");
            canvas->using_mitshm = 0;
            goto tryagain;
        }
        DEBUG_MITSHM(("Done."));
        DEBUG_MITSHM(("frame_buffer_alloc(): shmgetting %ld bytes...", (long)canvas->x_image->bytes_per_line * canvas->x_image->height));
        canvas->xshm_info.shmid = shmget(IPC_PRIVATE, canvas->x_image->bytes_per_line * canvas->x_image->height, IPC_CREAT | 0604);
        if (canvas->xshm_info.shmid == -1) {
            log_warning(x11video_log, "Cannot get shared memory; falling back to non MITSHM extension mode.");
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }
        DEBUG_MITSHM(("Done, id = 0x%x.", i->xshm_info.shmid));
        DEBUG_MITSHM(("frame_buffer_alloc(): getting address... "));
        canvas->xshm_info.shmaddr = shmat(canvas->xshm_info.shmid, 0, 0);
        canvas->x_image->data = canvas->xshm_info.shmaddr;
        if (canvas->xshm_info.shmaddr == (char *)-1) {
            log_warning(x11video_log, "Cannot get shared memory address; falling back to non MITSHM extension mode.");
            shmctl(canvas->xshm_info.shmid,IPC_RMID,0);
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }
        DEBUG_MITSHM(("0x%lx OK.", (unsigned long) i->xshm_info.shmaddr));
        canvas->xshm_info.readOnly = True;
        mitshm_failed = 0;

        XQueryExtension(display,"MIT-SHM",&shmmajor,&dummy,&dummy);
        olderrorhandler = XSetErrorHandler(shmhandler);

        if (!XShmAttach(display, &(canvas->xshm_info))) {
            log_warning(x11video_log, "Cannot attach shared memory; falling back to non MITSHM extension mode.");
            shmdt(canvas->xshm_info.shmaddr);
            shmctl(canvas->xshm_info.shmid,IPC_RMID,0);
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }

        /* Wait for XShmAttach to fail or to succede. */
        XSync(display,False);
        XSetErrorHandler(olderrorhandler);

        /* Mark memory segment for automatic deletion. */
        shmctl(canvas->xshm_info.shmid, IPC_RMID, 0);

        if (mitshm_failed) {
            log_warning(x11video_log, "Cannot attach shared memory; falling back to non MITSHM extension mode.");
            shmdt(canvas->xshm_info.shmaddr);
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }

        DEBUG_MITSHM((_("MITSHM initialization succeed.\n")));
        video_refresh_func((void (*)(void))XShmPutImage);
    } else
#endif
    {                           /* !i->using_mitshm */
        char *data;

        data = lib_malloc(width * height * sizeofpixel);

        if (data == NULL) {
            return -1;
        }

        canvas->x_image = XCreateImage(display, visual, canvas->depth, ZPixmap, 0, data, width, height, 32, 0);
        if (!canvas->x_image) {
            return -1;
        }

        video_refresh_func((void (*)(void))XPutImage);
    }

#ifdef USE_MITSHM
    log_message(x11video_log, "Successfully initialized%s shared memory.", (canvas->using_mitshm) ? ", using" : " without");

    if (!(canvas->using_mitshm)) {
        log_warning(x11video_log, "Performance will be poor.");
    }
#else
    log_message(x11video_log, "Successfully initialized without shared memory.");
#endif

    return 0;
}