1
/**************************************************************************
3
* Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4
* Copyright 2014 Advanced Micro Devices, Inc.
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:
15
* The above copyright notice and this permission notice (including the
16
* next paragraph) shall be included in all copies or substantial portions
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.
27
**************************************************************************/
29
#include "pipe/p_video_codec.h"
31
#include "util/u_handle_table.h"
32
#include "util/u_video.h"
33
#include "util/u_memory.h"
35
#include "util/vl_vlc.h"
36
#include "vl/vl_winsys.h"
38
#include "va_private.h"
41
vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID render_target)
48
return VA_STATUS_ERROR_INVALID_CONTEXT;
50
drv = VL_VA_DRIVER(ctx);
52
return VA_STATUS_ERROR_INVALID_CONTEXT;
54
mtx_lock(&drv->mutex);
55
context = handle_table_get(drv->htab, context_id);
57
mtx_unlock(&drv->mutex);
58
return VA_STATUS_ERROR_INVALID_CONTEXT;
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;
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;
71
context->target_id = render_target;
72
surf->ctx = context_id;
73
context->target = surf->buffer;
74
context->mjpeg.sampling_factor = 0;
76
if (!context->decoder) {
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;
89
return VA_STATUS_SUCCESS;
92
if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE)
93
context->needs_begin_frame = true;
95
return VA_STATUS_SUCCESS;
99
vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
100
struct pipe_video_buffer **ref_frame)
102
vlVaSurface *surf = handle_table_get(drv->htab, surface_id);
104
*ref_frame = surf->buffer;
110
handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
112
VAStatus vaStatus = VA_STATUS_SUCCESS;
113
enum pipe_video_format format =
114
u_reduce_video_profile(context->templat.profile);
117
case PIPE_VIDEO_FORMAT_MPEG12:
118
vlVaHandlePictureParameterBufferMPEG12(drv, context, buf);
121
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
122
vlVaHandlePictureParameterBufferH264(drv, context, buf);
125
case PIPE_VIDEO_FORMAT_VC1:
126
vlVaHandlePictureParameterBufferVC1(drv, context, buf);
129
case PIPE_VIDEO_FORMAT_MPEG4:
130
vlVaHandlePictureParameterBufferMPEG4(drv, context, buf);
133
case PIPE_VIDEO_FORMAT_HEVC:
134
vlVaHandlePictureParameterBufferHEVC(drv, context, buf);
137
case PIPE_VIDEO_FORMAT_JPEG:
138
vlVaHandlePictureParameterBufferMJPEG(drv, context, buf);
141
case PIPE_VIDEO_FORMAT_VP9:
142
vlVaHandlePictureParameterBufferVP9(drv, context, buf);
145
case PIPE_VIDEO_FORMAT_AV1:
146
vlVaHandlePictureParameterBufferAV1(drv, context, buf);
153
/* Create the decoder once max_references is known. */
154
if (!context->decoder) {
155
if (!context->target)
156
return VA_STATUS_ERROR_INVALID_CONTEXT;
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);
162
context->decoder = drv->pipe->create_video_codec(drv->pipe,
165
if (!context->decoder)
166
return VA_STATUS_ERROR_ALLOCATION_FAILED;
168
context->needs_begin_frame = true;
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;
182
handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
184
switch (u_reduce_video_profile(context->templat.profile)) {
185
case PIPE_VIDEO_FORMAT_MPEG12:
186
vlVaHandleIQMatrixBufferMPEG12(context, buf);
189
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
190
vlVaHandleIQMatrixBufferH264(context, buf);
193
case PIPE_VIDEO_FORMAT_MPEG4:
194
vlVaHandleIQMatrixBufferMPEG4(context, buf);
197
case PIPE_VIDEO_FORMAT_HEVC:
198
vlVaHandleIQMatrixBufferHEVC(context, buf);
201
case PIPE_VIDEO_FORMAT_JPEG:
202
vlVaHandleIQMatrixBufferMJPEG(context, buf);
211
handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num)
213
switch (u_reduce_video_profile(context->templat.profile)) {
214
case PIPE_VIDEO_FORMAT_MPEG12:
215
vlVaHandleSliceParameterBufferMPEG12(context, buf);
218
case PIPE_VIDEO_FORMAT_VC1:
219
vlVaHandleSliceParameterBufferVC1(context, buf);
222
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
223
vlVaHandleSliceParameterBufferH264(context, buf);
226
case PIPE_VIDEO_FORMAT_MPEG4:
227
vlVaHandleSliceParameterBufferMPEG4(context, buf);
230
case PIPE_VIDEO_FORMAT_HEVC:
231
vlVaHandleSliceParameterBufferHEVC(context, buf);
234
case PIPE_VIDEO_FORMAT_JPEG:
235
vlVaHandleSliceParameterBufferMJPEG(context, buf);
238
case PIPE_VIDEO_FORMAT_VP9:
239
vlVaHandleSliceParameterBufferVP9(context, buf);
242
case PIPE_VIDEO_FORMAT_AV1:
243
vlVaHandleSliceParameterBufferAV1(context, buf, num);
252
bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)
254
struct vl_vlc vlc = {0};
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)
262
vl_vlc_eatbits(&vlc, 8);
263
vl_vlc_fillbits(&vlc);
270
handleVAProtectedSliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
272
uint8_t* encrypted_data = (uint8_t*) buf->data;
274
unsigned int drm_key_size = buf->size;
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;
282
handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
284
enum pipe_video_format format = u_reduce_video_profile(context->templat.profile);
285
unsigned num_buffers = 0;
286
void * const *buffers[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 };
293
if (!context->decoder)
294
return VA_STATUS_ERROR_INVALID_CONTEXT;
296
format = u_reduce_video_profile(context->templat.profile);
297
if (!context->desc.base.protected_playback) {
299
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
300
if (bufHasStartcode(buf, 0x000001, 24))
303
buffers[num_buffers] = (void *const)&start_code_h264;
304
sizes[num_buffers++] = sizeof(start_code_h264);
306
case PIPE_VIDEO_FORMAT_HEVC:
307
if (bufHasStartcode(buf, 0x000001, 24))
310
buffers[num_buffers] = (void *const)&start_code_h265;
311
sizes[num_buffers++] = sizeof(start_code_h265);
313
case PIPE_VIDEO_FORMAT_VC1:
314
if (bufHasStartcode(buf, 0x0000010d, 32) ||
315
bufHasStartcode(buf, 0x0000010c, 32) ||
316
bufHasStartcode(buf, 0x0000010b, 32))
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);
324
case PIPE_VIDEO_FORMAT_MPEG4:
325
if (bufHasStartcode(buf, 0x000001, 24))
328
vlVaDecoderFixMPEG4Startcode(context);
329
buffers[num_buffers] = (void *)context->mpeg4.start_code;
330
sizes[num_buffers++] = context->mpeg4.start_code_size;
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;
337
case PIPE_VIDEO_FORMAT_VP9:
338
if (false == context->desc.base.protected_playback)
339
vlVaDecoderVP9BitstreamHeader(context, buf);
341
case PIPE_VIDEO_FORMAT_AV1:
348
buffers[num_buffers] = buf->data;
349
sizes[num_buffers] = buf->size;
352
if (format == PIPE_VIDEO_FORMAT_JPEG) {
353
buffers[num_buffers] = (void *const)&eoi_jpeg;
354
sizes[num_buffers++] = sizeof(eoi_jpeg);
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;
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;
368
handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc)
370
VAStatus status = VA_STATUS_SUCCESS;
372
switch (u_reduce_video_profile(context->templat.profile)) {
373
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
374
status = vlVaHandleVAEncMiscParameterTypeRateControlH264(context, misc);
377
case PIPE_VIDEO_FORMAT_HEVC:
378
status = vlVaHandleVAEncMiscParameterTypeRateControlHEVC(context, misc);
389
handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc)
391
VAStatus status = VA_STATUS_SUCCESS;
393
switch (u_reduce_video_profile(context->templat.profile)) {
394
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
395
status = vlVaHandleVAEncMiscParameterTypeFrameRateH264(context, misc);
398
case PIPE_VIDEO_FORMAT_HEVC:
399
status = vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(context, misc);
410
handleVAEncMiscParameterTypeTemporalLayer(vlVaContext *context, VAEncMiscParameterBuffer *misc)
412
VAStatus status = VA_STATUS_SUCCESS;
414
switch (u_reduce_video_profile(context->templat.profile)) {
415
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
416
status = vlVaHandleVAEncMiscParameterTypeTemporalLayerH264(context, misc);
419
case PIPE_VIDEO_FORMAT_HEVC:
430
handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
432
VAStatus status = VA_STATUS_SUCCESS;
434
switch (u_reduce_video_profile(context->templat.profile)) {
435
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
436
status = vlVaHandleVAEncSequenceParameterBufferTypeH264(drv, context, buf);
439
case PIPE_VIDEO_FORMAT_HEVC:
440
status = vlVaHandleVAEncSequenceParameterBufferTypeHEVC(drv, context, buf);
451
handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
453
VAStatus vaStatus = VA_STATUS_SUCCESS;
454
VAEncMiscParameterBuffer *misc;
457
switch (misc->type) {
458
case VAEncMiscParameterTypeRateControl:
459
vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc);
462
case VAEncMiscParameterTypeFrameRate:
463
vaStatus = handleVAEncMiscParameterTypeFrameRate(context, misc);
466
case VAEncMiscParameterTypeTemporalLayerStructure:
467
vaStatus = handleVAEncMiscParameterTypeTemporalLayer(context, misc);
478
handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
480
VAStatus status = VA_STATUS_SUCCESS;
482
switch (u_reduce_video_profile(context->templat.profile)) {
483
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
484
status = vlVaHandleVAEncPictureParameterBufferTypeH264(drv, context, buf);
487
case PIPE_VIDEO_FORMAT_HEVC:
488
status = vlVaHandleVAEncPictureParameterBufferTypeHEVC(drv, context, buf);
499
handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
501
VAStatus status = VA_STATUS_SUCCESS;
503
switch (u_reduce_video_profile(context->templat.profile)) {
504
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
505
status = vlVaHandleVAEncSliceParameterBufferTypeH264(drv, context, buf);
508
case PIPE_VIDEO_FORMAT_HEVC:
509
status = vlVaHandleVAEncSliceParameterBufferTypeHEVC(drv, context, buf);
520
handleVAEncPackedHeaderParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
522
VAStatus status = VA_STATUS_SUCCESS;
524
switch (u_reduce_video_profile(context->templat.profile)) {
525
case PIPE_VIDEO_FORMAT_HEVC:
529
return VA_STATUS_ERROR_UNIMPLEMENTED;
532
VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)buf->data;
533
if (param->type == VAEncPackedHeaderSequence)
534
context->packed_header_type = param->type;
536
status = VA_STATUS_ERROR_UNIMPLEMENTED;
542
handleVAEncPackedHeaderDataBufferType(vlVaContext *context, vlVaBuffer *buf)
544
VAStatus status = VA_STATUS_SUCCESS;
546
if (context->packed_header_type != VAEncPackedHeaderSequence)
547
return VA_STATUS_ERROR_UNIMPLEMENTED;
549
switch (u_reduce_video_profile(context->templat.profile)) {
550
case PIPE_VIDEO_FORMAT_HEVC:
551
status = vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(context, buf);
562
vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
565
vlVaContext *context;
566
VAStatus vaStatus = VA_STATUS_SUCCESS;
569
unsigned slice_param_idx = 0;
572
return VA_STATUS_ERROR_INVALID_CONTEXT;
574
drv = VL_VA_DRIVER(ctx);
576
return VA_STATUS_ERROR_INVALID_CONTEXT;
578
mtx_lock(&drv->mutex);
579
context = handle_table_get(drv->htab, context_id);
581
mtx_unlock(&drv->mutex);
582
return VA_STATUS_ERROR_INVALID_CONTEXT;
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]);
589
mtx_unlock(&drv->mutex);
590
return VA_STATUS_ERROR_INVALID_BUFFER;
593
if (buf->type == VAProtectedSliceDataBufferType)
594
handleVAProtectedSliceDataBufferType(context, buf);
597
for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; ++i) {
598
vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
601
case VAPictureParameterBufferType:
602
vaStatus = handlePictureParameterBuffer(drv, context, buf);
605
case VAIQMatrixBufferType:
606
handleIQMatrixBuffer(context, buf);
609
case VASliceParameterBufferType:
610
handleSliceParameterBuffer(context, buf, slice_param_idx++);
613
case VASliceDataBufferType:
614
vaStatus = handleVASliceDataBufferType(context, buf);
617
case VAProcPipelineParameterBufferType:
618
vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf);
621
case VAEncSequenceParameterBufferType:
622
vaStatus = handleVAEncSequenceParameterBufferType(drv, context, buf);
625
case VAEncMiscParameterBufferType:
626
vaStatus = handleVAEncMiscParameterBufferType(context, buf);
629
case VAEncPictureParameterBufferType:
630
vaStatus = handleVAEncPictureParameterBufferType(drv, context, buf);
633
case VAEncSliceParameterBufferType:
634
vaStatus = handleVAEncSliceParameterBufferType(drv, context, buf);
637
case VAHuffmanTableBufferType:
638
vlVaHandleHuffmanTableBufferType(context, buf);
641
case VAEncPackedHeaderParameterBufferType:
642
handleVAEncPackedHeaderParameterBufferType(context, buf);
644
case VAEncPackedHeaderDataBufferType:
645
handleVAEncPackedHeaderDataBufferType(context, buf);
652
mtx_unlock(&drv->mutex);
658
vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
661
vlVaContext *context;
662
vlVaBuffer *coded_buf;
665
struct pipe_screen *screen;
667
bool realloc = false;
668
enum pipe_format format;
671
return VA_STATUS_ERROR_INVALID_CONTEXT;
673
drv = VL_VA_DRIVER(ctx);
675
return VA_STATUS_ERROR_INVALID_CONTEXT;
677
mtx_lock(&drv->mutex);
678
context = handle_table_get(drv->htab, context_id);
679
mtx_unlock(&drv->mutex);
681
return VA_STATUS_ERROR_INVALID_CONTEXT;
683
if (!context->decoder) {
684
if (context->templat.profile != PIPE_VIDEO_PROFILE_UNKNOWN)
685
return VA_STATUS_ERROR_INVALID_CONTEXT;
688
return VA_STATUS_SUCCESS;
691
mtx_lock(&drv->mutex);
692
surf = handle_table_get(drv->htab, context->target_id);
693
context->mpeg4.frame_num++;
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);
703
surf->templat.interlaced = screen->get_video_param(screen,
704
context->decoder->profile,
705
context->decoder->entrypoint,
706
PIPE_VIDEO_CAP_PREFERS_INTERLACED);
710
format = screen->get_video_param(screen, context->decoder->profile,
711
context->decoder->entrypoint,
712
PIPE_VIDEO_CAP_PREFERED_FORMAT);
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;
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;
727
} else if (context->mjpeg.sampling_factor != 0x221111) {
728
/* Not NV12 either */
729
mtx_unlock(&drv->mutex);
730
return VA_STATUS_ERROR_INVALID_SURFACE;
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;
739
surf->templat.bind &= ~PIPE_BIND_PROTECTED;
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;
752
struct pipe_video_buffer *old_buf = surf->buffer;
754
if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) {
755
mtx_unlock(&drv->mutex);
756
return VA_STATUS_ERROR_ALLOCATION_FAILED;
759
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
760
if (old_buf->interlaced) {
761
struct u_rect src_rect, dst_rect;
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);
771
/* Can't convert from progressive to interlaced yet */
772
mtx_unlock(&drv->mutex);
773
return VA_STATUS_ERROR_INVALID_SURFACE;
777
old_buf->destroy(old_buf);
778
context->target = surf->buffer;
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);
789
context->desc.base.input_format = surf->buffer->buffer_format;
790
context->desc.base.output_format = surf->encoder_format;
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;
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;
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;
817
context->first_single_submitted = false;
818
surf->force_flushed = true;
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;