[Mesa-dev] [PATCH 1/3] vdpau: Add support for parameters
Maarten Lankhorst
m.b.lankhorst at gmail.com
Mon Dec 19 01:10:06 PST 2011
Currently only validating, since nothing else can be done with it yet
Signed-off-by: Maarten Lankhorst <m.b.lankhorst at gmail.com>
---
src/gallium/state_trackers/vdpau/mixer.c | 95 +++++++++++++++++++++-
src/gallium/state_trackers/vdpau/query.c | 41 +++++++++-
src/gallium/state_trackers/vdpau/vdpau_private.h | 3 +
3 files changed, 133 insertions(+), 6 deletions(-)
diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
index 1588744..276f5d5 100644
--- a/src/gallium/state_trackers/vdpau/mixer.c
+++ b/src/gallium/state_trackers/vdpau/mixer.c
@@ -49,12 +49,16 @@ vlVdpVideoMixerCreate(VdpDevice device,
vlVdpVideoMixer *vmixer = NULL;
VdpStatus ret;
float csc[16];
+ struct pipe_screen *screen;
+ unsigned max_width, max_height, i;
+ enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Creating VideoMixer\n");
vlVdpDevice *dev = vlGetDataHTAB(device);
if (!dev)
return VDP_STATUS_INVALID_HANDLE;
+ screen = dev->vscreen->pscreen;
vmixer = CALLOC(1, sizeof(vlVdpVideoMixer));
if (!vmixer)
@@ -72,7 +76,7 @@ vlVdpVideoMixerCreate(VdpDevice device,
vl_compositor_set_csc_matrix(&vmixer->compositor, csc);
/*
- * TODO: Handle features and parameters
+ * TODO: Handle features
*/
*mixer = vlAddDataHTAB(vmixer);
@@ -80,10 +84,49 @@ vlVdpVideoMixerCreate(VdpDevice device,
ret = VDP_STATUS_ERROR;
goto no_handle;
}
-
+ vmixer->chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
+ ret = VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
+ for (i = 0; i < parameter_count; ++i) {
+ switch (parameters[i]) {
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+ vmixer->video_width = *(uint32_t*)parameter_values[i];
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+ vmixer->video_height = *(uint32_t*)parameter_values[i];
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+ vmixer->chroma_format = ChromaToPipe(*(VdpChromaType*)parameter_values[i]);
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+ vmixer->max_layers = *(uint32_t*)parameter_values[i];
+ break;
+ default: goto no_params;
+ }
+ }
+ ret = VDP_STATUS_INVALID_VALUE;
+ if (vmixer->max_layers > 4) {
+ VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Max layers > 4 not supported\n", vmixer->max_layers);
+ goto no_params;
+ }
+ max_width = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
+ max_height = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
+ if (vmixer->video_width < 48 ||
+ vmixer->video_width > max_width) {
+ VDPAU_MSG(VDPAU_TRACE, "[VDPAU] 48 < %u < %u not valid for width\n", vmixer->video_width, max_width);
+ goto no_params;
+ }
+ if (vmixer->video_height < 48 ||
+ vmixer->video_height > max_height) {
+ VDPAU_MSG(VDPAU_TRACE, "[VDPAU] 48 < %u < %u not valid for height\n", vmixer->video_height, max_height);
+ goto no_params;
+ }
return VDP_STATUS_OK;
+no_params:
+ vlRemoveDataHTAB(*mixer);
no_handle:
+ vl_compositor_cleanup(&vmixer->compositor);
+ FREE(vmixer);
return ret;
}
@@ -100,6 +143,7 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
vmixer = vlGetDataHTAB(mixer);
if (!vmixer)
return VDP_STATUS_INVALID_HANDLE;
+ vlRemoveDataHTAB(mixer);
vl_compositor_cleanup(&vmixer->compositor);
@@ -133,6 +177,18 @@ vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer,
return VDP_STATUS_OK;
}
+static VdpStatus
+check_video_surface(vlVdpVideoMixer *mixer, vlVdpSurface *surf)
+{
+ if (surf->device != mixer->device)
+ return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
+ if (mixer->video_width > surf->video_buffer->width ||
+ mixer->video_height > surf->video_buffer->height ||
+ mixer->chroma_format != surf->video_buffer->chroma_format)
+ return VDP_STATUS_INVALID_SIZE;
+ return VDP_STATUS_OK;
+}
+
/**
* Perform a video post-processing and compositing operation.
*/
@@ -153,6 +209,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
VdpLayer const *layers)
{
struct pipe_video_rect src_rect, dst_rect, dst_clip;
+ VdpStatus ret;
vlVdpVideoMixer *vmixer;
vlVdpSurface *surf;
@@ -165,6 +222,11 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
surf = vlGetDataHTAB(video_surface_current);
if (!surf)
return VDP_STATUS_INVALID_HANDLE;
+ ret = check_video_surface(vmixer, surf);
+ if (ret)
+ return ret;
+ if (layer_count > vmixer->max_layers)
+ return VDP_STATUS_INVALID_VALUE;
dst = vlGetDataHTAB(destination_surface);
if (!dst)
@@ -237,7 +299,34 @@ vlVdpVideoMixerGetParameterValues(VdpVideoMixer mixer,
VdpVideoMixerParameter const *parameters,
void *const *parameter_values)
{
- return VDP_STATUS_NO_IMPLEMENTATION;
+ vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
+ unsigned i;
+ if (!vmixer)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ if (!parameter_count)
+ return VDP_STATUS_OK;
+ if (!(parameters && parameter_values))
+ return VDP_STATUS_INVALID_POINTER;
+ for (i = 0; i < parameter_count; ++i) {
+ switch (parameters[i]) {
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+ *(uint32_t*)parameter_values[i] = vmixer->video_width;
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+ *(uint32_t*)parameter_values[i] = vmixer->video_height;
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+ *(VdpChromaType*)parameter_values[i] = PipeToChroma(vmixer->chroma_format);
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+ *(uint32_t*)parameter_values[i] = vmixer->max_layers;
+ break;
+ default:
+ return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
+ }
+ }
+ return VDP_STATUS_OK;
}
/**
diff --git a/src/gallium/state_trackers/vdpau/query.c b/src/gallium/state_trackers/vdpau/query.c
index 191e163..cbd5afd 100644
--- a/src/gallium/state_trackers/vdpau/query.c
+++ b/src/gallium/state_trackers/vdpau/query.c
@@ -288,7 +288,18 @@ vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter pa
if (!is_supported)
return VDP_STATUS_INVALID_POINTER;
- return VDP_STATUS_NO_IMPLEMENTATION;
+ switch (parameter) {
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+ case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+ case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+ *is_supported = VDP_TRUE;
+ break;
+ default:
+ *is_supported = VDP_FALSE;
+ break;
+ }
+ return VDP_STATUS_OK;
}
/**
@@ -298,10 +309,34 @@ VdpStatus
vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
void *min_value, void *max_value)
{
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ struct pipe_screen *screen;
+ enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
+ if (!dev)
+ return VDP_STATUS_INVALID_HANDLE;
if (!(min_value && max_value))
return VDP_STATUS_INVALID_POINTER;
-
- return VDP_STATUS_NO_IMPLEMENTATION;
+ screen = dev->vscreen->pscreen;
+ switch (parameter) {
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+ *(uint32_t*)min_value = 48;
+ *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
+ break;
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+ *(uint32_t*)min_value = 48;
+ *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
+ break;
+
+ case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+ *(uint32_t*)min_value = 0;
+ *(uint32_t*)max_value = 4;
+ break;
+
+ case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+ default:
+ return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
+ }
+ return VDP_STATUS_OK;
}
/**
diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h
index 1922b70..fbada3b 100644
--- a/src/gallium/state_trackers/vdpau/vdpau_private.h
+++ b/src/gallium/state_trackers/vdpau/vdpau_private.h
@@ -306,6 +306,9 @@ typedef struct
{
vlVdpDevice *device;
struct vl_compositor compositor;
+ unsigned video_width, video_height;
+ enum pipe_video_chroma_format chroma_format;
+ unsigned max_layers;
} vlVdpVideoMixer;
typedef struct
--
1.7.7.4
More information about the mesa-dev
mailing list