Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/va/picture.c
4561 views
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 "vl/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
default:
146
break;
147
}
148
149
/* Create the decoder once max_references is known. */
150
if (!context->decoder) {
151
if (!context->target)
152
return VA_STATUS_ERROR_INVALID_CONTEXT;
153
154
if (format == PIPE_VIDEO_FORMAT_MPEG4_AVC)
155
context->templat.level = u_get_h264_level(context->templat.width,
156
context->templat.height, &context->templat.max_references);
157
158
context->decoder = drv->pipe->create_video_codec(drv->pipe,
159
&context->templat);
160
161
if (!context->decoder)
162
return VA_STATUS_ERROR_ALLOCATION_FAILED;
163
164
context->needs_begin_frame = true;
165
}
166
167
if (format == PIPE_VIDEO_FORMAT_VP9) {
168
context->decoder->width =
169
context->desc.vp9.picture_parameter.frame_width;
170
context->decoder->height =
171
context->desc.vp9.picture_parameter.frame_height;
172
}
173
174
return vaStatus;
175
}
176
177
static void
178
handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
179
{
180
switch (u_reduce_video_profile(context->templat.profile)) {
181
case PIPE_VIDEO_FORMAT_MPEG12:
182
vlVaHandleIQMatrixBufferMPEG12(context, buf);
183
break;
184
185
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
186
vlVaHandleIQMatrixBufferH264(context, buf);
187
break;
188
189
case PIPE_VIDEO_FORMAT_MPEG4:
190
vlVaHandleIQMatrixBufferMPEG4(context, buf);
191
break;
192
193
case PIPE_VIDEO_FORMAT_HEVC:
194
vlVaHandleIQMatrixBufferHEVC(context, buf);
195
break;
196
197
case PIPE_VIDEO_FORMAT_JPEG:
198
vlVaHandleIQMatrixBufferMJPEG(context, buf);
199
break;
200
201
default:
202
break;
203
}
204
}
205
206
static void
207
handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf)
208
{
209
switch (u_reduce_video_profile(context->templat.profile)) {
210
case PIPE_VIDEO_FORMAT_MPEG12:
211
vlVaHandleSliceParameterBufferMPEG12(context, buf);
212
break;
213
214
case PIPE_VIDEO_FORMAT_VC1:
215
vlVaHandleSliceParameterBufferVC1(context, buf);
216
break;
217
218
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
219
vlVaHandleSliceParameterBufferH264(context, buf);
220
break;
221
222
case PIPE_VIDEO_FORMAT_MPEG4:
223
vlVaHandleSliceParameterBufferMPEG4(context, buf);
224
break;
225
226
case PIPE_VIDEO_FORMAT_HEVC:
227
vlVaHandleSliceParameterBufferHEVC(context, buf);
228
break;
229
230
case PIPE_VIDEO_FORMAT_JPEG:
231
vlVaHandleSliceParameterBufferMJPEG(context, buf);
232
break;
233
234
case PIPE_VIDEO_FORMAT_VP9:
235
vlVaHandleSliceParameterBufferVP9(context, buf);
236
break;
237
238
default:
239
break;
240
}
241
}
242
243
static unsigned int
244
bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)
245
{
246
struct vl_vlc vlc = {0};
247
int i;
248
249
/* search the first 64 bytes for a startcode */
250
vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size);
251
for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= bits; ++i) {
252
if (vl_vlc_peekbits(&vlc, bits) == code)
253
return 1;
254
vl_vlc_eatbits(&vlc, 8);
255
vl_vlc_fillbits(&vlc);
256
}
257
258
return 0;
259
}
260
261
static void
262
handleVAProtectedSliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
263
{
264
uint8_t* encrypted_data = (uint8_t*) buf->data;
265
266
unsigned int drm_key_size = buf->size;
267
268
context->desc.base.decrypt_key = CALLOC(1, drm_key_size);
269
memcpy(context->desc.base.decrypt_key, encrypted_data, drm_key_size);
270
context->desc.base.protected_playback = true;
271
}
272
273
static void
274
handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
275
{
276
enum pipe_video_format format = u_reduce_video_profile(context->templat.profile);
277
unsigned num_buffers = 0;
278
void * const *buffers[3];
279
unsigned sizes[3];
280
static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 };
281
static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 };
282
static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d };
283
static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 };
284
285
format = u_reduce_video_profile(context->templat.profile);
286
if (!context->desc.base.protected_playback) {
287
switch (format) {
288
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
289
if (bufHasStartcode(buf, 0x000001, 24))
290
break;
291
292
buffers[num_buffers] = (void *const)&start_code_h264;
293
sizes[num_buffers++] = sizeof(start_code_h264);
294
break;
295
case PIPE_VIDEO_FORMAT_HEVC:
296
if (bufHasStartcode(buf, 0x000001, 24))
297
break;
298
299
buffers[num_buffers] = (void *const)&start_code_h265;
300
sizes[num_buffers++] = sizeof(start_code_h265);
301
break;
302
case PIPE_VIDEO_FORMAT_VC1:
303
if (bufHasStartcode(buf, 0x0000010d, 32) ||
304
bufHasStartcode(buf, 0x0000010c, 32) ||
305
bufHasStartcode(buf, 0x0000010b, 32))
306
break;
307
308
if (context->decoder->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) {
309
buffers[num_buffers] = (void *const)&start_code_vc1;
310
sizes[num_buffers++] = sizeof(start_code_vc1);
311
}
312
break;
313
case PIPE_VIDEO_FORMAT_MPEG4:
314
if (bufHasStartcode(buf, 0x000001, 24))
315
break;
316
317
vlVaDecoderFixMPEG4Startcode(context);
318
buffers[num_buffers] = (void *)context->mpeg4.start_code;
319
sizes[num_buffers++] = context->mpeg4.start_code_size;
320
break;
321
case PIPE_VIDEO_FORMAT_JPEG:
322
vlVaGetJpegSliceHeader(context);
323
buffers[num_buffers] = (void *)context->mjpeg.slice_header;
324
sizes[num_buffers++] = context->mjpeg.slice_header_size;
325
break;
326
case PIPE_VIDEO_FORMAT_VP9:
327
vlVaDecoderVP9BitstreamHeader(context, buf);
328
break;
329
default:
330
break;
331
}
332
}
333
334
if (context->desc.base.protected_playback && PIPE_VIDEO_FORMAT_VP9 == format){
335
vlVaDecoderVP9BitstreamHeader(context, buf);
336
buffers[num_buffers] = buf->data + context->desc.vp9.picture_parameter.frame_header_length_in_bytes;
337
sizes[num_buffers] = buf->size - context->desc.vp9.picture_parameter.frame_header_length_in_bytes;
338
++num_buffers;
339
} else {
340
buffers[num_buffers] = buf->data;
341
sizes[num_buffers] = buf->size;
342
++num_buffers;
343
}
344
345
if (format == PIPE_VIDEO_FORMAT_JPEG) {
346
buffers[num_buffers] = (void *const)&eoi_jpeg;
347
sizes[num_buffers++] = sizeof(eoi_jpeg);
348
}
349
350
if (context->needs_begin_frame) {
351
context->decoder->begin_frame(context->decoder, context->target,
352
&context->desc.base);
353
context->needs_begin_frame = false;
354
}
355
context->decoder->decode_bitstream(context->decoder, context->target, &context->desc.base,
356
num_buffers, (const void * const*)buffers, sizes);
357
}
358
359
static VAStatus
360
handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc)
361
{
362
VAStatus status = VA_STATUS_SUCCESS;
363
364
switch (u_reduce_video_profile(context->templat.profile)) {
365
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
366
status = vlVaHandleVAEncMiscParameterTypeRateControlH264(context, misc);
367
break;
368
369
case PIPE_VIDEO_FORMAT_HEVC:
370
status = vlVaHandleVAEncMiscParameterTypeRateControlHEVC(context, misc);
371
break;
372
373
default:
374
break;
375
}
376
377
return status;
378
}
379
380
static VAStatus
381
handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc)
382
{
383
VAStatus status = VA_STATUS_SUCCESS;
384
385
switch (u_reduce_video_profile(context->templat.profile)) {
386
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
387
status = vlVaHandleVAEncMiscParameterTypeFrameRateH264(context, misc);
388
break;
389
390
case PIPE_VIDEO_FORMAT_HEVC:
391
status = vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(context, misc);
392
break;
393
394
default:
395
break;
396
}
397
398
return status;
399
}
400
401
static VAStatus
402
handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
403
{
404
VAStatus status = VA_STATUS_SUCCESS;
405
406
switch (u_reduce_video_profile(context->templat.profile)) {
407
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
408
status = vlVaHandleVAEncSequenceParameterBufferTypeH264(drv, context, buf);
409
break;
410
411
case PIPE_VIDEO_FORMAT_HEVC:
412
status = vlVaHandleVAEncSequenceParameterBufferTypeHEVC(drv, context, buf);
413
break;
414
415
default:
416
break;
417
}
418
419
return status;
420
}
421
422
static VAStatus
423
handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
424
{
425
VAStatus vaStatus = VA_STATUS_SUCCESS;
426
VAEncMiscParameterBuffer *misc;
427
misc = buf->data;
428
429
switch (misc->type) {
430
case VAEncMiscParameterTypeRateControl:
431
vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc);
432
break;
433
434
case VAEncMiscParameterTypeFrameRate:
435
vaStatus = handleVAEncMiscParameterTypeFrameRate(context, misc);
436
break;
437
438
default:
439
break;
440
}
441
442
return vaStatus;
443
}
444
445
static VAStatus
446
handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
447
{
448
VAStatus status = VA_STATUS_SUCCESS;
449
450
switch (u_reduce_video_profile(context->templat.profile)) {
451
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
452
status = vlVaHandleVAEncPictureParameterBufferTypeH264(drv, context, buf);
453
break;
454
455
case PIPE_VIDEO_FORMAT_HEVC:
456
status = vlVaHandleVAEncPictureParameterBufferTypeHEVC(drv, context, buf);
457
break;
458
459
default:
460
break;
461
}
462
463
return status;
464
}
465
466
static VAStatus
467
handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
468
{
469
VAStatus status = VA_STATUS_SUCCESS;
470
471
switch (u_reduce_video_profile(context->templat.profile)) {
472
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
473
status = vlVaHandleVAEncSliceParameterBufferTypeH264(drv, context, buf);
474
break;
475
476
case PIPE_VIDEO_FORMAT_HEVC:
477
status = vlVaHandleVAEncSliceParameterBufferTypeHEVC(drv, context, buf);
478
break;
479
480
default:
481
break;
482
}
483
484
return status;
485
}
486
487
static VAStatus
488
handleVAEncPackedHeaderParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
489
{
490
VAStatus status = VA_STATUS_SUCCESS;
491
492
switch (u_reduce_video_profile(context->templat.profile)) {
493
case PIPE_VIDEO_FORMAT_HEVC:
494
break;
495
496
default:
497
return VA_STATUS_ERROR_UNIMPLEMENTED;
498
}
499
500
VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)buf->data;
501
if (param->type == VAEncPackedHeaderSequence)
502
context->packed_header_type = param->type;
503
else
504
status = VA_STATUS_ERROR_UNIMPLEMENTED;
505
506
return status;
507
}
508
509
static VAStatus
510
handleVAEncPackedHeaderDataBufferType(vlVaContext *context, vlVaBuffer *buf)
511
{
512
VAStatus status = VA_STATUS_SUCCESS;
513
514
if (context->packed_header_type != VAEncPackedHeaderSequence)
515
return VA_STATUS_ERROR_UNIMPLEMENTED;
516
517
switch (u_reduce_video_profile(context->templat.profile)) {
518
case PIPE_VIDEO_FORMAT_HEVC:
519
status = vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(context, buf);
520
break;
521
522
default:
523
break;
524
}
525
526
return status;
527
}
528
529
VAStatus
530
vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
531
{
532
vlVaDriver *drv;
533
vlVaContext *context;
534
VAStatus vaStatus = VA_STATUS_SUCCESS;
535
536
unsigned i;
537
538
if (!ctx)
539
return VA_STATUS_ERROR_INVALID_CONTEXT;
540
541
drv = VL_VA_DRIVER(ctx);
542
if (!drv)
543
return VA_STATUS_ERROR_INVALID_CONTEXT;
544
545
mtx_lock(&drv->mutex);
546
context = handle_table_get(drv->htab, context_id);
547
if (!context) {
548
mtx_unlock(&drv->mutex);
549
return VA_STATUS_ERROR_INVALID_CONTEXT;
550
}
551
552
/* Always process VAProtectedSliceDataBufferType first because it changes the state */
553
for (i = 0; i < num_buffers; ++i) {
554
vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
555
if (!buf) {
556
mtx_unlock(&drv->mutex);
557
return VA_STATUS_ERROR_INVALID_BUFFER;
558
}
559
560
if (buf->type == VAProtectedSliceDataBufferType)
561
handleVAProtectedSliceDataBufferType(context, buf);
562
}
563
564
for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; ++i) {
565
vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
566
567
switch (buf->type) {
568
case VAPictureParameterBufferType:
569
vaStatus = handlePictureParameterBuffer(drv, context, buf);
570
break;
571
572
case VAIQMatrixBufferType:
573
handleIQMatrixBuffer(context, buf);
574
break;
575
576
case VASliceParameterBufferType:
577
handleSliceParameterBuffer(context, buf);
578
break;
579
580
case VASliceDataBufferType:
581
handleVASliceDataBufferType(context, buf);
582
break;
583
584
case VAProcPipelineParameterBufferType:
585
vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf);
586
break;
587
588
case VAEncSequenceParameterBufferType:
589
vaStatus = handleVAEncSequenceParameterBufferType(drv, context, buf);
590
break;
591
592
case VAEncMiscParameterBufferType:
593
vaStatus = handleVAEncMiscParameterBufferType(context, buf);
594
break;
595
596
case VAEncPictureParameterBufferType:
597
vaStatus = handleVAEncPictureParameterBufferType(drv, context, buf);
598
break;
599
600
case VAEncSliceParameterBufferType:
601
vaStatus = handleVAEncSliceParameterBufferType(drv, context, buf);
602
break;
603
604
case VAHuffmanTableBufferType:
605
vlVaHandleHuffmanTableBufferType(context, buf);
606
break;
607
608
case VAEncPackedHeaderParameterBufferType:
609
handleVAEncPackedHeaderParameterBufferType(context, buf);
610
break;
611
case VAEncPackedHeaderDataBufferType:
612
handleVAEncPackedHeaderDataBufferType(context, buf);
613
break;
614
615
default:
616
break;
617
}
618
}
619
mtx_unlock(&drv->mutex);
620
621
return vaStatus;
622
}
623
624
VAStatus
625
vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
626
{
627
vlVaDriver *drv;
628
vlVaContext *context;
629
vlVaBuffer *coded_buf;
630
vlVaSurface *surf;
631
void *feedback;
632
struct pipe_screen *screen;
633
bool supported;
634
bool realloc = false;
635
enum pipe_format format;
636
637
if (!ctx)
638
return VA_STATUS_ERROR_INVALID_CONTEXT;
639
640
drv = VL_VA_DRIVER(ctx);
641
if (!drv)
642
return VA_STATUS_ERROR_INVALID_CONTEXT;
643
644
mtx_lock(&drv->mutex);
645
context = handle_table_get(drv->htab, context_id);
646
mtx_unlock(&drv->mutex);
647
if (!context)
648
return VA_STATUS_ERROR_INVALID_CONTEXT;
649
650
if (!context->decoder) {
651
if (context->templat.profile != PIPE_VIDEO_PROFILE_UNKNOWN)
652
return VA_STATUS_ERROR_INVALID_CONTEXT;
653
654
/* VPP */
655
return VA_STATUS_SUCCESS;
656
}
657
658
mtx_lock(&drv->mutex);
659
surf = handle_table_get(drv->htab, context->target_id);
660
context->mpeg4.frame_num++;
661
662
screen = context->decoder->context->screen;
663
supported = screen->get_video_param(screen, context->decoder->profile,
664
context->decoder->entrypoint,
665
surf->buffer->interlaced ?
666
PIPE_VIDEO_CAP_SUPPORTS_INTERLACED :
667
PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
668
669
if (!supported) {
670
surf->templat.interlaced = screen->get_video_param(screen,
671
context->decoder->profile,
672
context->decoder->entrypoint,
673
PIPE_VIDEO_CAP_PREFERS_INTERLACED);
674
realloc = true;
675
}
676
677
format = screen->get_video_param(screen, context->decoder->profile,
678
context->decoder->entrypoint,
679
PIPE_VIDEO_CAP_PREFERED_FORMAT);
680
681
if (surf->buffer->buffer_format != format &&
682
surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
683
/* check originally as NV12 only */
684
surf->templat.buffer_format = format;
685
realloc = true;
686
}
687
688
if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_JPEG &&
689
surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
690
if (context->mjpeg.sampling_factor == 0x211111 ||
691
context->mjpeg.sampling_factor == 0x221212) {
692
surf->templat.buffer_format = PIPE_FORMAT_YUYV;
693
realloc = true;
694
} else if (context->mjpeg.sampling_factor != 0x221111) {
695
/* Not NV12 either */
696
mtx_unlock(&drv->mutex);
697
return VA_STATUS_ERROR_INVALID_SURFACE;
698
}
699
}
700
701
if ((bool)(surf->templat.bind & PIPE_BIND_PROTECTED) != context->desc.base.protected_playback) {
702
if (context->desc.base.protected_playback) {
703
surf->templat.bind |= PIPE_BIND_PROTECTED;
704
}
705
else
706
surf->templat.bind &= ~PIPE_BIND_PROTECTED;
707
realloc = true;
708
}
709
710
if (realloc) {
711
struct pipe_video_buffer *old_buf = surf->buffer;
712
713
if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) {
714
mtx_unlock(&drv->mutex);
715
return VA_STATUS_ERROR_ALLOCATION_FAILED;
716
}
717
718
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
719
if (old_buf->interlaced) {
720
struct u_rect src_rect, dst_rect;
721
722
dst_rect.x0 = src_rect.x0 = 0;
723
dst_rect.y0 = src_rect.y0 = 0;
724
dst_rect.x1 = src_rect.x1 = surf->templat.width;
725
dst_rect.y1 = src_rect.y1 = surf->templat.height;
726
vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
727
old_buf, surf->buffer,
728
&src_rect, &dst_rect, VL_COMPOSITOR_WEAVE);
729
} else {
730
/* Can't convert from progressive to interlaced yet */
731
mtx_unlock(&drv->mutex);
732
return VA_STATUS_ERROR_INVALID_SURFACE;
733
}
734
}
735
736
old_buf->destroy(old_buf);
737
context->target = surf->buffer;
738
}
739
740
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
741
coded_buf = context->coded_buf;
742
if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
743
getEncParamPresetH264(context);
744
context->desc.h264enc.frame_num_cnt++;
745
} else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)
746
getEncParamPresetH265(context);
747
context->decoder->begin_frame(context->decoder, context->target, &context->desc.base);
748
context->decoder->encode_bitstream(context->decoder, context->target,
749
coded_buf->derived_surface.resource, &feedback);
750
surf->feedback = feedback;
751
surf->coded_buf = coded_buf;
752
}
753
754
context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
755
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&
756
u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
757
int idr_period = context->desc.h264enc.gop_size / context->gop_coeff;
758
int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num;
759
surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt;
760
surf->force_flushed = false;
761
if (context->first_single_submitted) {
762
context->decoder->flush(context->decoder);
763
context->first_single_submitted = false;
764
surf->force_flushed = true;
765
}
766
if (p_remain_in_idr == 1) {
767
if ((context->desc.h264enc.frame_num_cnt % 2) != 0) {
768
context->decoder->flush(context->decoder);
769
context->first_single_submitted = true;
770
}
771
else
772
context->first_single_submitted = false;
773
surf->force_flushed = true;
774
}
775
} else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&
776
u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)
777
context->desc.h265enc.frame_num++;
778
mtx_unlock(&drv->mutex);
779
return VA_STATUS_SUCCESS;
780
}
781
782