diff options
author | Anton Khirnov <anton@khirnov.net> | 2022-07-12 11:25:09 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2022-11-28 10:34:10 +0100 |
commit | 67f0e45daa758047b58c7f664bd5776c227e37f2 (patch) | |
tree | cfc84002f14b0be91b9e5a16e67b8a015735e42c | |
parent | 531b0d23e139411b3c3618bc6b1ac1dc5ef6c306 (diff) |
WIP lavc/amfenc: pass through frame durations to encoded packets
-rw-r--r-- | libavcodec/amfenc.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index a033e1220e..3c06d06433 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -68,6 +68,11 @@ typedef struct FormatMap { enum AMF_SURFACE_FORMAT amf_format; } FormatMap; +typedef struct FrameData { + int64_t pts; + int64_t duration; +} FrameData; + static const FormatMap format_map[] = { { AV_PIX_FMT_NONE, AMF_SURFACE_UNKNOWN }, @@ -119,7 +124,7 @@ static int amf_load_library(AVCodecContext *avctx) return AVERROR(ENOMEM); } // hardcoded to current HW queue size - will auto-realloc if too small - ctx->timestamp_list = av_fifo_alloc2(avctx->max_b_frames + 16, sizeof(int64_t), + ctx->timestamp_list = av_fifo_alloc2(avctx->max_b_frames + 16, sizeof(FrameData), AV_FIFO_FLAG_AUTO_GROW); if (!ctx->timestamp_list) { return AVERROR(ENOMEM); @@ -439,8 +444,8 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buff AmfContext *ctx = avctx->priv_data; int ret; AMFVariantStruct var = {0}; - int64_t timestamp = AV_NOPTS_VALUE; int64_t size = buffer->pVtbl->GetSize(buffer); + FrameData timestamp; if ((ret = ff_get_encode_buffer(avctx, pkt, size, 0)) < 0) { return ret; @@ -474,18 +479,19 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buff // calc dts shift if max_b_frames > 0 if (avctx->max_b_frames > 0 && ctx->dts_delay == 0) { - int64_t timestamp_last = AV_NOPTS_VALUE; + FrameData timestamp_last; size_t can_read = av_fifo_can_read(ctx->timestamp_list); AMF_RETURN_IF_FALSE(ctx, can_read > 0, AVERROR_UNKNOWN, "timestamp_list is empty while max_b_frames = %d\n", avctx->max_b_frames); av_fifo_peek(ctx->timestamp_list, ×tamp_last, 1, can_read - 1); - if (timestamp < 0 || timestamp_last < AV_NOPTS_VALUE) { + if (timestamp.pts < 0 || timestamp_last.pts < AV_NOPTS_VALUE) { return AVERROR(ERANGE); } - ctx->dts_delay = timestamp_last - timestamp; + ctx->dts_delay = timestamp_last.pts - timestamp.pts; } - pkt->dts = timestamp - ctx->dts_delay; + pkt->dts = timestamp.pts - ctx->dts_delay; + pkt->duration = timestamp.duration; return 0; } @@ -691,12 +697,12 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) //store surface for later submission ctx->delayed_surface = surface; } else { - int64_t pts = frame->pts; + FrameData timing = { .pts = frame->pts, duration = frame->duration }; surface->pVtbl->Release(surface); AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res); av_frame_unref(frame); - ret = av_fifo_write(ctx->timestamp_list, &pts, 1); + ret = av_fifo_write(ctx->timestamp_list, &timing, 1); if (ret < 0) return ret; } @@ -731,13 +737,13 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) if (ctx->delayed_surface != NULL) { // try to resubmit frame res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)ctx->delayed_surface); if (res != AMF_INPUT_FULL) { - int64_t pts = ctx->delayed_surface->pVtbl->GetPts(ctx->delayed_surface); + FrameData timing = { .pts = ctx->delayed_surface->pVtbl->GetPts(ctx->delayed_surface) }; ctx->delayed_surface->pVtbl->Release(ctx->delayed_surface); ctx->delayed_surface = NULL; av_frame_unref(ctx->delayed_frame); AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", res); - ret = av_fifo_write(ctx->timestamp_list, &pts, 1); + ret = av_fifo_write(ctx->timestamp_list, &timing, 1); if (ret < 0) return ret; } else { |