Path: blob/21.2-virgl/src/gallium/frontends/va/picture.c
4561 views
/**************************************************************************1*2* Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.3* Copyright 2014 Advanced Micro Devices, Inc.4* All Rights Reserved.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the8* "Software"), to deal in the Software without restriction, including9* without limitation the rights to use, copy, modify, merge, publish,10* distribute, sub license, and/or sell copies of the Software, and to11* permit persons to whom the Software is furnished to do so, subject to12* the following conditions:13*14* The above copyright notice and this permission notice (including the15* next paragraph) shall be included in all copies or substantial portions16* of the Software.17*18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS19* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF20* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.21* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR22* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,23* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE24* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.25*26**************************************************************************/2728#include "pipe/p_video_codec.h"2930#include "util/u_handle_table.h"31#include "util/u_video.h"32#include "util/u_memory.h"3334#include "vl/vl_vlc.h"35#include "vl/vl_winsys.h"3637#include "va_private.h"3839VAStatus40vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID render_target)41{42vlVaDriver *drv;43vlVaContext *context;44vlVaSurface *surf;4546if (!ctx)47return VA_STATUS_ERROR_INVALID_CONTEXT;4849drv = VL_VA_DRIVER(ctx);50if (!drv)51return VA_STATUS_ERROR_INVALID_CONTEXT;5253mtx_lock(&drv->mutex);54context = handle_table_get(drv->htab, context_id);55if (!context) {56mtx_unlock(&drv->mutex);57return VA_STATUS_ERROR_INVALID_CONTEXT;58}5960if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG12) {61context->desc.mpeg12.intra_matrix = NULL;62context->desc.mpeg12.non_intra_matrix = NULL;63}6465surf = handle_table_get(drv->htab, render_target);66mtx_unlock(&drv->mutex);67if (!surf || !surf->buffer)68return VA_STATUS_ERROR_INVALID_SURFACE;6970context->target_id = render_target;71surf->ctx = context_id;72context->target = surf->buffer;73context->mjpeg.sampling_factor = 0;7475if (!context->decoder) {7677/* VPP */78if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN &&79context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&80context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&81context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&82context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM &&83context->target->buffer_format != PIPE_FORMAT_NV12 &&84context->target->buffer_format != PIPE_FORMAT_P010 &&85context->target->buffer_format != PIPE_FORMAT_P016)86return VA_STATUS_ERROR_UNIMPLEMENTED;8788return VA_STATUS_SUCCESS;89}9091if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE)92context->needs_begin_frame = true;9394return VA_STATUS_SUCCESS;95}9697void98vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,99struct pipe_video_buffer **ref_frame)100{101vlVaSurface *surf = handle_table_get(drv->htab, surface_id);102if (surf)103*ref_frame = surf->buffer;104else105*ref_frame = NULL;106}107108static VAStatus109handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)110{111VAStatus vaStatus = VA_STATUS_SUCCESS;112enum pipe_video_format format =113u_reduce_video_profile(context->templat.profile);114115switch (format) {116case PIPE_VIDEO_FORMAT_MPEG12:117vlVaHandlePictureParameterBufferMPEG12(drv, context, buf);118break;119120case PIPE_VIDEO_FORMAT_MPEG4_AVC:121vlVaHandlePictureParameterBufferH264(drv, context, buf);122break;123124case PIPE_VIDEO_FORMAT_VC1:125vlVaHandlePictureParameterBufferVC1(drv, context, buf);126break;127128case PIPE_VIDEO_FORMAT_MPEG4:129vlVaHandlePictureParameterBufferMPEG4(drv, context, buf);130break;131132case PIPE_VIDEO_FORMAT_HEVC:133vlVaHandlePictureParameterBufferHEVC(drv, context, buf);134break;135136case PIPE_VIDEO_FORMAT_JPEG:137vlVaHandlePictureParameterBufferMJPEG(drv, context, buf);138break;139140case PIPE_VIDEO_FORMAT_VP9:141vlVaHandlePictureParameterBufferVP9(drv, context, buf);142break;143144default:145break;146}147148/* Create the decoder once max_references is known. */149if (!context->decoder) {150if (!context->target)151return VA_STATUS_ERROR_INVALID_CONTEXT;152153if (format == PIPE_VIDEO_FORMAT_MPEG4_AVC)154context->templat.level = u_get_h264_level(context->templat.width,155context->templat.height, &context->templat.max_references);156157context->decoder = drv->pipe->create_video_codec(drv->pipe,158&context->templat);159160if (!context->decoder)161return VA_STATUS_ERROR_ALLOCATION_FAILED;162163context->needs_begin_frame = true;164}165166if (format == PIPE_VIDEO_FORMAT_VP9) {167context->decoder->width =168context->desc.vp9.picture_parameter.frame_width;169context->decoder->height =170context->desc.vp9.picture_parameter.frame_height;171}172173return vaStatus;174}175176static void177handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)178{179switch (u_reduce_video_profile(context->templat.profile)) {180case PIPE_VIDEO_FORMAT_MPEG12:181vlVaHandleIQMatrixBufferMPEG12(context, buf);182break;183184case PIPE_VIDEO_FORMAT_MPEG4_AVC:185vlVaHandleIQMatrixBufferH264(context, buf);186break;187188case PIPE_VIDEO_FORMAT_MPEG4:189vlVaHandleIQMatrixBufferMPEG4(context, buf);190break;191192case PIPE_VIDEO_FORMAT_HEVC:193vlVaHandleIQMatrixBufferHEVC(context, buf);194break;195196case PIPE_VIDEO_FORMAT_JPEG:197vlVaHandleIQMatrixBufferMJPEG(context, buf);198break;199200default:201break;202}203}204205static void206handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf)207{208switch (u_reduce_video_profile(context->templat.profile)) {209case PIPE_VIDEO_FORMAT_MPEG12:210vlVaHandleSliceParameterBufferMPEG12(context, buf);211break;212213case PIPE_VIDEO_FORMAT_VC1:214vlVaHandleSliceParameterBufferVC1(context, buf);215break;216217case PIPE_VIDEO_FORMAT_MPEG4_AVC:218vlVaHandleSliceParameterBufferH264(context, buf);219break;220221case PIPE_VIDEO_FORMAT_MPEG4:222vlVaHandleSliceParameterBufferMPEG4(context, buf);223break;224225case PIPE_VIDEO_FORMAT_HEVC:226vlVaHandleSliceParameterBufferHEVC(context, buf);227break;228229case PIPE_VIDEO_FORMAT_JPEG:230vlVaHandleSliceParameterBufferMJPEG(context, buf);231break;232233case PIPE_VIDEO_FORMAT_VP9:234vlVaHandleSliceParameterBufferVP9(context, buf);235break;236237default:238break;239}240}241242static unsigned int243bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)244{245struct vl_vlc vlc = {0};246int i;247248/* search the first 64 bytes for a startcode */249vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size);250for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= bits; ++i) {251if (vl_vlc_peekbits(&vlc, bits) == code)252return 1;253vl_vlc_eatbits(&vlc, 8);254vl_vlc_fillbits(&vlc);255}256257return 0;258}259260static void261handleVAProtectedSliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)262{263uint8_t* encrypted_data = (uint8_t*) buf->data;264265unsigned int drm_key_size = buf->size;266267context->desc.base.decrypt_key = CALLOC(1, drm_key_size);268memcpy(context->desc.base.decrypt_key, encrypted_data, drm_key_size);269context->desc.base.protected_playback = true;270}271272static void273handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)274{275enum pipe_video_format format = u_reduce_video_profile(context->templat.profile);276unsigned num_buffers = 0;277void * const *buffers[3];278unsigned sizes[3];279static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 };280static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 };281static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d };282static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 };283284format = u_reduce_video_profile(context->templat.profile);285if (!context->desc.base.protected_playback) {286switch (format) {287case PIPE_VIDEO_FORMAT_MPEG4_AVC:288if (bufHasStartcode(buf, 0x000001, 24))289break;290291buffers[num_buffers] = (void *const)&start_code_h264;292sizes[num_buffers++] = sizeof(start_code_h264);293break;294case PIPE_VIDEO_FORMAT_HEVC:295if (bufHasStartcode(buf, 0x000001, 24))296break;297298buffers[num_buffers] = (void *const)&start_code_h265;299sizes[num_buffers++] = sizeof(start_code_h265);300break;301case PIPE_VIDEO_FORMAT_VC1:302if (bufHasStartcode(buf, 0x0000010d, 32) ||303bufHasStartcode(buf, 0x0000010c, 32) ||304bufHasStartcode(buf, 0x0000010b, 32))305break;306307if (context->decoder->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) {308buffers[num_buffers] = (void *const)&start_code_vc1;309sizes[num_buffers++] = sizeof(start_code_vc1);310}311break;312case PIPE_VIDEO_FORMAT_MPEG4:313if (bufHasStartcode(buf, 0x000001, 24))314break;315316vlVaDecoderFixMPEG4Startcode(context);317buffers[num_buffers] = (void *)context->mpeg4.start_code;318sizes[num_buffers++] = context->mpeg4.start_code_size;319break;320case PIPE_VIDEO_FORMAT_JPEG:321vlVaGetJpegSliceHeader(context);322buffers[num_buffers] = (void *)context->mjpeg.slice_header;323sizes[num_buffers++] = context->mjpeg.slice_header_size;324break;325case PIPE_VIDEO_FORMAT_VP9:326vlVaDecoderVP9BitstreamHeader(context, buf);327break;328default:329break;330}331}332333if (context->desc.base.protected_playback && PIPE_VIDEO_FORMAT_VP9 == format){334vlVaDecoderVP9BitstreamHeader(context, buf);335buffers[num_buffers] = buf->data + context->desc.vp9.picture_parameter.frame_header_length_in_bytes;336sizes[num_buffers] = buf->size - context->desc.vp9.picture_parameter.frame_header_length_in_bytes;337++num_buffers;338} else {339buffers[num_buffers] = buf->data;340sizes[num_buffers] = buf->size;341++num_buffers;342}343344if (format == PIPE_VIDEO_FORMAT_JPEG) {345buffers[num_buffers] = (void *const)&eoi_jpeg;346sizes[num_buffers++] = sizeof(eoi_jpeg);347}348349if (context->needs_begin_frame) {350context->decoder->begin_frame(context->decoder, context->target,351&context->desc.base);352context->needs_begin_frame = false;353}354context->decoder->decode_bitstream(context->decoder, context->target, &context->desc.base,355num_buffers, (const void * const*)buffers, sizes);356}357358static VAStatus359handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc)360{361VAStatus status = VA_STATUS_SUCCESS;362363switch (u_reduce_video_profile(context->templat.profile)) {364case PIPE_VIDEO_FORMAT_MPEG4_AVC:365status = vlVaHandleVAEncMiscParameterTypeRateControlH264(context, misc);366break;367368case PIPE_VIDEO_FORMAT_HEVC:369status = vlVaHandleVAEncMiscParameterTypeRateControlHEVC(context, misc);370break;371372default:373break;374}375376return status;377}378379static VAStatus380handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc)381{382VAStatus status = VA_STATUS_SUCCESS;383384switch (u_reduce_video_profile(context->templat.profile)) {385case PIPE_VIDEO_FORMAT_MPEG4_AVC:386status = vlVaHandleVAEncMiscParameterTypeFrameRateH264(context, misc);387break;388389case PIPE_VIDEO_FORMAT_HEVC:390status = vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(context, misc);391break;392393default:394break;395}396397return status;398}399400static VAStatus401handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)402{403VAStatus status = VA_STATUS_SUCCESS;404405switch (u_reduce_video_profile(context->templat.profile)) {406case PIPE_VIDEO_FORMAT_MPEG4_AVC:407status = vlVaHandleVAEncSequenceParameterBufferTypeH264(drv, context, buf);408break;409410case PIPE_VIDEO_FORMAT_HEVC:411status = vlVaHandleVAEncSequenceParameterBufferTypeHEVC(drv, context, buf);412break;413414default:415break;416}417418return status;419}420421static VAStatus422handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)423{424VAStatus vaStatus = VA_STATUS_SUCCESS;425VAEncMiscParameterBuffer *misc;426misc = buf->data;427428switch (misc->type) {429case VAEncMiscParameterTypeRateControl:430vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc);431break;432433case VAEncMiscParameterTypeFrameRate:434vaStatus = handleVAEncMiscParameterTypeFrameRate(context, misc);435break;436437default:438break;439}440441return vaStatus;442}443444static VAStatus445handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)446{447VAStatus status = VA_STATUS_SUCCESS;448449switch (u_reduce_video_profile(context->templat.profile)) {450case PIPE_VIDEO_FORMAT_MPEG4_AVC:451status = vlVaHandleVAEncPictureParameterBufferTypeH264(drv, context, buf);452break;453454case PIPE_VIDEO_FORMAT_HEVC:455status = vlVaHandleVAEncPictureParameterBufferTypeHEVC(drv, context, buf);456break;457458default:459break;460}461462return status;463}464465static VAStatus466handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)467{468VAStatus status = VA_STATUS_SUCCESS;469470switch (u_reduce_video_profile(context->templat.profile)) {471case PIPE_VIDEO_FORMAT_MPEG4_AVC:472status = vlVaHandleVAEncSliceParameterBufferTypeH264(drv, context, buf);473break;474475case PIPE_VIDEO_FORMAT_HEVC:476status = vlVaHandleVAEncSliceParameterBufferTypeHEVC(drv, context, buf);477break;478479default:480break;481}482483return status;484}485486static VAStatus487handleVAEncPackedHeaderParameterBufferType(vlVaContext *context, vlVaBuffer *buf)488{489VAStatus status = VA_STATUS_SUCCESS;490491switch (u_reduce_video_profile(context->templat.profile)) {492case PIPE_VIDEO_FORMAT_HEVC:493break;494495default:496return VA_STATUS_ERROR_UNIMPLEMENTED;497}498499VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)buf->data;500if (param->type == VAEncPackedHeaderSequence)501context->packed_header_type = param->type;502else503status = VA_STATUS_ERROR_UNIMPLEMENTED;504505return status;506}507508static VAStatus509handleVAEncPackedHeaderDataBufferType(vlVaContext *context, vlVaBuffer *buf)510{511VAStatus status = VA_STATUS_SUCCESS;512513if (context->packed_header_type != VAEncPackedHeaderSequence)514return VA_STATUS_ERROR_UNIMPLEMENTED;515516switch (u_reduce_video_profile(context->templat.profile)) {517case PIPE_VIDEO_FORMAT_HEVC:518status = vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(context, buf);519break;520521default:522break;523}524525return status;526}527528VAStatus529vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)530{531vlVaDriver *drv;532vlVaContext *context;533VAStatus vaStatus = VA_STATUS_SUCCESS;534535unsigned i;536537if (!ctx)538return VA_STATUS_ERROR_INVALID_CONTEXT;539540drv = VL_VA_DRIVER(ctx);541if (!drv)542return VA_STATUS_ERROR_INVALID_CONTEXT;543544mtx_lock(&drv->mutex);545context = handle_table_get(drv->htab, context_id);546if (!context) {547mtx_unlock(&drv->mutex);548return VA_STATUS_ERROR_INVALID_CONTEXT;549}550551/* Always process VAProtectedSliceDataBufferType first because it changes the state */552for (i = 0; i < num_buffers; ++i) {553vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);554if (!buf) {555mtx_unlock(&drv->mutex);556return VA_STATUS_ERROR_INVALID_BUFFER;557}558559if (buf->type == VAProtectedSliceDataBufferType)560handleVAProtectedSliceDataBufferType(context, buf);561}562563for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; ++i) {564vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);565566switch (buf->type) {567case VAPictureParameterBufferType:568vaStatus = handlePictureParameterBuffer(drv, context, buf);569break;570571case VAIQMatrixBufferType:572handleIQMatrixBuffer(context, buf);573break;574575case VASliceParameterBufferType:576handleSliceParameterBuffer(context, buf);577break;578579case VASliceDataBufferType:580handleVASliceDataBufferType(context, buf);581break;582583case VAProcPipelineParameterBufferType:584vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf);585break;586587case VAEncSequenceParameterBufferType:588vaStatus = handleVAEncSequenceParameterBufferType(drv, context, buf);589break;590591case VAEncMiscParameterBufferType:592vaStatus = handleVAEncMiscParameterBufferType(context, buf);593break;594595case VAEncPictureParameterBufferType:596vaStatus = handleVAEncPictureParameterBufferType(drv, context, buf);597break;598599case VAEncSliceParameterBufferType:600vaStatus = handleVAEncSliceParameterBufferType(drv, context, buf);601break;602603case VAHuffmanTableBufferType:604vlVaHandleHuffmanTableBufferType(context, buf);605break;606607case VAEncPackedHeaderParameterBufferType:608handleVAEncPackedHeaderParameterBufferType(context, buf);609break;610case VAEncPackedHeaderDataBufferType:611handleVAEncPackedHeaderDataBufferType(context, buf);612break;613614default:615break;616}617}618mtx_unlock(&drv->mutex);619620return vaStatus;621}622623VAStatus624vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)625{626vlVaDriver *drv;627vlVaContext *context;628vlVaBuffer *coded_buf;629vlVaSurface *surf;630void *feedback;631struct pipe_screen *screen;632bool supported;633bool realloc = false;634enum pipe_format format;635636if (!ctx)637return VA_STATUS_ERROR_INVALID_CONTEXT;638639drv = VL_VA_DRIVER(ctx);640if (!drv)641return VA_STATUS_ERROR_INVALID_CONTEXT;642643mtx_lock(&drv->mutex);644context = handle_table_get(drv->htab, context_id);645mtx_unlock(&drv->mutex);646if (!context)647return VA_STATUS_ERROR_INVALID_CONTEXT;648649if (!context->decoder) {650if (context->templat.profile != PIPE_VIDEO_PROFILE_UNKNOWN)651return VA_STATUS_ERROR_INVALID_CONTEXT;652653/* VPP */654return VA_STATUS_SUCCESS;655}656657mtx_lock(&drv->mutex);658surf = handle_table_get(drv->htab, context->target_id);659context->mpeg4.frame_num++;660661screen = context->decoder->context->screen;662supported = screen->get_video_param(screen, context->decoder->profile,663context->decoder->entrypoint,664surf->buffer->interlaced ?665PIPE_VIDEO_CAP_SUPPORTS_INTERLACED :666PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);667668if (!supported) {669surf->templat.interlaced = screen->get_video_param(screen,670context->decoder->profile,671context->decoder->entrypoint,672PIPE_VIDEO_CAP_PREFERS_INTERLACED);673realloc = true;674}675676format = screen->get_video_param(screen, context->decoder->profile,677context->decoder->entrypoint,678PIPE_VIDEO_CAP_PREFERED_FORMAT);679680if (surf->buffer->buffer_format != format &&681surf->buffer->buffer_format == PIPE_FORMAT_NV12) {682/* check originally as NV12 only */683surf->templat.buffer_format = format;684realloc = true;685}686687if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_JPEG &&688surf->buffer->buffer_format == PIPE_FORMAT_NV12) {689if (context->mjpeg.sampling_factor == 0x211111 ||690context->mjpeg.sampling_factor == 0x221212) {691surf->templat.buffer_format = PIPE_FORMAT_YUYV;692realloc = true;693} else if (context->mjpeg.sampling_factor != 0x221111) {694/* Not NV12 either */695mtx_unlock(&drv->mutex);696return VA_STATUS_ERROR_INVALID_SURFACE;697}698}699700if ((bool)(surf->templat.bind & PIPE_BIND_PROTECTED) != context->desc.base.protected_playback) {701if (context->desc.base.protected_playback) {702surf->templat.bind |= PIPE_BIND_PROTECTED;703}704else705surf->templat.bind &= ~PIPE_BIND_PROTECTED;706realloc = true;707}708709if (realloc) {710struct pipe_video_buffer *old_buf = surf->buffer;711712if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) {713mtx_unlock(&drv->mutex);714return VA_STATUS_ERROR_ALLOCATION_FAILED;715}716717if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {718if (old_buf->interlaced) {719struct u_rect src_rect, dst_rect;720721dst_rect.x0 = src_rect.x0 = 0;722dst_rect.y0 = src_rect.y0 = 0;723dst_rect.x1 = src_rect.x1 = surf->templat.width;724dst_rect.y1 = src_rect.y1 = surf->templat.height;725vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,726old_buf, surf->buffer,727&src_rect, &dst_rect, VL_COMPOSITOR_WEAVE);728} else {729/* Can't convert from progressive to interlaced yet */730mtx_unlock(&drv->mutex);731return VA_STATUS_ERROR_INVALID_SURFACE;732}733}734735old_buf->destroy(old_buf);736context->target = surf->buffer;737}738739if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {740coded_buf = context->coded_buf;741if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {742getEncParamPresetH264(context);743context->desc.h264enc.frame_num_cnt++;744} else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)745getEncParamPresetH265(context);746context->decoder->begin_frame(context->decoder, context->target, &context->desc.base);747context->decoder->encode_bitstream(context->decoder, context->target,748coded_buf->derived_surface.resource, &feedback);749surf->feedback = feedback;750surf->coded_buf = coded_buf;751}752753context->decoder->end_frame(context->decoder, context->target, &context->desc.base);754if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&755u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {756int idr_period = context->desc.h264enc.gop_size / context->gop_coeff;757int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num;758surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt;759surf->force_flushed = false;760if (context->first_single_submitted) {761context->decoder->flush(context->decoder);762context->first_single_submitted = false;763surf->force_flushed = true;764}765if (p_remain_in_idr == 1) {766if ((context->desc.h264enc.frame_num_cnt % 2) != 0) {767context->decoder->flush(context->decoder);768context->first_single_submitted = true;769}770else771context->first_single_submitted = false;772surf->force_flushed = true;773}774} else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&775u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)776context->desc.h265enc.frame_num++;777mtx_unlock(&drv->mutex);778return VA_STATUS_SUCCESS;779}780781782