~ubuntu-branches/ubuntu/trusty/vdpau-video/trusty-proposed

« back to all changes in this revision

Viewing changes to src/vdpau_subpic.c

  • Committer: Bazaar Package Importer
  • Author(s): Andres Mejia
  • Date: 2010-02-12 14:58:28 UTC
  • Revision ID: james.westby@ubuntu.com-20100212145828-f0q1g7qzq03din26
Tags: upstream-0.6.3
ImportĀ upstreamĀ versionĀ 0.6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  vdpau_subpic.c - VDPAU backend for VA API (VA subpictures)
 
3
 *
 
4
 *  vdpau-video (C) 2009-2010 Splitted-Desktop Systems
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 */
 
20
 
 
21
#include "sysdeps.h"
 
22
#include "vdpau_subpic.h"
 
23
#include "vdpau_video.h"
 
24
#include "vdpau_image.h"
 
25
#include "vdpau_buffer.h"
 
26
#include "utils.h"
 
27
 
 
28
#define DEBUG 1
 
29
#include "debug.h"
 
30
 
 
31
 
 
32
// List of supported subpicture formats
 
33
typedef struct {
 
34
    VdpImageFormatType  vdp_format_type;
 
35
    uint32_t            vdp_format;
 
36
    VAImageFormat       va_format;
 
37
    unsigned int        va_flags;
 
38
} vdpau_subpic_format_map_t;
 
39
 
 
40
static const vdpau_subpic_format_map_t
 
41
vdpau_subpic_formats_map[VDPAU_MAX_SUBPICTURE_FORMATS + 1] = {
 
42
    { VDP_IMAGE_FORMAT_TYPE_INDEXED, VDP_INDEXED_FORMAT_A4I4,
 
43
      { VA_FOURCC('A','I','4','4'), VA_MSB_FIRST, 8, },
 
44
      0 },
 
45
    { VDP_IMAGE_FORMAT_TYPE_INDEXED, VDP_INDEXED_FORMAT_I4A4,
 
46
      { VA_FOURCC('I','A','4','4'), VA_MSB_FIRST, 8, },
 
47
      0 },
 
48
    { VDP_IMAGE_FORMAT_TYPE_INDEXED, VDP_INDEXED_FORMAT_A8I8,
 
49
      { VA_FOURCC('A','I','8','8'), VA_MSB_FIRST, 16, },
 
50
      0 },
 
51
    { VDP_IMAGE_FORMAT_TYPE_INDEXED, VDP_INDEXED_FORMAT_I8A8,
 
52
      { VA_FOURCC('I','A','8','8'), VA_MSB_FIRST, 16, },
 
53
      0 },
 
54
#ifdef WORDS_BIGENDIAN
 
55
    { VDP_IMAGE_FORMAT_TYPE_RGBA, VDP_RGBA_FORMAT_B8G8R8A8,
 
56
      { VA_FOURCC('A','R','G','B'), VA_MSB_FIRST, 32,
 
57
        32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
 
58
      0 },
 
59
    { VDP_IMAGE_FORMAT_TYPE_RGBA, VDP_RGBA_FORMAT_R8G8B8A8,
 
60
      { VA_FOURCC('A','B','G','R'), VA_MSB_FIRST, 32,
 
61
        32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
 
62
      0 },
 
63
#else
 
64
    { VDP_IMAGE_FORMAT_TYPE_RGBA, VDP_RGBA_FORMAT_B8G8R8A8,
 
65
      { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32,
 
66
        32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
 
67
      0 },
 
68
    { VDP_IMAGE_FORMAT_TYPE_RGBA, VDP_RGBA_FORMAT_R8G8B8A8,
 
69
      { VA_FOURCC('R','G','B','A'), VA_LSB_FIRST, 32,
 
70
        32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
 
71
      0 },
 
72
#endif
 
73
    { 0, VDP_INVALID_HANDLE, }
 
74
};
 
75
 
 
76
// Returns a suitable VDPAU subpicture format for the specified VA image format
 
77
static const vdpau_subpic_format_map_t *get_format(const VAImageFormat *format)
 
78
{
 
79
    unsigned int i;
 
80
    for (i = 0; vdpau_subpic_formats_map[i].va_format.fourcc != 0; i++) {
 
81
        const vdpau_subpic_format_map_t * const m = &vdpau_subpic_formats_map[i];
 
82
        if (m->va_format.fourcc == format->fourcc &&
 
83
            (m->vdp_format_type == VDP_IMAGE_FORMAT_TYPE_RGBA ?
 
84
             (m->va_format.byte_order == format->byte_order &&
 
85
              m->va_format.red_mask   == format->red_mask   &&
 
86
              m->va_format.green_mask == format->green_mask &&
 
87
              m->va_format.blue_mask  == format->blue_mask  &&
 
88
              m->va_format.alpha_mask == format->alpha_mask) : 1))
 
89
            return m;
 
90
    }
 
91
    return NULL;
 
92
}
 
93
 
 
94
// Checks whether the VDPAU implementation supports the specified image format
 
95
static inline VdpBool
 
96
is_supported_format(
 
97
    vdpau_driver_data_t             *driver_data,
 
98
    const vdpau_subpic_format_map_t *format)
 
99
{
 
100
    VdpBool is_supported = VDP_FALSE;
 
101
    VdpStatus vdp_status;
 
102
    uint32_t max_width, max_height;
 
103
 
 
104
    switch (format->vdp_format_type) {
 
105
    case VDP_IMAGE_FORMAT_TYPE_RGBA:
 
106
        vdp_status = vdpau_bitmap_surface_query_capabilities(
 
107
            driver_data,
 
108
            driver_data->vdp_device,
 
109
            format->vdp_format,
 
110
            &is_supported,
 
111
            &max_width,
 
112
            &max_height
 
113
        );
 
114
        break;
 
115
    case VDP_IMAGE_FORMAT_TYPE_INDEXED:
 
116
        vdp_status = vdpau_output_surface_query_put_bits_indexed_capabilities(
 
117
            driver_data,
 
118
            driver_data->vdp_device,
 
119
            VDP_RGBA_FORMAT_B8G8R8A8,
 
120
            format->vdp_format,
 
121
            VDP_COLOR_TABLE_FORMAT_B8G8R8X8,
 
122
            &is_supported
 
123
        );
 
124
        break;
 
125
    default:
 
126
        vdp_status = VDP_STATUS_ERROR;
 
127
        break;
 
128
    }
 
129
    return vdp_status == VDP_STATUS_OK && is_supported;
 
130
}
 
131
 
 
132
// Append association to the subpicture
 
133
static int
 
134
subpicture_add_association(
 
135
    object_subpicture_p    obj_subpicture,
 
136
    SubpictureAssociationP assoc
 
137
)
 
138
{
 
139
    SubpictureAssociationP *assocs;
 
140
    assocs = realloc_buffer(&obj_subpicture->assocs,
 
141
                            &obj_subpicture->assocs_count_max,
 
142
                            1 + obj_subpicture->assocs_count,
 
143
                            sizeof(obj_subpicture->assocs[0]));
 
144
    if (!assocs)
 
145
        return -1;
 
146
 
 
147
    assocs[obj_subpicture->assocs_count++] = assoc;
 
148
    return 0;
 
149
}
 
150
 
 
151
// Remove association at the specified index from the subpicture
 
152
static inline int
 
153
subpicture_remove_association_at(object_subpicture_p obj_subpicture, int index)
 
154
{
 
155
    ASSERT(obj_subpicture->assocs && obj_subpicture->assocs_count > 0);
 
156
    if (!obj_subpicture->assocs || obj_subpicture->assocs_count == 0)
 
157
        return -1;
 
158
 
 
159
    /* Replace with the last association */
 
160
    const unsigned int last = obj_subpicture->assocs_count - 1;
 
161
    obj_subpicture->assocs[index] = obj_subpicture->assocs[last];
 
162
    obj_subpicture->assocs[last] = NULL;
 
163
    obj_subpicture->assocs_count--;
 
164
    return 0;
 
165
}
 
166
 
 
167
// Remove association from the subpicture
 
168
static int
 
169
subpicture_remove_association(
 
170
    object_subpicture_p    obj_subpicture,
 
171
    SubpictureAssociationP assoc
 
172
)
 
173
{
 
174
    ASSERT(obj_subpicture->assocs && obj_subpicture->assocs_count > 0);
 
175
    if (!obj_subpicture->assocs || obj_subpicture->assocs_count == 0)
 
176
        return -1;
 
177
 
 
178
    unsigned int i;
 
179
    for (i = 0; i < obj_subpicture->assocs_count; i++) {
 
180
        if (obj_subpicture->assocs[i] == assoc)
 
181
            return subpicture_remove_association_at(obj_subpicture, i);
 
182
    }
 
183
    return -1;
 
184
}
 
185
 
 
186
// Associate one surface to the subpicture
 
187
VAStatus
 
188
subpicture_associate_1(
 
189
    object_subpicture_p obj_subpicture,
 
190
    object_surface_p    obj_surface,
 
191
    const VARectangle  *src_rect,
 
192
    const VARectangle  *dst_rect,
 
193
    unsigned int        flags
 
194
)
 
195
{
 
196
    /* XXX: flags are not supported */
 
197
    if (flags)
 
198
        return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
 
199
 
 
200
    SubpictureAssociationP assoc = malloc(sizeof(*assoc));
 
201
    if (!assoc)
 
202
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
203
 
 
204
    assoc->subpicture = obj_subpicture->base.id;
 
205
    assoc->surface    = obj_surface->base.id;
 
206
    assoc->src_rect   = *src_rect;
 
207
    assoc->dst_rect   = *dst_rect;
 
208
    assoc->flags      = flags;
 
209
 
 
210
    VAStatus status = surface_add_association(obj_surface, assoc);
 
211
    if (status !=  VA_STATUS_SUCCESS) {
 
212
        free(assoc);
 
213
        return status;
 
214
    }
 
215
 
 
216
    if (subpicture_add_association(obj_subpicture, assoc) < 0) {
 
217
        surface_remove_association(obj_surface, assoc);
 
218
        free(assoc);
 
219
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
220
    }
 
221
    return VA_STATUS_SUCCESS;
 
222
}
 
223
 
 
224
// Associate surfaces to the subpicture
 
225
static VAStatus
 
226
associate_subpicture(
 
227
    vdpau_driver_data_t *driver_data,
 
228
    object_subpicture_p obj_subpicture,
 
229
    VASurfaceID        *surfaces,
 
230
    unsigned int        num_surfaces,
 
231
    const VARectangle  *src_rect,
 
232
    const VARectangle  *dst_rect,
 
233
    unsigned int        flags
 
234
)
 
235
{
 
236
    VAStatus status;
 
237
    unsigned int i;
 
238
 
 
239
    for (i = 0; i < num_surfaces; i++) {
 
240
        object_surface_p const obj_surface = VDPAU_SURFACE(surfaces[i]);
 
241
        if (!obj_surface)
 
242
            return VA_STATUS_ERROR_INVALID_SURFACE;
 
243
        status = subpicture_associate_1(obj_subpicture, obj_surface,
 
244
                                        src_rect, dst_rect, flags);
 
245
        if (status != VA_STATUS_SUCCESS)
 
246
            return status;
 
247
    }
 
248
    return VA_STATUS_SUCCESS;
 
249
}
 
250
 
 
251
// Deassociate one surface from the subpicture
 
252
VAStatus
 
253
subpicture_deassociate_1(
 
254
    object_subpicture_p obj_subpicture,
 
255
    object_surface_p    obj_surface
 
256
)
 
257
{
 
258
    ASSERT(obj_subpicture->assocs && obj_subpicture->assocs_count > 0);
 
259
    if (!obj_subpicture->assocs || obj_subpicture->assocs_count == 0)
 
260
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
261
 
 
262
    unsigned int i;
 
263
    for (i = 0; i < obj_subpicture->assocs_count; i++) {
 
264
        SubpictureAssociationP const assoc = obj_subpicture->assocs[i];
 
265
        ASSERT(assoc);
 
266
        if (assoc && assoc->surface == obj_surface->base.id) {
 
267
            surface_remove_association(obj_surface, assoc);
 
268
            subpicture_remove_association_at(obj_subpicture, i);
 
269
            free(assoc);
 
270
            return VA_STATUS_SUCCESS;
 
271
        }
 
272
    }
 
273
    return VA_STATUS_ERROR_OPERATION_FAILED;
 
274
}
 
275
 
 
276
// Deassociate surfaces from the subpicture
 
277
static VAStatus
 
278
deassociate_subpicture(
 
279
    vdpau_driver_data_t *driver_data,
 
280
    object_subpicture_p obj_subpicture,
 
281
    VASurfaceID        *surfaces,
 
282
    unsigned int        num_surfaces
 
283
)
 
284
{
 
285
    VAStatus status, error = VA_STATUS_SUCCESS;
 
286
    unsigned int i;
 
287
 
 
288
    for (i = 0; i < num_surfaces; i++) {
 
289
        object_surface_p const obj_surface = VDPAU_SURFACE(surfaces[i]);
 
290
        if (!obj_surface)
 
291
            return VA_STATUS_ERROR_INVALID_SURFACE;
 
292
        status = subpicture_deassociate_1(obj_subpicture, obj_surface);
 
293
        if (status != VA_STATUS_SUCCESS) {
 
294
            /* Simply report the first error to the user */
 
295
            if (error == VA_STATUS_SUCCESS)
 
296
                error = status;
 
297
        }
 
298
    }
 
299
    return error;
 
300
}
 
301
 
 
302
// Commit subpicture to VDPAU surface
 
303
VAStatus
 
304
commit_subpicture(
 
305
    vdpau_driver_data_p driver_data,
 
306
    object_subpicture_p obj_subpicture
 
307
)
 
308
{
 
309
    object_image_p obj_image = VDPAU_IMAGE(obj_subpicture->image_id);
 
310
    if (!obj_image)
 
311
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
312
 
 
313
    ASSERT(obj_subpicture->width == obj_image->image.width);
 
314
    if (obj_subpicture->width != obj_image->image.width)
 
315
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
316
 
 
317
    ASSERT(obj_subpicture->height == obj_image->image.height);
 
318
    if (obj_subpicture->height != obj_image->image.height)
 
319
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
320
 
 
321
    object_buffer_p obj_buffer = VDPAU_BUFFER(obj_image->image.buf);
 
322
    if (!obj_buffer)
 
323
        return VA_STATUS_ERROR_INVALID_BUFFER;
 
324
 
 
325
    /* Update video surface only if the image (hence its buffer) was
 
326
       updated since our last synchronisation.
 
327
 
 
328
       NOTE: this assumes the user really unmaps the buffer when he is
 
329
       done with it, as it is actually required */
 
330
    if (obj_subpicture->last_commit >= obj_buffer->mtime)
 
331
        return VA_STATUS_SUCCESS;
 
332
 
 
333
    VdpRect dirty_rect;
 
334
    dirty_rect.x0 = obj_subpicture->width;
 
335
    dirty_rect.y0 = obj_subpicture->height;
 
336
    dirty_rect.x1 = 0;
 
337
    dirty_rect.y1 = 0;
 
338
 
 
339
    unsigned int i;
 
340
    for (i = 0; i < obj_subpicture->assocs_count; i++) {
 
341
        const VARectangle * const rect = &obj_subpicture->assocs[i]->src_rect;
 
342
        dirty_rect.x0 = MIN(dirty_rect.x0, rect->x);
 
343
        dirty_rect.y0 = MIN(dirty_rect.y0, rect->y);
 
344
        dirty_rect.x1 = MAX(dirty_rect.x1, rect->x + rect->width);
 
345
        dirty_rect.y1 = MAX(dirty_rect.y1, rect->y + rect->height);
 
346
    }
 
347
 
 
348
    const uint8_t *src;
 
349
    uint32_t src_stride;
 
350
    src_stride = obj_image->image.pitches[0];
 
351
    src = ((uint8_t *)obj_buffer->buffer_data + obj_image->image.offsets[0] +
 
352
           dirty_rect.y0 * obj_image->image.pitches[0] +
 
353
           dirty_rect.x0 * ((obj_image->image.format.bits_per_pixel + 7) / 8));
 
354
 
 
355
    VdpStatus vdp_status;
 
356
    switch (obj_subpicture->vdp_format_type) {
 
357
    case VDP_IMAGE_FORMAT_TYPE_RGBA:
 
358
        vdp_status = vdpau_bitmap_surface_put_bits_native(
 
359
            driver_data,
 
360
            obj_subpicture->vdp_bitmap_surface,
 
361
            &src, &src_stride,
 
362
            &dirty_rect
 
363
        );
 
364
        break;
 
365
    case VDP_IMAGE_FORMAT_TYPE_INDEXED:
 
366
        vdp_status = vdpau_output_surface_put_bits_indexed(
 
367
            driver_data,
 
368
            obj_subpicture->vdp_output_surface,
 
369
            obj_subpicture->vdp_format,
 
370
            &src, &src_stride,
 
371
            &dirty_rect,
 
372
            VDP_COLOR_TABLE_FORMAT_B8G8R8X8,
 
373
            obj_image->vdp_palette
 
374
        );
 
375
        break;
 
376
    default:
 
377
        vdp_status = VDP_STATUS_ERROR;
 
378
        break;
 
379
    }
 
380
    if (vdp_status != VDP_STATUS_OK)
 
381
        return vdpau_get_VAStatus(driver_data, vdp_status);
 
382
 
 
383
    obj_subpicture->last_commit = obj_buffer->mtime;
 
384
    return VA_STATUS_SUCCESS;
 
385
}
 
386
 
 
387
// Create subpicture with image
 
388
static VAStatus
 
389
create_subpicture(
 
390
    vdpau_driver_data_t *driver_data,
 
391
    object_image_p       obj_image,
 
392
    VASubpictureID      *subpicture
 
393
)
 
394
{
 
395
    *subpicture = object_heap_allocate(&driver_data->subpicture_heap);
 
396
    if (*subpicture == VA_INVALID_ID)
 
397
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
398
 
 
399
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(*subpicture);
 
400
    ASSERT(obj_subpicture);
 
401
    if (!obj_subpicture)
 
402
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
403
 
 
404
    const vdpau_subpic_format_map_t *m = get_format(&obj_image->image.format);
 
405
    if (!is_supported_format(driver_data, m))
 
406
        return VA_STATUS_ERROR_UNKNOWN; /* VA_STATUS_ERROR_UNSUPPORTED_FORMAT */
 
407
 
 
408
    obj_subpicture->image_id           = obj_image->base.id;
 
409
    obj_subpicture->assocs             = NULL;
 
410
    obj_subpicture->assocs_count       = 0;
 
411
    obj_subpicture->assocs_count_max   = 0;
 
412
    obj_subpicture->width              = obj_image->image.width;
 
413
    obj_subpicture->height             = obj_image->image.height;
 
414
    obj_subpicture->vdp_bitmap_surface = VDP_INVALID_HANDLE;
 
415
    obj_subpicture->vdp_output_surface = VDP_INVALID_HANDLE;
 
416
    obj_subpicture->last_commit        = 0;
 
417
    obj_subpicture->vdp_format_type    = m->vdp_format_type;
 
418
    obj_subpicture->vdp_format         = m->vdp_format;
 
419
 
 
420
    VdpStatus vdp_status;
 
421
    switch (obj_subpicture->vdp_format_type) {
 
422
    case VDP_IMAGE_FORMAT_TYPE_RGBA:
 
423
        vdp_status = vdpau_bitmap_surface_create(
 
424
            driver_data,
 
425
            driver_data->vdp_device,
 
426
            obj_subpicture->vdp_format,
 
427
            obj_subpicture->width,
 
428
            obj_subpicture->height,
 
429
            VDP_FALSE,
 
430
            &obj_subpicture->vdp_bitmap_surface
 
431
        );
 
432
        break;
 
433
    case VDP_IMAGE_FORMAT_TYPE_INDEXED:
 
434
        vdp_status = vdpau_output_surface_create(
 
435
            driver_data,
 
436
            driver_data->vdp_device,
 
437
            VDP_RGBA_FORMAT_B8G8R8A8,
 
438
            obj_subpicture->width,
 
439
            obj_subpicture->height,
 
440
            &obj_subpicture->vdp_output_surface
 
441
        );
 
442
        break;
 
443
    default:
 
444
        vdp_status = VDP_STATUS_ERROR;
 
445
        break;
 
446
    }
 
447
    return vdpau_get_VAStatus(driver_data, vdp_status);
 
448
}
 
449
 
 
450
// Destroy subpicture
 
451
static void
 
452
destroy_subpicture(
 
453
    vdpau_driver_data_t *driver_data,
 
454
    object_subpicture_p obj_subpicture
 
455
)
 
456
{
 
457
    object_surface_p obj_surface;
 
458
    VAStatus status;
 
459
    unsigned int i, n;
 
460
 
 
461
    if (obj_subpicture->assocs) {
 
462
        const unsigned int n_assocs = obj_subpicture->assocs_count;
 
463
        for (i = 0, n = 0; i < n_assocs; i++) {
 
464
            SubpictureAssociationP const assoc = obj_subpicture->assocs[0];
 
465
            if (!assoc)
 
466
                continue;
 
467
            obj_surface = VDPAU_SURFACE(assoc->surface);
 
468
            ASSERT(obj_surface);
 
469
            if (!obj_surface)
 
470
                continue;
 
471
            status = subpicture_deassociate_1(obj_subpicture, obj_surface);
 
472
            if (status == VA_STATUS_SUCCESS)
 
473
                ++n;
 
474
        }
 
475
        if (n != n_assocs)
 
476
            vdpau_error_message("vaDestroySubpicture(): subpicture 0x%08x still "
 
477
                               "has %d surfaces associated to it\n",
 
478
                               obj_subpicture->base.id, n_assocs - n);
 
479
        free(obj_subpicture->assocs);
 
480
        obj_subpicture->assocs = NULL;
 
481
    }
 
482
    obj_subpicture->assocs_count = 0;
 
483
    obj_subpicture->assocs_count_max = 0;
 
484
 
 
485
    if (obj_subpicture->vdp_bitmap_surface != VDP_INVALID_HANDLE) {
 
486
        vdpau_bitmap_surface_destroy(
 
487
            driver_data,
 
488
            obj_subpicture->vdp_bitmap_surface
 
489
        );
 
490
        obj_subpicture->vdp_bitmap_surface = VDP_INVALID_HANDLE;
 
491
    }
 
492
 
 
493
    if (obj_subpicture->vdp_output_surface != VDP_INVALID_HANDLE) {
 
494
        vdpau_output_surface_destroy(
 
495
            driver_data,
 
496
            obj_subpicture->vdp_output_surface
 
497
        );
 
498
        obj_subpicture->vdp_output_surface = VDP_INVALID_HANDLE;
 
499
    }
 
500
 
 
501
    obj_subpicture->image_id = VA_INVALID_ID;
 
502
    object_heap_free(&driver_data->subpicture_heap,
 
503
                     (object_base_p)obj_subpicture);
 
504
}
 
505
 
 
506
// vaQuerySubpictureFormats
 
507
VAStatus
 
508
vdpau_QuerySubpictureFormats(
 
509
    VADriverContextP    ctx,
 
510
    VAImageFormat      *format_list,
 
511
    unsigned int       *flags,
 
512
    unsigned int       *num_formats
 
513
)
 
514
{
 
515
    VDPAU_DRIVER_DATA_INIT;
 
516
 
 
517
    int n;
 
518
    for (n = 0; vdpau_subpic_formats_map[n].va_format.fourcc != 0; n++) {
 
519
        const vdpau_subpic_format_map_t * const m = &vdpau_subpic_formats_map[n];
 
520
        if (is_supported_format(driver_data, m)) {
 
521
            if (format_list)
 
522
                format_list[n] = m->va_format;
 
523
            if (flags)
 
524
                flags[n] = m->va_flags;
 
525
        }
 
526
    }
 
527
 
 
528
    if (num_formats)
 
529
        *num_formats = n;
 
530
 
 
531
    return VA_STATUS_SUCCESS;
 
532
}
 
533
 
 
534
// vaCreateSubpicture
 
535
VAStatus
 
536
vdpau_CreateSubpicture(
 
537
    VADriverContextP    ctx,
 
538
    VAImageID           image,
 
539
    VASubpictureID     *subpicture
 
540
)
 
541
{
 
542
    VDPAU_DRIVER_DATA_INIT;
 
543
 
 
544
    if (!subpicture)
 
545
        return VA_STATUS_ERROR_INVALID_PARAMETER;
 
546
 
 
547
    object_image_p obj_image = VDPAU_IMAGE(image);
 
548
    if (!obj_image)
 
549
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
550
 
 
551
    return create_subpicture(driver_data, obj_image, subpicture);
 
552
}
 
553
 
 
554
// vaDestroySubpicture
 
555
VAStatus
 
556
vdpau_DestroySubpicture(
 
557
    VADriverContextP    ctx,
 
558
    VASubpictureID      subpicture
 
559
)
 
560
{
 
561
    VDPAU_DRIVER_DATA_INIT;
 
562
 
 
563
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
564
    if (!obj_subpicture)
 
565
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
566
 
 
567
    destroy_subpicture(driver_data, obj_subpicture);
 
568
    return VA_STATUS_SUCCESS;
 
569
}
 
570
 
 
571
// vaSetSubpictureImage
 
572
VAStatus
 
573
vdpau_SetSubpictureImage(
 
574
    VADriverContextP    ctx,
 
575
    VASubpictureID      subpicture,
 
576
    VAImageID           image
 
577
)
 
578
{
 
579
    VDPAU_DRIVER_DATA_INIT;
 
580
 
 
581
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
582
    if (!obj_subpicture)
 
583
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
584
 
 
585
    object_image_p obj_image = VDPAU_IMAGE(image);
 
586
    if (!obj_image)
 
587
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
588
 
 
589
    obj_subpicture->image_id = obj_image->base.id;
 
590
    return VA_STATUS_SUCCESS;
 
591
}
 
592
 
 
593
// vaSetSubpicturePalette (not a PUBLIC interface)
 
594
VAStatus
 
595
vdpau_SetSubpicturePalette(
 
596
    VADriverContextP    ctx,
 
597
    VASubpictureID      subpicture,
 
598
    unsigned char      *palette
 
599
)
 
600
{
 
601
    /* TODO */
 
602
    return VA_STATUS_ERROR_OPERATION_FAILED;
 
603
}
 
604
 
 
605
// vaSetSubpictureChromaKey
 
606
VAStatus
 
607
vdpau_SetSubpictureChromakey(
 
608
    VADriverContextP    ctx,
 
609
    VASubpictureID      subpicture,
 
610
    unsigned int        chromakey_min,
 
611
    unsigned int        chromakey_max,
 
612
    unsigned int        chromakey_mask
 
613
)
 
614
{
 
615
    VDPAU_DRIVER_DATA_INIT;
 
616
 
 
617
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
618
    if (!obj_subpicture)
 
619
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
620
 
 
621
    obj_subpicture->chromakey_min  = chromakey_min;
 
622
    obj_subpicture->chromakey_max  = chromakey_max;
 
623
    obj_subpicture->chromakey_mask = chromakey_mask;
 
624
    return VA_STATUS_SUCCESS;
 
625
}
 
626
 
 
627
// vaSetSubpictureGlobalAlpha
 
628
VAStatus
 
629
vdpau_SetSubpictureGlobalAlpha(
 
630
    VADriverContextP    ctx,
 
631
    VASubpictureID      subpicture,
 
632
    float               global_alpha
 
633
)
 
634
{
 
635
    VDPAU_DRIVER_DATA_INIT;
 
636
 
 
637
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
638
    if (!obj_subpicture)
 
639
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
640
 
 
641
    obj_subpicture->alpha = global_alpha;
 
642
    return VA_STATUS_SUCCESS;
 
643
}
 
644
 
 
645
// vaAssociateSubpicture
 
646
VAStatus
 
647
vdpau_AssociateSubpicture(
 
648
    VADriverContextP    ctx,
 
649
    VASubpictureID      subpicture,
 
650
    VASurfaceID        *target_surfaces,
 
651
    int                 num_surfaces,
 
652
    short               src_x,
 
653
    short               src_y,
 
654
    short               dest_x,
 
655
    short               dest_y,
 
656
    unsigned short      width,
 
657
    unsigned short      height,
 
658
    unsigned int        flags
 
659
)
 
660
{
 
661
    VDPAU_DRIVER_DATA_INIT;
 
662
 
 
663
    if (!target_surfaces || num_surfaces == 0)
 
664
        return VA_STATUS_SUCCESS;
 
665
 
 
666
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
667
    if (!obj_subpicture)
 
668
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
669
 
 
670
    VARectangle src_rect, dst_rect;
 
671
    src_rect.x      = src_x;
 
672
    src_rect.y      = src_y;
 
673
    src_rect.width  = width;
 
674
    src_rect.height = height;
 
675
    dst_rect.x      = dest_x;
 
676
    dst_rect.y      = dest_y;
 
677
    dst_rect.width  = width;
 
678
    dst_rect.height = height;
 
679
    return associate_subpicture(driver_data, obj_subpicture,
 
680
                                target_surfaces, num_surfaces,
 
681
                                &src_rect, &dst_rect, flags);
 
682
}
 
683
 
 
684
// vaAssociateSubpicture2
 
685
VAStatus
 
686
vdpau_AssociateSubpicture_full(
 
687
    VADriverContextP    ctx,
 
688
    VASubpictureID      subpicture,
 
689
    VASurfaceID        *target_surfaces,
 
690
    int                 num_surfaces,
 
691
    short               src_x,
 
692
    short               src_y,
 
693
    unsigned short      src_width,
 
694
    unsigned short      src_height,
 
695
    short               dest_x,
 
696
    short               dest_y,
 
697
    unsigned short      dest_width,
 
698
    unsigned short      dest_height,
 
699
    unsigned int        flags
 
700
)
 
701
{
 
702
    VDPAU_DRIVER_DATA_INIT;
 
703
 
 
704
    if (!target_surfaces || num_surfaces == 0)
 
705
        return VA_STATUS_SUCCESS;
 
706
 
 
707
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
708
    if (!obj_subpicture)
 
709
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
710
 
 
711
    VARectangle src_rect, dst_rect;
 
712
    src_rect.x      = src_x;
 
713
    src_rect.y      = src_y;
 
714
    src_rect.width  = src_width;
 
715
    src_rect.height = src_height;
 
716
    dst_rect.x      = dest_x;
 
717
    dst_rect.y      = dest_y;
 
718
    dst_rect.width  = dest_width;
 
719
    dst_rect.height = dest_height;
 
720
    return associate_subpicture(driver_data, obj_subpicture,
 
721
                                target_surfaces, num_surfaces,
 
722
                                &src_rect, &dst_rect, flags);
 
723
}
 
724
 
 
725
// vaDeassociateSubpicture
 
726
VAStatus
 
727
vdpau_DeassociateSubpicture(
 
728
    VADriverContextP    ctx,
 
729
    VASubpictureID      subpicture,
 
730
    VASurfaceID        *target_surfaces,
 
731
    int                 num_surfaces
 
732
)
 
733
{
 
734
    VDPAU_DRIVER_DATA_INIT;
 
735
 
 
736
    if (!target_surfaces || num_surfaces == 0)
 
737
        return VA_STATUS_SUCCESS;
 
738
 
 
739
    object_subpicture_p obj_subpicture = VDPAU_SUBPICTURE(subpicture);
 
740
    if (!obj_subpicture)
 
741
        return VA_STATUS_ERROR_INVALID_SUBPICTURE;
 
742
 
 
743
    return deassociate_subpicture(driver_data, obj_subpicture,
 
744
                                  target_surfaces, num_surfaces);
 
745
}