summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2022-07-12 11:25:09 +0200
committerAnton Khirnov <anton@khirnov.net>2022-08-23 16:50:33 +0200
commitee05c9bdee0ff6db7f3bc97fca1044f55b505daa (patch)
treeaddaa0496c1a4448b0e274b11c86b295a66769f3
parent5c6f4e4596a2616b951abf83bf6efc77ec5e1b5c (diff)
lavc/amfenc: pass through frame durations to encoded packets
-rw-r--r--libavcodec/amfenc.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index a033e1220e..af8d6f1e26 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 FrameTiming {
+ int64_t pts;
+ int64_t duration;
+} FrameTiming;
+
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(FrameTiming),
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);
+ FrameTiming 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;
+ FrameTiming 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, &timestamp_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;
+ FrameTiming 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);
+ FrameTiming 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 {