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

« back to all changes in this revision

Viewing changes to src/vdpau_image.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_image.c - VDPAU backend for VA API (VA images)
 
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_image.h"
 
23
#include "vdpau_video.h"
 
24
#include "vdpau_buffer.h"
 
25
#include "vdpau_mixer.h"
 
26
 
 
27
#define DEBUG 1
 
28
#include "debug.h"
 
29
 
 
30
 
 
31
// List of supported image formats
 
32
typedef struct {
 
33
    VdpImageFormatType  vdp_format_type;
 
34
    uint32_t            vdp_format;
 
35
    VAImageFormat       va_format;
 
36
    unsigned int        num_palette_entries;
 
37
    unsigned int        entry_bytes;
 
38
    char                component_order[4];
 
39
} vdpau_image_format_map_t;
 
40
 
 
41
static const vdpau_image_format_map_t vdpau_image_formats_map[] = {
 
42
#define DEF(TYPE, FORMAT) \
 
43
    VDP_IMAGE_FORMAT_TYPE_##TYPE, VDP_##TYPE##_FORMAT_##FORMAT
 
44
#define DEF_YUV(TYPE, FORMAT, FOURCC, ENDIAN, BPP) \
 
45
    { DEF(TYPE, FORMAT), { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, }
 
46
#define DEF_RGB(TYPE, FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \
 
47
    { DEF(TYPE, FORMAT), { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, }
 
48
#define DEF_IDX(TYPE, FORMAT, FOURCC, ENDIAN, BPP, NPE, EB, C0,C1,C2,C3) \
 
49
    { DEF(TYPE, FORMAT), { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, \
 
50
      NPE, EB, { C0, C1, C2, C3 } }
 
51
    DEF_YUV(YCBCR, NV12,        ('N','V','1','2'), LSB, 12),
 
52
    DEF_YUV(YCBCR, YV12,        ('Y','V','1','2'), LSB, 12),
 
53
    DEF_YUV(YCBCR, UYVY,        ('U','Y','V','Y'), LSB, 16),
 
54
    DEF_YUV(YCBCR, YUYV,        ('Y','U','Y','V'), LSB, 16),
 
55
    DEF_YUV(YCBCR, V8U8Y8A8,    ('A','Y','U','V'), LSB, 32),
 
56
#ifdef WORDS_BIGENDIAN
 
57
    DEF_RGB(RGBA, B8G8R8A8,     ('A','R','G','B'), MSB, 32,
 
58
            32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
 
59
    DEF_RGB(RGBA, R8G8B8A8,     ('A','B','G','R'), MSB, 32,
 
60
            32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
 
61
#else
 
62
    DEF_RGB(RGBA, B8G8R8A8,     ('B','G','R','A'), LSB, 32,
 
63
            32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
 
64
    DEF_RGB(RGBA, R8G8B8A8,     ('R','G','B','A'), LSB, 32,
 
65
            32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
 
66
#endif
 
67
    DEF_IDX(INDEXED, A4I4,      ('A','I','4','4'), MSB, 8,
 
68
            16, 3, 'R','G','B',0),
 
69
    DEF_IDX(INDEXED, I4A4,      ('I','A','4','4'), MSB, 8,
 
70
            16, 3, 'R','G','B',0),
 
71
    DEF_IDX(INDEXED, A8I8,      ('A','I','8','8'), MSB, 16,
 
72
            256, 3, 'R','G','B',0),
 
73
    DEF_IDX(INDEXED, I8A8,      ('I','A','8','8'), MSB, 16,
 
74
            256, 3, 'R','G','B',0),
 
75
#undef DEF_IDX
 
76
#undef DEF_RGB
 
77
#undef DEF_YUV
 
78
#undef DEF
 
79
};
 
80
 
 
81
// Returns a suitable VDPAU image format for the specified VA image format
 
82
static const vdpau_image_format_map_t *get_format(const VAImageFormat *format)
 
83
{
 
84
    unsigned int i;
 
85
    for (i = 0; i < ARRAY_ELEMS(vdpau_image_formats_map); i++) {
 
86
        const vdpau_image_format_map_t * const m = &vdpau_image_formats_map[i];
 
87
        if (m->va_format.fourcc == format->fourcc &&
 
88
            (m->vdp_format_type == VDP_IMAGE_FORMAT_TYPE_RGBA ?
 
89
             (m->va_format.byte_order == format->byte_order &&
 
90
              m->va_format.red_mask   == format->red_mask   &&
 
91
              m->va_format.green_mask == format->green_mask &&
 
92
              m->va_format.blue_mask  == format->blue_mask  &&
 
93
              m->va_format.alpha_mask == format->alpha_mask) : 1))
 
94
            return m;
 
95
    }
 
96
    return NULL;
 
97
}
 
98
 
 
99
// Checks whether the VDPAU implementation supports the specified image format
 
100
static inline VdpBool
 
101
is_supported_format(
 
102
    vdpau_driver_data_t *driver_data,
 
103
    VdpImageFormatType   type,
 
104
    uint32_t             format
 
105
)
 
106
{
 
107
    VdpBool is_supported = VDP_FALSE;
 
108
    VdpStatus vdp_status;
 
109
 
 
110
    switch (type) {
 
111
    case VDP_IMAGE_FORMAT_TYPE_YCBCR:
 
112
        vdp_status =
 
113
            vdpau_video_surface_query_ycbcr_caps(driver_data,
 
114
                                                 driver_data->vdp_device,
 
115
                                                 VDP_CHROMA_TYPE_420,
 
116
                                                 format,
 
117
                                                 &is_supported);
 
118
        break;
 
119
    case VDP_IMAGE_FORMAT_TYPE_RGBA:
 
120
        vdp_status =
 
121
            vdpau_output_surface_query_rgba_caps(driver_data,
 
122
                                                 driver_data->vdp_device,
 
123
                                                 format,
 
124
                                                 &is_supported);
 
125
        break;
 
126
    default:
 
127
        vdp_status = VDP_STATUS_INVALID_VALUE;
 
128
        break;
 
129
    }
 
130
    return vdp_status == VDP_STATUS_OK && is_supported;
 
131
}
 
132
 
 
133
// vaQueryImageFormats
 
134
VAStatus
 
135
vdpau_QueryImageFormats(
 
136
    VADriverContextP    ctx,
 
137
    VAImageFormat      *format_list,
 
138
    int                *num_formats
 
139
)
 
140
{
 
141
    VDPAU_DRIVER_DATA_INIT;
 
142
 
 
143
    if (num_formats)
 
144
        *num_formats = 0;
 
145
 
 
146
    if (format_list == NULL)
 
147
        return VA_STATUS_SUCCESS;
 
148
 
 
149
    int i, n = 0;
 
150
    for (i = 0; i < ARRAY_ELEMS(vdpau_image_formats_map); i++) {
 
151
        const vdpau_image_format_map_t * const f = &vdpau_image_formats_map[i];
 
152
        if (is_supported_format(driver_data, f->vdp_format_type, f->vdp_format))
 
153
            format_list[n++] = f->va_format;
 
154
    }
 
155
 
 
156
    /* If the assert fails then VDPAU_MAX_IMAGE_FORMATS needs to be bigger */
 
157
    ASSERT(n <= VDPAU_MAX_IMAGE_FORMATS);
 
158
    if (num_formats)
 
159
        *num_formats = n;
 
160
 
 
161
    return VA_STATUS_SUCCESS;
 
162
}
 
163
 
 
164
// vaCreateImage
 
165
VAStatus
 
166
vdpau_CreateImage(
 
167
    VADriverContextP    ctx,
 
168
    VAImageFormat      *format,
 
169
    int                 width,
 
170
    int                 height,
 
171
    VAImage            *out_image
 
172
)
 
173
{
 
174
    VDPAU_DRIVER_DATA_INIT;
 
175
 
 
176
    VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
 
177
    unsigned int i, width2, height2, size2, size;
 
178
 
 
179
    if (!format || !out_image)
 
180
        return VA_STATUS_ERROR_INVALID_PARAMETER;
 
181
 
 
182
    out_image->image_id = VA_INVALID_ID;
 
183
    out_image->buf      = VA_INVALID_ID;
 
184
 
 
185
    VAImageID image_id = object_heap_allocate(&driver_data->image_heap);
 
186
    if (image_id == VA_INVALID_ID)
 
187
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
188
 
 
189
    object_image_p obj_image = VDPAU_IMAGE(image_id);
 
190
    if (!obj_image)
 
191
        return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
192
 
 
193
    const vdpau_image_format_map_t *m = get_format(format);
 
194
    if (!m)
 
195
        return VA_STATUS_ERROR_UNKNOWN; /* VA_STATUS_ERROR_UNSUPPORTED_FORMAT */
 
196
 
 
197
    VAImage * const image = &obj_image->image;
 
198
    image->image_id       = image_id;
 
199
    image->buf            = VA_INVALID_ID;
 
200
 
 
201
    size    = width * height;
 
202
    width2  = (width  + 1) / 2;
 
203
    height2 = (height + 1) / 2;
 
204
    size2   = width2 * height2;
 
205
 
 
206
    switch (format->fourcc) {
 
207
    case VA_FOURCC('N','V','1','2'):
 
208
        image->num_planes = 2;
 
209
        image->pitches[0] = width;
 
210
        image->offsets[0] = 0;
 
211
        image->pitches[1] = width;
 
212
        image->offsets[1] = size;
 
213
        image->data_size  = size + 2 * size2;
 
214
        break;
 
215
    case VA_FOURCC('Y','V','1','2'):
 
216
        image->num_planes = 3;
 
217
        image->pitches[0] = width;
 
218
        image->offsets[0] = 0;
 
219
        image->pitches[1] = width2;
 
220
        image->offsets[1] = size + size2;
 
221
        image->pitches[2] = width2;
 
222
        image->offsets[2] = size;
 
223
        image->data_size  = size + 2 * size2;
 
224
        break;
 
225
    case VA_FOURCC('A','R','G','B'):
 
226
    case VA_FOURCC('A','B','G','R'):
 
227
    case VA_FOURCC('B','G','R','A'):
 
228
    case VA_FOURCC('R','G','B','A'):
 
229
    case VA_FOURCC('U','Y','V','Y'):
 
230
    case VA_FOURCC('Y','U','Y','V'):
 
231
        image->num_planes = 1;
 
232
        image->pitches[0] = width * 4;
 
233
        image->offsets[0] = 0;
 
234
        image->data_size  = image->offsets[0] + image->pitches[0] * height;
 
235
        break;
 
236
    case VA_FOURCC('I','A','4','4'):
 
237
    case VA_FOURCC('A','I','4','4'):
 
238
        image->num_planes = 1;
 
239
        image->pitches[0] = width;
 
240
        image->offsets[0] = 0;
 
241
        image->data_size  = image->offsets[0] + image->pitches[0] * height;
 
242
        break;
 
243
    case VA_FOURCC('I','A','8','8'):
 
244
    case VA_FOURCC('A','I','8','8'):
 
245
        image->num_planes = 1;
 
246
        image->pitches[0] = width * 2;
 
247
        image->offsets[0] = 0;
 
248
        image->data_size  = image->offsets[0] + image->pitches[0] * height;
 
249
        break;
 
250
    default:
 
251
        goto error;
 
252
    }
 
253
 
 
254
    va_status = vdpau_CreateBuffer(ctx, 0, VAImageBufferType,
 
255
                                   image->data_size, 1, NULL,
 
256
                                   &image->buf);
 
257
    if (va_status != VA_STATUS_SUCCESS)
 
258
        goto error;
 
259
 
 
260
    obj_image->vdp_rgba_output_surface = VDP_INVALID_HANDLE;
 
261
    obj_image->vdp_format_type  = m->vdp_format_type;
 
262
    obj_image->vdp_format       = m->vdp_format;
 
263
    obj_image->vdp_palette      = NULL;
 
264
 
 
265
    image->image_id             = image_id;
 
266
    image->format               = *format;
 
267
    image->width                = width;
 
268
    image->height               = height;
 
269
    image->num_palette_entries  = m->num_palette_entries;
 
270
    image->entry_bytes          = m->entry_bytes;
 
271
    for (i = 0; i < image->entry_bytes; i++)
 
272
        image->component_order[i] = m->component_order[i];
 
273
    for (; i < 4; i++)
 
274
        image->component_order[i] = 0;
 
275
 
 
276
    *out_image                  = *image;
 
277
    return VA_STATUS_SUCCESS;
 
278
 
 
279
 error:
 
280
    vdpau_DestroyImage(ctx, image_id);
 
281
    return va_status;
 
282
}
 
283
 
 
284
// vaDestroyImage
 
285
VAStatus
 
286
vdpau_DestroyImage(
 
287
    VADriverContextP    ctx,
 
288
    VAImageID           image_id
 
289
)
 
290
{
 
291
    VDPAU_DRIVER_DATA_INIT;
 
292
 
 
293
    object_image_p obj_image = VDPAU_IMAGE(image_id);
 
294
    if (!obj_image)
 
295
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
296
 
 
297
    if (obj_image->vdp_rgba_output_surface != VDP_INVALID_HANDLE)
 
298
        vdpau_output_surface_destroy(driver_data,
 
299
                                     obj_image->vdp_rgba_output_surface);
 
300
 
 
301
    if (obj_image->vdp_palette) {
 
302
        free(obj_image->vdp_palette);
 
303
        obj_image->vdp_palette = NULL;
 
304
    }
 
305
 
 
306
    VABufferID buf = obj_image->image.buf;
 
307
    object_heap_free(&driver_data->image_heap, (object_base_p)obj_image);
 
308
    return vdpau_DestroyBuffer(ctx, buf);
 
309
}
 
310
 
 
311
// vaDeriveImage
 
312
VAStatus
 
313
vdpau_DeriveImage(
 
314
    VADriverContextP    ctx,
 
315
    VASurfaceID         surface,
 
316
    VAImage             *image
 
317
)
 
318
{
 
319
    /* TODO */
 
320
    return VA_STATUS_ERROR_OPERATION_FAILED;
 
321
}
 
322
 
 
323
// Set image palette
 
324
static VAStatus
 
325
set_image_palette(
 
326
    vdpau_driver_data_t *driver_data,
 
327
    object_image_p       obj_image,
 
328
    const unsigned char *palette
 
329
)
 
330
{
 
331
    if (obj_image->vdp_format_type != VDP_IMAGE_FORMAT_TYPE_INDEXED)
 
332
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
333
 
 
334
    if (!obj_image->vdp_palette) {
 
335
        obj_image->vdp_palette = malloc(4 * obj_image->image.num_palette_entries);
 
336
        if (!obj_image->vdp_palette)
 
337
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
338
    }
 
339
 
 
340
    unsigned int i;
 
341
    for (i = 0; i < obj_image->image.num_palette_entries; i++) {
 
342
        /* B8G8R8X8 format */
 
343
        obj_image->vdp_palette[i] = ((palette[3*i + 0] << 16) |
 
344
                                     (palette[3*i + 1] <<  8) |
 
345
                                      palette[3*i + 2]);
 
346
    }
 
347
    return VA_STATUS_SUCCESS;
 
348
}
 
349
 
 
350
// vaSetImagePalette
 
351
VAStatus
 
352
vdpau_SetImagePalette(
 
353
    VADriverContextP    ctx,
 
354
    VAImageID           image,
 
355
    unsigned char      *palette
 
356
)
 
357
{
 
358
    VDPAU_DRIVER_DATA_INIT;
 
359
 
 
360
    object_image_p obj_image = VDPAU_IMAGE(image);
 
361
    if (!obj_image)
 
362
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
363
 
 
364
    return set_image_palette(driver_data, obj_image, palette);
 
365
}
 
366
 
 
367
// Get image from surface
 
368
static VAStatus
 
369
get_image(
 
370
    vdpau_driver_data_t *driver_data,
 
371
    object_surface_p     obj_surface,
 
372
    object_image_p       obj_image,
 
373
    const VARectangle   *rect
 
374
)
 
375
{
 
376
    VAImage * const image = &obj_image->image;
 
377
    VdpStatus vdp_status;
 
378
    uint8_t *src[3];
 
379
    unsigned int src_stride[3];
 
380
    int i;
 
381
 
 
382
    object_buffer_p obj_buffer = VDPAU_BUFFER(image->buf);
 
383
    if (!obj_buffer)
 
384
        return VA_STATUS_ERROR_INVALID_BUFFER;
 
385
 
 
386
    for (i = 0; i < image->num_planes; i++) {
 
387
        src[i] = (uint8_t *)obj_buffer->buffer_data + image->offsets[i];
 
388
        src_stride[i] = image->pitches[i];
 
389
    }
 
390
 
 
391
    switch (obj_image->vdp_format_type) {
 
392
    case VDP_IMAGE_FORMAT_TYPE_YCBCR: {
 
393
        /* VDPAU only supports full video surface readback */
 
394
        if (rect->x != 0 ||
 
395
            rect->y != 0 ||
 
396
            obj_surface->width  != rect->width ||
 
397
            obj_surface->height != rect->height)
 
398
            return VA_STATUS_ERROR_OPERATION_FAILED;
 
399
 
 
400
        vdp_status = vdpau_video_surface_get_bits_ycbcr(
 
401
            driver_data,
 
402
            obj_surface->vdp_surface,
 
403
            obj_image->vdp_format,
 
404
            src, src_stride
 
405
        );
 
406
        break;
 
407
    }
 
408
    case VDP_IMAGE_FORMAT_TYPE_RGBA: {
 
409
        if (obj_image->vdp_rgba_output_surface == VA_INVALID_ID) {
 
410
            vdp_status = vdpau_output_surface_create(
 
411
                driver_data,
 
412
                driver_data->vdp_device,
 
413
                obj_image->vdp_format,
 
414
                obj_image->image.width,
 
415
                obj_image->image.height,
 
416
                &obj_image->vdp_rgba_output_surface
 
417
            );
 
418
            if (vdp_status != VDP_STATUS_OK)
 
419
                return vdpau_get_VAStatus(driver_data, vdp_status);
 
420
        }
 
421
 
 
422
        VdpRect vdp_rect;
 
423
        vdp_rect.x0 = rect->x;
 
424
        vdp_rect.y0 = rect->y;
 
425
        vdp_rect.x1 = rect->x + rect->width;
 
426
        vdp_rect.y1 = rect->y + rect->height;
 
427
        vdp_status = video_mixer_render(
 
428
            driver_data,
 
429
            obj_surface,
 
430
            obj_image->vdp_rgba_output_surface,
 
431
            &vdp_rect,
 
432
            &vdp_rect,
 
433
            0
 
434
        );
 
435
        if (vdp_status != VDP_STATUS_OK)
 
436
            return vdpau_get_VAStatus(driver_data, vdp_status);
 
437
 
 
438
        vdp_status = vdpau_output_surface_get_bits_native(
 
439
            driver_data,
 
440
            obj_image->vdp_rgba_output_surface,
 
441
            &vdp_rect,
 
442
            src, src_stride
 
443
        );
 
444
        break;
 
445
    }
 
446
    default:
 
447
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
448
    }
 
449
    return vdpau_get_VAStatus(driver_data, vdp_status);
 
450
}
 
451
 
 
452
// vaGetImage
 
453
VAStatus
 
454
vdpau_GetImage(
 
455
    VADriverContextP    ctx,
 
456
    VASurfaceID         surface,
 
457
    int                 x,
 
458
    int                 y,
 
459
    unsigned int        width,
 
460
    unsigned int        height,
 
461
    VAImageID           image
 
462
)
 
463
{
 
464
    VDPAU_DRIVER_DATA_INIT;
 
465
 
 
466
    object_surface_p obj_surface = VDPAU_SURFACE(surface);
 
467
    if (!obj_surface)
 
468
        return VA_STATUS_ERROR_INVALID_SURFACE;
 
469
 
 
470
    object_image_p obj_image = VDPAU_IMAGE(image);
 
471
    if (!obj_image)
 
472
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
473
 
 
474
    VARectangle rect;
 
475
    rect.x      = x;
 
476
    rect.y      = y;
 
477
    rect.width  = width;
 
478
    rect.height = height;
 
479
    return get_image(driver_data, obj_surface, obj_image, &rect);
 
480
}
 
481
 
 
482
// Put image to surface
 
483
static VAStatus
 
484
put_image(
 
485
    vdpau_driver_data_t *driver_data,
 
486
    object_surface_p     obj_surface,
 
487
    object_image_p       obj_image,
 
488
    const VARectangle   *src_rect,
 
489
    const VARectangle   *dst_rect
 
490
)
 
491
{
 
492
    VAImage * const image = &obj_image->image;
 
493
    VdpStatus vdp_status;
 
494
    uint8_t *src[3];
 
495
    unsigned int src_stride[3];
 
496
    int i;
 
497
 
 
498
#if 0
 
499
    /* Don't do anything if the surface is used for rendering for example */
 
500
    /* XXX: VDPAU has no API to inform when decoding is completed... */
 
501
    if (obj_surface->va_surface_status != VASurfaceReady)
 
502
        return VA_STATUS_ERROR_SURFACE_BUSY;
 
503
#endif
 
504
 
 
505
    /* RGBA to video surface requires color space conversion */
 
506
    if (obj_image->vdp_rgba_output_surface != VDP_INVALID_HANDLE)
 
507
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
508
 
 
509
    /* VDPAU does not support partial video surface updates */
 
510
    if (src_rect->x != 0 ||
 
511
        src_rect->y != 0 ||
 
512
        src_rect->width != image->width ||
 
513
        src_rect->height != image->height)
 
514
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
515
    if (dst_rect->x != 0 ||
 
516
        dst_rect->y != 0 ||
 
517
        dst_rect->width != obj_surface->width ||
 
518
        dst_rect->height != obj_surface->height)
 
519
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
520
    if (src_rect->width != dst_rect->width ||
 
521
        src_rect->height != dst_rect->height)
 
522
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
523
 
 
524
    object_buffer_p obj_buffer = VDPAU_BUFFER(image->buf);
 
525
    if (!obj_buffer)
 
526
        return VA_STATUS_ERROR_INVALID_BUFFER;
 
527
 
 
528
    for (i = 0; i < image->num_planes; i++) {
 
529
        src[i] = (uint8_t *)obj_buffer->buffer_data + image->offsets[i];
 
530
        src_stride[i] = image->pitches[i];
 
531
    }
 
532
 
 
533
    /* XXX: only support YCbCr surfaces for now */
 
534
    if (obj_image->vdp_format_type != VDP_IMAGE_FORMAT_TYPE_YCBCR)
 
535
        return VA_STATUS_ERROR_OPERATION_FAILED;
 
536
 
 
537
    vdp_status = vdpau_video_surface_put_bits_ycbcr(
 
538
        driver_data,
 
539
        obj_surface->vdp_surface,
 
540
        obj_image->vdp_format,
 
541
        src, src_stride
 
542
    );
 
543
    return vdpau_get_VAStatus(driver_data, vdp_status);
 
544
}
 
545
 
 
546
// vaPutImage
 
547
VAStatus
 
548
vdpau_PutImage(
 
549
    VADriverContextP    ctx,
 
550
    VASurfaceID         surface,
 
551
    VAImageID           image,
 
552
    int                 src_x,
 
553
    int                 src_y,
 
554
    unsigned int        width,
 
555
    unsigned int        height,
 
556
    int                 dest_x,
 
557
    int                 dest_y
 
558
)
 
559
{
 
560
    VDPAU_DRIVER_DATA_INIT;
 
561
 
 
562
    object_surface_p obj_surface = VDPAU_SURFACE(surface);
 
563
    if (!obj_surface)
 
564
        return VA_STATUS_ERROR_INVALID_SURFACE;
 
565
 
 
566
    object_image_p obj_image = VDPAU_IMAGE(image);
 
567
    if (!obj_image)
 
568
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
569
 
 
570
    VARectangle src_rect, dst_rect;
 
571
    src_rect.x      = src_x;
 
572
    src_rect.y      = src_y;
 
573
    src_rect.width  = width;
 
574
    src_rect.height = height;
 
575
    dst_rect.x      = dest_x;
 
576
    dst_rect.y      = dest_y;
 
577
    dst_rect.width  = width;
 
578
    dst_rect.height = height;
 
579
    return put_image(driver_data, obj_surface, obj_image, &src_rect, &dst_rect);
 
580
}
 
581
 
 
582
// vaPutImage2
 
583
VAStatus
 
584
vdpau_PutImage_full(
 
585
    VADriverContextP    ctx,
 
586
    VASurfaceID         surface,
 
587
    VAImageID           image,
 
588
    int                 src_x,
 
589
    int                 src_y,
 
590
    unsigned int        src_width,
 
591
    unsigned int        src_height,
 
592
    int                 dest_x,
 
593
    int                 dest_y,
 
594
    unsigned int        dest_width,
 
595
    unsigned int        dest_height
 
596
)
 
597
{
 
598
    VDPAU_DRIVER_DATA_INIT;
 
599
 
 
600
    object_surface_p obj_surface = VDPAU_SURFACE(surface);
 
601
    if (!obj_surface)
 
602
        return VA_STATUS_ERROR_INVALID_SURFACE;
 
603
 
 
604
    object_image_p obj_image = VDPAU_IMAGE(image);
 
605
    if (!obj_image)
 
606
        return VA_STATUS_ERROR_INVALID_IMAGE;
 
607
 
 
608
    VARectangle src_rect, dst_rect;
 
609
    src_rect.x      = src_x;
 
610
    src_rect.y      = src_y;
 
611
    src_rect.width  = src_width;
 
612
    src_rect.height = src_height;
 
613
    dst_rect.x      = dest_x;
 
614
    dst_rect.y      = dest_y;
 
615
    dst_rect.width  = dest_width;
 
616
    dst_rect.height = dest_height;
 
617
    return put_image(driver_data, obj_surface, obj_image, &src_rect, &dst_rect);
 
618
}