2
* vdpau_decode.c - VDPAU backend for VA-API (decoder)
4
* vdpau-video (C) 2009-2011 Splitted-Desktop Systems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22
#include "vdpau_decode.h"
23
#include "vdpau_driver.h"
24
#include "vdpau_buffer.h"
25
#include "vdpau_video.h"
26
#include "vdpau_dump.h"
34
// Translates VdpDecoderProfile to VdpCodec
35
VdpCodec get_VdpCodec(VdpDecoderProfile 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;
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;
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:
68
// Translates VAProfile to VdpDecoderProfile
69
VdpDecoderProfile get_VdpDecoderProfile(VAProfile profile)
72
case VAProfileMPEG2Simple: return VDP_DECODER_PROFILE_MPEG2_SIMPLE;
73
case VAProfileMPEG2Main: return VDP_DECODER_PROFILE_MPEG2_MAIN;
75
case VAProfileMPEG4Simple: return VDP_DECODER_PROFILE_MPEG4_PART2_SP;
76
case VAProfileMPEG4AdvancedSimple: return VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
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;
86
return (VdpDecoderProfile)-1;
89
// Checks whether the VDPAU implementation supports the specified profile
92
vdpau_driver_data_t *driver_data,
93
VdpDecoderProfile profile
96
VdpBool is_supported = VDP_FALSE;
98
uint32_t max_level, max_references, max_width, max_height;
100
if (profile == (VdpDecoderProfile)-1)
103
vdp_status = vdpau_decoder_query_capabilities(
105
driver_data->vdp_device,
113
return (VDPAU_CHECK_STATUS(vdp_status, "VdpDecoderQueryCapabilities()") &&
117
// Checks decoder for profile/entrypoint is available
120
vdpau_driver_data_t *driver_data,
122
VAEntrypoint entrypoint
125
if (!is_supported_profile(driver_data, get_VdpDecoderProfile(profile)))
126
return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
128
/* VDPAU only supports VLD */
129
if (entrypoint != VAEntrypointVLD)
130
return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
132
return VA_STATUS_SUCCESS;
135
// Computes value for VdpDecoderCreate()::max_references parameter
138
VdpDecoderProfile profile,
143
int max_ref_frames = 2;
146
case VDP_DECODER_PROFILE_H264_MAIN:
147
case VDP_DECODER_PROFILE_H264_HIGH:
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)
158
return max_ref_frames;
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)
164
if (obj_context->vdp_codec == VDP_CODEC_H264)
165
return obj_context->vdp_picture_info.h264.num_ref_frames;
169
// Ensure VDPAU decoder is created for the specified number of reference frames
171
ensure_decoder_with_max_refs(
172
vdpau_driver_data_t *driver_data,
173
object_context_p obj_context,
177
VdpStatus vdp_status;
179
if (max_ref_frames < 0)
181
get_max_ref_frames(obj_context->vdp_profile,
182
obj_context->picture_width,
183
obj_context->picture_height);
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;
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;
194
vdp_status = vdpau_decoder_create(
196
driver_data->vdp_device,
197
obj_context->vdp_profile,
198
obj_context->picture_width,
199
obj_context->picture_height,
201
&obj_context->vdp_decoder
203
if (!VDPAU_CHECK_STATUS(vdp_status, "VdpDecoderCreate()"))
206
return VDP_STATUS_OK;
209
// Lazy allocate (generated) slice data buffer. Buffer lives until vaDestroyContext()
211
alloc_gen_slice_data(object_context_p obj_context, unsigned int size)
213
uint8_t *gen_slice_data = obj_context->gen_slice_data;
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);
221
obj_context->gen_slice_data = gen_slice_data;
223
gen_slice_data += obj_context->gen_slice_data_size;
224
obj_context->gen_slice_data_size += size;
225
return gen_slice_data;
228
// Lazy allocate VdpBitstreamBuffer. Buffer lives until vaDestroyContext()
229
static VdpBitstreamBuffer *
230
alloc_VdpBitstreamBuffer(object_context_p obj_context)
232
VdpBitstreamBuffer *vdp_bitstream_buffers;
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)
240
if (!vdp_bitstream_buffers)
243
return &vdp_bitstream_buffers[obj_context->vdp_bitstream_buffers_count++];
246
// Append VASliceDataBuffer hunk into VDPAU buffer
248
append_VdpBitstreamBuffer(
249
object_context_p obj_context,
250
const uint8_t *buffer,
254
VdpBitstreamBuffer *bitstream_buffer;
256
bitstream_buffer = alloc_VdpBitstreamBuffer(obj_context);
257
if (!bitstream_buffer)
260
bitstream_buffer->struct_version = VDP_BITSTREAM_BUFFER_VERSION;
261
bitstream_buffer->bitstream = buffer;
262
bitstream_buffer->bitstream_bytes = buffer_size;
266
// Initialize VdpReferenceFrameH264 to default values
267
static void init_VdpReferenceFrameH264(VdpReferenceFrameH264 *rf)
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;
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
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
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
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
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,
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,
344
// Compute integer log2
345
static inline int ilog2(uint32_t v)
347
/* From <http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
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;
356
// Translate VASurfaceID
358
translate_VASurfaceID(
359
vdpau_driver_data_t *driver_data,
360
VASurfaceID va_surface,
361
VdpVideoSurface *vdp_surface
364
object_surface_p obj_surface;
366
if (va_surface == VA_INVALID_SURFACE) {
367
*vdp_surface = VDP_INVALID_HANDLE;
371
obj_surface = VDPAU_SURFACE(va_surface);
375
*vdp_surface = obj_surface->vdp_surface;
379
// Translate VAPictureH264
381
translate_VAPictureH264(
382
vdpau_driver_data_t *driver_data,
383
const VAPictureH264 *va_pic,
384
VdpReferenceFrameH264 *rf
387
// Handle invalid surfaces specifically
388
if (va_pic->picture_id == VA_INVALID_SURFACE) {
389
init_VdpReferenceFrameH264(rf);
393
if (!translate_VASurfaceID(driver_data, va_pic->picture_id, &rf->surface))
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;
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;
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;
410
// Translate no buffer
413
vdpau_driver_data_t *driver_data,
414
object_context_p obj_context,
415
object_buffer_p obj_buffer
421
// Translate VASliceDataBuffer
423
translate_VASliceDataBuffer(
424
vdpau_driver_data_t *driver_data,
425
object_context_p obj_context,
426
object_buffer_p obj_buffer
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;
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,
442
sizeof(start_code_prefix)) < 0)
445
if (append_VdpBitstreamBuffer(obj_context,
447
slice_param->slice_data_size) < 0)
454
if (obj_context->vdp_codec == VDP_CODEC_MPEG4 &&
455
obj_context->vdp_bitstream_buffers_count == 0) {
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;
465
int time_incr = 1 + ilog2(pic_param->vop_time_increment_resolution - 1);
469
static const uint16_t VOP_STARTCODE = 0x01b6;
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" */
484
time_incr + /* vop_time_increment */
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) +
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)
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);
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);
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);
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)
525
const int r = 8 - (put_bits_count(&pb) % 8);
527
put_bits(&pb, r, slice_data[0] & ((1U << r) - 1));
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);
536
memcpy(slice_header, slice_header_buffer, slice_header_size);
537
if (append_VdpBitstreamBuffer(obj_context, slice_header, slice_header_size) < 0)
539
if (append_VdpBitstreamBuffer(obj_context, slice_data + 1, slice_data_size - 1) < 0)
545
if (append_VdpBitstreamBuffer(obj_context,
546
obj_buffer->buffer_data,
547
obj_buffer->buffer_size) < 0)
552
// Translate VAPictureParameterBufferMPEG2
554
translate_VAPictureParameterBufferMPEG2(
555
vdpau_driver_data_t *driver_data,
556
object_context_p obj_context,
557
object_buffer_p obj_buffer
560
VdpPictureInfoMPEG1Or2 * const pic_info = &obj_context->vdp_picture_info.mpeg2;
561
VAPictureParameterBufferMPEG2 * const pic_param = obj_buffer->buffer_data;
563
if (!translate_VASurfaceID(driver_data,
564
pic_param->forward_reference_picture,
565
&pic_info->forward_reference))
568
if (!translate_VASurfaceID(driver_data,
569
pic_param->backward_reference_picture,
570
&pic_info->backward_reference))
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;
591
// Translate VAIQMatrixBufferMPEG2
593
translate_VAIQMatrixBufferMPEG2(
594
vdpau_driver_data_t *driver_data,
595
object_context_p obj_context,
596
object_buffer_p obj_buffer
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;
607
if (iq_matrix->load_intra_quantiser_matrix) {
608
intra_matrix = iq_matrix->intra_quantiser_matrix;
609
intra_matrix_lookup = ff_zigzag_direct;
612
intra_matrix = ff_mpeg1_default_intra_matrix;
613
intra_matrix_lookup = ff_identity;
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;
621
inter_matrix = ff_mpeg1_default_non_intra_matrix;
622
inter_matrix_lookup = ff_identity;
625
for (i = 0; i < 64; i++) {
626
pic_info->intra_quantizer_matrix[intra_matrix_lookup[i]] =
628
pic_info->non_intra_quantizer_matrix[inter_matrix_lookup[i]] =
634
// Translate VASliceParameterBufferMPEG2
636
translate_VASliceParameterBufferMPEG2(
637
vdpau_driver_data_t *driver_data,
638
object_context_p obj_context,
639
object_buffer_p obj_buffer
642
VdpPictureInfoMPEG1Or2 * const pic_info = &obj_context->vdp_picture_info.mpeg2;
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;
651
// Translate VAPictureParameterBufferMPEG4
653
translate_VAPictureParameterBufferMPEG4(
654
vdpau_driver_data_p driver_data,
655
object_context_p obj_context,
656
object_buffer_p obj_buffer
659
VdpPictureInfoMPEG4Part2 * const pic_info = &obj_context->vdp_picture_info.mpeg4;
660
VAPictureParameterBufferMPEG4 * const pic_param = obj_buffer->buffer_data;
662
/* XXX: we don't support short-video-header formats */
663
if (pic_param->vol_fields.bits.short_video_header)
666
if (!translate_VASurfaceID(driver_data,
667
pic_param->forward_reference_picture,
668
&pic_info->forward_reference))
671
if (!translate_VASurfaceID(driver_data,
672
pic_param->backward_reference_picture,
673
&pic_info->backward_reference))
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) */
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;
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;
704
obj_context->last_pic_param = obj_buffer->buffer_data;
708
// Translate VAIQMatrixBufferMPEG4
710
translate_VAIQMatrixBufferMPEG4(
711
vdpau_driver_data_p driver_data,
712
object_context_p obj_context,
713
object_buffer_p obj_buffer
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;
724
if (iq_matrix->load_intra_quant_mat) {
725
intra_matrix = iq_matrix->intra_quant_mat;
726
intra_matrix_lookup = ff_zigzag_direct;
729
intra_matrix = ff_mpeg4_default_intra_matrix;
730
intra_matrix_lookup = ff_identity;
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;
738
inter_matrix = ff_mpeg4_default_non_intra_matrix;
739
inter_matrix_lookup = ff_identity;
742
for (i = 0; i < 64; i++) {
743
pic_info->intra_quantizer_matrix[intra_matrix_lookup[i]] =
745
pic_info->non_intra_quantizer_matrix[inter_matrix_lookup[i]] =
751
// Translate VASliceParameterBufferMPEG4
753
translate_VASliceParameterBufferMPEG4(
754
vdpau_driver_data_p driver_data,
755
object_context_p obj_context,
756
object_buffer_p obj_buffer
759
obj_context->last_slice_params = obj_buffer->buffer_data;
760
obj_context->last_slice_params_count = obj_buffer->num_elements;
765
// Translate VAPictureParameterBufferH264
767
translate_VAPictureParameterBufferH264(
768
vdpau_driver_data_t *driver_data,
769
object_context_p obj_context,
770
object_buffer_p obj_buffer
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;
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;
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;
805
for (i = 0; i < 16; i++) {
806
if (!translate_VAPictureH264(driver_data,
807
&pic_param->ReferenceFrames[i],
808
&pic_info->referenceFrames[i]))
814
// Translate VAIQMatrixBufferH264
816
translate_VAIQMatrixBufferH264(
817
vdpau_driver_data_t *driver_data,
818
object_context_p obj_context,
819
object_buffer_p obj_buffer
822
VdpPictureInfoH264 * const pic_info = &obj_context->vdp_picture_info.h264;
823
VAIQMatrixBufferH264 * const iq_matrix = obj_buffer->buffer_data;
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));
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];
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));
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];
848
// Translate VASliceParameterBufferH264
850
translate_VASliceParameterBufferH264(
851
vdpau_driver_data_t *driver_data,
852
object_context_p obj_context,
853
object_buffer_p obj_buffer
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];
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;
868
// Translate VAPictureParameterBufferVC1
870
translate_VAPictureParameterBufferVC1(
871
vdpau_driver_data_t *driver_data,
872
object_context_p obj_context,
873
object_buffer_p obj_buffer
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;
880
if (!translate_VASurfaceID(driver_data,
881
pic_param->forward_reference_picture,
882
&pic_info->forward_reference))
885
if (!translate_VASurfaceID(driver_data,
886
pic_param->backward_reference_picture,
887
&pic_info->backward_reference))
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" */
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;
933
// Translate VASliceParameterBufferVC1
935
translate_VASliceParameterBufferVC1(
936
vdpau_driver_data_t *driver_data,
937
object_context_p obj_context,
938
object_buffer_p obj_buffer
941
VdpPictureInfoVC1 * const pic_info = &obj_context->vdp_picture_info.vc1;
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;
949
// Translate VA buffer
951
(*translate_buffer_func_t)(vdpau_driver_data_t *driver_data,
952
object_context_p obj_context,
953
object_buffer_p obj_buffer);
955
typedef struct translate_buffer_info translate_buffer_info_t;
956
struct translate_buffer_info {
959
translate_buffer_func_t func;
964
vdpau_driver_data_t *driver_data,
965
object_context_p obj_context,
966
object_buffer_p obj_buffer
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),
975
_(MPEG2, SliceParameter),
977
_(MPEG4, PictureParameter),
979
_(MPEG4, SliceParameter),
981
_(H264, PictureParameter),
983
_(H264, SliceParameter),
984
_(VC1, PictureParameter),
985
_(VC1, SliceParameter),
987
{ VDP_CODEC_VC1, VABitPlaneBufferType, translate_nothing },
988
{ 0, VASliceDataBufferType, translate_VASliceDataBuffer },
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)
995
if (tbip->type != obj_buffer->type)
997
return tbip->func(driver_data, obj_context, obj_buffer);
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));
1005
// vaQueryConfigProfiles
1007
vdpau_QueryConfigProfiles(
1008
VADriverContextP ctx,
1009
VAProfile *profile_list,
1013
VDPAU_DRIVER_DATA_INIT;
1015
static const VAProfile va_profiles[] = {
1016
VAProfileMPEG2Simple,
1018
VAProfileMPEG4Simple,
1019
VAProfileMPEG4AdvancedSimple,
1021
VAProfileH264Baseline,
1026
VAProfileVC1Advanced
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;
1037
/* If the assert fails then VDPAU_MAX_PROFILES needs to be bigger */
1038
ASSERT(n <= VDPAU_MAX_PROFILES);
1042
return VA_STATUS_SUCCESS;
1045
// vaQueryConfigEntrypoints
1047
vdpau_QueryConfigEntrypoints(
1048
VADriverContextP ctx,
1050
VAEntrypoint *entrypoint_list,
1051
int *num_entrypoints
1054
VDPAU_DRIVER_DATA_INIT;
1056
VdpDecoderProfile vdp_profile = get_VdpDecoderProfile(profile);
1057
if (!is_supported_profile(driver_data, vdp_profile))
1058
return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1060
VAEntrypoint entrypoint;
1062
case VAProfileMPEG2Simple:
1063
case VAProfileMPEG2Main:
1064
entrypoint = VAEntrypointVLD;
1066
case VAProfileMPEG4Simple:
1067
case VAProfileMPEG4AdvancedSimple:
1068
case VAProfileMPEG4Main:
1069
entrypoint = VAEntrypointVLD;
1071
case VAProfileH264Baseline:
1072
case VAProfileH264Main:
1073
case VAProfileH264High:
1074
entrypoint = VAEntrypointVLD;
1076
case VAProfileVC1Simple:
1077
case VAProfileVC1Main:
1078
case VAProfileVC1Advanced:
1079
entrypoint = VAEntrypointVLD;
1086
if (entrypoint_list)
1087
*entrypoint_list = entrypoint;
1089
if (num_entrypoints)
1090
*num_entrypoints = entrypoint != 0;
1092
return VA_STATUS_SUCCESS;
1098
VADriverContextP ctx,
1099
VAContextID context,
1100
VASurfaceID render_target
1103
VDPAU_DRIVER_DATA_INIT;
1105
object_context_p obj_context = VDPAU_CONTEXT(context);
1107
return VA_STATUS_ERROR_INVALID_CONTEXT;
1109
object_surface_p obj_surface = VDPAU_SURFACE(render_target);
1111
return VA_STATUS_ERROR_INVALID_SURFACE;
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;
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;
1126
case VDP_CODEC_MPEG4:
1128
case VDP_CODEC_H264:
1129
obj_context->vdp_picture_info.h264.slice_count = 0;
1132
obj_context->vdp_picture_info.vc1.slice_count = 0;
1135
return VA_STATUS_ERROR_UNKNOWN;
1137
return VA_STATUS_SUCCESS;
1142
vdpau_RenderPicture(
1143
VADriverContextP ctx,
1144
VAContextID context,
1145
VABufferID *buffers,
1149
VDPAU_DRIVER_DATA_INIT;
1152
object_context_p obj_context = VDPAU_CONTEXT(context);
1154
return VA_STATUS_ERROR_INVALID_CONTEXT;
1156
object_surface_p obj_surface = VDPAU_SURFACE(obj_context->current_render_target);
1158
return VA_STATUS_ERROR_INVALID_SURFACE;
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]);
1164
return VA_STATUS_ERROR_INVALID_BUFFER;
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);
1179
case VAPictureParameterBufferType:
1180
/* Preserve VAPictureParameterBufferMPEG4 */
1181
if (obj_context->vdp_codec == VDP_CODEC_MPEG4) {
1182
schedule_destroy_va_buffer(driver_data, obj_buffer);
1187
destroy_va_buffer(driver_data, obj_buffer);
1192
return VA_STATUS_SUCCESS;
1198
VADriverContextP ctx,
1202
VDPAU_DRIVER_DATA_INIT;
1205
object_context_p obj_context = VDPAU_CONTEXT(context);
1207
return VA_STATUS_ERROR_INVALID_CONTEXT;
1209
object_surface_p obj_surface = VDPAU_SURFACE(obj_context->current_render_target);
1211
return VA_STATUS_ERROR_INVALID_SURFACE;
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);
1219
#if HAVE_VDPAU_MPEG4
1220
case VDP_CODEC_MPEG4:
1221
dump_VdpPictureInfoMPEG4Part2(&obj_context->vdp_picture_info.mpeg4);
1224
case VDP_CODEC_H264:
1225
dump_VdpPictureInfoH264(&obj_context->vdp_picture_info.h264);
1228
dump_VdpPictureInfoVC1(&obj_context->vdp_picture_info.vc1);
1233
for (i = 0; i < obj_context->vdp_bitstream_buffers_count; i++)
1234
dump_VdpBitstreamBuffer(&obj_context->vdp_bitstream_buffers[i]);
1238
VdpStatus vdp_status;
1239
vdp_status = ensure_decoder_with_max_refs(
1242
get_num_ref_frames(obj_context)
1244
if (vdp_status == VDP_STATUS_OK)
1245
vdp_status = vdpau_decoder_render(
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
1253
va_status = vdpau_get_VAStatus(vdp_status);
1255
/* XXX: assume we are done with rendering right away */
1256
obj_context->current_render_target = VA_INVALID_SURFACE;
1258
/* Release pending buffers */
1259
if (obj_context->dead_buffers_count > 0) {
1260
ASSERT(obj_context->dead_buffers);
1262
for (i = 0; i < obj_context->dead_buffers_count; i++) {
1263
object_buffer_p obj_buffer = VDPAU_BUFFER(obj_context->dead_buffers[i]);
1265
destroy_va_buffer(driver_data, obj_buffer);
1267
obj_context->dead_buffers_count = 0;