~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/va/picture.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4
 
 * Copyright 2014 Advanced Micro Devices, Inc.
5
 
 * All Rights Reserved.
6
 
 *
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 
 * copy of this software and associated documentation files (the
9
 
 * "Software"), to deal in the Software without restriction, including
10
 
 * without limitation the rights to use, copy, modify, merge, publish,
11
 
 * distribute, sub license, and/or sell copies of the Software, and to
12
 
 * permit persons to whom the Software is furnished to do so, subject to
13
 
 * the following conditions:
14
 
 *
15
 
 * The above copyright notice and this permission notice (including the
16
 
 * next paragraph) shall be included in all copies or substantial portions
17
 
 * of the Software.
18
 
 *
19
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22
 
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
 
 *
27
 
 **************************************************************************/
28
 
 
29
 
#include "pipe/p_video_codec.h"
30
 
 
31
 
#include "util/u_handle_table.h"
32
 
#include "util/u_video.h"
33
 
#include "util/u_memory.h"
34
 
 
35
 
#include "util/vl_vlc.h"
36
 
#include "vl/vl_winsys.h"
37
 
 
38
 
#include "va_private.h"
39
 
 
40
 
VAStatus
41
 
vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID render_target)
42
 
{
43
 
   vlVaDriver *drv;
44
 
   vlVaContext *context;
45
 
   vlVaSurface *surf;
46
 
 
47
 
   if (!ctx)
48
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
49
 
 
50
 
   drv = VL_VA_DRIVER(ctx);
51
 
   if (!drv)
52
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
53
 
 
54
 
   mtx_lock(&drv->mutex);
55
 
   context = handle_table_get(drv->htab, context_id);
56
 
   if (!context) {
57
 
      mtx_unlock(&drv->mutex);
58
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
59
 
   }
60
 
 
61
 
   if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG12) {
62
 
      context->desc.mpeg12.intra_matrix = NULL;
63
 
      context->desc.mpeg12.non_intra_matrix = NULL;
64
 
   }
65
 
 
66
 
   surf = handle_table_get(drv->htab, render_target);
67
 
   mtx_unlock(&drv->mutex);
68
 
   if (!surf || !surf->buffer)
69
 
      return VA_STATUS_ERROR_INVALID_SURFACE;
70
 
 
71
 
   context->target_id = render_target;
72
 
   surf->ctx = context_id;
73
 
   context->target = surf->buffer;
74
 
   context->mjpeg.sampling_factor = 0;
75
 
 
76
 
   if (!context->decoder) {
77
 
 
78
 
      /* VPP */
79
 
      if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN &&
80
 
          context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
81
 
          context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
82
 
          context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
83
 
          context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM &&
84
 
          context->target->buffer_format != PIPE_FORMAT_NV12 &&
85
 
          context->target->buffer_format != PIPE_FORMAT_P010 &&
86
 
          context->target->buffer_format != PIPE_FORMAT_P016)
87
 
         return VA_STATUS_ERROR_UNIMPLEMENTED;
88
 
 
89
 
      return VA_STATUS_SUCCESS;
90
 
   }
91
 
 
92
 
   if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE)
93
 
      context->needs_begin_frame = true;
94
 
 
95
 
   return VA_STATUS_SUCCESS;
96
 
}
97
 
 
98
 
void
99
 
vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
100
 
                      struct pipe_video_buffer **ref_frame)
101
 
{
102
 
   vlVaSurface *surf = handle_table_get(drv->htab, surface_id);
103
 
   if (surf)
104
 
      *ref_frame = surf->buffer;
105
 
   else
106
 
      *ref_frame = NULL;
107
 
}
108
 
 
109
 
static VAStatus
110
 
handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
111
 
{
112
 
   VAStatus vaStatus = VA_STATUS_SUCCESS;
113
 
   enum pipe_video_format format =
114
 
      u_reduce_video_profile(context->templat.profile);
115
 
 
116
 
   switch (format) {
117
 
   case PIPE_VIDEO_FORMAT_MPEG12:
118
 
      vlVaHandlePictureParameterBufferMPEG12(drv, context, buf);
119
 
      break;
120
 
 
121
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
122
 
      vlVaHandlePictureParameterBufferH264(drv, context, buf);
123
 
      break;
124
 
 
125
 
   case PIPE_VIDEO_FORMAT_VC1:
126
 
      vlVaHandlePictureParameterBufferVC1(drv, context, buf);
127
 
      break;
128
 
 
129
 
   case PIPE_VIDEO_FORMAT_MPEG4:
130
 
      vlVaHandlePictureParameterBufferMPEG4(drv, context, buf);
131
 
      break;
132
 
 
133
 
   case PIPE_VIDEO_FORMAT_HEVC:
134
 
      vlVaHandlePictureParameterBufferHEVC(drv, context, buf);
135
 
      break;
136
 
 
137
 
   case PIPE_VIDEO_FORMAT_JPEG:
138
 
      vlVaHandlePictureParameterBufferMJPEG(drv, context, buf);
139
 
      break;
140
 
 
141
 
   case PIPE_VIDEO_FORMAT_VP9:
142
 
      vlVaHandlePictureParameterBufferVP9(drv, context, buf);
143
 
      break;
144
 
 
145
 
   case PIPE_VIDEO_FORMAT_AV1:
146
 
      vlVaHandlePictureParameterBufferAV1(drv, context, buf);
147
 
      break;
148
 
 
149
 
   default:
150
 
      break;
151
 
   }
152
 
 
153
 
   /* Create the decoder once max_references is known. */
154
 
   if (!context->decoder) {
155
 
      if (!context->target)
156
 
         return VA_STATUS_ERROR_INVALID_CONTEXT;
157
 
 
158
 
      if (format == PIPE_VIDEO_FORMAT_MPEG4_AVC)
159
 
         context->templat.level = u_get_h264_level(context->templat.width,
160
 
            context->templat.height, &context->templat.max_references);
161
 
 
162
 
      context->decoder = drv->pipe->create_video_codec(drv->pipe,
163
 
         &context->templat);
164
 
 
165
 
      if (!context->decoder)
166
 
         return VA_STATUS_ERROR_ALLOCATION_FAILED;
167
 
 
168
 
      context->needs_begin_frame = true;
169
 
   }
170
 
 
171
 
   if (format == PIPE_VIDEO_FORMAT_VP9) {
172
 
      context->decoder->width =
173
 
         context->desc.vp9.picture_parameter.frame_width;
174
 
      context->decoder->height =
175
 
         context->desc.vp9.picture_parameter.frame_height;
176
 
   }
177
 
 
178
 
   return vaStatus;
179
 
}
180
 
 
181
 
static void
182
 
handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
183
 
{
184
 
   switch (u_reduce_video_profile(context->templat.profile)) {
185
 
   case PIPE_VIDEO_FORMAT_MPEG12:
186
 
      vlVaHandleIQMatrixBufferMPEG12(context, buf);
187
 
      break;
188
 
 
189
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
190
 
      vlVaHandleIQMatrixBufferH264(context, buf);
191
 
      break;
192
 
 
193
 
   case PIPE_VIDEO_FORMAT_MPEG4:
194
 
      vlVaHandleIQMatrixBufferMPEG4(context, buf);
195
 
      break;
196
 
 
197
 
   case PIPE_VIDEO_FORMAT_HEVC:
198
 
      vlVaHandleIQMatrixBufferHEVC(context, buf);
199
 
      break;
200
 
 
201
 
   case PIPE_VIDEO_FORMAT_JPEG:
202
 
      vlVaHandleIQMatrixBufferMJPEG(context, buf);
203
 
      break;
204
 
 
205
 
   default:
206
 
      break;
207
 
   }
208
 
}
209
 
 
210
 
static void
211
 
handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num)
212
 
{
213
 
   switch (u_reduce_video_profile(context->templat.profile)) {
214
 
   case PIPE_VIDEO_FORMAT_MPEG12:
215
 
      vlVaHandleSliceParameterBufferMPEG12(context, buf);
216
 
      break;
217
 
 
218
 
   case PIPE_VIDEO_FORMAT_VC1:
219
 
      vlVaHandleSliceParameterBufferVC1(context, buf);
220
 
      break;
221
 
 
222
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
223
 
      vlVaHandleSliceParameterBufferH264(context, buf);
224
 
      break;
225
 
 
226
 
   case PIPE_VIDEO_FORMAT_MPEG4:
227
 
      vlVaHandleSliceParameterBufferMPEG4(context, buf);
228
 
      break;
229
 
 
230
 
   case PIPE_VIDEO_FORMAT_HEVC:
231
 
      vlVaHandleSliceParameterBufferHEVC(context, buf);
232
 
      break;
233
 
 
234
 
   case PIPE_VIDEO_FORMAT_JPEG:
235
 
      vlVaHandleSliceParameterBufferMJPEG(context, buf);
236
 
      break;
237
 
 
238
 
   case PIPE_VIDEO_FORMAT_VP9:
239
 
      vlVaHandleSliceParameterBufferVP9(context, buf);
240
 
      break;
241
 
 
242
 
   case PIPE_VIDEO_FORMAT_AV1:
243
 
      vlVaHandleSliceParameterBufferAV1(context, buf, num);
244
 
      break;
245
 
 
246
 
   default:
247
 
      break;
248
 
   }
249
 
}
250
 
 
251
 
static unsigned int
252
 
bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)
253
 
{
254
 
   struct vl_vlc vlc = {0};
255
 
   int i;
256
 
 
257
 
   /* search the first 64 bytes for a startcode */
258
 
   vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size);
259
 
   for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= bits; ++i) {
260
 
      if (vl_vlc_peekbits(&vlc, bits) == code)
261
 
         return 1;
262
 
      vl_vlc_eatbits(&vlc, 8);
263
 
      vl_vlc_fillbits(&vlc);
264
 
   }
265
 
 
266
 
   return 0;
267
 
}
268
 
 
269
 
static void
270
 
handleVAProtectedSliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
271
 
{
272
 
        uint8_t* encrypted_data = (uint8_t*) buf->data;
273
 
 
274
 
        unsigned int drm_key_size = buf->size;
275
 
 
276
 
        context->desc.base.decrypt_key = CALLOC(1, drm_key_size);
277
 
        memcpy(context->desc.base.decrypt_key, encrypted_data, drm_key_size);
278
 
        context->desc.base.protected_playback = true;
279
 
}
280
 
 
281
 
static VAStatus
282
 
handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
283
 
{
284
 
   enum pipe_video_format format = u_reduce_video_profile(context->templat.profile);
285
 
   unsigned num_buffers = 0;
286
 
   void * const *buffers[3];
287
 
   unsigned sizes[3];
288
 
   static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 };
289
 
   static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 };
290
 
   static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d };
291
 
   static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 };
292
 
 
293
 
   if (!context->decoder)
294
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
295
 
 
296
 
   format = u_reduce_video_profile(context->templat.profile);
297
 
   if (!context->desc.base.protected_playback) {
298
 
      switch (format) {
299
 
      case PIPE_VIDEO_FORMAT_MPEG4_AVC:
300
 
         if (bufHasStartcode(buf, 0x000001, 24))
301
 
            break;
302
 
 
303
 
         buffers[num_buffers] = (void *const)&start_code_h264;
304
 
         sizes[num_buffers++] = sizeof(start_code_h264);
305
 
         break;
306
 
      case PIPE_VIDEO_FORMAT_HEVC:
307
 
         if (bufHasStartcode(buf, 0x000001, 24))
308
 
            break;
309
 
 
310
 
         buffers[num_buffers] = (void *const)&start_code_h265;
311
 
         sizes[num_buffers++] = sizeof(start_code_h265);
312
 
         break;
313
 
      case PIPE_VIDEO_FORMAT_VC1:
314
 
         if (bufHasStartcode(buf, 0x0000010d, 32) ||
315
 
             bufHasStartcode(buf, 0x0000010c, 32) ||
316
 
             bufHasStartcode(buf, 0x0000010b, 32))
317
 
            break;
318
 
 
319
 
         if (context->decoder->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) {
320
 
            buffers[num_buffers] = (void *const)&start_code_vc1;
321
 
            sizes[num_buffers++] = sizeof(start_code_vc1);
322
 
         }
323
 
         break;
324
 
      case PIPE_VIDEO_FORMAT_MPEG4:
325
 
         if (bufHasStartcode(buf, 0x000001, 24))
326
 
            break;
327
 
 
328
 
         vlVaDecoderFixMPEG4Startcode(context);
329
 
         buffers[num_buffers] = (void *)context->mpeg4.start_code;
330
 
         sizes[num_buffers++] = context->mpeg4.start_code_size;
331
 
         break;
332
 
      case PIPE_VIDEO_FORMAT_JPEG:
333
 
         vlVaGetJpegSliceHeader(context);
334
 
         buffers[num_buffers] = (void *)context->mjpeg.slice_header;
335
 
         sizes[num_buffers++] = context->mjpeg.slice_header_size;
336
 
         break;
337
 
      case PIPE_VIDEO_FORMAT_VP9:
338
 
         if (false == context->desc.base.protected_playback)
339
 
            vlVaDecoderVP9BitstreamHeader(context, buf);
340
 
         break;
341
 
      case PIPE_VIDEO_FORMAT_AV1:
342
 
         break;
343
 
      default:
344
 
         break;
345
 
      }
346
 
   }
347
 
 
348
 
   buffers[num_buffers] = buf->data;
349
 
   sizes[num_buffers] = buf->size;
350
 
   ++num_buffers;
351
 
 
352
 
   if (format == PIPE_VIDEO_FORMAT_JPEG) {
353
 
      buffers[num_buffers] = (void *const)&eoi_jpeg;
354
 
      sizes[num_buffers++] = sizeof(eoi_jpeg);
355
 
   }
356
 
 
357
 
   if (context->needs_begin_frame) {
358
 
      context->decoder->begin_frame(context->decoder, context->target,
359
 
         &context->desc.base);
360
 
      context->needs_begin_frame = false;
361
 
   }
362
 
   context->decoder->decode_bitstream(context->decoder, context->target, &context->desc.base,
363
 
      num_buffers, (const void * const*)buffers, sizes);
364
 
   return VA_STATUS_SUCCESS;
365
 
}
366
 
 
367
 
static VAStatus
368
 
handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc)
369
 
{
370
 
   VAStatus status = VA_STATUS_SUCCESS;
371
 
 
372
 
   switch (u_reduce_video_profile(context->templat.profile)) {
373
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
374
 
      status = vlVaHandleVAEncMiscParameterTypeRateControlH264(context, misc);
375
 
      break;
376
 
 
377
 
   case PIPE_VIDEO_FORMAT_HEVC:
378
 
      status = vlVaHandleVAEncMiscParameterTypeRateControlHEVC(context, misc);
379
 
      break;
380
 
 
381
 
   default:
382
 
      break;
383
 
   }
384
 
 
385
 
   return status;
386
 
}
387
 
 
388
 
static VAStatus
389
 
handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc)
390
 
{
391
 
   VAStatus status = VA_STATUS_SUCCESS;
392
 
 
393
 
   switch (u_reduce_video_profile(context->templat.profile)) {
394
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
395
 
      status = vlVaHandleVAEncMiscParameterTypeFrameRateH264(context, misc);
396
 
      break;
397
 
 
398
 
   case PIPE_VIDEO_FORMAT_HEVC:
399
 
      status = vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(context, misc);
400
 
      break;
401
 
 
402
 
   default:
403
 
      break;
404
 
   }
405
 
 
406
 
   return status;
407
 
}
408
 
 
409
 
static VAStatus
410
 
handleVAEncMiscParameterTypeTemporalLayer(vlVaContext *context, VAEncMiscParameterBuffer *misc)
411
 
{
412
 
   VAStatus status = VA_STATUS_SUCCESS;
413
 
 
414
 
   switch (u_reduce_video_profile(context->templat.profile)) {
415
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
416
 
      status = vlVaHandleVAEncMiscParameterTypeTemporalLayerH264(context, misc);
417
 
      break;
418
 
 
419
 
   case PIPE_VIDEO_FORMAT_HEVC:
420
 
      break;
421
 
 
422
 
   default:
423
 
      break;
424
 
   }
425
 
 
426
 
   return status;
427
 
}
428
 
 
429
 
static VAStatus
430
 
handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
431
 
{
432
 
   VAStatus status = VA_STATUS_SUCCESS;
433
 
 
434
 
   switch (u_reduce_video_profile(context->templat.profile)) {
435
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
436
 
      status = vlVaHandleVAEncSequenceParameterBufferTypeH264(drv, context, buf);
437
 
      break;
438
 
 
439
 
   case PIPE_VIDEO_FORMAT_HEVC:
440
 
      status = vlVaHandleVAEncSequenceParameterBufferTypeHEVC(drv, context, buf);
441
 
      break;
442
 
 
443
 
   default:
444
 
      break;
445
 
   }
446
 
 
447
 
   return status;
448
 
}
449
 
 
450
 
static VAStatus
451
 
handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
452
 
{
453
 
   VAStatus vaStatus = VA_STATUS_SUCCESS;
454
 
   VAEncMiscParameterBuffer *misc;
455
 
   misc = buf->data;
456
 
 
457
 
   switch (misc->type) {
458
 
   case VAEncMiscParameterTypeRateControl:
459
 
      vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc);
460
 
      break;
461
 
 
462
 
   case VAEncMiscParameterTypeFrameRate:
463
 
      vaStatus = handleVAEncMiscParameterTypeFrameRate(context, misc);
464
 
      break;
465
 
 
466
 
   case VAEncMiscParameterTypeTemporalLayerStructure:
467
 
      vaStatus = handleVAEncMiscParameterTypeTemporalLayer(context, misc);
468
 
      break;
469
 
 
470
 
   default:
471
 
      break;
472
 
   }
473
 
 
474
 
   return vaStatus;
475
 
}
476
 
 
477
 
static VAStatus
478
 
handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
479
 
{
480
 
   VAStatus status = VA_STATUS_SUCCESS;
481
 
 
482
 
   switch (u_reduce_video_profile(context->templat.profile)) {
483
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
484
 
      status = vlVaHandleVAEncPictureParameterBufferTypeH264(drv, context, buf);
485
 
      break;
486
 
 
487
 
   case PIPE_VIDEO_FORMAT_HEVC:
488
 
      status = vlVaHandleVAEncPictureParameterBufferTypeHEVC(drv, context, buf);
489
 
      break;
490
 
 
491
 
   default:
492
 
      break;
493
 
   }
494
 
 
495
 
   return status;
496
 
}
497
 
 
498
 
static VAStatus
499
 
handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
500
 
{
501
 
   VAStatus status = VA_STATUS_SUCCESS;
502
 
 
503
 
   switch (u_reduce_video_profile(context->templat.profile)) {
504
 
   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
505
 
      status = vlVaHandleVAEncSliceParameterBufferTypeH264(drv, context, buf);
506
 
      break;
507
 
 
508
 
   case PIPE_VIDEO_FORMAT_HEVC:
509
 
      status = vlVaHandleVAEncSliceParameterBufferTypeHEVC(drv, context, buf);
510
 
      break;
511
 
 
512
 
   default:
513
 
      break;
514
 
   }
515
 
 
516
 
   return status;
517
 
}
518
 
 
519
 
static VAStatus
520
 
handleVAEncPackedHeaderParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
521
 
{
522
 
   VAStatus status = VA_STATUS_SUCCESS;
523
 
 
524
 
   switch (u_reduce_video_profile(context->templat.profile)) {
525
 
   case PIPE_VIDEO_FORMAT_HEVC:
526
 
      break;
527
 
 
528
 
   default:
529
 
      return VA_STATUS_ERROR_UNIMPLEMENTED;
530
 
   }
531
 
 
532
 
   VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)buf->data;
533
 
   if (param->type == VAEncPackedHeaderSequence)
534
 
      context->packed_header_type = param->type;
535
 
   else
536
 
      status = VA_STATUS_ERROR_UNIMPLEMENTED;
537
 
 
538
 
   return status;
539
 
}
540
 
 
541
 
static VAStatus
542
 
handleVAEncPackedHeaderDataBufferType(vlVaContext *context, vlVaBuffer *buf)
543
 
{
544
 
   VAStatus status = VA_STATUS_SUCCESS;
545
 
 
546
 
   if (context->packed_header_type != VAEncPackedHeaderSequence)
547
 
      return VA_STATUS_ERROR_UNIMPLEMENTED;
548
 
 
549
 
   switch (u_reduce_video_profile(context->templat.profile)) {
550
 
   case PIPE_VIDEO_FORMAT_HEVC:
551
 
      status = vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(context, buf);
552
 
      break;
553
 
 
554
 
   default:
555
 
      break;
556
 
   }
557
 
 
558
 
   return status;
559
 
}
560
 
 
561
 
VAStatus
562
 
vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
563
 
{
564
 
   vlVaDriver *drv;
565
 
   vlVaContext *context;
566
 
   VAStatus vaStatus = VA_STATUS_SUCCESS;
567
 
 
568
 
   unsigned i;
569
 
   unsigned slice_param_idx = 0;
570
 
 
571
 
   if (!ctx)
572
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
573
 
 
574
 
   drv = VL_VA_DRIVER(ctx);
575
 
   if (!drv)
576
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
577
 
 
578
 
   mtx_lock(&drv->mutex);
579
 
   context = handle_table_get(drv->htab, context_id);
580
 
   if (!context) {
581
 
      mtx_unlock(&drv->mutex);
582
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
583
 
   }
584
 
 
585
 
   /* Always process VAProtectedSliceDataBufferType first because it changes the state */
586
 
   for (i = 0; i < num_buffers; ++i) {
587
 
      vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
588
 
      if (!buf) {
589
 
         mtx_unlock(&drv->mutex);
590
 
         return VA_STATUS_ERROR_INVALID_BUFFER;
591
 
      }
592
 
 
593
 
      if (buf->type == VAProtectedSliceDataBufferType)
594
 
         handleVAProtectedSliceDataBufferType(context, buf);
595
 
   }
596
 
 
597
 
   for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; ++i) {
598
 
      vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
599
 
 
600
 
      switch (buf->type) {
601
 
      case VAPictureParameterBufferType:
602
 
         vaStatus = handlePictureParameterBuffer(drv, context, buf);
603
 
         break;
604
 
 
605
 
      case VAIQMatrixBufferType:
606
 
         handleIQMatrixBuffer(context, buf);
607
 
         break;
608
 
 
609
 
      case VASliceParameterBufferType:
610
 
         handleSliceParameterBuffer(context, buf, slice_param_idx++);
611
 
         break;
612
 
 
613
 
      case VASliceDataBufferType:
614
 
         vaStatus = handleVASliceDataBufferType(context, buf);
615
 
         break;
616
 
 
617
 
      case VAProcPipelineParameterBufferType:
618
 
         vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf);
619
 
         break;
620
 
 
621
 
      case VAEncSequenceParameterBufferType:
622
 
         vaStatus = handleVAEncSequenceParameterBufferType(drv, context, buf);
623
 
         break;
624
 
 
625
 
      case VAEncMiscParameterBufferType:
626
 
         vaStatus = handleVAEncMiscParameterBufferType(context, buf);
627
 
         break;
628
 
 
629
 
      case VAEncPictureParameterBufferType:
630
 
         vaStatus = handleVAEncPictureParameterBufferType(drv, context, buf);
631
 
         break;
632
 
 
633
 
      case VAEncSliceParameterBufferType:
634
 
         vaStatus = handleVAEncSliceParameterBufferType(drv, context, buf);
635
 
         break;
636
 
 
637
 
      case VAHuffmanTableBufferType:
638
 
         vlVaHandleHuffmanTableBufferType(context, buf);
639
 
         break;
640
 
 
641
 
      case VAEncPackedHeaderParameterBufferType:
642
 
         handleVAEncPackedHeaderParameterBufferType(context, buf);
643
 
         break;
644
 
      case VAEncPackedHeaderDataBufferType:
645
 
         handleVAEncPackedHeaderDataBufferType(context, buf);
646
 
         break;
647
 
 
648
 
      default:
649
 
         break;
650
 
      }
651
 
   }
652
 
   mtx_unlock(&drv->mutex);
653
 
 
654
 
   return vaStatus;
655
 
}
656
 
 
657
 
VAStatus
658
 
vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
659
 
{
660
 
   vlVaDriver *drv;
661
 
   vlVaContext *context;
662
 
   vlVaBuffer *coded_buf;
663
 
   vlVaSurface *surf;
664
 
   void *feedback;
665
 
   struct pipe_screen *screen;
666
 
   bool supported;
667
 
   bool realloc = false;
668
 
   enum pipe_format format;
669
 
 
670
 
   if (!ctx)
671
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
672
 
 
673
 
   drv = VL_VA_DRIVER(ctx);
674
 
   if (!drv)
675
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
676
 
 
677
 
   mtx_lock(&drv->mutex);
678
 
   context = handle_table_get(drv->htab, context_id);
679
 
   mtx_unlock(&drv->mutex);
680
 
   if (!context)
681
 
      return VA_STATUS_ERROR_INVALID_CONTEXT;
682
 
 
683
 
   if (!context->decoder) {
684
 
      if (context->templat.profile != PIPE_VIDEO_PROFILE_UNKNOWN)
685
 
         return VA_STATUS_ERROR_INVALID_CONTEXT;
686
 
 
687
 
      /* VPP */
688
 
      return VA_STATUS_SUCCESS;
689
 
   }
690
 
 
691
 
   mtx_lock(&drv->mutex);
692
 
   surf = handle_table_get(drv->htab, context->target_id);
693
 
   context->mpeg4.frame_num++;
694
 
 
695
 
   screen = context->decoder->context->screen;
696
 
   supported = screen->get_video_param(screen, context->decoder->profile,
697
 
                                       context->decoder->entrypoint,
698
 
                                       surf->buffer->interlaced ?
699
 
                                       PIPE_VIDEO_CAP_SUPPORTS_INTERLACED :
700
 
                                       PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
701
 
 
702
 
   if (!supported) {
703
 
      surf->templat.interlaced = screen->get_video_param(screen,
704
 
                                       context->decoder->profile,
705
 
                                       context->decoder->entrypoint,
706
 
                                       PIPE_VIDEO_CAP_PREFERS_INTERLACED);
707
 
      realloc = true;
708
 
   }
709
 
 
710
 
   format = screen->get_video_param(screen, context->decoder->profile,
711
 
                                    context->decoder->entrypoint,
712
 
                                    PIPE_VIDEO_CAP_PREFERED_FORMAT);
713
 
 
714
 
   if (surf->buffer->buffer_format != format &&
715
 
       surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
716
 
      /* check originally as NV12 only */
717
 
      surf->templat.buffer_format = format;
718
 
      realloc = true;
719
 
   }
720
 
 
721
 
   if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_JPEG &&
722
 
       surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
723
 
      if (context->mjpeg.sampling_factor == 0x211111 ||
724
 
          context->mjpeg.sampling_factor == 0x221212) {
725
 
         surf->templat.buffer_format = PIPE_FORMAT_YUYV;
726
 
         realloc = true;
727
 
      } else if (context->mjpeg.sampling_factor != 0x221111) {
728
 
         /* Not NV12 either */
729
 
         mtx_unlock(&drv->mutex);
730
 
         return VA_STATUS_ERROR_INVALID_SURFACE;
731
 
      }
732
 
   }
733
 
 
734
 
   if ((bool)(surf->templat.bind & PIPE_BIND_PROTECTED) != context->desc.base.protected_playback) {
735
 
      if (context->desc.base.protected_playback) {
736
 
         surf->templat.bind |= PIPE_BIND_PROTECTED;
737
 
      }
738
 
      else
739
 
         surf->templat.bind &= ~PIPE_BIND_PROTECTED;
740
 
      realloc = true;
741
 
   }
742
 
 
743
 
   if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_AV1 &&
744
 
       surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
745
 
      if (context->desc.av1.picture_parameter.bit_depth_idx == 1) {
746
 
         surf->templat.buffer_format = PIPE_FORMAT_P010;
747
 
         realloc = true;
748
 
      }
749
 
   }
750
 
 
751
 
   if (realloc) {
752
 
      struct pipe_video_buffer *old_buf = surf->buffer;
753
 
 
754
 
      if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) {
755
 
         mtx_unlock(&drv->mutex);
756
 
         return VA_STATUS_ERROR_ALLOCATION_FAILED;
757
 
      }
758
 
 
759
 
      if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
760
 
         if (old_buf->interlaced) {
761
 
            struct u_rect src_rect, dst_rect;
762
 
 
763
 
            dst_rect.x0 = src_rect.x0 = 0;
764
 
            dst_rect.y0 = src_rect.y0 = 0;
765
 
            dst_rect.x1 = src_rect.x1 = surf->templat.width;
766
 
            dst_rect.y1 = src_rect.y1 = surf->templat.height;
767
 
            vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
768
 
                                         old_buf, surf->buffer,
769
 
                                         &src_rect, &dst_rect, VL_COMPOSITOR_WEAVE);
770
 
         } else {
771
 
            /* Can't convert from progressive to interlaced yet */
772
 
            mtx_unlock(&drv->mutex);
773
 
            return VA_STATUS_ERROR_INVALID_SURFACE;
774
 
         }
775
 
      }
776
 
 
777
 
      old_buf->destroy(old_buf);
778
 
      context->target = surf->buffer;
779
 
   }
780
 
 
781
 
   if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
782
 
      coded_buf = context->coded_buf;
783
 
      if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
784
 
         getEncParamPresetH264(context);
785
 
         context->desc.h264enc.frame_num_cnt++;
786
 
      } else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)
787
 
         getEncParamPresetH265(context);
788
 
 
789
 
      context->desc.base.input_format = surf->buffer->buffer_format;
790
 
      context->desc.base.output_format = surf->encoder_format;
791
 
 
792
 
      context->decoder->begin_frame(context->decoder, context->target, &context->desc.base);
793
 
      context->decoder->encode_bitstream(context->decoder, context->target,
794
 
                                         coded_buf->derived_surface.resource, &feedback);
795
 
      surf->feedback = feedback;
796
 
      surf->coded_buf = coded_buf;
797
 
   }
798
 
 
799
 
   context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
800
 
   if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&
801
 
      u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
802
 
      int idr_period = context->desc.h264enc.gop_size / context->gop_coeff;
803
 
      int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num;
804
 
      surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt;
805
 
      surf->force_flushed = false;
806
 
      if (context->first_single_submitted) {
807
 
         context->decoder->flush(context->decoder);
808
 
         context->first_single_submitted = false;
809
 
         surf->force_flushed = true;
810
 
      }
811
 
      if (p_remain_in_idr == 1) {
812
 
         if ((context->desc.h264enc.frame_num_cnt % 2) != 0) {
813
 
            context->decoder->flush(context->decoder);
814
 
            context->first_single_submitted = true;
815
 
         }
816
 
         else
817
 
            context->first_single_submitted = false;
818
 
         surf->force_flushed = true;
819
 
      }
820
 
      if (!context->desc.h264enc.not_referenced)
821
 
         context->desc.h264enc.frame_num++;
822
 
   } else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&
823
 
              u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)
824
 
      context->desc.h265enc.frame_num++;
825
 
   mtx_unlock(&drv->mutex);
826
 
   return VA_STATUS_SUCCESS;
827
 
}