The branch, master has been updated
       via  df1fd43db4e20145f6c60b03a5bdeb02b3e8235a (commit)
      from  dd80ecb666f03d07cc8bca115bd5074cd63f59ed (commit)


- Log -----------------------------------------------------------------
commit df1fd43db4e20145f6c60b03a5bdeb02b3e8235a
Author:     Michael Yang <[email protected]>
AuthorDate: Wed Oct 15 17:43:00 2025 +1100
Commit:     Lynne <[email protected]>
CommitDate: Thu Nov 6 22:06:42 2025 +0000

    libavcodec/vulkan_encode_av1: fix non-monotonic DTS
    
    Combine P-frame with following B-frame into a single packet with the
    latter's order. Emit a tail packet with a show_existing_frame header
    to show it at the correct PTS.

diff --git a/libavcodec/vulkan_encode.c b/libavcodec/vulkan_encode.c
index e5c0496f1c..7b534ffa30 100644
--- a/libavcodec/vulkan_encode.c
+++ b/libavcodec/vulkan_encode.c
@@ -464,6 +464,9 @@ static int vulkan_encode_output(AVCodecContext *avctx,
     VkResult ret;
     FFVulkanEncodePicture *vp = base_pic->priv;
     FFVulkanEncodeContext *ctx = avctx->priv_data;
+    FFHWBaseEncodeContext *base_ctx = &ctx->base;
+    AVPacket *pkt_ptr = pkt;
+
     FFVkBuffer *sd_buf = (FFVkBuffer *)vp->pkt_buf->data;
     uint32_t *query_data;
 
@@ -513,20 +516,56 @@ static int vulkan_encode_output(AVCodecContext *avctx,
         vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &invalidate_buf);
     }
 
-    pkt->data = sd_buf->mapped_mem;
-    pkt->size = vp->slices_offset + /* base offset */
-                query_data[0]       /* secondary offset */ +
-                query_data[1]       /* size */;
+    if (vp->non_independent_frame) {
+        av_assert0(!ctx->prev_buf_ref);
+        size_t prev_buf_size = vp->slices_offset + query_data[0] + 
query_data[1];
+        ctx->prev_buf_ref = vp->pkt_buf;
+        ctx->prev_buf_size = prev_buf_size;
+        vp->pkt_buf = NULL;
+
+        if (vp->tail_size) {
+            if (base_ctx->tail_pkt->size)
+                return AVERROR_BUG;
+
+            ret = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, 
vp->tail_size, 0);
+            if (ret < 0)
+                return ret;
+
+            memcpy(base_ctx->tail_pkt->data, vp->tail_data, vp->tail_size);
+            pkt_ptr = base_ctx->tail_pkt;
+        }
+    } else {
+        if (ctx->prev_buf_ref) {
+            FFVkBuffer *prev_sd_buf = (FFVkBuffer *)ctx->prev_buf_ref->data;
+            size_t prev_size = ctx->prev_buf_size;
+            size_t size = (vp->slices_offset + query_data[0] + query_data[1]);
+
+            ret = ff_get_encode_buffer(avctx, pkt, prev_size + size, 0);
+            if (ret < 0)
+                return ret;
+
+            memcpy(pkt->data, prev_sd_buf->mapped_mem, prev_size);
+            memcpy(pkt->data + prev_size, sd_buf->mapped_mem, size);
 
-    /* Move reference */
-    pkt->buf = vp->pkt_buf;
-    vp->pkt_buf = NULL;
+            av_buffer_unref(&ctx->prev_buf_ref);
+            av_buffer_unref(&vp->pkt_buf);
+        } else {
+            pkt->data = sd_buf->mapped_mem;
+            pkt->size = vp->slices_offset + /* base offset */
+                        query_data[0]       /* secondary offset */ +
+                        query_data[1]       /* size */;
+
+            /* Move reference */
+            pkt->buf = vp->pkt_buf;
+            vp->pkt_buf = NULL;
+        }
+    }
 
     av_log(avctx, AV_LOG_DEBUG, "Frame %"PRId64"/%"PRId64 " encoded\n",
            base_pic->display_order, base_pic->encode_order);
 
     return ff_hw_base_encode_set_output_property(&ctx->base, avctx,
-                                                 base_pic, pkt,
+                                                 base_pic, pkt_ptr,
                                                  ctx->codec->flags & 
VK_ENC_FLAG_NO_DELAY);
 }
 
diff --git a/libavcodec/vulkan_encode.h b/libavcodec/vulkan_encode.h
index 3df06e11d0..cf5f255628 100644
--- a/libavcodec/vulkan_encode.h
+++ b/libavcodec/vulkan_encode.h
@@ -57,6 +57,10 @@ typedef struct FFVulkanEncodePicture {
     FFVkExecContext       *exec;
     AVBufferRef           *pkt_buf;
     int                    slices_offset;
+
+    int non_independent_frame;
+    char tail_data[16];
+    size_t tail_size;
 } FFVulkanEncodePicture;
 
 /**
@@ -192,6 +196,9 @@ typedef struct FFVulkanEncodeContext {
     FFVkExecPool enc_pool;
 
     FFHWBaseEncodePicture *slots[32];
+
+    AVBufferRef *prev_buf_ref;
+    size_t prev_buf_size;
 } FFVulkanEncodeContext;
 
 #define VULKAN_ENCODE_COMMON_OPTIONS \
diff --git a/libavcodec/vulkan_encode_av1.c b/libavcodec/vulkan_encode_av1.c
index 1f26b37316..42ba30b302 100644
--- a/libavcodec/vulkan_encode_av1.c
+++ b/libavcodec/vulkan_encode_av1.c
@@ -80,6 +80,8 @@ typedef struct VulkanEncodeAV1Context {
     AV1RawOBU seq_hdr_obu;
     AV1RawOBU meta_cll_obu;
     AV1RawOBU meta_mastering_obu;
+    AV1RawOBU hidden_obu;
+    AV1RawOBU tail_obu;
 
     VkVideoEncodeAV1ProfileInfoKHR profile;
 
@@ -172,7 +174,6 @@ static void set_name_slot(int slot, int *slot_indices, 
uint32_t allowed_idx, int
     av_assert0(0);
 }
 
-
 static int init_pic_params(AVCodecContext *avctx, FFHWBaseEncodePicture *pic,
                            VkVideoEncodeInfoKHR *encode_info)
 {
@@ -542,6 +543,45 @@ static int init_pic_params(AVCodecContext *avctx, 
FFHWBaseEncodePicture *pic,
         }
     }
 
+    FFVulkanEncodePicture *vp = pic->priv;
+    vp->tail_size = 0;
+    vp->non_independent_frame = pic->encode_order < pic->display_order;
+    if (vp->non_independent_frame) {
+        AV1RawOBU *obu = &enc->hidden_obu;
+        AV1RawFrameHeader *fh = &obu->obu.frame_header;
+
+        /** hidden frame header */
+        memset(obu, 0, sizeof(*obu));
+        obu->header.obu_type = AV1_OBU_FRAME_HEADER;
+        obu->header.obu_has_size_field = 1;
+
+        fh->frame_type = AV1_FRAME_INTER;
+        fh->refresh_frame_flags = 1 << ap->slot;
+        fh->frame_width_minus_1   = base_ctx->surface_width - 1;
+        fh->frame_height_minus_1  = base_ctx->surface_height - 1;
+        fh->render_width_minus_1  = fh->frame_width_minus_1;
+        fh->render_height_minus_1 = fh->frame_height_minus_1;
+
+        memcpy(fh->loop_filter_ref_deltas, default_loop_filter_ref_deltas,
+               AV1_TOTAL_REFS_PER_FRAME * sizeof(int8_t));
+
+        obu = &enc->tail_obu;
+        fh = &obu->obu.frame_header;
+
+        /** tail frame header */
+        memset(obu, 0, sizeof(*obu));
+        obu->header.obu_type = AV1_OBU_FRAME_HEADER;
+        obu->header.obu_has_size_field = 1;
+
+        fh->show_existing_frame   = 1;
+        fh->frame_to_show_map_idx = ap->slot != 0;
+        fh->frame_type            = AV1_FRAME_INTER;
+        fh->frame_width_minus_1   = base_ctx->surface_width - 1;
+        fh->frame_height_minus_1  = base_ctx->surface_height - 1;
+        fh->render_width_minus_1  = fh->frame_width_minus_1;
+        fh->render_height_minus_1 = fh->frame_height_minus_1;
+    }
+
     return 0;
 }
 
@@ -1079,8 +1119,31 @@ static int write_extra_headers(AVCodecContext *avctx,
     int err;
     VulkanEncodeAV1Context *enc = avctx->priv_data;
     VulkanEncodeAV1Picture  *ap = base_pic->codec_priv;
+    FFVulkanEncodePicture *vp = base_pic->priv;
     CodedBitstreamFragment *obu = &enc->current_access_unit;
 
+    if (vp->non_independent_frame) {
+        err = vulkan_encode_av1_add_obu(avctx, obu, AV1_OBU_FRAME_HEADER, 
&enc->hidden_obu);
+        if (err < 0)
+            goto fail;
+
+        // Only for tracking ref frame in context, not to be output
+        err = ff_cbs_write_fragment_data(enc->cbs, obu);
+        if (err < 0)
+            goto fail;
+
+        ff_cbs_fragment_reset(obu);
+        ((CodedBitstreamAV1Context *)enc->cbs->priv_data)->seen_frame_header = 
0;
+
+        err = vulkan_encode_av1_add_obu(avctx, obu, AV1_OBU_FRAME_HEADER, 
&enc->tail_obu);
+        if (err < 0)
+            goto fail;
+
+        err = vulkan_encode_av1_write_obu(avctx, vp->tail_data, 
&vp->tail_size, obu);
+        if (err < 0)
+            goto fail;
+    }
+
     if (ap->units_needed & UNIT_MASTERING_DISPLAY) {
         err = vulkan_encode_av1_add_obu(avctx, obu,
                                         AV1_OBU_METADATA,

-----------------------------------------------------------------------

Summary of changes:
 libavcodec/vulkan_encode.c     | 55 +++++++++++++++++++++++++++++------
 libavcodec/vulkan_encode.h     |  7 +++++
 libavcodec/vulkan_encode_av1.c | 65 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 118 insertions(+), 9 deletions(-)


hooks/post-receive
-- 

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to