2
* vdpau_video.c - VDPAU backend for VA API
4
* vdpau-video (C) 2009-2010 Splitted-Desktop Systems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22
#include "vdpau_video.h"
23
#include "vdpau_video_x11.h"
24
#include "vdpau_decode.h"
25
#include "vdpau_subpic.h"
26
#include "vdpau_mixer.h"
33
/* Define wait delay (in microseconds) for vaSyncSurface() implementation
35
#define VDPAU_SYNC_DELAY 5000
37
// Translates VA API chroma format to VdpChromaType
38
static VdpChromaType get_VdpChromaType(int format)
41
case VA_RT_FORMAT_YUV420: return VDP_CHROMA_TYPE_420;
42
case VA_RT_FORMAT_YUV422: return VDP_CHROMA_TYPE_422;
43
case VA_RT_FORMAT_YUV444: return VDP_CHROMA_TYPE_444;
46
return (VdpChromaType)-1;
50
/* ====================================================================== */
51
/* === VA API Implementation with VDPAU === */
52
/* ====================================================================== */
54
// Returns the maximum dimensions supported by the VDPAU implementation for that profile
57
vdpau_driver_data_t *driver_data,
58
VdpDecoderProfile profile,
63
VdpBool is_supported = VDP_FALSE;
65
uint32_t max_level, max_references, max_width, max_height;
67
vdp_status = vdpau_decoder_query_capabilities(driver_data,
68
driver_data->vdp_device,
81
if (vdp_status != VDP_STATUS_OK || !is_supported)
85
*pmax_width = max_width;
87
*pmax_height = max_height;
92
// vaGetConfigAttributes
94
vdpau_GetConfigAttributes(
97
VAEntrypoint entrypoint,
98
VAConfigAttrib *attrib_list,
104
for (i = 0; i < num_attribs; i++) {
105
switch (attrib_list[i].type) {
106
case VAConfigAttribRTFormat:
107
attrib_list[i].value = VA_RT_FORMAT_YUV420;
110
attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
115
return VA_STATUS_SUCCESS;
119
vdpau_update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
123
/* Check existing attrbiutes */
124
for (i = 0; obj_config->attrib_count < i; i++) {
125
if (obj_config->attrib_list[i].type == attrib->type) {
126
/* Update existing attribute */
127
obj_config->attrib_list[i].value = attrib->value;
128
return VA_STATUS_SUCCESS;
131
if (obj_config->attrib_count < VDPAU_MAX_CONFIG_ATTRIBUTES) {
132
i = obj_config->attrib_count;
133
obj_config->attrib_list[i].type = attrib->type;
134
obj_config->attrib_list[i].value = attrib->value;
135
obj_config->attrib_count++;
136
return VA_STATUS_SUCCESS;
138
return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
142
VAStatus vdpau_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
144
VDPAU_DRIVER_DATA_INIT;
146
object_config_p obj_config = VDPAU_CONFIG(config_id);
148
if (obj_config == NULL)
149
return VA_STATUS_ERROR_INVALID_CONFIG;
151
object_heap_free(&driver_data->config_heap, (object_base_p)obj_config);
152
return VA_STATUS_SUCCESS;
158
VADriverContextP ctx,
160
VAEntrypoint entrypoint,
161
VAConfigAttrib *attrib_list,
163
VAConfigID *config_id
166
VDPAU_DRIVER_DATA_INIT;
170
object_config_p obj_config;
173
/* Validate profile and entrypoint */
175
case VAProfileMPEG2Simple:
176
case VAProfileMPEG2Main:
177
if (entrypoint == VAEntrypointVLD)
178
va_status = VA_STATUS_SUCCESS;
180
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
182
case VAProfileMPEG4Simple:
183
case VAProfileMPEG4AdvancedSimple:
184
case VAProfileMPEG4Main:
185
if (entrypoint == VAEntrypointVLD)
186
va_status = VA_STATUS_SUCCESS;
188
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
190
case VAProfileH264Baseline:
191
case VAProfileH264Main:
192
case VAProfileH264High:
193
if (entrypoint == VAEntrypointVLD)
194
va_status = VA_STATUS_SUCCESS;
196
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
198
case VAProfileVC1Simple:
199
case VAProfileVC1Main:
200
case VAProfileVC1Advanced:
201
if (entrypoint == VAEntrypointVLD)
202
va_status = VA_STATUS_SUCCESS;
204
va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
207
va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
211
if (va_status != VA_STATUS_SUCCESS)
214
configID = object_heap_allocate(&driver_data->config_heap);
215
if ((obj_config = VDPAU_CONFIG(configID)) == NULL)
216
return VA_STATUS_ERROR_ALLOCATION_FAILED;
218
obj_config->profile = profile;
219
obj_config->entrypoint = entrypoint;
220
obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
221
obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
222
obj_config->attrib_count = 1;
224
for(i = 0; i < num_attribs; i++) {
225
va_status = vdpau_update_attribute(obj_config, &attrib_list[i]);
226
if (va_status != VA_STATUS_SUCCESS) {
227
vdpau_DestroyConfig(ctx, configID);
233
*config_id = configID;
238
// vaQueryConfigAttributes
240
vdpau_QueryConfigAttributes(
241
VADriverContextP ctx,
242
VAConfigID config_id,
244
VAEntrypoint *entrypoint,
245
VAConfigAttrib *attrib_list,
249
VDPAU_DRIVER_DATA_INIT;
251
VAStatus va_status = VA_STATUS_SUCCESS;
252
object_config_p obj_config;
255
obj_config = VDPAU_CONFIG(config_id);
257
if (obj_config == NULL)
258
return VA_STATUS_ERROR_INVALID_CONFIG;
261
*profile = obj_config->profile;
264
*entrypoint = obj_config->entrypoint;
267
*num_attribs = obj_config->attrib_count;
270
for (i = 0; i < obj_config->attrib_count; i++)
271
attrib_list[i] = obj_config->attrib_list[i];
277
// Add subpicture association to surface
278
// NOTE: the subpicture owns the SubpictureAssociation object
279
int surface_add_association(
280
object_surface_p obj_surface,
281
SubpictureAssociationP assoc
284
/* Check that we don't already have this association */
285
if (obj_surface->assocs) {
287
for (i = 0; i < obj_surface->assocs_count; i++) {
288
if (obj_surface->assocs[i] == assoc)
290
if (obj_surface->assocs[i]->surface == assoc->surface) {
291
/* XXX: this should not happen, but replace it in the interim */
292
ASSERT(obj_surface->assocs[i]->surface != assoc->surface);
293
obj_surface->assocs[i] = assoc;
299
/* Check that we have not reached the maximum subpictures capacity yet */
300
if (obj_surface->assocs_count >= VDPAU_MAX_SUBPICTURES)
303
/* Append this subpicture association */
304
SubpictureAssociationP *assocs;
305
assocs = realloc_buffer(&obj_surface->assocs,
306
&obj_surface->assocs_count_max,
307
1 + obj_surface->assocs_count,
308
sizeof(obj_surface->assocs[0]));
312
assocs[obj_surface->assocs_count++] = assoc;
316
// Remove subpicture association from surface
317
// NOTE: the subpicture owns the SubpictureAssociation object
318
int surface_remove_association(
319
object_surface_p obj_surface,
320
SubpictureAssociationP assoc
323
if (!obj_surface->assocs || obj_surface->assocs_count == 0)
327
const unsigned int last = obj_surface->assocs_count - 1;
328
for (i = 0; i <= last; i++) {
329
if (obj_surface->assocs[i] == assoc) {
330
/* Swap with the last subpicture */
331
obj_surface->assocs[i] = obj_surface->assocs[last];
332
obj_surface->assocs[last] = NULL;
333
obj_surface->assocs_count--;
342
vdpau_DestroySurfaces(
343
VADriverContextP ctx,
344
VASurfaceID *surface_list,
348
VDPAU_DRIVER_DATA_INIT;
351
for (i = num_surfaces - 1; i >= 0; i--) {
352
object_surface_p obj_surface = VDPAU_SURFACE(surface_list[i]);
355
if (obj_surface->vdp_surface != VDP_INVALID_HANDLE) {
356
vdpau_video_surface_destroy(driver_data, obj_surface->vdp_surface);
357
obj_surface->vdp_surface = VDP_INVALID_HANDLE;
360
for (j = 0; j < obj_surface->output_surfaces_count; j++) {
361
output_surface_unref(driver_data, obj_surface->output_surfaces[j]);
362
obj_surface->output_surfaces[j] = NULL;
364
free(obj_surface->output_surfaces);
365
obj_surface->output_surfaces_count = 0;
366
obj_surface->output_surfaces_count_max = 0;
368
if (obj_surface->video_mixer) {
369
video_mixer_unref(driver_data, obj_surface->video_mixer);
370
obj_surface->video_mixer = NULL;
373
if (obj_surface->assocs) {
374
object_subpicture_p obj_subpicture;
376
const unsigned int n_assocs = obj_surface->assocs_count;
378
for (j = 0, n = 0; j < n_assocs; j++) {
379
SubpictureAssociationP const assoc = obj_surface->assocs[0];
382
obj_subpicture = VDPAU_SUBPICTURE(assoc->subpicture);
383
ASSERT(obj_subpicture);
386
status = subpicture_deassociate_1(obj_subpicture, obj_surface);
387
if (status == VA_STATUS_SUCCESS)
391
vdpau_error_message("vaDestroySurfaces(): surface 0x%08x still "
392
"has %d subpictures associated to it\n",
393
obj_surface->base.id, n_assocs - n);
394
free(obj_surface->assocs);
395
obj_surface->assocs = NULL;
397
obj_surface->assocs_count = 0;
398
obj_surface->assocs_count_max = 0;
400
object_heap_free(&driver_data->surface_heap, (object_base_p)obj_surface);
402
return VA_STATUS_SUCCESS;
407
vdpau_CreateSurfaces(
408
VADriverContextP ctx,
413
VASurfaceID *surfaces
416
VDPAU_DRIVER_DATA_INIT;
418
VAStatus va_status = VA_STATUS_SUCCESS;
419
VdpVideoSurface vdp_surface = VDP_INVALID_HANDLE;
420
VdpChromaType vdp_chroma_type = get_VdpChromaType(format);
421
VdpStatus vdp_status;
424
/* We only support one format */
425
if (format != VA_RT_FORMAT_YUV420)
426
return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
428
for (i = 0; i < num_surfaces; i++) {
429
vdp_status = vdpau_video_surface_create(driver_data,
430
driver_data->vdp_device,
434
if (vdp_status != VDP_STATUS_OK) {
435
va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
439
int va_surface = object_heap_allocate(&driver_data->surface_heap);
440
object_surface_p obj_surface;
441
if ((obj_surface = VDPAU_SURFACE(va_surface)) == NULL) {
442
va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
445
obj_surface->va_context = VA_INVALID_ID;
446
obj_surface->va_surface_status = VASurfaceReady;
447
obj_surface->vdp_surface = vdp_surface;
448
obj_surface->width = width;
449
obj_surface->height = height;
450
obj_surface->assocs = NULL;
451
obj_surface->assocs_count = 0;
452
obj_surface->assocs_count_max = 0;
453
obj_surface->vdp_chroma_type = vdp_chroma_type;
454
obj_surface->output_surfaces = NULL;
455
obj_surface->output_surfaces_count = 0;
456
obj_surface->output_surfaces_count_max = 0;
457
obj_surface->video_mixer = NULL;
458
surfaces[i] = va_surface;
459
vdp_surface = VDP_INVALID_HANDLE;
463
if (va_status != VA_STATUS_SUCCESS) {
464
if (vdp_surface != VDP_INVALID_HANDLE)
465
vdpau_video_surface_destroy(driver_data, vdp_surface);
466
vdpau_DestroySurfaces(ctx, surfaces, i);
473
VAStatus vdpau_DestroyContext(VADriverContextP ctx, VAContextID context)
475
VDPAU_DRIVER_DATA_INIT;
478
object_context_p obj_context = VDPAU_CONTEXT(context);
480
if (obj_context == NULL)
481
return VA_STATUS_ERROR_INVALID_CONTEXT;
483
if (obj_context->gen_slice_data) {
484
free(obj_context->gen_slice_data);
485
obj_context->gen_slice_data = NULL;
486
obj_context->gen_slice_data_size = 0;
487
obj_context->gen_slice_data_size_max = 0;
490
if (obj_context->vdp_bitstream_buffers) {
491
free(obj_context->vdp_bitstream_buffers);
492
obj_context->vdp_bitstream_buffers = NULL;
493
obj_context->vdp_bitstream_buffers_count = 0;
494
obj_context->vdp_bitstream_buffers_count_max = 0;
497
if (obj_context->vdp_video_surfaces) {
498
for (i = 0; i < obj_context->num_render_targets; i++) {
499
VdpVideoSurface surface = obj_context->vdp_video_surfaces[i];
500
if (surface != VDP_INVALID_HANDLE) {
501
vdpau_video_surface_destroy(driver_data, surface);
502
obj_context->vdp_video_surfaces[i] = VDP_INVALID_HANDLE;
505
free(obj_context->vdp_video_surfaces);
506
obj_context->vdp_video_surfaces = NULL;
509
if (obj_context->vdp_decoder != VDP_INVALID_HANDLE) {
510
vdpau_decoder_destroy(driver_data, obj_context->vdp_decoder);
511
obj_context->vdp_decoder = VDP_INVALID_HANDLE;
514
if (obj_context->dead_buffers) {
515
free(obj_context->dead_buffers);
516
obj_context->dead_buffers = NULL;
519
if (obj_context->render_targets) {
520
free(obj_context->render_targets);
521
obj_context->render_targets = NULL;
524
obj_context->context_id = -1;
525
obj_context->config_id = -1;
526
obj_context->current_render_target = VA_INVALID_SURFACE;
527
obj_context->picture_width = 0;
528
obj_context->picture_height = 0;
529
obj_context->num_render_targets = 0;
530
obj_context->flags = 0;
531
obj_context->dead_buffers_count = 0;
532
obj_context->dead_buffers_count_max = 0;
534
object_heap_free(&driver_data->context_heap, (object_base_p)obj_context);
535
return VA_STATUS_SUCCESS;
541
VADriverContextP ctx,
542
VAConfigID config_id,
546
VASurfaceID *render_targets,
547
int num_render_targets,
551
VDPAU_DRIVER_DATA_INIT;
554
*context = VA_INVALID_ID;
556
object_config_p obj_config;
557
if ((obj_config = VDPAU_CONFIG(config_id)) == NULL)
558
return VA_STATUS_ERROR_INVALID_CONFIG;
560
/* XXX: validate flag */
562
VdpDecoderProfile vdp_profile;
563
uint32_t max_width, max_height;
565
vdp_profile = get_VdpDecoderProfile(obj_config->profile);
566
if (!get_max_surface_size(driver_data, vdp_profile, &max_width, &max_height))
567
return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
568
if (picture_width > max_width || picture_height > max_height)
569
return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
571
VAContextID context_id = object_heap_allocate(&driver_data->context_heap);
572
if (context_id == VA_INVALID_ID)
573
return VA_STATUS_ERROR_ALLOCATION_FAILED;
575
object_context_p obj_context = VDPAU_CONTEXT(context_id);
578
return VA_STATUS_ERROR_ALLOCATION_FAILED;
580
*context = context_id;
582
obj_context->context_id = context_id;
583
obj_context->config_id = config_id;
584
obj_context->current_render_target = VA_INVALID_SURFACE;
585
obj_context->picture_width = picture_width;
586
obj_context->picture_height = picture_height;
587
obj_context->num_render_targets = num_render_targets;
588
obj_context->flags = flag;
589
obj_context->max_ref_frames = -1;
590
obj_context->render_targets = (VASurfaceID *)
591
calloc(num_render_targets, sizeof(VASurfaceID));
592
obj_context->dead_buffers = NULL;
593
obj_context->dead_buffers_count = 0;
594
obj_context->dead_buffers_count_max = 0;
595
obj_context->vdp_codec = get_VdpCodec(vdp_profile);
596
obj_context->vdp_profile = vdp_profile;
597
obj_context->vdp_decoder = VDP_INVALID_HANDLE;
598
obj_context->vdp_video_surfaces = (VdpVideoSurface *)
599
calloc(num_render_targets, sizeof(VdpVideoSurface));
600
obj_context->gen_slice_data = NULL;
601
obj_context->gen_slice_data_size = 0;
602
obj_context->gen_slice_data_size_max = 0;
603
obj_context->vdp_bitstream_buffers = NULL;
604
obj_context->vdp_bitstream_buffers_count = 0;
605
obj_context->vdp_bitstream_buffers_count_max = 0;
606
obj_context->ref_frames_count = 0;
607
for (i = 0; i < ARRAY_ELEMS(obj_context->ref_frames); i++)
608
obj_context->ref_frames[i] = VA_INVALID_SURFACE;
610
if (obj_context->render_targets == NULL || obj_context->vdp_video_surfaces == NULL) {
611
vdpau_DestroyContext(ctx, context_id);
612
return VA_STATUS_ERROR_ALLOCATION_FAILED;
615
for (i = 0; i < num_render_targets; i++) {
616
object_surface_t *obj_surface;
617
if ((obj_surface = VDPAU_SURFACE(render_targets[i])) == NULL) {
618
vdpau_DestroyContext(ctx, context_id);
619
return VA_STATUS_ERROR_INVALID_SURFACE;
621
obj_context->render_targets[i] = render_targets[i];
622
obj_context->vdp_video_surfaces[i] = obj_surface->vdp_surface;
623
/* XXX: assume we can only associate a surface to a single context */
624
ASSERT(obj_surface->va_context == VA_INVALID_ID);
625
obj_surface->va_context = context_id;
627
return VA_STATUS_SUCCESS;
630
// Query surface status
632
query_surface_status(
633
vdpau_driver_data_t *driver_data,
634
object_surface_p obj_surface,
635
VASurfaceStatus *status
638
VAStatus va_status = VA_STATUS_SUCCESS;
640
if (obj_surface->va_surface_status == VASurfaceDisplaying) {
641
unsigned int i, num_output_surfaces_displaying = 0;
642
for (i = 0; i < obj_surface->output_surfaces_count; i++) {
643
object_output_p obj_output = obj_surface->output_surfaces[i];
646
return VA_STATUS_ERROR_INVALID_SURFACE;
648
VdpOutputSurface vdp_output_surface;
649
vdp_output_surface = obj_output->vdp_output_surfaces[(obj_output->current_output_surface + VDPAU_MAX_OUTPUT_SURFACES - 1) % VDPAU_MAX_OUTPUT_SURFACES];
650
if (vdp_output_surface == VDP_INVALID_HANDLE)
653
VdpPresentationQueueStatus vdp_queue_status;
654
VdpTime vdp_dummy_time;
655
VdpStatus vdp_status;
656
vdp_status = vdpau_presentation_queue_query_surface_status(
658
obj_output->vdp_flip_queue,
663
va_status = vdpau_get_VAStatus(driver_data, vdp_status);
665
if (vdp_queue_status != VDP_PRESENTATION_QUEUE_STATUS_VISIBLE)
666
++num_output_surfaces_displaying;
669
if (num_output_surfaces_displaying == 0)
670
obj_surface->va_surface_status = VASurfaceReady;
674
*status = obj_surface->va_surface_status;
679
// vaQuerySurfaceStatus
681
vdpau_QuerySurfaceStatus(
682
VADriverContextP ctx,
683
VASurfaceID render_target,
684
VASurfaceStatus *status
687
VDPAU_DRIVER_DATA_INIT;
689
object_surface_p obj_surface = VDPAU_SURFACE(render_target);
691
if (obj_surface == NULL)
692
return VA_STATUS_ERROR_INVALID_SURFACE;
694
return query_surface_status(driver_data, obj_surface, status);
697
// Wait for the surface to complete pending operations
700
vdpau_driver_data_t *driver_data,
701
object_surface_p obj_surface
704
/* VDPAU only supports status interface for in-progress display */
705
/* XXX: polling is bad but there currently is no alternative */
707
VASurfaceStatus va_surface_status;
708
VAStatus va_status = query_surface_status(driver_data,
712
if (va_status != VA_STATUS_SUCCESS)
715
if (va_surface_status != VASurfaceDisplaying)
717
delay_usec(VDPAU_SYNC_DELAY);
719
return VA_STATUS_SUCCESS;
725
VADriverContextP ctx,
726
VASurfaceID render_target
729
VDPAU_DRIVER_DATA_INIT;
731
object_surface_p obj_surface = VDPAU_SURFACE(render_target);
734
return VA_STATUS_ERROR_INVALID_SURFACE;
736
/* Assume that this shouldn't be called before vaEndPicture() */
737
object_context_p obj_context = VDPAU_CONTEXT(obj_surface->va_context);
739
ASSERT(obj_context->current_render_target != obj_surface->base.id);
740
if (obj_context->current_render_target == obj_surface->base.id)
741
return VA_STATUS_ERROR_INVALID_CONTEXT;
744
return sync_surface(driver_data, obj_surface);
749
VADriverContextP ctx,
751
VASurfaceID render_target
754
VDPAU_DRIVER_DATA_INIT;
756
object_surface_p obj_surface = VDPAU_SURFACE(render_target);
759
return VA_STATUS_ERROR_INVALID_SURFACE;
761
/* Assume that this shouldn't be called before vaEndPicture() */
762
object_context_p obj_context = VDPAU_CONTEXT(context);
764
ASSERT(obj_context->current_render_target != obj_surface->base.id);
765
if (obj_context->current_render_target == obj_surface->base.id)
766
return VA_STATUS_ERROR_INVALID_CONTEXT;
769
return sync_surface(driver_data, obj_surface);
772
// Ensure VA Display Attributes are initialized
773
static int ensure_display_attributes(vdpau_driver_data_t *driver_data)
775
VADisplayAttribute *attr;
777
if (driver_data->va_display_attrs_count > 0)
780
memset(driver_data->va_display_attrs_mtime, 0, sizeof(driver_data->va_display_attrs_mtime));
782
attr = &driver_data->va_display_attrs[0];
784
attr->type = VADisplayAttribDirectSurface;
785
attr->value = 0; /* VdpVideoSurface is copied into VdpOutputSurface */
786
attr->min_value = attr->value;
787
attr->max_value = attr->value;
788
attr->flags = VA_DISPLAY_ATTRIB_GETTABLE;
791
attr->type = VADisplayAttribBrightness;
793
attr->min_value = -100;
794
attr->max_value = 100;
795
attr->flags = VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE;
798
attr->type = VADisplayAttribContrast;
800
attr->min_value = -100;
801
attr->max_value = 100;
802
attr->flags = VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE;
805
attr->type = VADisplayAttribHue;
807
attr->min_value = -100;
808
attr->max_value = 100;
809
attr->flags = VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE;
812
attr->type = VADisplayAttribSaturation;
814
attr->min_value = -100;
815
attr->max_value = 100;
816
attr->flags = VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE;
819
attr->type = VADisplayAttribBackgroundColor;
822
attr->max_value = 0xffffff;
823
attr->flags = VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE;
826
driver_data->va_display_attrs_count = attr - driver_data->va_display_attrs;
827
ASSERT(driver_data->va_display_attrs_count <= VDPAU_MAX_DISPLAY_ATTRIBUTES);
831
// Look up for the specified VA display attribute
832
static VADisplayAttribute *
833
get_display_attribute(
834
vdpau_driver_data_t *driver_data,
835
VADisplayAttribType type
838
if (ensure_display_attributes(driver_data) < 0)
842
for (i = 0; i < driver_data->va_display_attrs_count; i++) {
843
if (driver_data->va_display_attrs[i].type == type)
844
return &driver_data->va_display_attrs[i];
849
// vaQueryDisplayAttributes
851
vdpau_QueryDisplayAttributes(
852
VADriverContextP ctx,
853
VADisplayAttribute *attr_list,
857
VDPAU_DRIVER_DATA_INIT;
859
if (ensure_display_attributes(driver_data) < 0)
860
return VA_STATUS_ERROR_OPERATION_FAILED;
863
memcpy(attr_list, driver_data->va_display_attrs,
864
driver_data->va_display_attrs_count * sizeof(attr_list[0]));
867
*num_attributes = driver_data->va_display_attrs_count;
869
return VA_STATUS_SUCCESS;
872
// vaGetDisplayAttributes
874
vdpau_GetDisplayAttributes(
875
VADriverContextP ctx,
876
VADisplayAttribute *attr_list,
880
VDPAU_DRIVER_DATA_INIT;
883
for (i = 0; i < num_attributes; i++) {
884
VADisplayAttribute * const dst_attr = &attr_list[i];
885
VADisplayAttribute *src_attr;
887
src_attr = get_display_attribute(driver_data, dst_attr->type);
888
if (src_attr && (src_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) != 0) {
889
dst_attr->min_value = src_attr->min_value;
890
dst_attr->max_value = src_attr->max_value;
891
dst_attr->value = src_attr->value;
894
dst_attr->flags &= ~VA_DISPLAY_ATTRIB_GETTABLE;
896
return VA_STATUS_SUCCESS;
899
// vaSetDisplayAttributes
901
vdpau_SetDisplayAttributes(
902
VADriverContextP ctx,
903
VADisplayAttribute *attr_list,
907
VDPAU_DRIVER_DATA_INIT;
910
for (i = 0; i < num_attributes; i++) {
911
VADisplayAttribute * const src_attr = &attr_list[i];
912
VADisplayAttribute *dst_attr;
914
dst_attr = get_display_attribute(driver_data, src_attr->type);
916
return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
918
if ((dst_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) != 0) {
919
dst_attr->value = src_attr->value;
921
static uint64_t mtime;
922
const int display_attr_index = dst_attr - driver_data->va_display_attrs;
923
ASSERT(display_attr_index < VDPAU_MAX_DISPLAY_ATTRIBUTES);
924
driver_data->va_display_attrs_mtime[display_attr_index] = ++mtime;
927
return VA_STATUS_SUCCESS;
930
// vaDbgCopySurfaceToBuffer (not a PUBLIC interface)
932
vdpau_DbgCopySurfaceToBuffer(
933
VADriverContextP ctx,
940
return VA_STATUS_ERROR_UNKNOWN;
943
#if VA_CHECK_VERSION(0,30,0)
944
// vaCreateSurfaceFromCIFrame
946
vdpau_CreateSurfaceFromCIFrame(
947
VADriverContextP ctx,
948
unsigned long frame_id,
953
return VA_STATUS_ERROR_UNKNOWN;
956
// vaCreateSurfaceFromV4L2Buf
958
vdpau_CreateSurfaceFromV4L2Buf(
959
VADriverContextP ctx,
961
struct v4l2_format *v4l2_fmt,
962
struct v4l2_buffer *v4l2_buf,
967
return VA_STATUS_ERROR_UNKNOWN;
970
// vaCopySurfaceToBuffer
972
vdpau_CopySurfaceToBuffer(
973
VADriverContextP ctx,
975
unsigned int *fourcc,
976
unsigned int *luma_stride,
977
unsigned int *chroma_u_stride,
978
unsigned int *chroma_v_stride,
979
unsigned int *luma_offset,
980
unsigned int *chroma_u_offset,
981
unsigned int *chroma_v_offset,
986
return VA_STATUS_ERROR_UNKNOWN;