~ubuntu-branches/ubuntu/wily/vdpau-video/wily

« back to all changes in this revision

Viewing changes to .pc/02_purge_va_buffers_on_context_destroy_or_new_picture_decode_seq.patch/src/vdpau_decode.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Ramacher
  • Date: 2014-05-09 17:17:38 UTC
  • mfrom: (2.2.3 sid)
  • Revision ID: package-import@ubuntu.com-20140509171738-p0zwgb5cyw6c77op
Tags: 0.7.4-1
* New upstream release.
* debian/control:
  - Add myself to Uploaders.
  - Remove Andres Mejia from Uploaders since he is MIA. Thank you for
    maintaing vdpau-video. (Closes: #743561)
  - Point Homepage to the new home at freedesktop.org.
  - Bump Standards-Version to 3.9.5.
  - Add dh-autoreconf to Build-Depends.
  - Update Vcs-* to use canonical URLs.
* debian/watch: Update watch file to fetch tarball from from the new home at
  freedesktop.org. Thanks to Ross Gammon.
* debian/patches:
  - autoreconf.patch: Removed, no longer needed.
  - cast.patch: Fix build with libvdpau-dev >= 0.7-2. Bump Build-Depends on
    libvdpau-dev accordingly.
  - GL-version-1_3.patch: Apply workaround from Ubuntu to fix build
    failure. (Closes: #713612)
  - libva-constants.patch: Apply patch from upstream to fix build with
    recent libva versions.
* debian/copyright: Convert to Copyright Format 1.0.
* debian/rules:
  - Install upstream changelog.
  - Build with autoreconf.
  - Remove obsolete bits.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  vdpau_decode.c - VDPAU backend for VA-API (decoder)
3
 
 *
4
 
 *  vdpau-video (C) 2009-2011 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_decode.h"
23
 
#include "vdpau_driver.h"
24
 
#include "vdpau_buffer.h"
25
 
#include "vdpau_video.h"
26
 
#include "vdpau_dump.h"
27
 
#include "utils.h"
28
 
#include "put_bits.h"
29
 
 
30
 
#define DEBUG 1
31
 
#include "debug.h"
32
 
 
33
 
 
34
 
// Translates VdpDecoderProfile to VdpCodec
35
 
VdpCodec get_VdpCodec(VdpDecoderProfile profile)
36
 
{
37
 
    switch (profile) {
38
 
    case VDP_DECODER_PROFILE_MPEG1:
39
 
        return VDP_CODEC_MPEG1;
40
 
    case VDP_DECODER_PROFILE_MPEG2_SIMPLE:
41
 
    case VDP_DECODER_PROFILE_MPEG2_MAIN:
42
 
        return VDP_CODEC_MPEG2;
43
 
#if USE_VDPAU_MPEG4
44
 
    case VDP_DECODER_PROFILE_MPEG4_PART2_SP:
45
 
    case VDP_DECODER_PROFILE_MPEG4_PART2_ASP:
46
 
    case VDP_DECODER_PROFILE_DIVX4_QMOBILE:
47
 
    case VDP_DECODER_PROFILE_DIVX4_MOBILE:
48
 
    case VDP_DECODER_PROFILE_DIVX4_HOME_THEATER:
49
 
    case VDP_DECODER_PROFILE_DIVX4_HD_1080P:
50
 
    case VDP_DECODER_PROFILE_DIVX5_QMOBILE:
51
 
    case VDP_DECODER_PROFILE_DIVX5_MOBILE:
52
 
    case VDP_DECODER_PROFILE_DIVX5_HOME_THEATER:
53
 
    case VDP_DECODER_PROFILE_DIVX5_HD_1080P:
54
 
        return VDP_CODEC_MPEG4;
55
 
#endif
56
 
    case VDP_DECODER_PROFILE_H264_BASELINE:
57
 
    case VDP_DECODER_PROFILE_H264_MAIN:
58
 
    case VDP_DECODER_PROFILE_H264_HIGH:
59
 
        return VDP_CODEC_H264;
60
 
    case VDP_DECODER_PROFILE_VC1_SIMPLE:
61
 
    case VDP_DECODER_PROFILE_VC1_MAIN:
62
 
    case VDP_DECODER_PROFILE_VC1_ADVANCED:
63
 
        return VDP_CODEC_VC1;
64
 
    }
65
 
    return 0;
66
 
}
67
 
 
68
 
// Translates VAProfile to VdpDecoderProfile
69
 
VdpDecoderProfile get_VdpDecoderProfile(VAProfile profile)
70
 
{
71
 
    switch (profile) {
72
 
    case VAProfileMPEG2Simple:  return VDP_DECODER_PROFILE_MPEG2_SIMPLE;
73
 
    case VAProfileMPEG2Main:    return VDP_DECODER_PROFILE_MPEG2_MAIN;
74
 
#if USE_VDPAU_MPEG4
75
 
    case VAProfileMPEG4Simple:  return VDP_DECODER_PROFILE_MPEG4_PART2_SP;
76
 
    case VAProfileMPEG4AdvancedSimple: return VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
77
 
#endif
78
 
    case VAProfileH264Baseline: return VDP_DECODER_PROFILE_H264_BASELINE;
79
 
    case VAProfileH264Main:     return VDP_DECODER_PROFILE_H264_MAIN;
80
 
    case VAProfileH264High:     return VDP_DECODER_PROFILE_H264_HIGH;
81
 
    case VAProfileVC1Simple:    return VDP_DECODER_PROFILE_VC1_SIMPLE;
82
 
    case VAProfileVC1Main:      return VDP_DECODER_PROFILE_VC1_MAIN;
83
 
    case VAProfileVC1Advanced:  return VDP_DECODER_PROFILE_VC1_ADVANCED;
84
 
    default:                    break;
85
 
    }
86
 
    return (VdpDecoderProfile)-1;
87
 
}
88
 
 
89
 
// Checks whether the VDPAU implementation supports the specified profile
90
 
static inline VdpBool
91
 
is_supported_profile(
92
 
    vdpau_driver_data_t *driver_data,
93
 
    VdpDecoderProfile    profile
94
 
)
95
 
{
96
 
    VdpBool is_supported = VDP_FALSE;
97
 
    VdpStatus vdp_status;
98
 
    uint32_t max_level, max_references, max_width, max_height;
99
 
 
100
 
    if (profile == (VdpDecoderProfile)-1)
101
 
        return VDP_FALSE;
102
 
 
103
 
    vdp_status = vdpau_decoder_query_capabilities(
104
 
        driver_data,
105
 
        driver_data->vdp_device,
106
 
        profile,
107
 
        &is_supported,
108
 
        &max_level,
109
 
        &max_references,
110
 
        &max_width,
111
 
        &max_height
112
 
    );
113
 
    return (VDPAU_CHECK_STATUS(vdp_status, "VdpDecoderQueryCapabilities()") &&
114
 
            is_supported);
115
 
}
116
 
 
117
 
// Checks decoder for profile/entrypoint is available
118
 
VAStatus
119
 
check_decoder(
120
 
    vdpau_driver_data_t *driver_data,
121
 
    VAProfile            profile,
122
 
    VAEntrypoint         entrypoint
123
 
)
124
 
{
125
 
    if (!is_supported_profile(driver_data, get_VdpDecoderProfile(profile)))
126
 
        return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
127
 
 
128
 
    /* VDPAU only supports VLD */
129
 
    if (entrypoint != VAEntrypointVLD)
130
 
        return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
131
 
 
132
 
    return VA_STATUS_SUCCESS;
133
 
}
134
 
 
135
 
// Computes value for VdpDecoderCreate()::max_references parameter
136
 
static int
137
 
get_max_ref_frames(
138
 
    VdpDecoderProfile profile,
139
 
    unsigned int      width,
140
 
    unsigned int      height
141
 
)
142
 
{
143
 
    int max_ref_frames = 2;
144
 
 
145
 
    switch (profile) {
146
 
    case VDP_DECODER_PROFILE_H264_MAIN:
147
 
    case VDP_DECODER_PROFILE_H264_HIGH:
148
 
    {
149
 
        /* level 4.1 limits */
150
 
        unsigned int aligned_width  = (width + 15) & -16;
151
 
        unsigned int aligned_height = (height + 15) & -16;
152
 
        unsigned int surface_size   = (aligned_width * aligned_height * 3) / 2;
153
 
        if ((max_ref_frames = (12 * 1024 * 1024) / surface_size) > 16)
154
 
            max_ref_frames = 16;
155
 
        break;
156
 
    }
157
 
    }
158
 
    return max_ref_frames;
159
 
}
160
 
 
161
 
// Returns the maximum number of reference frames of a decode session
162
 
static inline int get_num_ref_frames(object_context_p obj_context)
163
 
{
164
 
    if (obj_context->vdp_codec == VDP_CODEC_H264)
165
 
        return obj_context->vdp_picture_info.h264.num_ref_frames;
166
 
    return 2;
167
 
}
168
 
 
169
 
// Ensure VDPAU decoder is created for the specified number of reference frames
170
 
static VdpStatus
171
 
ensure_decoder_with_max_refs(
172
 
    vdpau_driver_data_t *driver_data,
173
 
    object_context_p     obj_context,
174
 
    int                  max_ref_frames
175
 
)
176
 
{
177
 
    VdpStatus vdp_status;
178
 
 
179
 
    if (max_ref_frames < 0)
180
 
        max_ref_frames =
181
 
            get_max_ref_frames(obj_context->vdp_profile,
182
 
                               obj_context->picture_width,
183
 
                               obj_context->picture_height);
184
 
 
185
 
    if (obj_context->vdp_decoder == VDP_INVALID_HANDLE ||
186
 
        obj_context->max_ref_frames < max_ref_frames) {
187
 
        obj_context->max_ref_frames = max_ref_frames;
188
 
 
189
 
        if (obj_context->vdp_decoder != VDP_INVALID_HANDLE) {
190
 
            vdpau_decoder_destroy(driver_data, obj_context->vdp_decoder);
191
 
            obj_context->vdp_decoder = VDP_INVALID_HANDLE;
192
 
        }
193
 
 
194
 
        vdp_status = vdpau_decoder_create(
195
 
            driver_data,
196
 
            driver_data->vdp_device,
197
 
            obj_context->vdp_profile,
198
 
            obj_context->picture_width,
199
 
            obj_context->picture_height,
200
 
            max_ref_frames,
201
 
            &obj_context->vdp_decoder
202
 
        );
203
 
        if (!VDPAU_CHECK_STATUS(vdp_status, "VdpDecoderCreate()"))
204
 
            return vdp_status;
205
 
    }
206
 
    return VDP_STATUS_OK;
207
 
}
208
 
 
209
 
// Lazy allocate (generated) slice data buffer. Buffer lives until vaDestroyContext()
210
 
static uint8_t *
211
 
alloc_gen_slice_data(object_context_p obj_context, unsigned int size)
212
 
{
213
 
    uint8_t *gen_slice_data = obj_context->gen_slice_data;
214
 
 
215
 
    if (obj_context->gen_slice_data_size + size > obj_context->gen_slice_data_size_max) {
216
 
        obj_context->gen_slice_data_size_max += size;
217
 
        gen_slice_data = realloc(obj_context->gen_slice_data,
218
 
                                 obj_context->gen_slice_data_size_max);
219
 
        if (!gen_slice_data)
220
 
            return NULL;
221
 
        obj_context->gen_slice_data = gen_slice_data;
222
 
    }
223
 
    gen_slice_data += obj_context->gen_slice_data_size;
224
 
    obj_context->gen_slice_data_size += size;
225
 
    return gen_slice_data;
226
 
}
227
 
 
228
 
// Lazy allocate VdpBitstreamBuffer. Buffer lives until vaDestroyContext()
229
 
static VdpBitstreamBuffer *
230
 
alloc_VdpBitstreamBuffer(object_context_p obj_context)
231
 
{
232
 
    VdpBitstreamBuffer *vdp_bitstream_buffers;
233
 
 
234
 
    vdp_bitstream_buffers = realloc_buffer(
235
 
        &obj_context->vdp_bitstream_buffers,
236
 
        &obj_context->vdp_bitstream_buffers_count_max,
237
 
        1 + obj_context->vdp_bitstream_buffers_count,
238
 
        sizeof(*obj_context->vdp_bitstream_buffers)
239
 
    );
240
 
    if (!vdp_bitstream_buffers)
241
 
        return NULL;
242
 
 
243
 
    return &vdp_bitstream_buffers[obj_context->vdp_bitstream_buffers_count++];
244
 
}
245
 
 
246
 
// Append VASliceDataBuffer hunk into VDPAU buffer
247
 
static int
248
 
append_VdpBitstreamBuffer(
249
 
    object_context_p obj_context,
250
 
    const uint8_t   *buffer,
251
 
    uint32_t         buffer_size
252
 
)
253
 
{
254
 
    VdpBitstreamBuffer *bitstream_buffer;
255
 
 
256
 
    bitstream_buffer = alloc_VdpBitstreamBuffer(obj_context);
257
 
    if (!bitstream_buffer)
258
 
        return -1;
259
 
 
260
 
    bitstream_buffer->struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
261
 
    bitstream_buffer->bitstream       = buffer;
262
 
    bitstream_buffer->bitstream_bytes = buffer_size;
263
 
    return 0;
264
 
}
265
 
 
266
 
// Initialize VdpReferenceFrameH264 to default values
267
 
static void init_VdpReferenceFrameH264(VdpReferenceFrameH264 *rf)
268
 
{
269
 
    rf->surface             = VDP_INVALID_HANDLE;
270
 
    rf->is_long_term        = VDP_FALSE;
271
 
    rf->top_is_reference    = VDP_FALSE;
272
 
    rf->bottom_is_reference = VDP_FALSE;
273
 
    rf->field_order_cnt[0]  = 0;
274
 
    rf->field_order_cnt[1]  = 0;
275
 
    rf->frame_idx           = 0;
276
 
}
277
 
 
278
 
static const uint8_t ff_identity[64] = {
279
 
    0,   1,  2,  3,  4,  5,  6,  7,
280
 
    8,   9, 10, 11, 12, 13, 14, 15,
281
 
    16, 17, 18, 19, 20, 21, 22, 23,
282
 
    24, 25, 26, 27, 28, 29, 30, 31,
283
 
    32, 33, 34, 35, 36, 37, 38, 39,
284
 
    40, 41, 42, 43, 44, 45, 46, 47,
285
 
    48, 49, 50, 51, 52, 53, 54, 55,
286
 
    56, 57, 58, 59, 60, 61, 62, 63
287
 
};
288
 
 
289
 
static const uint8_t ff_zigzag_direct[64] = {
290
 
    0,   1,  8, 16,  9,  2,  3, 10,
291
 
    17, 24, 32, 25, 18, 11,  4,  5,
292
 
    12, 19, 26, 33, 40, 48, 41, 34,
293
 
    27, 20, 13,  6,  7, 14, 21, 28,
294
 
    35, 42, 49, 56, 57, 50, 43, 36,
295
 
    29, 22, 15, 23, 30, 37, 44, 51,
296
 
    58, 59, 52, 45, 38, 31, 39, 46,
297
 
    53, 60, 61, 54, 47, 55, 62, 63
298
 
};
299
 
 
300
 
static const uint8_t ff_mpeg1_default_intra_matrix[64] = {
301
 
     8, 16, 19, 22, 26, 27, 29, 34,
302
 
    16, 16, 22, 24, 27, 29, 34, 37,
303
 
    19, 22, 26, 27, 29, 34, 34, 38,
304
 
    22, 22, 26, 27, 29, 34, 37, 40,
305
 
    22, 26, 27, 29, 32, 35, 40, 48,
306
 
    26, 27, 29, 32, 35, 40, 48, 58,
307
 
    26, 27, 29, 34, 38, 46, 56, 69,
308
 
    27, 29, 35, 38, 46, 56, 69, 83
309
 
};
310
 
 
311
 
static const uint8_t ff_mpeg1_default_non_intra_matrix[64] = {
312
 
    16, 16, 16, 16, 16, 16, 16, 16,
313
 
    16, 16, 16, 16, 16, 16, 16, 16,
314
 
    16, 16, 16, 16, 16, 16, 16, 16,
315
 
    16, 16, 16, 16, 16, 16, 16, 16,
316
 
    16, 16, 16, 16, 16, 16, 16, 16,
317
 
    16, 16, 16, 16, 16, 16, 16, 16,
318
 
    16, 16, 16, 16, 16, 16, 16, 16,
319
 
    16, 16, 16, 16, 16, 16, 16, 16
320
 
};
321
 
 
322
 
static const uint8_t ff_mpeg4_default_intra_matrix[64] = {
323
 
     8, 17, 18, 19, 21, 23, 25, 27,
324
 
    17, 18, 19, 21, 23, 25, 27, 28,
325
 
    20, 21, 22, 23, 24, 26, 28, 30,
326
 
    21, 22, 23, 24, 26, 28, 30, 32,
327
 
    22, 23, 24, 26, 28, 30, 32, 35,
328
 
    23, 24, 26, 28, 30, 32, 35, 38,
329
 
    25, 26, 28, 30, 32, 35, 38, 41,
330
 
    27, 28, 30, 32, 35, 38, 41, 45,
331
 
};
332
 
 
333
 
static const uint8_t ff_mpeg4_default_non_intra_matrix[64] = {
334
 
    16, 17, 18, 19, 20, 21, 22, 23,
335
 
    17, 18, 19, 20, 21, 22, 23, 24,
336
 
    18, 19, 20, 21, 22, 23, 24, 25,
337
 
    19, 20, 21, 22, 23, 24, 26, 27,
338
 
    20, 21, 22, 23, 25, 26, 27, 28,
339
 
    21, 22, 23, 24, 26, 27, 28, 30,
340
 
    22, 23, 24, 26, 27, 28, 30, 31,
341
 
    23, 24, 25, 27, 28, 30, 31, 33,
342
 
};
343
 
 
344
 
// Compute integer log2
345
 
static inline int ilog2(uint32_t v)
346
 
{
347
 
    /* From <http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
348
 
    uint32_t r, shift;
349
 
    r     = (v > 0xffff) << 4; v >>= r;
350
 
    shift = (v > 0xff  ) << 3; v >>= shift; r |= shift;
351
 
    shift = (v > 0xf   ) << 2; v >>= shift; r |= shift;
352
 
    shift = (v > 0x3   ) << 1; v >>= shift; r |= shift;
353
 
    return r | (v >> 1);
354
 
}
355
 
 
356
 
// Translate VASurfaceID
357
 
static int
358
 
translate_VASurfaceID(
359
 
    vdpau_driver_data_t *driver_data,
360
 
    VASurfaceID          va_surface,
361
 
    VdpVideoSurface     *vdp_surface
362
 
)
363
 
{
364
 
    object_surface_p obj_surface;
365
 
 
366
 
    if (va_surface == VA_INVALID_SURFACE) {
367
 
        *vdp_surface = VDP_INVALID_HANDLE;
368
 
        return 1;
369
 
    }
370
 
 
371
 
    obj_surface = VDPAU_SURFACE(va_surface);
372
 
    if (!obj_surface)
373
 
        return 0;
374
 
 
375
 
    *vdp_surface = obj_surface->vdp_surface;
376
 
    return 1;
377
 
}
378
 
 
379
 
// Translate VAPictureH264
380
 
static int
381
 
translate_VAPictureH264(
382
 
    vdpau_driver_data_t   *driver_data,
383
 
    const VAPictureH264   *va_pic,
384
 
    VdpReferenceFrameH264 *rf
385
 
)
386
 
{
387
 
    // Handle invalid surfaces specifically
388
 
    if (va_pic->picture_id == VA_INVALID_SURFACE) {
389
 
        init_VdpReferenceFrameH264(rf);
390
 
        return 1;
391
 
    }
392
 
 
393
 
    if (!translate_VASurfaceID(driver_data, va_pic->picture_id, &rf->surface))
394
 
        return 0;
395
 
    rf->is_long_term            = (va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE) != 0;
396
 
    if ((va_pic->flags & (VA_PICTURE_H264_TOP_FIELD|VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
397
 
        rf->top_is_reference    = VDP_TRUE;
398
 
        rf->bottom_is_reference = VDP_TRUE;
399
 
    }
400
 
    else {
401
 
        rf->top_is_reference    = (va_pic->flags & VA_PICTURE_H264_TOP_FIELD) != 0;
402
 
        rf->bottom_is_reference = (va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD) != 0;
403
 
    }
404
 
    rf->field_order_cnt[0]      = va_pic->TopFieldOrderCnt;
405
 
    rf->field_order_cnt[1]      = va_pic->BottomFieldOrderCnt;
406
 
    rf->frame_idx               = va_pic->frame_idx;
407
 
    return 1;
408
 
}
409
 
 
410
 
// Translate no buffer
411
 
static int
412
 
translate_nothing(
413
 
    vdpau_driver_data_t *driver_data,
414
 
    object_context_p    obj_context,
415
 
    object_buffer_p     obj_buffer
416
 
)
417
 
{
418
 
    return 1;
419
 
}
420
 
 
421
 
// Translate VASliceDataBuffer
422
 
static int
423
 
translate_VASliceDataBuffer(
424
 
    vdpau_driver_data_t *driver_data,
425
 
    object_context_p    obj_context,
426
 
    object_buffer_p     obj_buffer
427
 
)
428
 
{
429
 
    if (obj_context->vdp_codec == VDP_CODEC_H264) {
430
 
        /* Check we have the start code */
431
 
        /* XXX: check for other codecs too? */
432
 
        /* XXX: this assumes we get SliceParams before SliceData */
433
 
        static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
434
 
        VASliceParameterBufferH264 * const slice_params = obj_context->last_slice_params;
435
 
        unsigned int i;
436
 
        for (i = 0; i < obj_context->last_slice_params_count; i++) {
437
 
            VASliceParameterBufferH264 * const slice_param = &slice_params[i];
438
 
            uint8_t *buf = (uint8_t *)obj_buffer->buffer_data + slice_param->slice_data_offset;
439
 
            if (memcmp(buf, start_code_prefix, sizeof(start_code_prefix)) != 0) {
440
 
                if (append_VdpBitstreamBuffer(obj_context,
441
 
                                              start_code_prefix,
442
 
                                              sizeof(start_code_prefix)) < 0)
443
 
                    return 0;
444
 
            }
445
 
            if (append_VdpBitstreamBuffer(obj_context,
446
 
                                          buf,
447
 
                                          slice_param->slice_data_size) < 0)
448
 
                return 0;
449
 
        }
450
 
        return 1;
451
 
    }
452
 
 
453
 
#if USE_VDPAU_MPEG4
454
 
    if (obj_context->vdp_codec == VDP_CODEC_MPEG4 &&
455
 
        obj_context->vdp_bitstream_buffers_count == 0) {
456
 
        PutBitContext pb;
457
 
        uint8_t slice_header_buffer[32];
458
 
        uint8_t *slice_header;
459
 
        int slice_header_size;
460
 
        const uint8_t *slice_data = obj_buffer->buffer_data;
461
 
        uint32_t slice_data_size = obj_buffer->buffer_size;
462
 
        VAPictureParameterBufferMPEG4 * const pic_param = obj_context->last_pic_param;
463
 
        VASliceParameterBufferMPEG4 * const slice_param = obj_context->last_slice_params;
464
 
 
465
 
        int time_incr = 1 + ilog2(pic_param->vop_time_increment_resolution - 1);
466
 
        if (time_incr < 1)
467
 
            time_incr = 1;
468
 
 
469
 
        static const uint16_t VOP_STARTCODE = 0x01b6;
470
 
        enum {
471
 
            VOP_I_TYPE = 0,
472
 
            VOP_P_TYPE,
473
 
            VOP_B_TYPE,
474
 
            VOP_S_TYPE
475
 
        };
476
 
 
477
 
        /* XXX: this is a hack to compute the length of
478
 
           modulo_time_base "1" sequence. We probably should be
479
 
           reconstructing through an extra VOP field in VA-API? */
480
 
        int nbits = (32 +                               /* VOP start code       */
481
 
                     2 +                                /* vop_coding_type      */
482
 
                     1 +                                /* modulo_time_base "0" */
483
 
                     1 +                                /* marker_bit           */
484
 
                     time_incr +                        /* vop_time_increment   */
485
 
                     1 +                                /* marker_bit           */
486
 
                     1 +                                /* vop_coded            */
487
 
                     (pic_param->vop_fields.bits.vop_coding_type == VOP_P_TYPE ? 1 : 0) +
488
 
                     3 +                                /* intra_dc_vlc_thr     */
489
 
                     (pic_param->vol_fields.bits.interlaced ? 2 : 0) +
490
 
                     5 +                                /* vop_quant            */
491
 
                     (pic_param->vop_fields.bits.vop_coding_type != VOP_I_TYPE ? 3 : 0) +
492
 
                     (pic_param->vop_fields.bits.vop_coding_type == VOP_B_TYPE ? 3 : 0));
493
 
        if ((nbits = slice_param->macroblock_offset - (nbits % 8)) < 0)
494
 
            nbits += 8;
495
 
 
496
 
        /* Reconstruct the VOP header */
497
 
        init_put_bits(&pb, slice_header_buffer, sizeof(slice_header_buffer));
498
 
        put_bits(&pb, 16, 0);                   /* vop header */
499
 
        put_bits(&pb, 16, VOP_STARTCODE);       /* vop header */
500
 
        put_bits(&pb, 2, pic_param->vop_fields.bits.vop_coding_type);
501
 
        while (nbits-- > 0)
502
 
            put_bits(&pb, 1, 1);                /* modulo_time_base "1" */
503
 
        put_bits(&pb, 1, 0);                    /* modulo_time_base "0" */
504
 
        put_bits(&pb, 1, 1);                    /* marker */
505
 
        put_bits(&pb, time_incr, 0);            /* time increment */
506
 
        put_bits(&pb, 1, 1);                    /* marker */
507
 
        put_bits(&pb, 1, 1);                    /* vop coded */
508
 
        if (pic_param->vop_fields.bits.vop_coding_type == VOP_P_TYPE)
509
 
            put_bits(&pb, 1, pic_param->vop_fields.bits.vop_rounding_type);
510
 
        put_bits(&pb, 3, pic_param->vop_fields.bits.intra_dc_vlc_thr);
511
 
        if (pic_param->vol_fields.bits.interlaced) {
512
 
            put_bits(&pb, 1, pic_param->vop_fields.bits.top_field_first);
513
 
            put_bits(&pb, 1, pic_param->vop_fields.bits.alternate_vertical_scan_flag);
514
 
        }
515
 
        put_bits(&pb, 5, slice_param->quant_scale);
516
 
        if (pic_param->vop_fields.bits.vop_coding_type != VOP_I_TYPE)
517
 
            put_bits(&pb, 3, pic_param->vop_fcode_forward);
518
 
        if (pic_param->vop_fields.bits.vop_coding_type == VOP_B_TYPE)
519
 
            put_bits(&pb, 3, pic_param->vop_fcode_backward);
520
 
 
521
 
        /* Merge in bits from the first byte of the slice */
522
 
        ASSERT((put_bits_count(&pb) % 8) == slice_param->macroblock_offset);
523
 
        if ((put_bits_count(&pb) % 8) != slice_param->macroblock_offset)
524
 
            return 0;
525
 
        const int r = 8 - (put_bits_count(&pb) % 8);
526
 
        if (r > 0)
527
 
            put_bits(&pb, r, slice_data[0] & ((1U << r) - 1));
528
 
        flush_put_bits(&pb);
529
 
 
530
 
        ASSERT((put_bits_count(&pb) % 8) == 0);
531
 
        slice_header_size = put_bits_count(&pb) / 8;
532
 
        ASSERT(slice_header_size <= sizeof(slice_header_buffer));
533
 
        slice_header = alloc_gen_slice_data(obj_context, slice_header_size);
534
 
        if (!slice_header)
535
 
            return 0;
536
 
        memcpy(slice_header, slice_header_buffer, slice_header_size);
537
 
        if (append_VdpBitstreamBuffer(obj_context, slice_header, slice_header_size) < 0)
538
 
            return 0;
539
 
        if (append_VdpBitstreamBuffer(obj_context, slice_data + 1, slice_data_size - 1) < 0)
540
 
            return 0;
541
 
        return 1;
542
 
    }
543
 
#endif
544
 
 
545
 
    if (append_VdpBitstreamBuffer(obj_context,
546
 
                                  obj_buffer->buffer_data,
547
 
                                  obj_buffer->buffer_size) < 0)
548
 
        return 0;
549
 
    return 1;
550
 
}
551
 
 
552
 
// Translate VAPictureParameterBufferMPEG2
553
 
static int
554
 
translate_VAPictureParameterBufferMPEG2(
555
 
    vdpau_driver_data_t *driver_data,
556
 
    object_context_p    obj_context,
557
 
    object_buffer_p     obj_buffer
558
 
)
559
 
{
560
 
    VdpPictureInfoMPEG1Or2 * const pic_info = &obj_context->vdp_picture_info.mpeg2;
561
 
    VAPictureParameterBufferMPEG2 * const pic_param = obj_buffer->buffer_data;
562
 
 
563
 
    if (!translate_VASurfaceID(driver_data,
564
 
                               pic_param->forward_reference_picture,
565
 
                               &pic_info->forward_reference))
566
 
        return 0;
567
 
 
568
 
    if (!translate_VASurfaceID(driver_data,
569
 
                               pic_param->backward_reference_picture,
570
 
                               &pic_info->backward_reference))
571
 
        return 0;
572
 
 
573
 
    pic_info->picture_structure          = pic_param->picture_coding_extension.bits.picture_structure;
574
 
    pic_info->picture_coding_type        = pic_param->picture_coding_type;
575
 
    pic_info->intra_dc_precision         = pic_param->picture_coding_extension.bits.intra_dc_precision;
576
 
    pic_info->frame_pred_frame_dct       = pic_param->picture_coding_extension.bits.frame_pred_frame_dct;
577
 
    pic_info->concealment_motion_vectors = pic_param->picture_coding_extension.bits.concealment_motion_vectors;
578
 
    pic_info->intra_vlc_format           = pic_param->picture_coding_extension.bits.intra_vlc_format;
579
 
    pic_info->alternate_scan             = pic_param->picture_coding_extension.bits.alternate_scan;
580
 
    pic_info->q_scale_type               = pic_param->picture_coding_extension.bits.q_scale_type;
581
 
    pic_info->top_field_first            = pic_param->picture_coding_extension.bits.top_field_first;
582
 
    pic_info->full_pel_forward_vector    = 0;
583
 
    pic_info->full_pel_backward_vector   = 0;
584
 
    pic_info->f_code[0][0]               = (pic_param->f_code >> 12) & 0xf;
585
 
    pic_info->f_code[0][1]               = (pic_param->f_code >>  8) & 0xf;
586
 
    pic_info->f_code[1][0]               = (pic_param->f_code >>  4) & 0xf;
587
 
    pic_info->f_code[1][1]               = pic_param->f_code & 0xf;
588
 
    return 1;
589
 
}
590
 
 
591
 
// Translate VAIQMatrixBufferMPEG2
592
 
static int
593
 
translate_VAIQMatrixBufferMPEG2(
594
 
    vdpau_driver_data_t *driver_data,
595
 
    object_context_p    obj_context,
596
 
    object_buffer_p     obj_buffer
597
 
)
598
 
{
599
 
    VdpPictureInfoMPEG1Or2 * const pic_info = &obj_context->vdp_picture_info.mpeg2;
600
 
    VAIQMatrixBufferMPEG2 * const iq_matrix = obj_buffer->buffer_data;
601
 
    const uint8_t *intra_matrix;
602
 
    const uint8_t *intra_matrix_lookup;
603
 
    const uint8_t *inter_matrix;
604
 
    const uint8_t *inter_matrix_lookup;
605
 
    int i;
606
 
 
607
 
    if (iq_matrix->load_intra_quantiser_matrix) {
608
 
        intra_matrix = iq_matrix->intra_quantiser_matrix;
609
 
        intra_matrix_lookup = ff_zigzag_direct;
610
 
    }
611
 
    else {
612
 
        intra_matrix = ff_mpeg1_default_intra_matrix;
613
 
        intra_matrix_lookup = ff_identity;
614
 
    }
615
 
 
616
 
    if (iq_matrix->load_non_intra_quantiser_matrix) {
617
 
        inter_matrix = iq_matrix->non_intra_quantiser_matrix;
618
 
        inter_matrix_lookup = ff_zigzag_direct;
619
 
    }
620
 
    else {
621
 
        inter_matrix = ff_mpeg1_default_non_intra_matrix;
622
 
        inter_matrix_lookup = ff_identity;
623
 
    }
624
 
 
625
 
    for (i = 0; i < 64; i++) {
626
 
        pic_info->intra_quantizer_matrix[intra_matrix_lookup[i]] =
627
 
            intra_matrix[i];
628
 
        pic_info->non_intra_quantizer_matrix[inter_matrix_lookup[i]] =
629
 
            inter_matrix[i];
630
 
    }
631
 
    return 1;
632
 
}
633
 
 
634
 
// Translate VASliceParameterBufferMPEG2
635
 
static int
636
 
translate_VASliceParameterBufferMPEG2(
637
 
    vdpau_driver_data_t *driver_data,
638
 
    object_context_p    obj_context,
639
 
    object_buffer_p     obj_buffer
640
 
    )
641
 
{
642
 
    VdpPictureInfoMPEG1Or2 * const pic_info = &obj_context->vdp_picture_info.mpeg2;
643
 
 
644
 
    pic_info->slice_count               += obj_buffer->num_elements;
645
 
    obj_context->last_slice_params       = obj_buffer->buffer_data;
646
 
    obj_context->last_slice_params_count = obj_buffer->num_elements;
647
 
    return 1;
648
 
}
649
 
 
650
 
#if USE_VDPAU_MPEG4
651
 
// Translate VAPictureParameterBufferMPEG4
652
 
static int
653
 
translate_VAPictureParameterBufferMPEG4(
654
 
    vdpau_driver_data_p driver_data,
655
 
    object_context_p    obj_context,
656
 
    object_buffer_p     obj_buffer
657
 
)
658
 
{
659
 
    VdpPictureInfoMPEG4Part2 * const pic_info = &obj_context->vdp_picture_info.mpeg4;
660
 
    VAPictureParameterBufferMPEG4 * const pic_param = obj_buffer->buffer_data;
661
 
 
662
 
    /* XXX: we don't support short-video-header formats */
663
 
    if (pic_param->vol_fields.bits.short_video_header)
664
 
        return 0;
665
 
 
666
 
    if (!translate_VASurfaceID(driver_data,
667
 
                               pic_param->forward_reference_picture,
668
 
                               &pic_info->forward_reference))
669
 
        return 0;
670
 
 
671
 
    if (!translate_VASurfaceID(driver_data,
672
 
                               pic_param->backward_reference_picture,
673
 
                               &pic_info->backward_reference))
674
 
        return 0;
675
 
 
676
 
    if (pic_param->vol_fields.bits.interlaced) {
677
 
        vdpau_information_message("unsupported MPEG-4 video with interlaced "
678
 
                                  "content, please report this video\n");
679
 
        pic_info->trd[0] = 2*pic_param->TRD; /* XXX: + d(0) */
680
 
        pic_info->trb[0] = 2*pic_param->TRB; /* XXX: + d(0) */
681
 
        pic_info->trd[1] = 2*pic_param->TRD; /* XXX: + d(1) */
682
 
        pic_info->trb[1] = 2*pic_param->TRB; /* XXX: + d(1) */
683
 
    }
684
 
    else {
685
 
        pic_info->trd[0] = pic_param->TRD;
686
 
        pic_info->trb[0] = pic_param->TRB;
687
 
        pic_info->trd[1] = 0;
688
 
        pic_info->trb[1] = 0;
689
 
    }
690
 
 
691
 
    pic_info->vop_time_increment_resolution     = pic_param->vop_time_increment_resolution;
692
 
    pic_info->vop_coding_type                   = pic_param->vop_fields.bits.vop_coding_type;
693
 
    pic_info->vop_fcode_forward                 = pic_param->vop_fcode_forward;
694
 
    pic_info->vop_fcode_backward                = pic_param->vop_fcode_backward;
695
 
    pic_info->resync_marker_disable             = pic_param->vol_fields.bits.resync_marker_disable;
696
 
    pic_info->interlaced                        = pic_param->vol_fields.bits.interlaced;
697
 
    pic_info->quant_type                        = pic_param->vol_fields.bits.quant_type;
698
 
    pic_info->quarter_sample                    = pic_param->vol_fields.bits.quarter_sample;
699
 
    pic_info->short_video_header                = pic_param->vol_fields.bits.short_video_header;
700
 
    pic_info->rounding_control                  = pic_param->vop_fields.bits.vop_rounding_type;
701
 
    pic_info->alternate_vertical_scan_flag      = pic_param->vop_fields.bits.alternate_vertical_scan_flag;
702
 
    pic_info->top_field_first                   = pic_param->vop_fields.bits.top_field_first;
703
 
 
704
 
    obj_context->last_pic_param                 = obj_buffer->buffer_data;
705
 
    return 1;
706
 
}
707
 
 
708
 
// Translate VAIQMatrixBufferMPEG4
709
 
static int
710
 
translate_VAIQMatrixBufferMPEG4(
711
 
    vdpau_driver_data_p driver_data,
712
 
    object_context_p    obj_context,
713
 
    object_buffer_p     obj_buffer
714
 
)
715
 
{
716
 
    VdpPictureInfoMPEG4Part2 * const pic_info = &obj_context->vdp_picture_info.mpeg4;
717
 
    VAIQMatrixBufferMPEG4 * const iq_matrix = obj_buffer->buffer_data;
718
 
    const uint8_t *intra_matrix;
719
 
    const uint8_t *intra_matrix_lookup;
720
 
    const uint8_t *inter_matrix;
721
 
    const uint8_t *inter_matrix_lookup;
722
 
    int i;
723
 
 
724
 
    if (iq_matrix->load_intra_quant_mat) {
725
 
        intra_matrix = iq_matrix->intra_quant_mat;
726
 
        intra_matrix_lookup = ff_zigzag_direct;
727
 
    }
728
 
    else {
729
 
        intra_matrix = ff_mpeg4_default_intra_matrix;
730
 
        intra_matrix_lookup = ff_identity;
731
 
    }
732
 
 
733
 
    if (iq_matrix->load_non_intra_quant_mat) {
734
 
        inter_matrix = iq_matrix->non_intra_quant_mat;
735
 
        inter_matrix_lookup = ff_zigzag_direct;
736
 
    }
737
 
    else {
738
 
        inter_matrix = ff_mpeg4_default_non_intra_matrix;
739
 
        inter_matrix_lookup = ff_identity;
740
 
    }
741
 
 
742
 
    for (i = 0; i < 64; i++) {
743
 
        pic_info->intra_quantizer_matrix[intra_matrix_lookup[i]] =
744
 
            intra_matrix[i];
745
 
        pic_info->non_intra_quantizer_matrix[inter_matrix_lookup[i]] =
746
 
            inter_matrix[i];
747
 
    }
748
 
    return 1;
749
 
}
750
 
 
751
 
// Translate VASliceParameterBufferMPEG4
752
 
static int
753
 
translate_VASliceParameterBufferMPEG4(
754
 
    vdpau_driver_data_p driver_data,
755
 
    object_context_p    obj_context,
756
 
    object_buffer_p     obj_buffer
757
 
    )
758
 
{
759
 
    obj_context->last_slice_params       = obj_buffer->buffer_data;
760
 
    obj_context->last_slice_params_count = obj_buffer->num_elements;
761
 
    return 1;
762
 
}
763
 
#endif
764
 
 
765
 
// Translate VAPictureParameterBufferH264
766
 
static int
767
 
translate_VAPictureParameterBufferH264(
768
 
    vdpau_driver_data_t *driver_data,
769
 
    object_context_p    obj_context,
770
 
    object_buffer_p     obj_buffer
771
 
)
772
 
{
773
 
    VdpPictureInfoH264 * const pic_info = &obj_context->vdp_picture_info.h264;
774
 
    VAPictureParameterBufferH264 * const pic_param = obj_buffer->buffer_data;
775
 
    VAPictureH264 * const CurrPic = &pic_param->CurrPic;
776
 
    unsigned int i;
777
 
 
778
 
    pic_info->field_order_cnt[0]                = CurrPic->TopFieldOrderCnt;
779
 
    pic_info->field_order_cnt[1]                = CurrPic->BottomFieldOrderCnt;
780
 
    pic_info->is_reference                      = pic_param->pic_fields.bits.reference_pic_flag;
781
 
 
782
 
    pic_info->frame_num                         = pic_param->frame_num;
783
 
    pic_info->field_pic_flag                    = pic_param->pic_fields.bits.field_pic_flag;
784
 
    pic_info->bottom_field_flag                 = pic_param->pic_fields.bits.field_pic_flag && (CurrPic->flags & VA_PICTURE_H264_BOTTOM_FIELD) != 0;
785
 
    pic_info->num_ref_frames                    = pic_param->num_ref_frames;
786
 
    pic_info->mb_adaptive_frame_field_flag      = pic_param->seq_fields.bits.mb_adaptive_frame_field_flag && !pic_info->field_pic_flag;
787
 
    pic_info->constrained_intra_pred_flag       = pic_param->pic_fields.bits.constrained_intra_pred_flag;
788
 
    pic_info->weighted_pred_flag                = pic_param->pic_fields.bits.weighted_pred_flag;
789
 
    pic_info->weighted_bipred_idc               = pic_param->pic_fields.bits.weighted_bipred_idc;
790
 
    pic_info->frame_mbs_only_flag               = pic_param->seq_fields.bits.frame_mbs_only_flag;
791
 
    pic_info->transform_8x8_mode_flag           = pic_param->pic_fields.bits.transform_8x8_mode_flag;
792
 
    pic_info->chroma_qp_index_offset            = pic_param->chroma_qp_index_offset;
793
 
    pic_info->second_chroma_qp_index_offset     = pic_param->second_chroma_qp_index_offset;
794
 
    pic_info->pic_init_qp_minus26               = pic_param->pic_init_qp_minus26;
795
 
    pic_info->log2_max_frame_num_minus4         = pic_param->seq_fields.bits.log2_max_frame_num_minus4;
796
 
    pic_info->pic_order_cnt_type                = pic_param->seq_fields.bits.pic_order_cnt_type;
797
 
    pic_info->log2_max_pic_order_cnt_lsb_minus4 = pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4;
798
 
    pic_info->delta_pic_order_always_zero_flag  = pic_param->seq_fields.bits.delta_pic_order_always_zero_flag;
799
 
    pic_info->direct_8x8_inference_flag         = pic_param->seq_fields.bits.direct_8x8_inference_flag;
800
 
    pic_info->entropy_coding_mode_flag          = pic_param->pic_fields.bits.entropy_coding_mode_flag;
801
 
    pic_info->pic_order_present_flag            = pic_param->pic_fields.bits.pic_order_present_flag;
802
 
    pic_info->deblocking_filter_control_present_flag = pic_param->pic_fields.bits.deblocking_filter_control_present_flag;
803
 
    pic_info->redundant_pic_cnt_present_flag    = pic_param->pic_fields.bits.redundant_pic_cnt_present_flag;
804
 
 
805
 
    for (i = 0; i < 16; i++) {
806
 
        if (!translate_VAPictureH264(driver_data,
807
 
                                     &pic_param->ReferenceFrames[i],
808
 
                                     &pic_info->referenceFrames[i]))
809
 
                return 0;
810
 
    }
811
 
    return 1;
812
 
}
813
 
 
814
 
// Translate VAIQMatrixBufferH264
815
 
static int
816
 
translate_VAIQMatrixBufferH264(
817
 
    vdpau_driver_data_t *driver_data,
818
 
    object_context_p    obj_context,
819
 
    object_buffer_p     obj_buffer
820
 
)
821
 
{
822
 
    VdpPictureInfoH264 * const pic_info = &obj_context->vdp_picture_info.h264;
823
 
    VAIQMatrixBufferH264 * const iq_matrix = obj_buffer->buffer_data;
824
 
    int i, j;
825
 
 
826
 
    if (sizeof(pic_info->scaling_lists_4x4) == sizeof(iq_matrix->ScalingList4x4))
827
 
        memcpy(pic_info->scaling_lists_4x4, iq_matrix->ScalingList4x4,
828
 
               sizeof(pic_info->scaling_lists_4x4));
829
 
    else {
830
 
        for (j = 0; j < 6; j++) {
831
 
            for (i = 0; i < 16; i++)
832
 
                pic_info->scaling_lists_4x4[j][i] = iq_matrix->ScalingList4x4[j][i];
833
 
        }
834
 
    }
835
 
 
836
 
    if (sizeof(pic_info->scaling_lists_8x8) == sizeof(iq_matrix->ScalingList8x8))
837
 
        memcpy(pic_info->scaling_lists_8x8, iq_matrix->ScalingList8x8,
838
 
               sizeof(pic_info->scaling_lists_8x8));
839
 
    else {
840
 
        for (j = 0; j < 2; j++) {
841
 
            for (i = 0; i < 64; i++)
842
 
                pic_info->scaling_lists_8x8[j][i] = iq_matrix->ScalingList8x8[j][i];
843
 
        }
844
 
    }
845
 
    return 1;
846
 
}
847
 
 
848
 
// Translate VASliceParameterBufferH264
849
 
static int
850
 
translate_VASliceParameterBufferH264(
851
 
    vdpau_driver_data_t *driver_data,
852
 
    object_context_p    obj_context,
853
 
    object_buffer_p     obj_buffer
854
 
)
855
 
{
856
 
    VdpPictureInfoH264 * const pic_info = &obj_context->vdp_picture_info.h264;
857
 
    VASliceParameterBufferH264 * const slice_params = obj_buffer->buffer_data;
858
 
    VASliceParameterBufferH264 * const slice_param = &slice_params[obj_buffer->num_elements - 1];
859
 
 
860
 
    pic_info->slice_count                 += obj_buffer->num_elements;
861
 
    pic_info->num_ref_idx_l0_active_minus1 = slice_param->num_ref_idx_l0_active_minus1;
862
 
    pic_info->num_ref_idx_l1_active_minus1 = slice_param->num_ref_idx_l1_active_minus1;
863
 
    obj_context->last_slice_params         = obj_buffer->buffer_data;
864
 
    obj_context->last_slice_params_count   = obj_buffer->num_elements;
865
 
    return 1;
866
 
}
867
 
 
868
 
// Translate VAPictureParameterBufferVC1
869
 
static int
870
 
translate_VAPictureParameterBufferVC1(
871
 
    vdpau_driver_data_t *driver_data,
872
 
    object_context_p    obj_context,
873
 
    object_buffer_p     obj_buffer
874
 
)
875
 
{
876
 
    VdpPictureInfoVC1 * const pic_info = &obj_context->vdp_picture_info.vc1;
877
 
    VAPictureParameterBufferVC1 * const pic_param = obj_buffer->buffer_data;
878
 
    int picture_type, major_version, minor_version;
879
 
 
880
 
    if (!translate_VASurfaceID(driver_data,
881
 
                               pic_param->forward_reference_picture,
882
 
                               &pic_info->forward_reference))
883
 
        return 0;
884
 
 
885
 
    if (!translate_VASurfaceID(driver_data,
886
 
                               pic_param->backward_reference_picture,
887
 
                               &pic_info->backward_reference))
888
 
        return 0;
889
 
 
890
 
    switch (pic_param->picture_fields.bits.picture_type) {
891
 
    case 0: picture_type = 0; break; /* I */
892
 
    case 1: picture_type = 1; break; /* P */
893
 
    case 2: picture_type = 3; break; /* B */
894
 
    case 3: picture_type = 4; break; /* BI */
895
 
    case 4: picture_type = 1; break; /* P "skipped" */
896
 
    default: return 0;
897
 
    }
898
 
 
899
 
    pic_info->picture_type      = picture_type;
900
 
    pic_info->frame_coding_mode = pic_param->picture_fields.bits.frame_coding_mode;
901
 
    pic_info->postprocflag      = pic_param->post_processing != 0;
902
 
    pic_info->pulldown          = pic_param->sequence_fields.bits.pulldown;
903
 
    pic_info->interlace         = pic_param->sequence_fields.bits.interlace;
904
 
    pic_info->tfcntrflag        = pic_param->sequence_fields.bits.tfcntrflag;
905
 
    pic_info->finterpflag       = pic_param->sequence_fields.bits.finterpflag;
906
 
    pic_info->psf               = pic_param->sequence_fields.bits.psf;
907
 
    pic_info->dquant            = pic_param->pic_quantizer_fields.bits.dquant;
908
 
    pic_info->panscan_flag      = pic_param->entrypoint_fields.bits.panscan_flag;
909
 
    pic_info->refdist_flag      = pic_param->reference_fields.bits.reference_distance_flag;
910
 
    pic_info->quantizer         = pic_param->pic_quantizer_fields.bits.quantizer;
911
 
    pic_info->extended_mv       = pic_param->mv_fields.bits.extended_mv_flag;
912
 
    pic_info->extended_dmv      = pic_param->mv_fields.bits.extended_dmv_flag;
913
 
    pic_info->overlap           = pic_param->sequence_fields.bits.overlap;
914
 
    pic_info->vstransform       = pic_param->transform_fields.bits.variable_sized_transform_flag;
915
 
    pic_info->loopfilter        = pic_param->entrypoint_fields.bits.loopfilter;
916
 
    pic_info->fastuvmc          = pic_param->fast_uvmc_flag;
917
 
    pic_info->range_mapy_flag   = pic_param->range_mapping_fields.bits.luma_flag;
918
 
    pic_info->range_mapy        = pic_param->range_mapping_fields.bits.luma;
919
 
    pic_info->range_mapuv_flag  = pic_param->range_mapping_fields.bits.chroma_flag;
920
 
    pic_info->range_mapuv       = pic_param->range_mapping_fields.bits.chroma;
921
 
    pic_info->multires          = pic_param->sequence_fields.bits.multires;
922
 
    pic_info->syncmarker        = pic_param->sequence_fields.bits.syncmarker;
923
 
    pic_info->rangered          = pic_param->sequence_fields.bits.rangered;
924
 
    if (!vdpau_is_nvidia(driver_data, &major_version, &minor_version) ||
925
 
        (major_version > 180 || minor_version >= 35))
926
 
        pic_info->rangered     |= pic_param->range_reduction_frame << 1;
927
 
    pic_info->maxbframes        = pic_param->sequence_fields.bits.max_b_frames;
928
 
    pic_info->deblockEnable     = pic_param->post_processing != 0; /* XXX: this is NVIDIA's vdpau.c semantics (postprocflag & 1) */
929
 
    pic_info->pquant            = pic_param->pic_quantizer_fields.bits.pic_quantizer_scale;
930
 
    return 1;
931
 
}
932
 
 
933
 
// Translate VASliceParameterBufferVC1
934
 
static int
935
 
translate_VASliceParameterBufferVC1(
936
 
    vdpau_driver_data_t *driver_data,
937
 
    object_context_p    obj_context,
938
 
    object_buffer_p     obj_buffer
939
 
)
940
 
{
941
 
    VdpPictureInfoVC1 * const pic_info = &obj_context->vdp_picture_info.vc1;
942
 
 
943
 
    pic_info->slice_count               += obj_buffer->num_elements;
944
 
    obj_context->last_slice_params       = obj_buffer->buffer_data;
945
 
    obj_context->last_slice_params_count = obj_buffer->num_elements;
946
 
    return 1;
947
 
}
948
 
 
949
 
// Translate VA buffer
950
 
typedef int
951
 
(*translate_buffer_func_t)(vdpau_driver_data_t *driver_data,
952
 
                           object_context_p    obj_context,
953
 
                           object_buffer_p     obj_buffer);
954
 
 
955
 
typedef struct translate_buffer_info translate_buffer_info_t;
956
 
struct translate_buffer_info {
957
 
    VdpCodec codec;
958
 
    VABufferType type;
959
 
    translate_buffer_func_t func;
960
 
};
961
 
 
962
 
static int
963
 
translate_buffer(
964
 
    vdpau_driver_data_t *driver_data,
965
 
    object_context_p    obj_context,
966
 
    object_buffer_p     obj_buffer
967
 
)
968
 
{
969
 
    static const translate_buffer_info_t translate_info[] = {
970
 
#define _(CODEC, TYPE)                                  \
971
 
        { VDP_CODEC_##CODEC, VA##TYPE##BufferType,      \
972
 
          translate_VA##TYPE##Buffer##CODEC }
973
 
        _(MPEG2, PictureParameter),
974
 
        _(MPEG2, IQMatrix),
975
 
        _(MPEG2, SliceParameter),
976
 
#if USE_VDPAU_MPEG4
977
 
        _(MPEG4, PictureParameter),
978
 
        _(MPEG4, IQMatrix),
979
 
        _(MPEG4, SliceParameter),
980
 
#endif
981
 
        _(H264, PictureParameter),
982
 
        _(H264, IQMatrix),
983
 
        _(H264, SliceParameter),
984
 
        _(VC1, PictureParameter),
985
 
        _(VC1, SliceParameter),
986
 
#undef _
987
 
        { VDP_CODEC_VC1, VABitPlaneBufferType, translate_nothing },
988
 
        { 0, VASliceDataBufferType, translate_VASliceDataBuffer },
989
 
        { 0, 0, NULL }
990
 
    };
991
 
    const translate_buffer_info_t *tbip;
992
 
    for (tbip = translate_info; tbip->func != NULL; tbip++) {
993
 
        if (tbip->codec && tbip->codec != obj_context->vdp_codec)
994
 
            continue;
995
 
        if (tbip->type != obj_buffer->type)
996
 
            continue;
997
 
        return tbip->func(driver_data, obj_context, obj_buffer);
998
 
    }
999
 
    D(bug("ERROR: no translate function found for %s%s\n",
1000
 
          string_of_VABufferType(obj_buffer->type),
1001
 
          obj_context->vdp_codec ? string_of_VdpCodec(obj_context->vdp_codec) : NULL));
1002
 
    return 0;
1003
 
}
1004
 
 
1005
 
// vaQueryConfigProfiles
1006
 
VAStatus
1007
 
vdpau_QueryConfigProfiles(
1008
 
    VADriverContextP    ctx,
1009
 
    VAProfile          *profile_list,
1010
 
    int                *num_profiles
1011
 
)
1012
 
{
1013
 
    VDPAU_DRIVER_DATA_INIT;
1014
 
 
1015
 
    static const VAProfile va_profiles[] = {
1016
 
        VAProfileMPEG2Simple,
1017
 
        VAProfileMPEG2Main,
1018
 
        VAProfileMPEG4Simple,
1019
 
        VAProfileMPEG4AdvancedSimple,
1020
 
        VAProfileMPEG4Main,
1021
 
        VAProfileH264Baseline,
1022
 
        VAProfileH264Main,
1023
 
        VAProfileH264High,
1024
 
        VAProfileVC1Simple,
1025
 
        VAProfileVC1Main,
1026
 
        VAProfileVC1Advanced
1027
 
    };
1028
 
 
1029
 
    int i, n = 0;
1030
 
    for (i = 0; i < ARRAY_ELEMS(va_profiles); i++) {
1031
 
        VAProfile profile = va_profiles[i];
1032
 
        VdpDecoderProfile vdp_profile = get_VdpDecoderProfile(profile);
1033
 
        if (is_supported_profile(driver_data, vdp_profile))
1034
 
            profile_list[n++] = profile;
1035
 
    }
1036
 
 
1037
 
    /* If the assert fails then VDPAU_MAX_PROFILES needs to be bigger */
1038
 
    ASSERT(n <= VDPAU_MAX_PROFILES);
1039
 
    if (num_profiles)
1040
 
        *num_profiles = n;
1041
 
 
1042
 
    return VA_STATUS_SUCCESS;
1043
 
}
1044
 
 
1045
 
// vaQueryConfigEntrypoints
1046
 
VAStatus
1047
 
vdpau_QueryConfigEntrypoints(
1048
 
    VADriverContextP    ctx,
1049
 
    VAProfile           profile,
1050
 
    VAEntrypoint       *entrypoint_list,
1051
 
    int                *num_entrypoints
1052
 
)
1053
 
{
1054
 
    VDPAU_DRIVER_DATA_INIT;
1055
 
 
1056
 
    VdpDecoderProfile vdp_profile = get_VdpDecoderProfile(profile);
1057
 
    if (!is_supported_profile(driver_data, vdp_profile))
1058
 
        return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1059
 
 
1060
 
    VAEntrypoint entrypoint;
1061
 
    switch (profile) {
1062
 
    case VAProfileMPEG2Simple:
1063
 
    case VAProfileMPEG2Main:
1064
 
        entrypoint = VAEntrypointVLD;
1065
 
        break;
1066
 
    case VAProfileMPEG4Simple:
1067
 
    case VAProfileMPEG4AdvancedSimple:
1068
 
    case VAProfileMPEG4Main:
1069
 
        entrypoint = VAEntrypointVLD;
1070
 
        break;
1071
 
    case VAProfileH264Baseline:
1072
 
    case VAProfileH264Main:
1073
 
    case VAProfileH264High:
1074
 
        entrypoint = VAEntrypointVLD;
1075
 
        break;
1076
 
    case VAProfileVC1Simple:
1077
 
    case VAProfileVC1Main:
1078
 
    case VAProfileVC1Advanced:
1079
 
        entrypoint = VAEntrypointVLD;
1080
 
        break;
1081
 
    default:
1082
 
        entrypoint = 0;
1083
 
        break;
1084
 
    }
1085
 
 
1086
 
    if (entrypoint_list)
1087
 
        *entrypoint_list = entrypoint;
1088
 
 
1089
 
    if (num_entrypoints)
1090
 
        *num_entrypoints = entrypoint != 0;
1091
 
 
1092
 
    return VA_STATUS_SUCCESS;
1093
 
}
1094
 
 
1095
 
// vaBeginPicture
1096
 
VAStatus
1097
 
vdpau_BeginPicture(
1098
 
    VADriverContextP    ctx,
1099
 
    VAContextID         context,
1100
 
    VASurfaceID         render_target
1101
 
)
1102
 
{
1103
 
    VDPAU_DRIVER_DATA_INIT;
1104
 
 
1105
 
    object_context_p obj_context = VDPAU_CONTEXT(context);
1106
 
    if (!obj_context)
1107
 
        return VA_STATUS_ERROR_INVALID_CONTEXT;
1108
 
 
1109
 
    object_surface_p obj_surface = VDPAU_SURFACE(render_target);
1110
 
    if (!obj_surface)
1111
 
        return VA_STATUS_ERROR_INVALID_SURFACE;
1112
 
 
1113
 
    obj_surface->va_surface_status           = VASurfaceRendering;
1114
 
    obj_context->last_pic_param              = NULL;
1115
 
    obj_context->last_slice_params           = NULL;
1116
 
    obj_context->last_slice_params_count     = 0;
1117
 
    obj_context->current_render_target       = obj_surface->base.id;
1118
 
    obj_context->gen_slice_data_size         = 0;
1119
 
    obj_context->vdp_bitstream_buffers_count = 0;
1120
 
 
1121
 
    switch (obj_context->vdp_codec) {
1122
 
    case VDP_CODEC_MPEG1:
1123
 
    case VDP_CODEC_MPEG2:
1124
 
        obj_context->vdp_picture_info.mpeg2.slice_count = 0;
1125
 
        break;
1126
 
    case VDP_CODEC_MPEG4:
1127
 
        break;
1128
 
    case VDP_CODEC_H264:
1129
 
        obj_context->vdp_picture_info.h264.slice_count = 0;
1130
 
        break;
1131
 
    case VDP_CODEC_VC1:
1132
 
        obj_context->vdp_picture_info.vc1.slice_count = 0;
1133
 
        break;
1134
 
    default:
1135
 
        return VA_STATUS_ERROR_UNKNOWN;
1136
 
    }
1137
 
    return VA_STATUS_SUCCESS;
1138
 
}
1139
 
 
1140
 
// vaRenderPicture
1141
 
VAStatus
1142
 
vdpau_RenderPicture(
1143
 
    VADriverContextP    ctx,
1144
 
    VAContextID         context,
1145
 
    VABufferID         *buffers,
1146
 
    int                 num_buffers
1147
 
)
1148
 
{
1149
 
    VDPAU_DRIVER_DATA_INIT;
1150
 
    int i;
1151
 
 
1152
 
    object_context_p obj_context = VDPAU_CONTEXT(context);
1153
 
    if (!obj_context)
1154
 
        return VA_STATUS_ERROR_INVALID_CONTEXT;
1155
 
 
1156
 
    object_surface_p obj_surface = VDPAU_SURFACE(obj_context->current_render_target);
1157
 
    if (!obj_surface)
1158
 
        return VA_STATUS_ERROR_INVALID_SURFACE;
1159
 
 
1160
 
    /* Verify that we got valid buffer references */
1161
 
    for (i = 0; i < num_buffers; i++) {
1162
 
        object_buffer_p obj_buffer = VDPAU_BUFFER(buffers[i]);
1163
 
        if (!obj_buffer)
1164
 
            return VA_STATUS_ERROR_INVALID_BUFFER;
1165
 
    }
1166
 
 
1167
 
    /* Translate buffers */
1168
 
    for (i = 0; i < num_buffers; i++) {
1169
 
        object_buffer_p obj_buffer = VDPAU_BUFFER(buffers[i]);
1170
 
        if (!translate_buffer(driver_data, obj_context, obj_buffer))
1171
 
            return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1172
 
        /* Release any buffer that is not VASliceDataBuffer */
1173
 
        /* VASliceParameterBuffer is also needed to check for start_codes */
1174
 
        switch (obj_buffer->type) {
1175
 
        case VASliceParameterBufferType:
1176
 
        case VASliceDataBufferType:
1177
 
            schedule_destroy_va_buffer(driver_data, obj_buffer);
1178
 
            break;
1179
 
        case VAPictureParameterBufferType:
1180
 
            /* Preserve VAPictureParameterBufferMPEG4 */
1181
 
            if (obj_context->vdp_codec == VDP_CODEC_MPEG4) {
1182
 
                schedule_destroy_va_buffer(driver_data, obj_buffer);
1183
 
                break;
1184
 
            }
1185
 
            /* fall-through */
1186
 
        default:
1187
 
            destroy_va_buffer(driver_data, obj_buffer);
1188
 
            break;
1189
 
        }
1190
 
    }
1191
 
 
1192
 
    return VA_STATUS_SUCCESS;
1193
 
}
1194
 
 
1195
 
// vaEndPicture
1196
 
VAStatus
1197
 
vdpau_EndPicture(
1198
 
    VADriverContextP    ctx,
1199
 
    VAContextID         context
1200
 
)
1201
 
{
1202
 
    VDPAU_DRIVER_DATA_INIT;
1203
 
    unsigned int i;
1204
 
 
1205
 
    object_context_p obj_context = VDPAU_CONTEXT(context);
1206
 
    if (!obj_context)
1207
 
        return VA_STATUS_ERROR_INVALID_CONTEXT;
1208
 
 
1209
 
    object_surface_p obj_surface = VDPAU_SURFACE(obj_context->current_render_target);
1210
 
    if (!obj_surface)
1211
 
        return VA_STATUS_ERROR_INVALID_SURFACE;
1212
 
 
1213
 
    if (trace_enabled()) {
1214
 
        switch (obj_context->vdp_codec) {
1215
 
        case VDP_CODEC_MPEG1:
1216
 
        case VDP_CODEC_MPEG2:
1217
 
            dump_VdpPictureInfoMPEG1Or2(&obj_context->vdp_picture_info.mpeg2);
1218
 
            break;
1219
 
#if HAVE_VDPAU_MPEG4
1220
 
        case VDP_CODEC_MPEG4:
1221
 
            dump_VdpPictureInfoMPEG4Part2(&obj_context->vdp_picture_info.mpeg4);
1222
 
            break;
1223
 
#endif
1224
 
        case VDP_CODEC_H264:
1225
 
            dump_VdpPictureInfoH264(&obj_context->vdp_picture_info.h264);
1226
 
            break;
1227
 
        case VDP_CODEC_VC1:
1228
 
            dump_VdpPictureInfoVC1(&obj_context->vdp_picture_info.vc1);
1229
 
            break;
1230
 
        default:
1231
 
            break;
1232
 
        }
1233
 
        for (i = 0; i < obj_context->vdp_bitstream_buffers_count; i++)
1234
 
            dump_VdpBitstreamBuffer(&obj_context->vdp_bitstream_buffers[i]);
1235
 
    }
1236
 
 
1237
 
    VAStatus va_status;
1238
 
    VdpStatus vdp_status;
1239
 
    vdp_status = ensure_decoder_with_max_refs(
1240
 
        driver_data,
1241
 
        obj_context,
1242
 
        get_num_ref_frames(obj_context)
1243
 
    );
1244
 
    if (vdp_status == VDP_STATUS_OK)
1245
 
        vdp_status = vdpau_decoder_render(
1246
 
            driver_data,
1247
 
            obj_context->vdp_decoder,
1248
 
            obj_surface->vdp_surface,
1249
 
            (VdpPictureInfo)&obj_context->vdp_picture_info,
1250
 
            obj_context->vdp_bitstream_buffers_count,
1251
 
            obj_context->vdp_bitstream_buffers
1252
 
        );
1253
 
    va_status = vdpau_get_VAStatus(vdp_status);
1254
 
 
1255
 
    /* XXX: assume we are done with rendering right away */
1256
 
    obj_context->current_render_target = VA_INVALID_SURFACE;
1257
 
 
1258
 
    /* Release pending buffers */
1259
 
    if (obj_context->dead_buffers_count > 0) {
1260
 
        ASSERT(obj_context->dead_buffers);
1261
 
        int i;
1262
 
        for (i = 0; i < obj_context->dead_buffers_count; i++) {
1263
 
            object_buffer_p obj_buffer = VDPAU_BUFFER(obj_context->dead_buffers[i]);
1264
 
            ASSERT(obj_buffer);
1265
 
            destroy_va_buffer(driver_data, obj_buffer);
1266
 
        }
1267
 
        obj_context->dead_buffers_count = 0;
1268
 
    }
1269
 
 
1270
 
    return va_status;
1271
 
}