Exemplo n.º 1
0
VdpStatus vdp_video_mixer_render(VdpVideoMixer mixer, VdpOutputSurface background_surface, VdpRect const *background_source_rect, VdpVideoMixerPictureStructure current_picture_structure, uint32_t video_surface_past_count, VdpVideoSurface const *video_surface_past, VdpVideoSurface video_surface_current, uint32_t video_surface_future_count, VdpVideoSurface const *video_surface_future, VdpRect const *video_source_rect, VdpOutputSurface destination_surface, VdpRect const *destination_rect, VdpRect const *destination_video_rect, uint32_t layer_count, VdpLayer const *layers)
{
	mixer_ctx_t *mix = handle_get(mixer);
	if (!mix)
		return VDP_STATUS_INVALID_HANDLE;

	if (background_surface != VDP_INVALID_HANDLE)
		VDPAU_DBG_ONCE("Requested unimplemented background_surface");


	if (current_picture_structure != VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME)
		VDPAU_DBG_ONCE("Requested unimplemented picture_structure");



	output_surface_ctx_t *os = handle_get(destination_surface);
	if (!os)
		return VDP_STATUS_INVALID_HANDLE;

	os->vs = handle_get(video_surface_current);
	if (!(os->vs))
		return VDP_STATUS_INVALID_HANDLE;

	if (destination_video_rect)
	{
		os->video_dst_rect = *destination_video_rect;
		if (video_source_rect)
			os->video_src_rect = *video_source_rect;
		else
		{
			os->video_src_rect.x0 = os->video_src_rect.y0 = 0;
			os->video_src_rect.x1 = os->vs->width;
			os->video_src_rect.y1 = os->vs->height;
		}
	}
	os->csc_change = mix->csc_change;
	os->brightness = mix->brightness;
	os->contrast = mix->contrast;
	os->saturation = mix->saturation;
	os->hue = mix->hue;
	mix->csc_change = 0;

	if (layer_count != 0)
		VDPAU_DBG_ONCE("Requested unimplemented additional layers");

        handle_release(mixer);
        handle_release(destination_surface);
        handle_release(video_surface_current);
	return VDP_STATUS_OK;
}
Exemplo n.º 2
0
VdpStatus vdp_output_surface_put_bits_native(VdpOutputSurface surface, void const *const *source_data, uint32_t const *source_pitches, VdpRect const *destination_rect)
{
	output_surface_ctx_t *out = handle_get(surface);
	if (!out)
		return VDP_STATUS_INVALID_HANDLE;

	VDPAU_DBG_ONCE("%s called but unimplemented!", __func__);


        handle_release(surface);
	return VDP_STATUS_OK;
}
Exemplo n.º 3
0
VdpStatus vdp_output_surface_render_bitmap_surface(VdpOutputSurface destination_surface, VdpRect const *destination_rect, VdpBitmapSurface source_surface, VdpRect const *source_rect, VdpColor const *colors, VdpOutputSurfaceRenderBlendState const *blend_state, uint32_t flags)
{
	output_surface_ctx_t *out = handle_get(destination_surface);
	if (!out)
		return VDP_STATUS_INVALID_HANDLE;

	VDPAU_DBG_ONCE("%s called but unimplemented!", __func__);


        handle_release(destination_surface);
	return VDP_STATUS_OK;
}
Exemplo n.º 4
0
VdpStatus vdp_output_surface_put_bits_y_cb_cr(VdpOutputSurface surface, VdpYCbCrFormat source_ycbcr_format, void const *const *source_data, uint32_t const *source_pitches, VdpRect const *destination_rect, VdpCSCMatrix const *csc_matrix)
{
	output_surface_ctx_t *out = handle_get(surface);
	if (!out)
		return VDP_STATUS_INVALID_HANDLE;

	VDPAU_DBG_ONCE("%s called but unimplemented!", __func__);


        handle_release(surface);
	return VDP_STATUS_OK;
}
Exemplo n.º 5
0
VdpStatus vdp_output_surface_put_bits_indexed(VdpOutputSurface surface, VdpIndexedFormat source_indexed_format, void const *const *source_data, uint32_t const *source_pitch, VdpRect const *destination_rect, VdpColorTableFormat color_table_format, void const *color_table)
{
	output_surface_ctx_t *out = handle_get(surface);
	if (!out)
		return VDP_STATUS_INVALID_HANDLE;

	VDPAU_DBG_ONCE("%s called but unimplemented!", __func__);


        handle_release(surface);
	return VDP_STATUS_OK;
}
Exemplo n.º 6
0
VdpStatus vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, VdpGetProcAddress **get_proc_address)
{
	if (!device || !get_proc_address) {
		VDPAU_DBG_ONCE("device=NULL || get_proc_address");
		return VDP_STATUS_INVALID_POINTER;
	}

	device_ctx_t *dev = handle_create(sizeof(*dev), device, htype_device);
	if (!dev)
		return VDP_STATUS_RESOURCES;

	//dev->display = XOpenDisplay(XDisplayString(display));
	dev->screen = screen;
        dev->fb_id = 0;

	if (!cedarv_open())
	{
		VDPAU_DBG_ONCE("cedarv_open failed");
		handle_destroy(*device);
		return VDP_STATUS_ERROR;
	}

	char *env_vdpau_osd = getenv("VDPAU_OSD");
	if (env_vdpau_osd && strncmp(env_vdpau_osd, "1", 1) == 0)
	{
		dev->g2d_fd = open("/dev/g2d", O_RDWR);
		if (dev->g2d_fd != -1)
			dev->osd_enabled = 1;
		else
			VDPAU_DBG("Failed to open /dev/g2d! OSD disabled.");
	}

        VDPAU_DBG("VE version 0x%04x opened", cedarv_get_version());
	*get_proc_address = &vdp_get_proc_address;
        
	return VDP_STATUS_OK;
}
Exemplo n.º 7
0
VdpStatus rgba_render_surface(rgba_surface_t *dest,
                              VdpRect const *destination_rect,
                              rgba_surface_t *src,
                              VdpRect const *source_rect,
                              VdpColor const *colors,
                              VdpOutputSurfaceRenderBlendState const *blend_state,
                              uint32_t flags)
{
	if (!dest->device->osd_enabled)
		return VDP_STATUS_OK;

	if (colors || flags)
		VDPAU_DBG_ONCE("%s: colors and flags not implemented!", __func__);

	// set up source/destination rects using defaults where required
	VdpRect s_rect = {0, 0, 0, 0};
	VdpRect d_rect = {0, 0, dest->width, dest->height};
	s_rect.x1 = src ? src->width : 1;
	s_rect.y1 = src ? src->height : 1;

	if (source_rect)
		s_rect = *source_rect;
	if (destination_rect)
		d_rect = *destination_rect;

	// ignore zero-sized surfaces (also workaround for g2d driver bug)
	if (s_rect.x0 == s_rect.x1 || s_rect.y0 == s_rect.y1 ||
	    d_rect.x0 == d_rect.x1 || d_rect.y0 == d_rect.y1)
		return VDP_STATUS_OK;

	if (rgba_changed(dest, destination_rect, src, source_rect, colors, blend_state, flags))
	{
		if ((dest->flags & RGBA_FLAG_NEEDS_CLEAR) && !dirty_in_rect(&dest->dirty, &d_rect))
			rgba_clear(dest);

		if (!src)
			rgba_fill(dest, &d_rect, 0xffffffff);
		else
			rgba_blit(dest, &d_rect, src, &s_rect);

		dirty_add_rect(&dest->dirty, &d_rect);
	}

	dest->flags &= ~RGBA_FLAG_NEEDS_CLEAR;
	dest->flags |= RGBA_FLAG_DIRTY;

	return VDP_STATUS_OK;
}
VdpStatus vdp_presentation_queue_display(VdpPresentationQueue presentation_queue,
        VdpOutputSurface surface,
        uint32_t clip_width,
        uint32_t clip_height,
        VdpTime earliest_presentation_time)
{
    queue_ctx_t *q = handle_get(presentation_queue);
    if (!q)
        return VDP_STATUS_INVALID_HANDLE;

    output_surface_ctx_t *os = handle_get(surface);
    if (!os)
        return VDP_STATUS_INVALID_HANDLE;

    if (earliest_presentation_time != 0)
        VDPAU_DBG_ONCE("Presentation time not supported");

    Window c;
    int x,y;
    XTranslateCoordinates(q->device->display, q->target->drawable, RootWindow(q->device->display, q->device->screen), 0, 0, &x, &y, &c);
    XClearWindow(q->device->display, q->target->drawable);

    if (os->vs)
    {
        // VIDEO layer
        __disp_layer_info_t layer_info;
        memset(&layer_info, 0, sizeof(layer_info));
        layer_info.pipe = q->device->osd_enabled ? 0 : 1;
        layer_info.mode = DISP_LAYER_WORK_MODE_SCALER;
        layer_info.fb.format = DISP_FORMAT_YUV420;
        layer_info.fb.seq = DISP_SEQ_UVUV;
        switch (os->vs->source_format) {
        case VDP_YCBCR_FORMAT_YUYV:
            layer_info.fb.mode = DISP_MOD_INTERLEAVED;
            layer_info.fb.format = DISP_FORMAT_YUV422;
            layer_info.fb.seq = DISP_SEQ_YUYV;
            break;
        case VDP_YCBCR_FORMAT_UYVY:
            layer_info.fb.mode = DISP_MOD_INTERLEAVED;
            layer_info.fb.format = DISP_FORMAT_YUV422;
            layer_info.fb.seq = DISP_SEQ_UYVY;
            break;
        case VDP_YCBCR_FORMAT_NV12:
            layer_info.fb.mode = DISP_MOD_NON_MB_UV_COMBINED;
            break;
        case VDP_YCBCR_FORMAT_YV12:
            layer_info.fb.mode = DISP_MOD_NON_MB_PLANAR;
            break;
        default:
        case INTERNAL_YCBCR_FORMAT:
            layer_info.fb.mode = DISP_MOD_MB_UV_COMBINED;
            break;
        }
        layer_info.fb.br_swap = 0;
        layer_info.fb.addr[0] = ve_virt2phys(os->vs->data) + 0x40000000;
        layer_info.fb.addr[1] = ve_virt2phys(os->vs->data + os->vs->plane_size) + 0x40000000;
        layer_info.fb.addr[2] = ve_virt2phys(os->vs->data + os->vs->plane_size + os->vs->plane_size / 4) + 0x40000000;

        layer_info.fb.cs_mode = DISP_BT601;
        layer_info.fb.size.width = os->vs->width;
        layer_info.fb.size.height = os->vs->height;
        layer_info.src_win.x = os->video_src_rect.x0;
        layer_info.src_win.y = os->video_src_rect.y0;
        layer_info.src_win.width = os->video_src_rect.x1 - os->video_src_rect.x0;
        layer_info.src_win.height = os->video_src_rect.y1 - os->video_src_rect.y0;
        layer_info.scn_win.x = x + os->video_dst_rect.x0;
        layer_info.scn_win.y = y + os->video_dst_rect.y0;
        layer_info.scn_win.width = os->video_dst_rect.x1 - os->video_dst_rect.x0;
        layer_info.scn_win.height = os->video_dst_rect.y1 - os->video_dst_rect.y0;
        layer_info.ck_enable = q->device->osd_enabled ? 0 : 1;

        if (layer_info.scn_win.y < 0)
        {
            int cutoff = -(layer_info.scn_win.y);
            layer_info.src_win.y += cutoff;
            layer_info.src_win.height -= cutoff;
            layer_info.scn_win.y = 0;
            layer_info.scn_win.height -= cutoff;
        }

        uint32_t args[4] = { 0, q->target->layer, (unsigned long)(&layer_info), 0 };
        ioctl(q->target->fd, DISP_CMD_LAYER_SET_PARA, args);

        ioctl(q->target->fd, DISP_CMD_LAYER_OPEN, args);
        // Note: might be more reliable (but slower and problematic when there
        // are driver issues and the GET functions return wrong values) to query the
        // old values instead of relying on our internal csc_change.
        // Since the driver calculates a matrix out of these values after each
        // set doing this unconditionally is costly.
        if (os->csc_change) {
            ioctl(q->target->fd, DISP_CMD_LAYER_ENHANCE_OFF, args);
            args[2] = 0xff * os->brightness + 0x20;
            ioctl(q->target->fd, DISP_CMD_LAYER_SET_BRIGHT, args);
            args[2] = 0x20 * os->contrast;
            ioctl(q->target->fd, DISP_CMD_LAYER_SET_CONTRAST, args);
            args[2] = 0x20 * os->saturation;
            ioctl(q->target->fd, DISP_CMD_LAYER_SET_SATURATION, args);
            // hue scale is randomly chosen, no idea how it maps exactly
            args[2] = (32 / 3.14) * os->hue + 0x20;
            ioctl(q->target->fd, DISP_CMD_LAYER_SET_HUE, args);
            ioctl(q->target->fd, DISP_CMD_LAYER_ENHANCE_ON, args);
            os->csc_change = 0;
        }
    }
    else
    {
        uint32_t args[4] = { 0, q->target->layer, 0, 0 };
        ioctl(q->target->fd, DISP_CMD_LAYER_CLOSE, args);
    }

    if (!q->device->osd_enabled)
        return VDP_STATUS_OK;

    if (os->rgba.flags & RGBA_FLAG_NEEDS_CLEAR)
        rgba_clear(&os->rgba);

    if (os->rgba.flags & RGBA_FLAG_DIRTY)
    {
        // TOP layer
        rgba_flush(&os->rgba);

        __disp_layer_info_t layer_info;
        memset(&layer_info, 0, sizeof(layer_info));
        layer_info.pipe = 1;
        layer_info.mode = DISP_LAYER_WORK_MODE_NORMAL;
        layer_info.fb.mode = DISP_MOD_INTERLEAVED;
        layer_info.fb.format = DISP_FORMAT_ARGB8888;
        layer_info.fb.seq = DISP_SEQ_ARGB;
        switch (os->rgba.format)
        {
        case VDP_RGBA_FORMAT_R8G8B8A8:
            layer_info.fb.br_swap = 1;
            break;
        case VDP_RGBA_FORMAT_B8G8R8A8:
        default:
            layer_info.fb.br_swap = 0;
            break;
        }
        layer_info.fb.addr[0] = ve_virt2phys(os->rgba.data) + 0x40000000;
        layer_info.fb.cs_mode = DISP_BT601;
        layer_info.fb.size.width = os->rgba.width;
        layer_info.fb.size.height = os->rgba.height;
        layer_info.src_win.x = os->rgba.dirty.x0;
        layer_info.src_win.y = os->rgba.dirty.y0;
        layer_info.src_win.width = os->rgba.dirty.x1 - os->rgba.dirty.x0;
        layer_info.src_win.height = os->rgba.dirty.y1 - os->rgba.dirty.y0;
        layer_info.scn_win.x = x + os->rgba.dirty.x0;
        layer_info.scn_win.y = y + os->rgba.dirty.y0;
        layer_info.scn_win.width = min_nz(clip_width, os->rgba.dirty.x1) - os->rgba.dirty.x0;
        layer_info.scn_win.height = min_nz(clip_height, os->rgba.dirty.y1) - os->rgba.dirty.y0;

        uint32_t args[4] = { 0, q->target->layer_top, (unsigned long)(&layer_info), 0 };
        ioctl(q->target->fd, DISP_CMD_LAYER_SET_PARA, args);

        ioctl(q->target->fd, DISP_CMD_LAYER_OPEN, args);
    }
    else
    {
        uint32_t args[4] = { 0, q->target->layer_top, 0, 0 };
        ioctl(q->target->fd, DISP_CMD_LAYER_CLOSE, args);
    }

    return VDP_STATUS_OK;
}