mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-08 06:09:50 +00:00
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.
This commit is contained in:
parent
dd80ecb666
commit
df1fd43db4
3 changed files with 118 additions and 9 deletions
|
|
@ -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;
|
||||
|
||||
/* Move reference */
|
||||
pkt->buf = vp->pkt_buf;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue