mixer.c revision 89b9863252272a7109d468738517a0d68376a909
1/************************************************************************** 2 * 3 * Copyright 2010 Thomas Balling Sørensen. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include <vdpau/vdpau.h> 29 30#include "util/u_memory.h" 31#include "util/u_debug.h" 32 33#include "vl/vl_csc.h" 34 35#include "vdpau_private.h" 36 37/** 38 * Create a VdpVideoMixer. 39 */ 40VdpStatus 41vlVdpVideoMixerCreate(VdpDevice device, 42 uint32_t feature_count, 43 VdpVideoMixerFeature const *features, 44 uint32_t parameter_count, 45 VdpVideoMixerParameter const *parameters, 46 void const *const *parameter_values, 47 VdpVideoMixer *mixer) 48{ 49 vlVdpVideoMixer *vmixer = NULL; 50 VdpStatus ret; 51 float csc[16]; 52 struct pipe_screen *screen; 53 unsigned max_width, max_height, i; 54 enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN; 55 56 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Creating VideoMixer\n"); 57 58 vlVdpDevice *dev = vlGetDataHTAB(device); 59 if (!dev) 60 return VDP_STATUS_INVALID_HANDLE; 61 screen = dev->vscreen->pscreen; 62 63 vmixer = CALLOC(1, sizeof(vlVdpVideoMixer)); 64 if (!vmixer) 65 return VDP_STATUS_RESOURCES; 66 67 vmixer->device = dev; 68 vl_compositor_init(&vmixer->compositor, dev->context->pipe); 69 70 vl_csc_get_matrix 71 ( 72 debug_get_bool_option("G3DVL_NO_CSC", FALSE) ? 73 VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601, 74 NULL, true, csc 75 ); 76 vl_compositor_set_csc_matrix(&vmixer->compositor, csc); 77 78 /* 79 * TODO: Handle features 80 */ 81 82 *mixer = vlAddDataHTAB(vmixer); 83 if (*mixer == 0) { 84 ret = VDP_STATUS_ERROR; 85 goto no_handle; 86 } 87 vmixer->chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; 88 ret = VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER; 89 for (i = 0; i < parameter_count; ++i) { 90 switch (parameters[i]) { 91 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH: 92 vmixer->video_width = *(uint32_t*)parameter_values[i]; 93 break; 94 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT: 95 vmixer->video_height = *(uint32_t*)parameter_values[i]; 96 break; 97 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE: 98 vmixer->chroma_format = ChromaToPipe(*(VdpChromaType*)parameter_values[i]); 99 break; 100 case VDP_VIDEO_MIXER_PARAMETER_LAYERS: 101 vmixer->max_layers = *(uint32_t*)parameter_values[i]; 102 break; 103 default: goto no_params; 104 } 105 } 106 ret = VDP_STATUS_INVALID_VALUE; 107 if (vmixer->max_layers > 4) { 108 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Max layers > 4 not supported\n", vmixer->max_layers); 109 goto no_params; 110 } 111 max_width = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH); 112 max_height = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT); 113 if (vmixer->video_width < 48 || 114 vmixer->video_width > max_width) { 115 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] 48 < %u < %u not valid for width\n", vmixer->video_width, max_width); 116 goto no_params; 117 } 118 if (vmixer->video_height < 48 || 119 vmixer->video_height > max_height) { 120 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] 48 < %u < %u not valid for height\n", vmixer->video_height, max_height); 121 goto no_params; 122 } 123 return VDP_STATUS_OK; 124 125no_params: 126 vlRemoveDataHTAB(*mixer); 127no_handle: 128 vl_compositor_cleanup(&vmixer->compositor); 129 FREE(vmixer); 130 return ret; 131} 132 133/** 134 * Destroy a VdpVideoMixer. 135 */ 136VdpStatus 137vlVdpVideoMixerDestroy(VdpVideoMixer mixer) 138{ 139 vlVdpVideoMixer *vmixer; 140 141 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Destroying VideoMixer\n"); 142 143 vmixer = vlGetDataHTAB(mixer); 144 if (!vmixer) 145 return VDP_STATUS_INVALID_HANDLE; 146 vlRemoveDataHTAB(mixer); 147 148 vl_compositor_cleanup(&vmixer->compositor); 149 150 FREE(vmixer); 151 152 return VDP_STATUS_OK; 153} 154 155/** 156 * Enable or disable features. 157 */ 158VdpStatus 159vlVdpVideoMixerSetFeatureEnables(VdpVideoMixer mixer, 160 uint32_t feature_count, 161 VdpVideoMixerFeature const *features, 162 VdpBool const *feature_enables) 163{ 164 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Setting VideoMixer features\n"); 165 166 if (!(features && feature_enables)) 167 return VDP_STATUS_INVALID_POINTER; 168 169 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer); 170 if (!vmixer) 171 return VDP_STATUS_INVALID_HANDLE; 172 173 /* 174 * TODO: Set features 175 */ 176 177 return VDP_STATUS_OK; 178} 179 180/** 181 * Perform a video post-processing and compositing operation. 182 */ 183VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer, 184 VdpOutputSurface background_surface, 185 VdpRect const *background_source_rect, 186 VdpVideoMixerPictureStructure current_picture_structure, 187 uint32_t video_surface_past_count, 188 VdpVideoSurface const *video_surface_past, 189 VdpVideoSurface video_surface_current, 190 uint32_t video_surface_future_count, 191 VdpVideoSurface const *video_surface_future, 192 VdpRect const *video_source_rect, 193 VdpOutputSurface destination_surface, 194 VdpRect const *destination_rect, 195 VdpRect const *destination_video_rect, 196 uint32_t layer_count, 197 VdpLayer const *layers) 198{ 199 struct pipe_video_rect src_rect, dst_rect, dst_clip; 200 201 vlVdpVideoMixer *vmixer; 202 vlVdpSurface *surf; 203 vlVdpOutputSurface *dst; 204 205 vmixer = vlGetDataHTAB(mixer); 206 if (!vmixer) 207 return VDP_STATUS_INVALID_HANDLE; 208 209 surf = vlGetDataHTAB(video_surface_current); 210 if (!surf) 211 return VDP_STATUS_INVALID_HANDLE; 212 213 if (surf->device != vmixer->device) 214 return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 215 216 if (vmixer->video_width > surf->video_buffer->width || 217 vmixer->video_height > surf->video_buffer->height || 218 vmixer->chroma_format != surf->video_buffer->chroma_format) 219 return VDP_STATUS_INVALID_SIZE; 220 221 if (layer_count > vmixer->max_layers) 222 return VDP_STATUS_INVALID_VALUE; 223 224 dst = vlGetDataHTAB(destination_surface); 225 if (!dst) 226 return VDP_STATUS_INVALID_HANDLE; 227 228 vl_compositor_clear_layers(&vmixer->compositor); 229 vl_compositor_set_buffer_layer(&vmixer->compositor, 0, surf->video_buffer, 230 RectToPipe(video_source_rect, &src_rect), NULL); 231 vl_compositor_render(&vmixer->compositor, dst->surface, 232 RectToPipe(destination_video_rect, &dst_rect), 233 RectToPipe(destination_rect, &dst_clip), 234 &dst->dirty_area); 235 236 return VDP_STATUS_OK; 237} 238 239/** 240 * Set attribute values. 241 */ 242VdpStatus 243vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer, 244 uint32_t attribute_count, 245 VdpVideoMixerAttribute const *attributes, 246 void const *const *attribute_values) 247{ 248 if (!(attributes && attribute_values)) 249 return VDP_STATUS_INVALID_POINTER; 250 251 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer); 252 if (!vmixer) 253 return VDP_STATUS_INVALID_HANDLE; 254 255 /* 256 * TODO: Implement the function 257 */ 258 259 return VDP_STATUS_OK; 260} 261 262/** 263 * Retrieve whether features were requested at creation time. 264 */ 265VdpStatus 266vlVdpVideoMixerGetFeatureSupport(VdpVideoMixer mixer, 267 uint32_t feature_count, 268 VdpVideoMixerFeature const *features, 269 VdpBool *feature_supports) 270{ 271 return VDP_STATUS_NO_IMPLEMENTATION; 272} 273 274/** 275 * Retrieve whether features are enabled. 276 */ 277VdpStatus 278vlVdpVideoMixerGetFeatureEnables(VdpVideoMixer mixer, 279 uint32_t feature_count, 280 VdpVideoMixerFeature const *features, 281 VdpBool *feature_enables) 282{ 283 return VDP_STATUS_NO_IMPLEMENTATION; 284} 285 286/** 287 * Retrieve parameter values given at creation time. 288 */ 289VdpStatus 290vlVdpVideoMixerGetParameterValues(VdpVideoMixer mixer, 291 uint32_t parameter_count, 292 VdpVideoMixerParameter const *parameters, 293 void *const *parameter_values) 294{ 295 vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer); 296 unsigned i; 297 if (!vmixer) 298 return VDP_STATUS_INVALID_HANDLE; 299 300 if (!parameter_count) 301 return VDP_STATUS_OK; 302 if (!(parameters && parameter_values)) 303 return VDP_STATUS_INVALID_POINTER; 304 for (i = 0; i < parameter_count; ++i) { 305 switch (parameters[i]) { 306 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH: 307 *(uint32_t*)parameter_values[i] = vmixer->video_width; 308 break; 309 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT: 310 *(uint32_t*)parameter_values[i] = vmixer->video_height; 311 break; 312 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE: 313 *(VdpChromaType*)parameter_values[i] = PipeToChroma(vmixer->chroma_format); 314 break; 315 case VDP_VIDEO_MIXER_PARAMETER_LAYERS: 316 *(uint32_t*)parameter_values[i] = vmixer->max_layers; 317 break; 318 default: 319 return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER; 320 } 321 } 322 return VDP_STATUS_OK; 323} 324 325/** 326 * Retrieve current attribute values. 327 */ 328VdpStatus 329vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer, 330 uint32_t attribute_count, 331 VdpVideoMixerAttribute const *attributes, 332 void *const *attribute_values) 333{ 334 return VDP_STATUS_NO_IMPLEMENTATION; 335} 336 337/** 338 * Generate a color space conversion matrix. 339 */ 340VdpStatus 341vlVdpGenerateCSCMatrix(VdpProcamp *procamp, 342 VdpColorStandard standard, 343 VdpCSCMatrix *csc_matrix) 344{ 345 float matrix[16]; 346 enum VL_CSC_COLOR_STANDARD vl_std; 347 struct vl_procamp camp; 348 349 if (!(csc_matrix && procamp)) 350 return VDP_STATUS_INVALID_POINTER; 351 352 if (procamp->struct_version > VDP_PROCAMP_VERSION) 353 return VDP_STATUS_INVALID_STRUCT_VERSION; 354 355 switch (standard) { 356 case VDP_COLOR_STANDARD_ITUR_BT_601: vl_std = VL_CSC_COLOR_STANDARD_BT_601; break; 357 case VDP_COLOR_STANDARD_ITUR_BT_709: vl_std = VL_CSC_COLOR_STANDARD_BT_709; break; 358 case VDP_COLOR_STANDARD_SMPTE_240M: vl_std = VL_CSC_COLOR_STANDARD_SMPTE_240M; break; 359 default: return VDP_STATUS_INVALID_COLOR_STANDARD; 360 } 361 camp.brightness = procamp->brightness; 362 camp.contrast = procamp->contrast; 363 camp.saturation = procamp->saturation; 364 camp.hue = procamp->hue; 365 vl_csc_get_matrix(vl_std, &camp, 1, matrix); 366 memcpy(csc_matrix, matrix, sizeof(float)*12); 367 return VDP_STATUS_OK; 368} 369