From 31f6fe13561e7610aadb9cab97edf5ee1d7a8a90 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Wed, 24 Jul 2024 10:00:46 +0200 Subject: [PATCH] frontends/va: Keep track if VPS/SPS/PPS/AUD was sent FFmpeg sends AUD as part of VA_ENC_PACKED_HEADER_SEQUENCE and VA_ENC_PACKED_HEADER_SLICE. GStreamer sends it separately as VA_ENC_PACKED_HEADER_RAW_DATA. It's now also needed to keep track what packed headers were enabled to include VPS/SPS/PPS with VAEncSequenceParameterBuffer when sequence packed headers are disabled. Reviewed-By: Sil Vilerino Reviewed-by: Ruijing Dong Part-of: --- src/gallium/frontends/va/config.c | 1 + src/gallium/frontends/va/context.c | 1 + src/gallium/frontends/va/picture.c | 20 +++++++++++++++++++- src/gallium/frontends/va/picture_h264_enc.c | 13 +++++++++++++ src/gallium/frontends/va/picture_hevc_enc.c | 17 +++++++++++++++-- src/gallium/frontends/va/va_private.h | 11 +++++++++-- src/gallium/include/pipe/p_video_state.h | 1 + 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/gallium/frontends/va/config.c b/src/gallium/frontends/va/config.c index 4900a566da7..acd5bc16305 100644 --- a/src/gallium/frontends/va/config.c +++ b/src/gallium/frontends/va/config.c @@ -744,6 +744,7 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin FREE(config); return VA_STATUS_ERROR_INVALID_VALUE; } + config->packed_headers = attrib_value; } } diff --git a/src/gallium/frontends/va/context.c b/src/gallium/frontends/va/context.c index e2a12db4df7..07d9589261d 100644 --- a/src/gallium/frontends/va/context.c +++ b/src/gallium/frontends/va/context.c @@ -383,6 +383,7 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, default: break; } + context->desc.base.packed_headers = config->packed_headers; } context->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index 0a3795a45b7..d4dedcf5696 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -151,6 +151,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende context->desc.h265enc.header_flags.value = 0; break; case PIPE_VIDEO_FORMAT_MPEG4_AVC: + context->desc.h264enc.header_flags.value = 0; + break; default: break; } @@ -732,8 +734,24 @@ handleVAEncMiscParameterTypeRIR(vlVaContext *context, VAEncMiscParameterBuffer * if (p_intra_refresh->mode) { p_intra_refresh->region_size = ir->intra_insert_size; p_intra_refresh->offset = ir->intra_insertion_location; - if (p_intra_refresh->offset == 0) + if (p_intra_refresh->offset == 0) { p_intra_refresh->need_sequence_header = 1; + if (!(context->desc.base.packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE)) { + switch (u_reduce_video_profile(context->templat.profile)) { + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + context->desc.h264enc.header_flags.sps = 1; + context->desc.h264enc.header_flags.pps = 1; + break; + case PIPE_VIDEO_FORMAT_HEVC: + context->desc.h265enc.header_flags.vps = 1; + context->desc.h265enc.header_flags.sps = 1; + context->desc.h265enc.header_flags.pps = 1; + break; + default: + break; + } + } + } } } else { p_intra_refresh->mode = INTRA_REFRESH_MODE_NONE; diff --git a/src/gallium/frontends/va/picture_h264_enc.c b/src/gallium/frontends/va/picture_h264_enc.c index e381d4884d6..eddc6fddf72 100644 --- a/src/gallium/frontends/va/picture_h264_enc.c +++ b/src/gallium/frontends/va/picture_h264_enc.c @@ -34,6 +34,7 @@ enum H264NALUnitType { H264_NAL_SPS = 7, H264_NAL_PPS = 8, + H264_NAL_AUD = 9, }; VAStatus @@ -273,6 +274,12 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con context->desc.h264enc.seq.enc_frame_crop_top_offset = h264->frame_crop_top_offset; context->desc.h264enc.seq.enc_frame_crop_bottom_offset = h264->frame_crop_bottom_offset; } + + if (!(context->desc.base.packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE)) { + context->desc.h264enc.header_flags.sps = 1; + context->desc.h264enc.header_flags.pps = 1; + } + return VA_STATUS_SUCCESS; } @@ -527,8 +534,14 @@ vlVaHandleVAEncPackedHeaderDataBufferTypeH264(vlVaContext *context, vlVaBuffer * switch(nal_unit_type) { case H264_NAL_SPS: parseEncSpsParamsH264(context, &rbsp); + context->desc.h264enc.header_flags.sps = 1; break; case H264_NAL_PPS: + context->desc.h264enc.header_flags.pps = 1; + break; + case H264_NAL_AUD: + context->desc.h264enc.header_flags.aud = 1; + break; default: break; } diff --git a/src/gallium/frontends/va/picture_hevc_enc.c b/src/gallium/frontends/va/picture_hevc_enc.c index 1256dd1f7a3..38c40457938 100644 --- a/src/gallium/frontends/va/picture_hevc_enc.c +++ b/src/gallium/frontends/va/picture_hevc_enc.c @@ -35,6 +35,7 @@ enum HEVCNALUnitType { HEVC_NAL_VPS = 32, HEVC_NAL_SPS = 33, HEVC_NAL_PPS = 34, + HEVC_NAL_AUD = 35, HEVC_NAL_PREFIX_SEI = 39, }; @@ -280,6 +281,12 @@ vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *con context->desc.h265enc.rc.frame_rate_num = time_scale; context->desc.h265enc.rc.frame_rate_den = num_units_in_tick; + if (!(context->desc.base.packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE)) { + context->desc.h265enc.header_flags.vps = 1; + context->desc.h265enc.header_flags.sps = 1; + context->desc.h265enc.header_flags.pps = 1; + } + return VA_STATUS_SUCCESS; } @@ -761,12 +768,18 @@ vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer * vl_rbsp_init(&rbsp, &vlc, ~0, context->packed_header_emulation_bytes); switch(nal_unit_type) { + case HEVC_NAL_VPS: + context->desc.h265enc.header_flags.vps = 1; + break; case HEVC_NAL_SPS: parseEncSpsParamsH265(context, &rbsp); - break; - case HEVC_NAL_VPS: + context->desc.h265enc.header_flags.sps = 1; break; case HEVC_NAL_PPS: + context->desc.h265enc.header_flags.pps = 1; + break; + case HEVC_NAL_AUD: + context->desc.h265enc.header_flags.aud = 1; break; case HEVC_NAL_PREFIX_SEI: parseEncSeiH265(context, &rbsp); diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index af8c67ca210..42a6a50ca1f 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -85,9 +85,15 @@ #define VBAQ_DISABLE (0) #define VBAQ_AUTO (1) -#define ENC_PACKED_HEADERS_H264 (VA_ENC_PACKED_HEADER_SEQUENCE) +#define ENC_PACKED_HEADERS_H264 (VA_ENC_PACKED_HEADER_SEQUENCE | \ + VA_ENC_PACKED_HEADER_PICTURE | \ + VA_ENC_PACKED_HEADER_SLICE | \ + VA_ENC_PACKED_HEADER_RAW_DATA) #define ENC_PACKED_HEADERS_HEVC (VA_ENC_PACKED_HEADER_SEQUENCE | \ - VA_ENC_PACKED_HEADER_MISC) + VA_ENC_PACKED_HEADER_PICTURE | \ + VA_ENC_PACKED_HEADER_SLICE | \ + VA_ENC_PACKED_HEADER_MISC | \ + VA_ENC_PACKED_HEADER_RAW_DATA) #define ENC_PACKED_HEADERS_AV1 (VA_ENC_PACKED_HEADER_SEQUENCE | \ VA_ENC_PACKED_HEADER_PICTURE | \ VA_ENC_PACKED_HEADER_MISC) @@ -425,6 +431,7 @@ typedef struct { enum pipe_video_entrypoint entrypoint; enum pipe_h2645_enc_rate_control_method rc; unsigned int rt_format; + unsigned int packed_headers; } vlVaConfig; typedef struct vlVaSurface { diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index b83943cc482..e27f62eda1e 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -195,6 +195,7 @@ struct pipe_picture_desc unsigned flush_flags; /* A fence used on PIPE_VIDEO_ENTRYPOINT_DECODE/PROCESSING to signal job completion */ struct pipe_fence_handle **fence; + unsigned packed_headers; }; struct pipe_quant_matrix