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 34#include "vl/vl_vlc.h" 35#include "vl/vl_winsys.h" 36 37#include "va_private.h" 38 39VAStatus 40vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID render_target) 41{ 42 vlVaDriver *drv; 43 vlVaContext *context; 44 vlVaSurface *surf; 45 46 if (!ctx) 47 return VA_STATUS_ERROR_INVALID_CONTEXT; 48 49 drv = VL_VA_DRIVER(ctx); 50 if (!drv) 51 return VA_STATUS_ERROR_INVALID_CONTEXT; 52 53 mtx_lock(&drv->mutex); 54 context = handle_table_get(drv->htab, context_id); 55 if (!context) { 56 mtx_unlock(&drv->mutex); 57 return VA_STATUS_ERROR_INVALID_CONTEXT; 58 } 59 60 if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG12) { 61 context->desc.mpeg12.intra_matrix = NULL; 62 context->desc.mpeg12.non_intra_matrix = NULL; 63 } 64 65 surf = handle_table_get(drv->htab, render_target); 66 mtx_unlock(&drv->mutex); 67 if (!surf || !surf->buffer) 68 return VA_STATUS_ERROR_INVALID_SURFACE; 69 70 context->target_id = render_target; 71 surf->ctx = context_id; 72 context->target = surf->buffer; 73 context->mjpeg.sampling_factor = 0; 74 75 if (!context->decoder) { 76 77 /* VPP */ 78 if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN && 79 context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM && 80 context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM && 81 context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM && 82 context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM && 83 context->target->buffer_format != PIPE_FORMAT_NV12 && 84 context->target->buffer_format != PIPE_FORMAT_P016) 85 return VA_STATUS_ERROR_UNIMPLEMENTED; 86 87 return VA_STATUS_SUCCESS; 88 } 89 90 if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) 91 context->needs_begin_frame = true; 92 93 return VA_STATUS_SUCCESS; 94} 95 96void 97vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, 98 struct pipe_video_buffer **ref_frame) 99{ 100 vlVaSurface *surf = handle_table_get(drv->htab, surface_id); 101 if (surf) 102 *ref_frame = surf->buffer; 103 else 104 *ref_frame = NULL; 105} 106 107static VAStatus 108handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 109{ 110 VAStatus vaStatus = VA_STATUS_SUCCESS; 111 112 switch (u_reduce_video_profile(context->templat.profile)) { 113 case PIPE_VIDEO_FORMAT_MPEG12: 114 vlVaHandlePictureParameterBufferMPEG12(drv, context, buf); 115 break; 116 117 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 118 vlVaHandlePictureParameterBufferH264(drv, context, buf); 119 break; 120 121 case PIPE_VIDEO_FORMAT_VC1: 122 vlVaHandlePictureParameterBufferVC1(drv, context, buf); 123 break; 124 125 case PIPE_VIDEO_FORMAT_MPEG4: 126 vlVaHandlePictureParameterBufferMPEG4(drv, context, buf); 127 break; 128 129 case PIPE_VIDEO_FORMAT_HEVC: 130 vlVaHandlePictureParameterBufferHEVC(drv, context, buf); 131 break; 132 133 case PIPE_VIDEO_FORMAT_JPEG: 134 vlVaHandlePictureParameterBufferMJPEG(drv, context, buf); 135 break; 136 137 case PIPE_VIDEO_FORMAT_VP9: 138 vlVaHandlePictureParameterBufferVP9(drv, context, buf); 139 break; 140 141 default: 142 break; 143 } 144 145 /* Create the decoder once max_references is known. */ 146 if (!context->decoder) { 147 enum pipe_video_format format = 148 u_reduce_video_profile(context->templat.profile); 149 150 if (!context->target) 151 return VA_STATUS_ERROR_INVALID_CONTEXT; 152 153 if (context->templat.max_references == 0 && 154 format != PIPE_VIDEO_FORMAT_JPEG) 155 return VA_STATUS_ERROR_INVALID_BUFFER; 156 157 if (format == PIPE_VIDEO_FORMAT_MPEG4_AVC) 158 context->templat.level = u_get_h264_level(context->templat.width, 159 context->templat.height, &context->templat.max_references); 160 161 context->decoder = drv->pipe->create_video_codec(drv->pipe, 162 &context->templat); 163 164 if (!context->decoder) 165 return VA_STATUS_ERROR_ALLOCATION_FAILED; 166 167 context->needs_begin_frame = true; 168 } 169 170 return vaStatus; 171} 172 173static void 174handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf) 175{ 176 switch (u_reduce_video_profile(context->templat.profile)) { 177 case PIPE_VIDEO_FORMAT_MPEG12: 178 vlVaHandleIQMatrixBufferMPEG12(context, buf); 179 break; 180 181 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 182 vlVaHandleIQMatrixBufferH264(context, buf); 183 break; 184 185 case PIPE_VIDEO_FORMAT_MPEG4: 186 vlVaHandleIQMatrixBufferMPEG4(context, buf); 187 break; 188 189 case PIPE_VIDEO_FORMAT_HEVC: 190 vlVaHandleIQMatrixBufferHEVC(context, buf); 191 break; 192 193 case PIPE_VIDEO_FORMAT_JPEG: 194 vlVaHandleIQMatrixBufferMJPEG(context, buf); 195 break; 196 197 default: 198 break; 199 } 200} 201 202static void 203handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf) 204{ 205 switch (u_reduce_video_profile(context->templat.profile)) { 206 case PIPE_VIDEO_FORMAT_MPEG12: 207 vlVaHandleSliceParameterBufferMPEG12(context, buf); 208 break; 209 210 case PIPE_VIDEO_FORMAT_VC1: 211 vlVaHandleSliceParameterBufferVC1(context, buf); 212 break; 213 214 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 215 vlVaHandleSliceParameterBufferH264(context, buf); 216 break; 217 218 case PIPE_VIDEO_FORMAT_MPEG4: 219 vlVaHandleSliceParameterBufferMPEG4(context, buf); 220 break; 221 222 case PIPE_VIDEO_FORMAT_HEVC: 223 vlVaHandleSliceParameterBufferHEVC(context, buf); 224 break; 225 226 case PIPE_VIDEO_FORMAT_JPEG: 227 vlVaHandleSliceParameterBufferMJPEG(context, buf); 228 break; 229 230 case PIPE_VIDEO_FORMAT_VP9: 231 vlVaHandleSliceParameterBufferVP9(context, buf); 232 break; 233 234 default: 235 break; 236 } 237} 238 239static unsigned int 240bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits) 241{ 242 struct vl_vlc vlc = {0}; 243 int i; 244 245 /* search the first 64 bytes for a startcode */ 246 vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size); 247 for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= bits; ++i) { 248 if (vl_vlc_peekbits(&vlc, bits) == code) 249 return 1; 250 vl_vlc_eatbits(&vlc, 8); 251 vl_vlc_fillbits(&vlc); 252 } 253 254 return 0; 255} 256 257static void 258handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) 259{ 260 enum pipe_video_format format; 261 unsigned num_buffers = 0; 262 void * const *buffers[3]; 263 unsigned sizes[3]; 264 static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 }; 265 static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 }; 266 static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d }; 267 static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 }; 268 269 format = u_reduce_video_profile(context->templat.profile); 270 switch (format) { 271 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 272 if (bufHasStartcode(buf, 0x000001, 24)) 273 break; 274 275 buffers[num_buffers] = (void *const)&start_code_h264; 276 sizes[num_buffers++] = sizeof(start_code_h264); 277 break; 278 case PIPE_VIDEO_FORMAT_HEVC: 279 if (bufHasStartcode(buf, 0x000001, 24)) 280 break; 281 282 buffers[num_buffers] = (void *const)&start_code_h265; 283 sizes[num_buffers++] = sizeof(start_code_h265); 284 break; 285 case PIPE_VIDEO_FORMAT_VC1: 286 if (bufHasStartcode(buf, 0x0000010d, 32) || 287 bufHasStartcode(buf, 0x0000010c, 32) || 288 bufHasStartcode(buf, 0x0000010b, 32)) 289 break; 290 291 if (context->decoder->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) { 292 buffers[num_buffers] = (void *const)&start_code_vc1; 293 sizes[num_buffers++] = sizeof(start_code_vc1); 294 } 295 break; 296 case PIPE_VIDEO_FORMAT_MPEG4: 297 if (bufHasStartcode(buf, 0x000001, 24)) 298 break; 299 300 vlVaDecoderFixMPEG4Startcode(context); 301 buffers[num_buffers] = (void *)context->mpeg4.start_code; 302 sizes[num_buffers++] = context->mpeg4.start_code_size; 303 break; 304 case PIPE_VIDEO_FORMAT_JPEG: 305 vlVaGetJpegSliceHeader(context); 306 buffers[num_buffers] = (void *)context->mjpeg.slice_header; 307 sizes[num_buffers++] = context->mjpeg.slice_header_size; 308 break; 309 case PIPE_VIDEO_FORMAT_VP9: 310 vlVaDecoderVP9BitstreamHeader(context, buf); 311 break; 312 default: 313 break; 314 } 315 316 buffers[num_buffers] = buf->data; 317 sizes[num_buffers] = buf->size; 318 ++num_buffers; 319 320 if (format == PIPE_VIDEO_FORMAT_JPEG) { 321 buffers[num_buffers] = (void *const)&eoi_jpeg; 322 sizes[num_buffers++] = sizeof(eoi_jpeg); 323 } 324 325 if (context->needs_begin_frame) { 326 context->decoder->begin_frame(context->decoder, context->target, 327 &context->desc.base); 328 context->needs_begin_frame = false; 329 } 330 context->decoder->decode_bitstream(context->decoder, context->target, &context->desc.base, 331 num_buffers, (const void * const*)buffers, sizes); 332} 333 334static VAStatus 335handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) 336{ 337 VAStatus status = VA_STATUS_SUCCESS; 338 339 switch (u_reduce_video_profile(context->templat.profile)) { 340 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 341 status = vlVaHandleVAEncMiscParameterTypeRateControlH264(context, misc); 342 break; 343 344 case PIPE_VIDEO_FORMAT_HEVC: 345 status = vlVaHandleVAEncMiscParameterTypeRateControlHEVC(context, misc); 346 break; 347 348 default: 349 break; 350 } 351 352 return status; 353} 354 355static VAStatus 356handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc) 357{ 358 VAStatus status = VA_STATUS_SUCCESS; 359 360 switch (u_reduce_video_profile(context->templat.profile)) { 361 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 362 status = vlVaHandleVAEncMiscParameterTypeFrameRateH264(context, misc); 363 break; 364 365 case PIPE_VIDEO_FORMAT_HEVC: 366 status = vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(context, misc); 367 break; 368 369 default: 370 break; 371 } 372 373 return status; 374} 375 376static VAStatus 377handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 378{ 379 VAStatus status = VA_STATUS_SUCCESS; 380 381 switch (u_reduce_video_profile(context->templat.profile)) { 382 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 383 status = vlVaHandleVAEncSequenceParameterBufferTypeH264(drv, context, buf); 384 break; 385 386 case PIPE_VIDEO_FORMAT_HEVC: 387 status = vlVaHandleVAEncSequenceParameterBufferTypeHEVC(drv, context, buf); 388 break; 389 390 default: 391 break; 392 } 393 394 return status; 395} 396 397static VAStatus 398handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) 399{ 400 VAStatus vaStatus = VA_STATUS_SUCCESS; 401 VAEncMiscParameterBuffer *misc; 402 misc = buf->data; 403 404 switch (misc->type) { 405 case VAEncMiscParameterTypeRateControl: 406 vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); 407 break; 408 409 case VAEncMiscParameterTypeFrameRate: 410 vaStatus = handleVAEncMiscParameterTypeFrameRate(context, misc); 411 break; 412 413 default: 414 break; 415 } 416 417 return vaStatus; 418} 419 420static VAStatus 421handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 422{ 423 VAStatus status = VA_STATUS_SUCCESS; 424 425 switch (u_reduce_video_profile(context->templat.profile)) { 426 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 427 status = vlVaHandleVAEncPictureParameterBufferTypeH264(drv, context, buf); 428 break; 429 430 case PIPE_VIDEO_FORMAT_HEVC: 431 status = vlVaHandleVAEncPictureParameterBufferTypeHEVC(drv, context, buf); 432 break; 433 434 default: 435 break; 436 } 437 438 return status; 439} 440 441static VAStatus 442handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 443{ 444 VAStatus status = VA_STATUS_SUCCESS; 445 446 switch (u_reduce_video_profile(context->templat.profile)) { 447 case PIPE_VIDEO_FORMAT_MPEG4_AVC: 448 status = vlVaHandleVAEncSliceParameterBufferTypeH264(drv, context, buf); 449 break; 450 451 case PIPE_VIDEO_FORMAT_HEVC: 452 status = vlVaHandleVAEncSliceParameterBufferTypeHEVC(drv, context, buf); 453 break; 454 455 default: 456 break; 457 } 458 459 return status; 460} 461 462VAStatus 463vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers) 464{ 465 vlVaDriver *drv; 466 vlVaContext *context; 467 VAStatus vaStatus = VA_STATUS_SUCCESS; 468 469 unsigned i; 470 471 if (!ctx) 472 return VA_STATUS_ERROR_INVALID_CONTEXT; 473 474 drv = VL_VA_DRIVER(ctx); 475 if (!drv) 476 return VA_STATUS_ERROR_INVALID_CONTEXT; 477 478 mtx_lock(&drv->mutex); 479 context = handle_table_get(drv->htab, context_id); 480 if (!context) { 481 mtx_unlock(&drv->mutex); 482 return VA_STATUS_ERROR_INVALID_CONTEXT; 483 } 484 485 for (i = 0; i < num_buffers; ++i) { 486 vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]); 487 if (!buf) { 488 mtx_unlock(&drv->mutex); 489 return VA_STATUS_ERROR_INVALID_BUFFER; 490 } 491 492 switch (buf->type) { 493 case VAPictureParameterBufferType: 494 vaStatus = handlePictureParameterBuffer(drv, context, buf); 495 break; 496 497 case VAIQMatrixBufferType: 498 handleIQMatrixBuffer(context, buf); 499 break; 500 501 case VASliceParameterBufferType: 502 handleSliceParameterBuffer(context, buf); 503 break; 504 505 case VASliceDataBufferType: 506 handleVASliceDataBufferType(context, buf); 507 break; 508 case VAProcPipelineParameterBufferType: 509 vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf); 510 break; 511 512 case VAEncSequenceParameterBufferType: 513 vaStatus = handleVAEncSequenceParameterBufferType(drv, context, buf); 514 break; 515 516 case VAEncMiscParameterBufferType: 517 vaStatus = handleVAEncMiscParameterBufferType(context, buf); 518 break; 519 520 case VAEncPictureParameterBufferType: 521 vaStatus = handleVAEncPictureParameterBufferType(drv, context, buf); 522 break; 523 524 case VAEncSliceParameterBufferType: 525 vaStatus = handleVAEncSliceParameterBufferType(drv, context, buf); 526 break; 527 528 case VAHuffmanTableBufferType: 529 vlVaHandleHuffmanTableBufferType(context, buf); 530 break; 531 532 default: 533 break; 534 } 535 } 536 mtx_unlock(&drv->mutex); 537 538 return vaStatus; 539} 540 541VAStatus 542vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) 543{ 544 vlVaDriver *drv; 545 vlVaContext *context; 546 vlVaBuffer *coded_buf; 547 vlVaSurface *surf; 548 void *feedback; 549 struct pipe_screen *screen; 550 bool supported; 551 bool realloc = false; 552 enum pipe_format format; 553 554 if (!ctx) 555 return VA_STATUS_ERROR_INVALID_CONTEXT; 556 557 drv = VL_VA_DRIVER(ctx); 558 if (!drv) 559 return VA_STATUS_ERROR_INVALID_CONTEXT; 560 561 mtx_lock(&drv->mutex); 562 context = handle_table_get(drv->htab, context_id); 563 mtx_unlock(&drv->mutex); 564 if (!context) 565 return VA_STATUS_ERROR_INVALID_CONTEXT; 566 567 if (!context->decoder) { 568 if (context->templat.profile != PIPE_VIDEO_PROFILE_UNKNOWN) 569 return VA_STATUS_ERROR_INVALID_CONTEXT; 570 571 /* VPP */ 572 return VA_STATUS_SUCCESS; 573 } 574 575 mtx_lock(&drv->mutex); 576 surf = handle_table_get(drv->htab, context->target_id); 577 context->mpeg4.frame_num++; 578 579 screen = context->decoder->context->screen; 580 supported = screen->get_video_param(screen, context->decoder->profile, 581 context->decoder->entrypoint, 582 surf->buffer->interlaced ? 583 PIPE_VIDEO_CAP_SUPPORTS_INTERLACED : 584 PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE); 585 586 if (!supported) { 587 surf->templat.interlaced = screen->get_video_param(screen, 588 context->decoder->profile, 589 context->decoder->entrypoint, 590 PIPE_VIDEO_CAP_PREFERS_INTERLACED); 591 realloc = true; 592 } 593 594 format = screen->get_video_param(screen, context->decoder->profile, 595 PIPE_VIDEO_ENTRYPOINT_BITSTREAM, 596 PIPE_VIDEO_CAP_PREFERED_FORMAT); 597 598 if (surf->buffer->buffer_format != format && 599 surf->buffer->buffer_format == PIPE_FORMAT_NV12) { 600 /* check originally as NV12 only */ 601 surf->templat.buffer_format = format; 602 realloc = true; 603 } 604 605 if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_JPEG && 606 surf->buffer->buffer_format == PIPE_FORMAT_NV12) { 607 if (context->mjpeg.sampling_factor == 0x211111 || 608 context->mjpeg.sampling_factor == 0x221212) { 609 surf->templat.buffer_format = PIPE_FORMAT_YUYV; 610 realloc = true; 611 } else if (context->mjpeg.sampling_factor != 0x221111) { 612 /* Not NV12 either */ 613 mtx_unlock(&drv->mutex); 614 return VA_STATUS_ERROR_INVALID_SURFACE; 615 } 616 } 617 618 if (realloc) { 619 struct pipe_video_buffer *old_buf = surf->buffer; 620 621 if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat) != VA_STATUS_SUCCESS) { 622 mtx_unlock(&drv->mutex); 623 return VA_STATUS_ERROR_ALLOCATION_FAILED; 624 } 625 626 if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { 627 if (old_buf->interlaced) { 628 struct u_rect src_rect, dst_rect; 629 630 dst_rect.x0 = src_rect.x0 = 0; 631 dst_rect.y0 = src_rect.y0 = 0; 632 dst_rect.x1 = src_rect.x1 = surf->templat.width; 633 dst_rect.y1 = src_rect.y1 = surf->templat.height; 634 vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor, 635 old_buf, surf->buffer, 636 &src_rect, &dst_rect, VL_COMPOSITOR_WEAVE); 637 } else { 638 /* Can't convert from progressive to interlaced yet */ 639 mtx_unlock(&drv->mutex); 640 return VA_STATUS_ERROR_INVALID_SURFACE; 641 } 642 } 643 644 old_buf->destroy(old_buf); 645 context->target = surf->buffer; 646 } 647 648 if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { 649 coded_buf = context->coded_buf; 650 if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { 651 getEncParamPresetH264(context); 652 context->desc.h264enc.frame_num_cnt++; 653 } else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC) 654 getEncParamPresetH265(context); 655 context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); 656 context->decoder->encode_bitstream(context->decoder, context->target, 657 coded_buf->derived_surface.resource, &feedback); 658 surf->feedback = feedback; 659 surf->coded_buf = coded_buf; 660 } 661 662 context->decoder->end_frame(context->decoder, context->target, &context->desc.base); 663 if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && 664 u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { 665 int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; 666 int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; 667 surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; 668 surf->force_flushed = false; 669 if (context->first_single_submitted) { 670 context->decoder->flush(context->decoder); 671 context->first_single_submitted = false; 672 surf->force_flushed = true; 673 } 674 if (p_remain_in_idr == 1) { 675 if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { 676 context->decoder->flush(context->decoder); 677 context->first_single_submitted = true; 678 } 679 else 680 context->first_single_submitted = false; 681 surf->force_flushed = true; 682 } 683 } else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && 684 u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC) 685 context->desc.h265enc.frame_num++; 686 mtx_unlock(&drv->mutex); 687 return VA_STATUS_SUCCESS; 688} 689