diff --git a/src/gallium/frontends/va/picture_h264_enc.c b/src/gallium/frontends/va/picture_h264_enc.c index fc9a23e1b51..ac691772293 100644 --- a/src/gallium/frontends/va/picture_h264_enc.c +++ b/src/gallium/frontends/va/picture_h264_enc.c @@ -72,6 +72,12 @@ vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *cont if (!context->desc.h264enc.dpb[i].id) { assert(!surf->is_dpb); surf->is_dpb = true; + if (surf->buffer) { + surf->buffer->destroy(surf->buffer); + surf->buffer = NULL; + } + if (context->decoder && context->decoder->create_dpb_buffer) + surf->buffer = context->decoder->create_dpb_buffer(context->decoder, &context->desc.base, &surf->templat); vlVaSetSurfaceContext(drv, surf, context); context->desc.h264enc.dpb_size++; break; @@ -84,6 +90,7 @@ vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *cont context->desc.h264enc.dpb[i].frame_idx = h264->CurrPic.frame_idx; context->desc.h264enc.dpb[i].pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; context->desc.h264enc.dpb[i].is_ltr = h264->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE; + context->desc.h264enc.dpb[i].buffer = surf->buffer; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -240,6 +247,16 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; + struct pipe_h264_enc_dpb_entry *dpb = + &context->desc.h264enc.dpb[context->desc.h264enc.dpb_curr_pic]; + if (dpb->id && !dpb->buffer && context->decoder->create_dpb_buffer) { + vlVaSurface *surf = handle_table_get(drv->htab, dpb->id); + if (!surf) + return VA_STATUS_ERROR_INVALID_PARAMETER; + surf->buffer = context->decoder->create_dpb_buffer(context->decoder, &context->desc.base, &surf->templat); + dpb->buffer = surf->buffer; + } + getEncParamPresetH264(context); context->desc.h264enc.rate_ctrl[0].vbv_buffer_size = 20000000; context->desc.h264enc.rate_ctrl[0].vbv_buf_lv = 48; diff --git a/src/gallium/frontends/va/picture_hevc_enc.c b/src/gallium/frontends/va/picture_hevc_enc.c index 8455a3e7533..a377fa9fa77 100644 --- a/src/gallium/frontends/va/picture_hevc_enc.c +++ b/src/gallium/frontends/va/picture_hevc_enc.c @@ -80,6 +80,12 @@ vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *cont if (!context->desc.h265enc.dpb[i].id) { assert(!surf->is_dpb); surf->is_dpb = true; + if (surf->buffer) { + surf->buffer->destroy(surf->buffer); + surf->buffer = NULL; + } + if (context->decoder && context->decoder->create_dpb_buffer) + surf->buffer = context->decoder->create_dpb_buffer(context->decoder, &context->desc.base, &surf->templat); vlVaSetSurfaceContext(drv, surf, context); context->desc.h265enc.dpb_size++; break; @@ -91,6 +97,7 @@ vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *cont context->desc.h265enc.dpb[i].id = h265->decoded_curr_pic.picture_id; context->desc.h265enc.dpb[i].pic_order_cnt = h265->decoded_curr_pic.pic_order_cnt; context->desc.h265enc.dpb[i].is_ltr = h265->decoded_curr_pic.flags & VA_PICTURE_HEVC_LONG_TERM_REFERENCE; + context->desc.h265enc.dpb[i].buffer = surf->buffer; context->desc.h265enc.pic_order_cnt = h265->decoded_curr_pic.pic_order_cnt; coded_buf = handle_table_get(drv->htab, h265->coded_buf); @@ -251,6 +258,16 @@ vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *con if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; + struct pipe_h265_enc_dpb_entry *dpb = + &context->desc.h265enc.dpb[context->desc.h265enc.dpb_curr_pic]; + if (dpb->id && !dpb->buffer && context->decoder->create_dpb_buffer) { + vlVaSurface *surf = handle_table_get(drv->htab, dpb->id); + if (!surf) + return VA_STATUS_ERROR_INVALID_PARAMETER; + surf->buffer = context->decoder->create_dpb_buffer(context->decoder, &context->desc.base, &surf->templat); + dpb->buffer = surf->buffer; + } + getEncParamPresetH265(context); context->desc.h265enc.rc[0].vbv_buffer_size = 20000000; context->desc.h265enc.rc[0].vbv_buf_lv = 48; diff --git a/src/gallium/include/pipe/p_video_codec.h b/src/gallium/include/pipe/p_video_codec.h index a6c14d80ecc..e528a61722b 100644 --- a/src/gallium/include/pipe/p_video_codec.h +++ b/src/gallium/include/pipe/p_video_codec.h @@ -201,6 +201,13 @@ struct pipe_video_codec struct pipe_picture_desc *picture, void* bitstream_buf, unsigned *size); + + /** + * Creates a DPB buffer used for a single reconstructed picture. + */ + struct pipe_video_buffer *(*create_dpb_buffer)(struct pipe_video_codec *codec, + struct pipe_picture_desc *picture, + const struct pipe_video_buffer *templat); }; /** diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 21eee752aa8..13aa2d03ee0 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -719,6 +719,7 @@ struct pipe_h264_enc_dpb_entry uint32_t frame_idx; uint32_t pic_order_cnt; bool is_ltr; + struct pipe_video_buffer *buffer; }; struct pipe_h264_enc_picture_desc @@ -1106,6 +1107,7 @@ struct pipe_h265_enc_dpb_entry uint32_t id; uint32_t pic_order_cnt; bool is_ltr; + struct pipe_video_buffer *buffer; }; struct pipe_h265_enc_picture_desc