diff --git a/src/gallium/frontends/va/context.c b/src/gallium/frontends/va/context.c index da493977762..40138bdf2d2 100644 --- a/src/gallium/frontends/va/context.c +++ b/src/gallium/frontends/va/context.c @@ -507,6 +507,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) if (buf && !context->desc.av1enc.dpb[i].id) buf->destroy(buf); } + util_dynarray_fini(&context->desc.av1enc.raw_headers); } } else { if (u_reduce_video_profile(context->decoder->profile) == diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index e14bfdedd92..c35e7e427bb 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -1368,6 +1368,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) switch (u_reduce_video_profile(context->templat.profile)) { case PIPE_VIDEO_FORMAT_AV1: context->desc.av1enc.frame_num++; + vlVaClearRawHeaders(&context->desc.av1enc.raw_headers); break; case PIPE_VIDEO_FORMAT_HEVC: context->desc.h265enc.frame_num++; diff --git a/src/gallium/frontends/va/picture_av1_enc.c b/src/gallium/frontends/va/picture_av1_enc.c index e58bdd8aa68..23f6e5a08c2 100644 --- a/src/gallium/frontends/va/picture_av1_enc.c +++ b/src/gallium/frontends/va/picture_av1_enc.c @@ -675,7 +675,8 @@ static void av1_read_interpolation_filter(vlVaContext *context, struct vl_vlc *v av1_f(vlc, 2); } -static void av1_frame_header(vlVaContext *context, struct vl_vlc *vlc) +static bool av1_frame_header(vlVaContext *context, struct vl_vlc *vlc, + uint32_t extension_flag, uint32_t temporal_id, uint32_t spatial_id) { struct pipe_av1_enc_picture_desc *av1 = &context->desc.av1enc; uint32_t frame_type; @@ -687,10 +688,12 @@ static void av1_frame_header(vlVaContext *context, struct vl_vlc *vlc) id_len = av1->seq.delta_frame_id_length + av1->seq.additional_frame_id_length; all_frames = 255; - av1->show_existing_frame = av1_f(vlc, 1); - /* use the last reference frame to show */ - if (av1->show_existing_frame) - return; + if (av1_f(vlc, 1)) /* show_existing_frame */ + return false; + + av1->obu_extension_flag = extension_flag; + av1->temporal_id = temporal_id; + av1->spatial_id = spatial_id; frame_type = av1_f(vlc, 2); frame_is_intra = (frame_type == FRAME_TYPE_KEY_FRAME || @@ -824,6 +827,8 @@ static void av1_frame_header(vlVaContext *context, struct vl_vlc *vlc) */ av1->uniform_tile_spacing = av1_f(vlc, 1); + + return true; } static void av1_metatype_hdr_cll(vlVaContext *context, struct vl_vlc *vlc) @@ -873,29 +878,40 @@ vlVaHandleVAEncPackedHeaderDataBufferTypeAV1(vlVaContext *context, vlVaBuffer *b if (obu_type != OBU_TYPE_SEQUENCE_HEADER && obu_type != OBU_TYPE_FRAME_HEADER && obu_type != OBU_TYPE_FRAME && - obu_type != OBU_TYPE_META) + obu_type != OBU_TYPE_META) { + vlVaAddRawHeader(&context->desc.av1enc.raw_headers, obu_type, + buf->size, buf->data, false, 0); return VA_STATUS_SUCCESS; + } uint32_t extension_flag = av1_f(&vlc, 1); uint32_t has_size = av1_f(&vlc, 1); av1_f(&vlc, 1); /* obu_reserved_1bit */ + uint32_t temporal_id = 0; + uint32_t spatial_id = 0; + if (extension_flag) { - context->desc.av1enc.temporal_id = av1_f(&vlc, 3); - context->desc.av1enc.spatial_id = av1_f(&vlc, 2); + temporal_id = av1_f(&vlc, 3); + spatial_id = av1_f(&vlc, 2); av1_f(&vlc, 3); /* extension_header_reserved_3bits */ } if (has_size) av1_uleb128(&vlc); + bool is_frame = false; + if (obu_type == OBU_TYPE_SEQUENCE_HEADER) av1_sequence_header(context, &vlc); else if (obu_type == OBU_TYPE_FRAME_HEADER || obu_type == OBU_TYPE_FRAME) - av1_frame_header(context, &vlc); + is_frame = av1_frame_header(context, &vlc, extension_flag, temporal_id, spatial_id); else if (obu_type == OBU_TYPE_META) av1_meta_obu(context, &vlc); + vlVaAddRawHeader(&context->desc.av1enc.raw_headers, obu_type, + buf->size, buf->data, is_frame, 0); + return VA_STATUS_SUCCESS; } diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index 917c13c6f1a..01d34e014c6 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -97,7 +97,8 @@ 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) + VA_ENC_PACKED_HEADER_MISC | \ + VA_ENC_PACKED_HEADER_RAW_DATA) static inline enum pipe_video_chroma_format ChromaToPipe(int format) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 439b27983ee..b836402146a 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -1334,6 +1334,7 @@ struct pipe_av1_enc_picture_desc struct pipe_av1_enc_seq_param seq; struct pipe_av1_enc_rate_control rc[4]; struct { + uint32_t obu_extension_flag:1; uint32_t enable_frame_obu:1; uint32_t error_resilient_mode:1; uint32_t disable_cdf_update:1; @@ -1469,6 +1470,8 @@ struct pipe_av1_enc_picture_desc uint8_t dpb_ref_frame_idx[PIPE_AV1_REFS_PER_FRAME]; /* index in dpb, PIPE_H2645_LIST_REF_INVALID_ENTRY invalid */ uint8_t ref_list0[PIPE_AV1_REFS_PER_FRAME]; /* index in dpb_ref_frame_idx, PIPE_H2645_LIST_REF_INVALID_ENTRY invalid */ uint8_t ref_list1[PIPE_AV1_REFS_PER_FRAME]; /* index in dpb_ref_frame_idx, PIPE_H2645_LIST_REF_INVALID_ENTRY invalid */ + + struct util_dynarray raw_headers; /* struct pipe_enc_raw_header */ }; struct pipe_h265_sps