Re: [FFmpeg-devel] [PATCH, v2] libavcodec/amfenc: Update AMF encoder options

2024-05-20 Thread Araz
Please review the attached patch and provide your feedback.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH, v2] libavcodec/amfenc: Update AMF encoder options

2024-05-27 Thread Araz
That patch is a key part to support new features of  amd next generation
gpu product.
Please review the attached patch and provide your feedback.

>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] [v4] avcodec/vaapi_encode: add customized surface alignment

2024-03-27 Thread Araz
>>On Fri, Mar 22, 2024 at 11:35 AM Anton Khirnov  wrote:
>>Why this unnecessary complication? Just use two ints, or two uint8_t's
>>if you really need to save space, though that also seems unncessary as
>>this struct is allocated rarely and usually does not live long.

https://github.com/intel/libva/pull/794
The alignment range for log2_size of 4bit is in range of
[2**0, 2**15] = [1, 32768] this is large enough, or other way is to
directly use the alignment value, however I would want it to be in
powers of 2 and not any number, to force this condition, the common
way is to use log2_size(), which is using less bits and forcing
the alignment to be in powers of 2.

>>On Sun, Mar 24, 2024 at 5:38 PM Mark Thompson  wrote:
>>What other users do you have in mind for this?  (Are you expecting
hwupload to use it as well, say?)
>>
>>If this is only used in VAAPI encode then I would suggest putting the
query there rather than adding new library API for it.
>>
>>Also agree with Anton that this form is unnecessarily confusing - just
make it a normal field, don't pack it like this.  (And possibly drop the
log2 as well?  That doesn't seem like it adds anything useful.)

The limitation is for AMD HW, and it is not limited to VAAPI, and for other
HW encoding protocols this limitation also exists.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] [v4] avcodec/vaapi_encode: add customized surface alignment

2024-04-03 Thread Araz
> On Mon, Apr 1, 2024 at 9:33 PM Mark Thompson  wrote:
> It is not necessary to copy exactly the same field layout.
> Are you sure that there is never a meaningful non-power-of-two-bytes case?
> Given that this is defining new public API to libavutil we don't want to
be artificially constrained to precisely what happens to be needed in this
case.
If you think copying the field is not preferred,  any other ways in your
mind? How to use the VA interface to query the surface alignment data?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/4, v2] avcodec/amfenc: Fixes the color information in the output.

2024-08-01 Thread Araz
> > +AV_PIX_FMT_P010,
> >  AV_PIX_FMT_NONE
> >};
> >
> >   @@ -72,6 +73,7 @@ static const FormatMap format_map[] =
> >{
> >{ AV_PIX_FMT_NONE,   AMF_SURFACE_UNKNOWN },
> >{ AV_PIX_FMT_NV12,   AMF_SURFACE_NV12 },
> >   +{ AV_PIX_FMT_P010,   AMF_SURFACE_P010 },

>  Why is this in this commit?

This patch mostly fixes color information.
10-bit pixel format update is too small to make a separate patch for it.
I can rename that patch or split it on 2 patches.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/amf_enc: new encoder features support

2024-08-14 Thread Araz
Can anyone take a look at this patch please?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/4, v2] avcodec/amfenc: Fixes the color information in the output.

2024-09-09 Thread Araz
> Apologies for missing this prior to merge, but you can't safely make these
> assumptions about primaries and TRC just based on the input bit depth.
Just
> because it's 8-bit content doesn't mean it will be BT.709 and likewise for
> 10-bit and BT.2020+SMPTE 2084 PQ.
>
> Why doesn't amfenc_hevc (and amfenc_av1) use the values from avctx like
> amfenc_h264 does?

Current hardware color space converter does not support transfer
characteristics other than this:
(BT709 for 8-bit output and BT2084 for 10-bit output) so for RGB input
we need them hard-coded. If conversion is done before AMF encoder, the
encoder can accept any value as it is just fields in VUI header.
So, we will come with a separate patch which would reflect this logic.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/amfenc: Fix HEVC/AV1 colorspace assumptions

2024-09-09 Thread Araz
> -if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
> -/// Color Transfer Characteristics (AMF matches ISO/IEC)
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC,
AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
> -/// Color Primaries (AMF matches ISO/IEC)
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
> -} else {
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC,
AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
> -}
> +/// Color Transfer Characteristics (AMF matches ISO/IEC)
> +AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC,
(amf_int64)avctx->color_trc);
> +/// Color Primaries (AMF matches ISO/IEC)
> +AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES,
(amf_int64)avctx->color_primaries);

> -if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
> -/// Color Transfer Characteristics (AMF matches ISO/IEC)
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC,
AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
> -/// Color Primaries (AMF matches ISO/IEC)
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
> -} else {
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC,
AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
> -AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
> -}
> +/// Color Transfer Characteristics (AMF matches ISO/IEC)
> +AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC,
(amf_int64)avctx->color_trc);
> +/// Color Primaries (AMF matches ISO/IEC)
> +AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES,
(amf_int64)avctx->color_primaries);

Current hardware color space converter does not support transfer
characteristics other than this:
(BT709 for 8-bit output and BT2084 for 10-bit output) so for RGB input
we need them hard-coded. If conversion is done before AMF encoder, the
encoder can accept any value as it is just fields in VUI header.
So, we will come with a separate patch which would reflect this logic.
I also answered the same on your comment to my patch:
avcodec/amfenc: Fixes the color information in the output.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH, v2] avcodec/amfenc: increase precision of Sleep() on Windows

2024-09-09 Thread Araz
>
> > I took a look at this using AMD's AMF EncoderLatency sample and found
> that
> > setting the QUERY_TIMEOUT option to 50 ms (as is default for the new AMF
> > HQ and HQLL usage values) results in latency that is better than the
> > current AMF code in FFmpeg *and* this patch without having to touch
> > the process's timer precision.
> >
> > Here are the results from QUERY_TIMEOUT=0, amf_sleep(1), 1ms timer
> period:
> > Encoder: AMFVideoEncoderVCE_AVC
> > Total  : Frames = 500 Duration = 1157.16ms FPS = 432.09frames
> > Latency: First,Min,Max = 7.12ms, 1.53ms, 3.73ms
> > Latency: Average = 1.99ms
> >
> > and the results from QUERY_TIMEOUT=50, default timer period:
> > Encoder: AMFVideoEncoderVCE_AVC
> > Total  : Frames = 500 Duration = 933.03ms FPS = 535.89frames
> > Latency: First,Min,Max = 5.80ms, 1.49ms, 2.50ms
> > Latency: Average = 1.58ms
> >
> > This seems to clearly demonstrate that QUERY_TIMEOUT is a better approach
> > than adjusting timer resolution. It avoids process-wide effects *and*
> > it even performs better on top of that.
> >
> >
> > Cameron
>

Thanks everyone and Cameron,
TIMEOUT might be a possible solution.
Need some time for evaluating the performance impact of using it.
The problem is that FFmpeg calls SubmitInput and QueryOutput
from the same thread and if B-frames and/or look-ahead enabled, initially
not enough input submitted and QueryOutput will wait till timeout value.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/amfenc: Avoid polling with fixed sleep

2024-10-10 Thread Araz
Thanks Cameron, your patch timeout mechanism has been tested and improves
performance.
But still works with some issues when B-frames are presented.
This issue was resolved in the attached data, please update your patch
with information
below:

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
> index 41eaef9758..4c6ee58639 100644
> --- a/libavcodec/amfenc.c
> +++ b/libavcodec/amfenc.c
> @@ -426,6 +426,8 @@ static int amf_init_encoder(AVCodecContext *avctx)
>  res = ctx->factory->pVtbl->CreateComponent(ctx->factory,
> ctx->context, codec_id, &ctx->encoder);
>  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND,
> "CreateComponent(%ls) failed with error %d\n", codec_id, res);
>
> +ctx->submitted_frame = 0;
> +
>  return 0;
>  }
>
> @@ -541,7 +543,6 @@ static int amf_copy_buffer(AVCodecContext *avctx,
> AVPacket *pkt, AMFBuffer *buff
>  if ((ctx->max_b_frames > 0 || ((ctx->pa_adaptive_mini_gop == 1) ?
> true : false)) && ctx->dts_delay == 0) {
>  int64_t timestamp_last = AV_NOPTS_VALUE;
>  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);
> @@ -787,6 +788,13 @@ int ff_amf_receive_packet(AVCodecContext *avctx,
> AVPacket *avpkt)
>
>  av_frame_unref(frame);
>  ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
> +
> +if (ctx->submitted_frame == 0)
> +{
> +ctx->use_b_frame = (ctx->max_b_frames > 0 ||
> ((ctx->pa_adaptive_mini_gop == 1) ? true : false));
> +}
> +ctx->submitted_frame++;
> +
>  if (ret < 0)
>  return ret;
>  }
> @@ -796,7 +804,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx,
> AVPacket *avpkt)
>  do {
>  block_and_wait = 0;
>  // poll data
> -if (!avpkt->data && !avpkt->buf) {
> +if (!avpkt->data && !avpkt->buf && (ctx->use_b_frame ?
> (ctx->submitted_frame >= 2) : true) ) {
>  res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder,
> &data);
>  if (data) {
>  // copy data to packet
> @@ -806,6 +814,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx,
> AVPacket *avpkt)
>  data->pVtbl->QueryInterface(data, &guid,
> (void**)&buffer); // query for buffer interface
>  ret = amf_copy_buffer(avctx, avpkt, buffer);
>
> +ctx->submitted_frame++;
>  buffer->pVtbl->Release(buffer);
>
>  if (data->pVtbl->HasProperty(data, L"av_frame_ref")) {
> @@ -843,6 +852,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx,
> AVPacket *avpkt)
>  av_frame_unref(ctx->delayed_frame);
>  AMF_RETURN_IF_FALSE(ctx, res_resubmit == AMF_OK,
> AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n",
> res_resubmit);
>
> +ctx->submitted_frame++;
>  ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
>  if (ret < 0)
>  return ret;
> @@ -861,7 +871,12 @@ int ff_amf_receive_packet(AVCodecContext *avctx,
> AVPacket *avpkt)
>  if (query_output_data_flag == 0) {
>  if (res_resubmit == AMF_INPUT_FULL || ctx->delayed_drain ||
> (ctx->eof && res_query != AMF_EOF) || (ctx->hwsurfaces_in_queue >=
> ctx->hwsurfaces_in_queue_max)) {
>  block_and_wait = 1;
> -av_usleep(1000);
> +
> +// Only sleep if the driver doesn't support waiting in
> QueryOutput()
> +// or if we already have output data so we will skip
> calling it.
> +if (!ctx->query_timeout_supported || avpkt->data ||
> avpkt->buf) {
> +av_usleep(1000);
> +}
>  }
>  }
>  } while (block_and_wait);
> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> index d985d01bb1..0b8ddd99ed 100644
> --- a/libavcodec/amfenc.h
> +++ b/libavcodec/amfenc.h
> @@ -68,6 +68,7 @@ typedef struct AmfContext {
>
>  int hwsurfaces_in_queue;
>  int hwsurfaces_in_queue_max;
> +int query_timeout_supported;
>
>  // helpers to handle async calls
>  int delayed_drain;
> @@ -77,6 +78,8 @@ typedef struct AmfContext {
>  // shift dts back by max_b_frames in timing
>  AVFifo *timestamp_list;
>  int64_t dts_delay;
> +int submitted_frame;
> +amf_booluse_b_frame;
>
>  // common encoder option options
>
> diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
> index 2a7a782063..f3058c5b96 100644
> --- a/libavcodec/amfenc_av1.c
> +++ b/libavcodec/amfenc_av1.c
> @@ -467,6 +467,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
>

Re: [FFmpeg-devel] [PATCH] avcodec/amfenc: add smart access video option

2025-03-11 Thread Araz
> It’s almost impossible to get what does this option do for user with good
> background on video encoding.
> Please add some comments here.
>
Yes, as Dennis Mungai said, this feature allows to use both APU and GPU
for decoding/encoding in a single pipeline.
It is supported on AMD Radeon CPU 5000 series and higher and RX 6000
series and higher graphics cards.
The average transcoding speed improves up to 30%.
This patch is tested on AMD Ryzen 5 7600X + AMD GPU RX6700XT.
To enable this feature, you need to select the hwaccel AMF input
and output as in the example below:
ffmpeg.exe -hwaccel amf -hwaccel_output_format amf -extra_hw_frames 33
-i input.mp4 -c:v hevc_amf -smart_access_video 1 -y output.mp4
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/amfenc: DX12 Reference-only feature support

2025-02-21 Thread Araz
>
> Benjamin Cheng Jan. 31, 2025, 1:22 a.m. UTC

This patch only affects d3d12va, why is the commit message amfenc?
>

We accept this review comment and update it in this patch:
avcodec/d3d12va_decode: enable reference-only decoder mode


> You could optimize these barriers since reference-only resources don't
> need to be transitioned to COMMON, and can remain in
> VIDEO_DECODE_{READ,WRITE}.
>
> I propose the following:
> - Transition all reference texture to VIDEO_DECODE_READ at creation time.
> - When preparing resources for input to DecodeFrame(), transition only
> the texture for reference output to VIDEO_DECODE_WRITE
> - After DecodeFrame(), transition the reference output texture to
> VIDEO_DECODE_READ. This is already implicitly handled by the barrier SWAP.
>
> All-in-all, for the cost of an initial transition at creation time, you
> decrease the number of barriers in each frame to just 2.


We have conducted some evaluation work
regarding the suggestions from the review:

1. The proposed method can successfully complete decoding,
and the playback quality of the decoded YUV raw data is normal.
However, during the execution, a large number of D3D12 errors
were encountered, and error sample is shown below.

D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists:
Using DecodeFrame on Command List (0x018A94557FD0:
'Unnamed ID3D12VideoDecodeCommandList Object'):
Resource state(0x 1: D3D12_RESOURCE_STATE_VIDEO_DECODE_READ) of
resource(0x018A95B1C740:'Unnamed ID3D12Resource Object')
(subresource : 1) must be in COMMON state when transitioning
to use in a different Command List type, because resource state on
previous Command List type : D3D12_COMMAND_LIST_TYPE_DIRECT,
is actually incompatible and different from that on the
next Command List type : D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE.
[RESOURCE_MANIPULATION ERROR #990:
RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE]

Further analysis revealed that...
According to the suggestion, when decoding each frame,
only the current reference texture should be transitioned
to VIDEO_DECODE_WRITE, and after DecodeFrame(), the current reference
texture should be transitioned to VIDEO_DECODE_READ (this is already
implicitly handled by the barrier FFSWAP).
For all other reference textures, they should remain in the READ state.
However, the evaluation shows that there is a problem when keeping
the all other reference textures in the READ state.
It expects a transition from COMMON to READ every time,
even if the texture is already in the READ state.
If the other reference textures does not transition to COMMON,
they will throw the D3D12 error mentioned above.
In other words, transitioning to the COMMON state is mandatory.

2. Performance testing.
We evaluated the performance of the currently submitted patent
and the performance of the suggested method from the review.
After conducting few dozen tests, minor changes were identified
that can be attributed to error,
since only 10 out of 18 tests showed a speed improvement of 0.2%.
The remaining 8 showed that the current method is faster
than the proposed one.

Tong Wu Feb. 10, 2025, 3:18 p.m. UTC
> Need to handle when DecodeTier == D3D12_VIDEO_DECODE_TIER_2?


The submitted patch has been tested on GPUs
supporting D3D12_VIDEO_DECODE_TIER_2
(GPU such as AMD RTX 7900XTX), and it works perfectly.
Therefore, no additional work is needed for D3D12_VIDEO_DECODE_TIER_2.

Lynne Feb. 10, 2025, 4:34 p.m. UTC
> This information doesn't belong here, and this value does definitely not
> belong here, as the hwcontext_d3d12.c code doesn't even touch it.
> We try to not put random internal fields in public structs anymore.


We accept this review comment and update it in this patch:
avcodec/d3d12va_decode: enable reference-only decoder mode
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/2] libavcodec/amfenc: Update AMF encoder options

2024-06-13 Thread Araz Iusubov
Encoder options have been updated to the current version of the AMF.

Signed-off-by: Araz Iusubov 
---
 libavcodec/amfenc_av1.c  | 108 +++--
 libavcodec/amfenc_h264.c | 146 +--
 libavcodec/amfenc_hevc.c | 143 +-
 3 files changed, 259 insertions(+), 138 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 9f18aac648..d40c71cb33 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -25,15 +25,16 @@
 #define OFFSET(x) offsetof(AmfContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, .unit = "usage" },
-{ "transcoding","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
-{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
 
-{ "profile","Set the profile (default main)",   
OFFSET(profile),AV_OPT_TYPE_INT,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
+{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, .unit = "usage" },
+{ "transcoding","Generic Transcoding",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING  
 }, 0, 0, VE, .unit = "usage" },
+{ "lowlatency", "Low latency usecase",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY  
 }, 0, 0, VE, .unit = "usage" },
+
+{ "profile","Set the profile",   OFFSET(profile),  
  AV_OPT_TYPE_INT,{.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
 { "main",   "", 0, AV_OPT_TYPE_CONST,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
 
-{ "level",  "Set the encoding level (default auto)",
OFFSET(level),  AV_OPT_TYPE_INT,{.i64 = 0 }, 0, 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, .unit = "level" },
-{ "auto",   "", 0, AV_OPT_TYPE_CONST, {.i64 = 0
   }, 0, 0, VE, .unit = "level" },
+{ "level",  "Set the encoding level (default auto)",
OFFSET(level),  AV_OPT_TYPE_INT,{.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, .unit = "level" },
+{ "auto",   "", 0, AV_OPT_TYPE_CONST, {.i64 = -1   
   }, 0, 0, VE, .unit = "level" },
 { "2.0","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_2_0 }, 0, 0, VE, .unit = "level" },
 { "2.1","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_2_1 }, 0, 0, VE, .unit = "level" },
 { "2.2","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_2_2 }, 0, 0, VE, .unit = "level" },
@@ -59,11 +60,12 @@ static const AVOption options[] = {
 { "7.2","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_2 }, 0, 0, VE, .unit = "level" },
 { "7.3","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_3 }, 0, 0, VE, .unit = "level" },
 
-{ "quality","Set the encoding quality", 
OFFSET(quality),AV_OPT_TYPE_INT,   {.i64 = 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY, 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, .unit = "quality" },
+{ "quality","Set the encoding quality preset", 
OFFSET(quality), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, .unit = "quality" },
+{ "

[FFmpeg-devel] [PATCH 1/2] libavcodec/amfenc: Update AMF release version

2024-06-13 Thread Araz Iusubov
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 8101b4fce6..23b140dc78 100755
--- a/configure
+++ b/configure
@@ -7364,7 +7364,7 @@ fi
 
 enabled amf &&
 check_cpp_condition amf "AMF/core/Version.h" \
-"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | 
AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x00010004001d"
+"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | 
AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x000100040021"
 
 # Funny iconv installations are not unusual, so check it after all flags have 
been set
 if enabled libc_iconv; then
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/4] avcodec/amfenc: Fixes the color information in the output.

2024-04-15 Thread Araz Iusubov
From: Michael Fabian 'Xaymar' Dirks 

added 10 bit support for amf hevc.

before:

command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file.mkv -an -c:v h264_amf res.dx11_hw_h264.mkv
output -  Format of input frames context (p010le) is not supported by AMF.
command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v hevc_amf res.dx11_hw_hevc.mkv
output -  Format of input frames context (p010le) is not supported by AMF.

after:

command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v h264_amf res.dx11_hw_h264.mkv
output -  10-bit input video is not supported by AMF H264 encoder
command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v hevc_amf res.dx11_hw_hevc.mkv
output -  10bit file

v2 - lost line returned in ff_amf_pix_fmts
v3 - fixes after review
v4 - extract duplicated code, fix incorrect processing of 10-bit input for h264
v5 - non-functional changes after review

Co-authored-by: Evgeny Pavlov 
---
 libavcodec/amfenc.c  | 37 +
 libavcodec/amfenc.h  |  3 +++
 libavcodec/amfenc_h264.c | 24 
 libavcodec/amfenc_hevc.c | 26 +-
 4 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 061859f85c..0bd15dd812 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -60,6 +60,7 @@ const enum AVPixelFormat ff_amf_pix_fmts[] = {
 #if CONFIG_DXVA2
 AV_PIX_FMT_DXVA2_VLD,
 #endif
+AV_PIX_FMT_P010,
 AV_PIX_FMT_NONE
 };
 
@@ -72,6 +73,7 @@ static const FormatMap format_map[] =
 {
 { AV_PIX_FMT_NONE,   AMF_SURFACE_UNKNOWN },
 { AV_PIX_FMT_NV12,   AMF_SURFACE_NV12 },
+{ AV_PIX_FMT_P010,   AMF_SURFACE_P010 },
 { AV_PIX_FMT_BGR0,   AMF_SURFACE_BGRA },
 { AV_PIX_FMT_RGB0,   AMF_SURFACE_RGBA },
 { AV_PIX_FMT_GRAY8,  AMF_SURFACE_GRAY8 },
@@ -785,6 +787,41 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 return ret;
 }
 
+int ff_amf_get_color_profile(AVCodecContext *avctx)
+{
+amf_int64 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+if (avctx->color_range == AVCOL_RANGE_JPEG) {
+/// Color Space for Full (JPEG) Range
+switch (avctx->colorspace) {
+case AVCOL_SPC_SMPTE170M:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+break;
+case AVCOL_SPC_BT709:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+break;
+case AVCOL_SPC_BT2020_NCL:
+case AVCOL_SPC_BT2020_CL:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+break;
+}
+} else {
+/// Color Space for Limited (MPEG) range
+switch (avctx->colorspace) {
+case AVCOL_SPC_SMPTE170M:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+break;
+case AVCOL_SPC_BT709:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+break;
+case AVCOL_SPC_BT2020_NCL:
+case AVCOL_SPC_BT2020_CL:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+break;
+}
+}
+return color_profile;
+}
+
 const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[] = {
 #if CONFIG_D3D11VA
 HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA),
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..62736ef579 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -21,6 +21,7 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -170,6 +171,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt);
 */
 extern const enum AVPixelFormat ff_amf_pix_fmts[];
 
+int ff_amf_get_color_profile(AVCodecContext *avctx);
+
 /**
 * Error handling helper
 */
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index bd544d12df..f785e091c9 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -199,6 +199,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext 
*avctx)
 AMFRate  framerate;
 AMFSize  framesize = 
AMFConstructSize(avctx->width, avctx->height);
 int  deblocking_filter = (avctx->flags & 
AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+amf_int64color_profile;
+enum AVPixelFormat pix_fmt;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 framerate = AMFConstructRate(avctx->framerate.num, 
avctx->framerate.den);
@@ -262,10 +264,24 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, 
AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
 }
 
-/// Color Range (Partial/TV/MPEG or Full/PC/JPEG)
- 

[FFmpeg-devel] [PATCH 2/4] avcodec/amfenc: HDR metadata.

2024-04-15 Thread Araz Iusubov
From: nyanmisaka 

v2: fixes for indentation
---
 libavcodec/amfenc.c | 83 +
 1 file changed, 83 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 0bd15dd812..068bb53002 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -36,6 +36,57 @@
 #include "amfenc.h"
 #include "encode.h"
 #include "internal.h"
+#include "libavutil/mastering_display_metadata.h"
+
+static int amf_save_hdr_metadata(AVCodecContext *avctx, const AVFrame *frame, 
AMFHDRMetadata *hdrmeta)
+{
+AVFrameSideData*sd_display;
+AVFrameSideData*sd_light;
+AVMasteringDisplayMetadata *display_meta;
+AVContentLightMetadata *light_meta;
+
+sd_display = av_frame_get_side_data(frame, 
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+if (sd_display) {
+display_meta = (AVMasteringDisplayMetadata *)sd_display->data;
+if (display_meta->has_luminance) {
+const unsigned int luma_den = 1;
+hdrmeta->maxMasteringLuminance =
+(amf_uint32)(luma_den * av_q2d(display_meta->max_luminance));
+hdrmeta->minMasteringLuminance =
+FFMIN((amf_uint32)(luma_den * 
av_q2d(display_meta->min_luminance)), hdrmeta->maxMasteringLuminance);
+}
+if (display_meta->has_primaries) {
+const unsigned int chroma_den = 5;
+hdrmeta->redPrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[0][0])), chroma_den);
+hdrmeta->redPrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[0][1])), chroma_den);
+hdrmeta->greenPrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[1][0])), chroma_den);
+hdrmeta->greenPrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[1][1])), chroma_den);
+hdrmeta->bluePrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[2][0])), chroma_den);
+hdrmeta->bluePrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[2][1])), chroma_den);
+hdrmeta->whitePoint[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->white_point[0])), chroma_den);
+hdrmeta->whitePoint[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->white_point[1])), chroma_den);
+}
+
+sd_light = av_frame_get_side_data(frame, 
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+if (sd_light) {
+light_meta = (AVContentLightMetadata *)sd_light->data;
+if (light_meta) {
+hdrmeta->maxContentLightLevel = (amf_uint16)light_meta->MaxCLL;
+hdrmeta->maxFrameAverageLightLevel = 
(amf_uint16)light_meta->MaxFALL;
+}
+}
+return 0;
+}
+return 1;
+}
 
 #if CONFIG_D3D11VA
 #include 
@@ -683,6 +734,26 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
 }
 
+// HDR10 metadata
+if (frame->color_trc == AVCOL_TRC_SMPTE2084) {
+AMFBuffer * hdrmeta_buffer = NULL;
+res = ctx->context->pVtbl->AllocBuffer(ctx->context, 
AMF_MEMORY_HOST, sizeof(AMFHDRMetadata), &hdrmeta_buffer);
+if (res == AMF_OK) {
+AMFHDRMetadata * hdrmeta = 
(AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
+if (amf_save_hdr_metadata(avctx, frame, hdrmeta) == 0) {
+switch (avctx->codec->id) {
+case AV_CODEC_ID_H264:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+case AV_CODEC_ID_HEVC:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+}
+res = amf_set_property_buffer(surface, 
L"av_frame_hdrmeta", hdrmeta_buffer);
+AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"SetProperty failed for \"av_frame_hdrmeta\" with error %d\n", res);
+}
+hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
+}
+}
+
 surface->pVtbl->SetPts(surface, frame->pts);
 AMF_ASSIGN_PROPERTY_INT64(res, surface, PTS_PROP, frame->pts);
 
@@ -746,6 +817,18 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 }
 res_resubmit = AMF_OK;
 if (ctx->delayed_surface != NULL) { // try to resubmit frame
+if (ctx->delayed_surface->pVtbl->HasProperty(ctx->delayed_surface, 
L"av_frame_hdrmeta")) {
+AMFBuffer

[FFmpeg-devel] [PATCH 3/4] avcodec/amfenc: add 10 bit encoding in av1_amf

2024-04-15 Thread Araz Iusubov
From: Evgeny Pavlov 

v2: refactored after review

Signed-off-by: Evgeny Pavlov 
Co-authored-by: Dmitrii Ovchinnikov 
---
 libavcodec/amfenc.c |  2 ++
 libavcodec/amfenc_av1.c | 22 ++
 2 files changed, 24 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 068bb53002..f1b76bd6aa 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -826,6 +826,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer); break;
 case AV_CODEC_ID_HEVC:
 AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+case AV_CODEC_ID_AV1:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_INPUT_HDR_METADATA, hdrmeta_buffer); break;
 }
 hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
 }
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 8f13aea29e..634eeea48f 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -165,6 +165,9 @@ static av_cold int amf_encode_init_av1(AVCodecContext* 
avctx)
 AMFGuid guid;
 AMFRate framerate;
 AMFSize framesize = AMFConstructSize(avctx->width, 
avctx->height);
+amf_int64   color_depth;
+amf_int64   color_profile;
+enumAVPixelFormat pix_fmt;
 
 
 
@@ -203,6 +206,25 @@ FF_ENABLE_DEPRECATION_WARNINGS
 }
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_PROFILE, profile);
 
+/// Color profile
+color_profile = ff_amf_get_color_profile(avctx);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+
+/// Color Depth
+pix_fmt = avctx->hw_frames_ctx ? 
((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
+: avctx->pix_fmt;
+color_depth = AMF_COLOR_BIT_DEPTH_8;
+if (pix_fmt == AV_PIX_FMT_P010) {
+color_depth = AMF_COLOR_BIT_DEPTH_10;
+}
+
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+/// Color Transfer Characteristics (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
(amf_int64)avctx->color_trc);
+/// Color Primaries (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, 
(amf_int64)avctx->color_primaries);
+
 profile_level = avctx->level;
 if (profile_level == AV_LEVEL_UNKNOWN) {
 profile_level = ctx->level;
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/4] avcodec/amfenc: GPU driver version check

2024-04-15 Thread Araz Iusubov
Implemented gpu driver check.
10-bit patch works incorrectly on driver version lower than 23.30.

---
 libavcodec/amfenc_av1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 634eeea48f..7463251529 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -215,6 +215,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 : avctx->pix_fmt;
 color_depth = AMF_COLOR_BIT_DEPTH_8;
 if (pix_fmt == AV_PIX_FMT_P010) {
+AMF_RETURN_IF_FALSE(ctx, ctx->version >= AMF_MAKE_FULL_VERSION(1, 4, 
32, 0), AVERROR_UNKNOWN, "HEVC 10-bit encoder is not supported by AMD GPU 
drivers versions lower than 23.30.\n");
 color_depth = AMF_COLOR_BIT_DEPTH_10;
 }
 
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH, v2] libavcodec/amfenc: Update AMF encoder options

2024-04-27 Thread Araz Iusubov
Encoder options have been updated to the current version of the AMF.

Signed-off-by: Araz Iusubov 
---
 libavcodec/amfenc_av1.c  | 108 +++--
 libavcodec/amfenc_h264.c | 146 +--
 libavcodec/amfenc_hevc.c | 143 +-
 3 files changed, 259 insertions(+), 138 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 9f18aac648..d40c71cb33 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -25,15 +25,16 @@
 #define OFFSET(x) offsetof(AmfContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, .unit = "usage" },
-{ "transcoding","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
-{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
 
-{ "profile","Set the profile (default main)",   
OFFSET(profile),AV_OPT_TYPE_INT,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
+{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, .unit = "usage" },
+{ "transcoding","Generic Transcoding",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING  
 }, 0, 0, VE, .unit = "usage" },
+{ "lowlatency", "Low latency usecase",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY  
 }, 0, 0, VE, .unit = "usage" },
+
+{ "profile","Set the profile",   OFFSET(profile),  
  AV_OPT_TYPE_INT,{.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
 { "main",   "", 0, AV_OPT_TYPE_CONST,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
 
-{ "level",  "Set the encoding level (default auto)",
OFFSET(level),  AV_OPT_TYPE_INT,{.i64 = 0 }, 0, 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, .unit = "level" },
-{ "auto",   "", 0, AV_OPT_TYPE_CONST, {.i64 = 0
   }, 0, 0, VE, .unit = "level" },
+{ "level",  "Set the encoding level (default auto)",
OFFSET(level),  AV_OPT_TYPE_INT,{.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_3, VE, .unit = "level" },
+{ "auto",   "", 0, AV_OPT_TYPE_CONST, {.i64 = -1   
   }, 0, 0, VE, .unit = "level" },
 { "2.0","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_2_0 }, 0, 0, VE, .unit = "level" },
 { "2.1","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_2_1 }, 0, 0, VE, .unit = "level" },
 { "2.2","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_2_2 }, 0, 0, VE, .unit = "level" },
@@ -59,11 +60,12 @@ static const AVOption options[] = {
 { "7.2","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_2 }, 0, 0, VE, .unit = "level" },
 { "7.3","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_LEVEL_7_3 }, 0, 0, VE, .unit = "level" },
 
-{ "quality","Set the encoding quality", 
OFFSET(quality),AV_OPT_TYPE_INT,   {.i64 = 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED }, 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY, 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, .unit = "quality" },
+{ "quality","Set the encoding quality preset", 
OFFSET(quality), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_SPEED, VE, .unit = "quality" },
+{ "

[FFmpeg-devel] [PATCH] avcodec/vaapi_encode: add customized surface alignment

2024-03-06 Thread Araz Iusubov
This commit fixes issues with AMD HEVC encoding. 
By default AMD hevc encoder asks for the alignment 64x16, while FFMPEG VAAPI 
has 16x16. 
Adding support for customzied surface size from VASurfaceAttribAlignmentSize in 
VAAPI version 1.21.0.

To: primeadv...@gmail.com

Signed-off-by: Araz Iusubov 
---
 libavcodec/vaapi_encode.c   | 11 +++
 libavutil/hwcontext.h   |  7 +++
 libavutil/hwcontext_vaapi.c |  5 +
 3 files changed, 23 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 808b79c0c7..dc1b7465b7 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -2700,6 +2700,17 @@ static av_cold int 
vaapi_encode_create_recon_frames(AVCodecContext *avctx)
 av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
"reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
 
+if (constraints->log2_alignment) {
+ctx->surface_width = FFALIGN(avctx->width,
+  1 << (constraints->log2_alignment & 0xf));
+ctx->surface_height = FFALIGN(avctx->height,
+  1 << ((constraints->log2_alignment & 0xf0) >> 
4));
+av_log(avctx, AV_LOG_VERBOSE, "Using customized alignment size "
+"[%dx%d].\n",
+(1 << (constraints->log2_alignment & 0xf)),
+(1 << ((constraints->log2_alignment & 0xf0) >> 4)));
+}
+
 if (ctx->surface_width  < constraints->min_width  ||
 ctx->surface_height < constraints->min_height ||
 ctx->surface_width  > constraints->max_width ||
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index df7733fe5e..5725245be4 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -481,6 +481,13 @@ typedef struct AVHWFramesConstraints {
  */
 int max_width;
 int max_height;
+
+/**
+ * The frame width/height log2 alignment when available
+ * the lower 4 bits, width; another 4 bits, height
+ * (Zero is not applied, use the default value)
+ */
+int log2_alignment;
 } AVHWFramesConstraints;
 
 /**
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 2c75f5f5b1..161623bc27 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -294,6 +294,11 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext 
*hwdev,
 case VASurfaceAttribMaxHeight:
 constraints->max_height = attr_list[i].value.value.i;
 break;
+#if VA_CHECK_VERSION(1, 21, 0)
+case VASurfaceAttribAlignmentSize:
+constraints->log2_alignment = attr_list[i].value.value.i;
+break;
+#endif
 }
 }
 if (pix_fmt_count == 0) {
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] libavcodec/amfenc: Update AMF encoder options

2024-03-14 Thread Araz Iusubov
The encoder options have been updated to the current version of the AMF.

Signed-off-by: Araz Iusubov 
---
 libavcodec/amfenc.c  |   1 +
 libavcodec/amfenc.h  |   4 +
 libavcodec/amfenc_av1.c  | 154 +-
 libavcodec/amfenc_h264.c | 155 +-
 libavcodec/amfenc_hevc.c | 158 ++-
 5 files changed, 314 insertions(+), 158 deletions(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 061859f85c..6b1e635a03 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -468,6 +468,7 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket 
*pkt, AMFBuffer *buff
 if (var.int64Value == AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_KEY) 
{
 pkt->flags = AV_PKT_FLAG_KEY;
 }
+break;
 default:
 break;
 }
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..1b8cfdf4a5 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -59,6 +59,7 @@ typedef struct AmfContext {
 AMFContext *context; ///< AMF context
 //encoder
 AMFComponent   *encoder; ///< AMF encoder object
+AMFCaps*encoder_caps;
 amf_booleof; ///< flag indicating EOF happened
 AMF_SURFACE_FORMAT  format;  ///< AMF surface format
 
@@ -85,6 +86,7 @@ typedef struct AmfContext {
 int usage;
 int profile;
 int level;
+int latency;
 int preencode;
 int quality;
 int b_frame_delta_qp;
@@ -112,6 +114,7 @@ typedef struct AmfContext {
 int max_b_frames;
 int qvbr_quality_level;
 int hw_high_motion_quality_boost;
+int encoder_instance_id;
 
 // HEVC - specific options
 
@@ -126,6 +129,7 @@ typedef struct AmfContext {
 // AV1 - specific options
 
 enum AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_ENUM align;
+enum AMF_VIDEO_ENCODER_AV1_AQ_MODE_ENUMaq_mode;
 
 // Preanalysis - specific options
 
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 3878f0d461..50f75b53e2 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -24,12 +24,17 @@
 
 #define OFFSET(x) offsetof(AmfContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
-static const AVOption options[] = {
-{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, .unit = "usage" },
-{ "transcoding","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
-{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
 
-{ "profile","Set the profile (default main)",   
OFFSET(profile),AV_OPT_TYPE_INT,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
+static const AVOption options[] = {
+{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
+{ "transcoding","Generic Transcoding",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING  
 }, 0, 0, VE, "usage" },
+{ "ultralowlatency","ultra low latency trancoding", 0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_ULTRA_LOW_LATENCY
 }, 0, 0, VE, "usage" },
+{ "lowlatency", "low latency trancoding",   0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY  
 }, 0, 0, VE, "usage" },
+{ "webcam", "Webcam",   0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_WEBCAM   
 }, 0, 0, VE, "usage" },
+{ "high_quality",   "high quality trancoding",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_HIGH_QUALITY 
 }, 0, 0, VE, "usage" },
+{ "lowlatency_high_quality","low latency yet high quality

[FFmpeg-devel] [PATCH] [FFmpeg-devel, v2] avcodec/vaapi_encode: add customized surface alignment

2024-03-21 Thread Araz Iusubov
This commit fixes issues with AMD HEVC encoding. 
By default AMD hevc encoder asks for the alignment 64x16, while FFMPEG VAAPI 
has 16x16. 
Adding support for customized surface size from VASurfaceAttribAlignmentSize in 
VAAPI version 1.21.0

Signed-off-by: Araz Iusubov 
---
 libavcodec/vaapi_encode.c   | 11 +++
 libavutil/hwcontext.h   |  7 +++
 libavutil/hwcontext_vaapi.c |  5 +
 3 files changed, 23 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 940f0678a5..2a74db23b1 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -2711,6 +2711,17 @@ static av_cold int 
vaapi_encode_create_recon_frames(AVCodecContext *avctx)
 av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
"reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
 
+if (constraints->log2_alignment) {
+ctx->surface_width = FFALIGN(avctx->width,
+  1 << (constraints->log2_alignment & 0xf));
+ctx->surface_height = FFALIGN(avctx->height,
+  1 << ((constraints->log2_alignment & 0xf0) >> 
4));
+av_log(avctx, AV_LOG_VERBOSE, "Using customized alignment size "
+"[%dx%d].\n",
+(1 << (constraints->log2_alignment & 0xf)),
+(1 << ((constraints->log2_alignment & 0xf0) >> 4)));
+}
+
 if (ctx->surface_width  < constraints->min_width  ||
 ctx->surface_height < constraints->min_height ||
 ctx->surface_width  > constraints->max_width ||
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..1eb56aff78 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -465,6 +465,13 @@ typedef struct AVHWFramesConstraints {
  */
 int max_width;
 int max_height;
+
+/**
+ * The frame width/height log2 alignment when available
+ * the lower 4 bits, width; another 4 bits, height
+ * (Zero is not applied, use the default value)
+ */
+int log2_alignment;
 } AVHWFramesConstraints;
 
 /**
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 56d03aa4cd..6cda0fd811 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -294,6 +294,11 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext 
*hwdev,
 case VASurfaceAttribMaxHeight:
 constraints->max_height = attr_list[i].value.value.i;
 break;
+#if VA_CHECK_VERSION(1, 21, 0)
+case VASurfaceAttribAlignmentSize:
+constraints->log2_alignment = attr_list[i].value.value.i;
+break;
+#endif
 }
 }
 if (pix_fmt_count == 0) {
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] [FFmpeg-devel, v3] avcodec/vaapi_encode: add customized surface alignment

2024-03-21 Thread Araz Iusubov
This commit fixes issues with AMD HEVC encoding. 
By default AMD hevc encoder asks for the alignment 64x16, while FFMPEG VAAPI 
has 16x16. 
Adding support for customized surface size from VASurfaceAttribAlignmentSize in 
VAAPI version 1.21.0

Signed-off-by: Araz Iusubov 
---
 libavcodec/vaapi_encode.c   | 11 +++
 libavutil/hwcontext.h   |  7 +++
 libavutil/hwcontext_vaapi.c |  5 +
 3 files changed, 23 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 940f0678a5..2a74db23b1 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -2711,6 +2711,17 @@ static av_cold int 
vaapi_encode_create_recon_frames(AVCodecContext *avctx)
 av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
"reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
 
+if (constraints->log2_alignment) {
+ctx->surface_width = FFALIGN(avctx->width,
+  1 << (constraints->log2_alignment & 0xf));
+ctx->surface_height = FFALIGN(avctx->height,
+  1 << ((constraints->log2_alignment & 0xf0) >> 
4));
+av_log(avctx, AV_LOG_VERBOSE, "Using customized alignment size "
+"[%dx%d].\n",
+(1 << (constraints->log2_alignment & 0xf)),
+(1 << ((constraints->log2_alignment & 0xf0) >> 4)));
+}
+
 if (ctx->surface_width  < constraints->min_width  ||
 ctx->surface_height < constraints->min_height ||
 ctx->surface_width  > constraints->max_width ||
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..1eb56aff78 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -465,6 +465,13 @@ typedef struct AVHWFramesConstraints {
  */
 int max_width;
 int max_height;
+
+/**
+ * The frame width/height log2 alignment when available
+ * the lower 4 bits, width; another 4 bits, height
+ * (Zero is not applied, use the default value)
+ */
+int log2_alignment;
 } AVHWFramesConstraints;
 
 /**
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 56d03aa4cd..6cda0fd811 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -294,6 +294,11 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext 
*hwdev,
 case VASurfaceAttribMaxHeight:
 constraints->max_height = attr_list[i].value.value.i;
 break;
+#if VA_CHECK_VERSION(1, 21, 0)
+case VASurfaceAttribAlignmentSize:
+constraints->log2_alignment = attr_list[i].value.value.i;
+break;
+#endif
 }
 }
 if (pix_fmt_count == 0) {
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] [v4] avcodec/vaapi_encode: add customized surface alignment

2024-03-21 Thread Araz Iusubov
This commit fixes issues with AMD HEVC encoding. 
By default AMD hevc encoder asks for the alignment 64x16, while FFMPEG VAAPI 
has 16x16. 
Adding support for customized surface size from VASurfaceAttribAlignmentSize in 
VAAPI version 1.21.0

Signed-off-by: Araz Iusubov 
---
 libavcodec/vaapi_encode.c   | 11 +++
 libavutil/hwcontext.h   |  7 +++
 libavutil/hwcontext_vaapi.c |  5 +
 3 files changed, 23 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 940f0678a5..2a74db23b1 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -2711,6 +2711,17 @@ static av_cold int 
vaapi_encode_create_recon_frames(AVCodecContext *avctx)
 av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
"reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
 
+if (constraints->log2_alignment) {
+ctx->surface_width = FFALIGN(avctx->width,
+  1 << (constraints->log2_alignment & 0xf));
+ctx->surface_height = FFALIGN(avctx->height,
+  1 << ((constraints->log2_alignment & 0xf0) >> 
4));
+av_log(avctx, AV_LOG_VERBOSE, "Using customized alignment size "
+"[%dx%d].\n",
+(1 << (constraints->log2_alignment & 0xf)),
+(1 << ((constraints->log2_alignment & 0xf0) >> 4)));
+}
+
 if (ctx->surface_width  < constraints->min_width  ||
 ctx->surface_height < constraints->min_height ||
 ctx->surface_width  > constraints->max_width ||
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..1eb56aff78 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -465,6 +465,13 @@ typedef struct AVHWFramesConstraints {
  */
 int max_width;
 int max_height;
+
+/**
+ * The frame width/height log2 alignment when available
+ * the lower 4 bits, width; another 4 bits, height
+ * (Zero is not applied, use the default value)
+ */
+int log2_alignment;
 } AVHWFramesConstraints;
 
 /**
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 56d03aa4cd..6cda0fd811 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -294,6 +294,11 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext 
*hwdev,
 case VASurfaceAttribMaxHeight:
 constraints->max_height = attr_list[i].value.value.i;
 break;
+#if VA_CHECK_VERSION(1, 21, 0)
+case VASurfaceAttribAlignmentSize:
+constraints->log2_alignment = attr_list[i].value.value.i;
+break;
+#endif
 }
 }
 if (pix_fmt_count == 0) {
-- 
2.43.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/4] avcodec/amfenc: Fixes the color information in the output.

2024-07-15 Thread Araz Iusubov
added 10 bit support for amf hevc.

before:

command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file.mkv -an -c:v h264_amf res.dx11_hw_h264.mkv
output -  Format of input frames context (p010le) is not supported by AMF.
command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v hevc_amf res.dx11_hw_hevc.mkv
output -  Format of input frames context (p010le) is not supported by AMF.

after:

command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v h264_amf res.dx11_hw_h264.mkv
output -  10-bit input video is not supported by AMF H264 encoder
command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v hevc_amf res.dx11_hw_hevc.mkv
output -  10bit file

v2 - lost line returned in ff_amf_pix_fmts
v3 - fixes after review
v4 - extract duplicated code, fix incorrect processing of 10-bit input for h264
v5 - non-functional changes after review

Co-authored-by: Evgeny Pavlov 
---
 libavcodec/amfenc.c  | 37 +
 libavcodec/amfenc.h  |  3 +++
 libavcodec/amfenc_h264.c | 24 
 libavcodec/amfenc_hevc.c | 31 ++-
 4 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 061859f85c..0bd15dd812 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -60,6 +60,7 @@ const enum AVPixelFormat ff_amf_pix_fmts[] = {
 #if CONFIG_DXVA2
 AV_PIX_FMT_DXVA2_VLD,
 #endif
+AV_PIX_FMT_P010,
 AV_PIX_FMT_NONE
 };
 
@@ -72,6 +73,7 @@ static const FormatMap format_map[] =
 {
 { AV_PIX_FMT_NONE,   AMF_SURFACE_UNKNOWN },
 { AV_PIX_FMT_NV12,   AMF_SURFACE_NV12 },
+{ AV_PIX_FMT_P010,   AMF_SURFACE_P010 },
 { AV_PIX_FMT_BGR0,   AMF_SURFACE_BGRA },
 { AV_PIX_FMT_RGB0,   AMF_SURFACE_RGBA },
 { AV_PIX_FMT_GRAY8,  AMF_SURFACE_GRAY8 },
@@ -785,6 +787,41 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 return ret;
 }
 
+int ff_amf_get_color_profile(AVCodecContext *avctx)
+{
+amf_int64 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+if (avctx->color_range == AVCOL_RANGE_JPEG) {
+/// Color Space for Full (JPEG) Range
+switch (avctx->colorspace) {
+case AVCOL_SPC_SMPTE170M:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+break;
+case AVCOL_SPC_BT709:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+break;
+case AVCOL_SPC_BT2020_NCL:
+case AVCOL_SPC_BT2020_CL:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+break;
+}
+} else {
+/// Color Space for Limited (MPEG) range
+switch (avctx->colorspace) {
+case AVCOL_SPC_SMPTE170M:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+break;
+case AVCOL_SPC_BT709:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+break;
+case AVCOL_SPC_BT2020_NCL:
+case AVCOL_SPC_BT2020_CL:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+break;
+}
+}
+return color_profile;
+}
+
 const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[] = {
 #if CONFIG_D3D11VA
 HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA),
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..62736ef579 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -21,6 +21,7 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -170,6 +171,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt);
 */
 extern const enum AVPixelFormat ff_amf_pix_fmts[];
 
+int ff_amf_get_color_profile(AVCodecContext *avctx);
+
 /**
 * Error handling helper
 */
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 32baa8e91a..7caeca748d 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -200,6 +200,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext 
*avctx)
 AMFRate  framerate;
 AMFSize  framesize = 
AMFConstructSize(avctx->width, avctx->height);
 int  deblocking_filter = (avctx->flags & 
AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+amf_int64color_profile;
+enum AVPixelFormat pix_fmt;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 framerate = AMFConstructRate(avctx->framerate.num, 
avctx->framerate.den);
@@ -270,10 +272,24 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, 
AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
 }
 
-/// Color Range (Partial/TV/MPEG or Full/PC/JPEG)
-if (avctx->color_range == AVCO

[FFmpeg-devel] [PATCH 2/4] avcodec/amfenc: HDR metadata.

2024-07-15 Thread Araz Iusubov
v2: fixes for indentation
---
 libavcodec/amfenc.c | 83 +
 1 file changed, 83 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 0bd15dd812..068bb53002 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -36,6 +36,57 @@
 #include "amfenc.h"
 #include "encode.h"
 #include "internal.h"
+#include "libavutil/mastering_display_metadata.h"
+
+static int amf_save_hdr_metadata(AVCodecContext *avctx, const AVFrame *frame, 
AMFHDRMetadata *hdrmeta)
+{
+AVFrameSideData*sd_display;
+AVFrameSideData*sd_light;
+AVMasteringDisplayMetadata *display_meta;
+AVContentLightMetadata *light_meta;
+
+sd_display = av_frame_get_side_data(frame, 
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+if (sd_display) {
+display_meta = (AVMasteringDisplayMetadata *)sd_display->data;
+if (display_meta->has_luminance) {
+const unsigned int luma_den = 1;
+hdrmeta->maxMasteringLuminance =
+(amf_uint32)(luma_den * av_q2d(display_meta->max_luminance));
+hdrmeta->minMasteringLuminance =
+FFMIN((amf_uint32)(luma_den * 
av_q2d(display_meta->min_luminance)), hdrmeta->maxMasteringLuminance);
+}
+if (display_meta->has_primaries) {
+const unsigned int chroma_den = 5;
+hdrmeta->redPrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[0][0])), chroma_den);
+hdrmeta->redPrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[0][1])), chroma_den);
+hdrmeta->greenPrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[1][0])), chroma_den);
+hdrmeta->greenPrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[1][1])), chroma_den);
+hdrmeta->bluePrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[2][0])), chroma_den);
+hdrmeta->bluePrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[2][1])), chroma_den);
+hdrmeta->whitePoint[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->white_point[0])), chroma_den);
+hdrmeta->whitePoint[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->white_point[1])), chroma_den);
+}
+
+sd_light = av_frame_get_side_data(frame, 
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+if (sd_light) {
+light_meta = (AVContentLightMetadata *)sd_light->data;
+if (light_meta) {
+hdrmeta->maxContentLightLevel = (amf_uint16)light_meta->MaxCLL;
+hdrmeta->maxFrameAverageLightLevel = 
(amf_uint16)light_meta->MaxFALL;
+}
+}
+return 0;
+}
+return 1;
+}
 
 #if CONFIG_D3D11VA
 #include 
@@ -683,6 +734,26 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
 }
 
+// HDR10 metadata
+if (frame->color_trc == AVCOL_TRC_SMPTE2084) {
+AMFBuffer * hdrmeta_buffer = NULL;
+res = ctx->context->pVtbl->AllocBuffer(ctx->context, 
AMF_MEMORY_HOST, sizeof(AMFHDRMetadata), &hdrmeta_buffer);
+if (res == AMF_OK) {
+AMFHDRMetadata * hdrmeta = 
(AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
+if (amf_save_hdr_metadata(avctx, frame, hdrmeta) == 0) {
+switch (avctx->codec->id) {
+case AV_CODEC_ID_H264:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+case AV_CODEC_ID_HEVC:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+}
+res = amf_set_property_buffer(surface, 
L"av_frame_hdrmeta", hdrmeta_buffer);
+AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"SetProperty failed for \"av_frame_hdrmeta\" with error %d\n", res);
+}
+hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
+}
+}
+
 surface->pVtbl->SetPts(surface, frame->pts);
 AMF_ASSIGN_PROPERTY_INT64(res, surface, PTS_PROP, frame->pts);
 
@@ -746,6 +817,18 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 }
 res_resubmit = AMF_OK;
 if (ctx->delayed_surface != NULL) { // try to resubmit frame
+if (ctx->delayed_surface->pVtbl->HasProperty(ctx->delayed_surface, 
L"av_frame_hdrmeta")) {
+AMFBuffer * hdrmeta_buffer =

[FFmpeg-devel] [PATCH 3/4] avcodec/amfenc: add 10 bit encoding in av1_amf

2024-07-15 Thread Araz Iusubov
v2: refactored after review

Signed-off-by: Evgeny Pavlov 
Co-authored-by: Dmitrii Ovchinnikov 
---
 libavcodec/amfenc.c |  2 ++
 libavcodec/amfenc_av1.c | 27 +++
 2 files changed, 29 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 068bb53002..f1b76bd6aa 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -826,6 +826,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer); break;
 case AV_CODEC_ID_HEVC:
 AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+case AV_CODEC_ID_AV1:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_INPUT_HDR_METADATA, hdrmeta_buffer); break;
 }
 hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
 }
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index d40c71cb33..a8629d74b0 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -166,6 +166,9 @@ static av_cold int amf_encode_init_av1(AVCodecContext* 
avctx)
 AMFGuid guid;
 AMFRate framerate;
 AMFSize framesize = AMFConstructSize(avctx->width, 
avctx->height);
+amf_int64   color_depth;
+amf_int64   color_profile;
+enumAVPixelFormat pix_fmt;
 
 
 
@@ -211,6 +214,30 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_PROFILE, profile);
 }
 
+/// Color profile
+color_profile = ff_amf_get_color_profile(avctx);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+
+/// Color Depth
+pix_fmt = avctx->hw_frames_ctx ? 
((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
+: avctx->pix_fmt;
+color_depth = AMF_COLOR_BIT_DEPTH_8;
+if (pix_fmt == AV_PIX_FMT_P010) {
+color_depth = AMF_COLOR_BIT_DEPTH_10;
+}
+
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
+/// Color Transfer Characteristics (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
+/// Color Primaries (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
+} else {
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
+}
+
 profile_level = avctx->level;
 if (profile_level == AV_LEVEL_UNKNOWN) {
 profile_level = ctx->level;
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/4] avcodec/amfenc: GPU driver version check

2024-07-15 Thread Araz Iusubov
Implemented gpu driver check.
10-bit patch works incorrectly on driver version lower than 23.30.

---
 libavcodec/amfenc_av1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index a8629d74b0..cfa319f933 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -223,6 +223,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 : avctx->pix_fmt;
 color_depth = AMF_COLOR_BIT_DEPTH_8;
 if (pix_fmt == AV_PIX_FMT_P010) {
+AMF_RETURN_IF_FALSE(ctx, ctx->version >= AMF_MAKE_FULL_VERSION(1, 4, 
32, 0), AVERROR_UNKNOWN, "HEVC 10-bit encoder is not supported by AMD GPU 
drivers versions lower than 23.30.\n");
 color_depth = AMF_COLOR_BIT_DEPTH_10;
 }
 
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/amf_enc: new encoder features support

2024-07-17 Thread Araz Iusubov
Implemented:
New usage modes for AV1 encoder.
Latency mode for H264, HEVC and AV1 encoders.
Adaptive Quantization (AQ) mode in AV1 encoder.

---
 libavcodec/amfenc.h  |  2 ++
 libavcodec/amfenc_av1.c  | 24 +++-
 libavcodec/amfenc_h264.c |  5 +
 libavcodec/amfenc_hevc.c |  6 ++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index cee47888a4..e53b57d369 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -86,6 +86,7 @@ typedef struct AmfContext {
 int usage;
 int profile;
 int level;
+int latency;
 int preencode;
 int quality;
 int b_frame_delta_qp;
@@ -127,6 +128,7 @@ typedef struct AmfContext {
 // AV1 - specific options
 
 enum AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_ENUM align;
+enum AMF_VIDEO_ENCODER_AV1_AQ_MODE_ENUMaq_mode;
 
 // Preanalysis - specific options
 
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index de76161524..f23d94b692 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -25,9 +25,13 @@
 #define OFFSET(x) offsetof(AmfContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY, VE, .unit = "usage" },
+{ "usage",  "Set the encoding usage",   
OFFSET(usage),  AV_OPT_TYPE_INT,   {.i64 = -1 }, -1, 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, .unit = "usage" },
 { "transcoding","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
+{ "ultralowlatency","ultra low latency trancoding", 0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_ULTRA_LOW_LATENCY
 }, 0, 0, VE, .unit = "usage" },
 { "lowlatency", "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY }, 0, 0, VE, .unit = "usage" },
+{ "webcam", "Webcam",   0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_WEBCAM   
 }, 0, 0, VE, .unit = "usage" },
+{ "high_quality",   "high quality trancoding",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_HIGH_QUALITY 
 }, 0, 0, VE, .unit = "usage" },
+{ "lowlatency_high_quality","low latency yet high quality trancoding",  0, 
AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY 
 }, 0, 0, VE, .unit = "usage" },
 
 { "profile","Set the profile (default main)",   
OFFSET(profile),AV_OPT_TYPE_INT,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN, VE, .unit = "profile" },
 { "main",   "", 0, AV_OPT_TYPE_CONST,{.i64 = 
AMF_VIDEO_ENCODER_AV1_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
@@ -65,6 +69,12 @@ static const AVOption options[] = {
 { "quality","", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_QUALITY   }, 0, 0, VE, .unit = 
"quality" },
 { "high_quality",   "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_HIGH_QUALITY  }, 0, 0, VE, .unit = 
"quality" },
 
+{ "latency","Set the encoding latency mode",
OFFSET(latency),AV_OPT_TYPE_INT,{.i64 = -1 }, 
-1, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY, VE, .unit = 
"latency_mode" },
+{ "none",   "No encoding latency requirement.", 0, 
 AV_OPT_TYPE_CONST,  {.i64 = 
AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_NONE  }, 0, 0, 
VE, .unit = "latency_mode" },
+{ "power_saving_real_time", "Try the best to finish encoding a frame 
within 1/framerate sec.", 0,   AV_OPT_TYPE_CONST,  {.i64 = 
AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_POWER_SAVING_REAL_TIME}, 0, 0, 
VE, .unit = "latency_mode" },
+{ "real_time",  "Try the best to finish encoding a frame 
within 1/(2 x framerate) sec.", 0, AV_OPT_TYPE_CONST,  {.i64 = 
AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_REAL_TIME }, 0, 0, 
VE, .unit = "latency_mode" },
+{ "lowest_latency", "Encoding as fast as possible. This mode 
causes highest power consumption", 0,  AV_OPT_TYPE_CONST,  {.i64 = 
AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY  

[FFmpeg-devel] [PATCH] avcodec/amf_enc: av1 cropping support

2024-07-23 Thread Araz Iusubov
---
 libavcodec/amfenc_av1.c | 82 -
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index d40c71cb33..27599b9fbe 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -22,6 +22,9 @@
 #include "amfenc.h"
 #include "codec_internal.h"
 
+#define AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL
L"Av1WidthAlignmentFactor"  // amf_int64; default = 1
+#define AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL   
L"Av1HeightAlignmentFactor" // amf_int64; default = 1
+
 #define OFFSET(x) offsetof(AmfContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
@@ -167,7 +170,13 @@ static av_cold int amf_encode_init_av1(AVCodecContext* 
avctx)
 AMFRate framerate;
 AMFSize framesize = AMFConstructSize(avctx->width, 
avctx->height);
 
-
+//for av1 alignment and crop
+AVPacketSideData*   sd_crop = NULL;
+uint32_t*   crop= NULL;
+uint32_tcrop_right  = 0;
+uint32_tcrop_bottom = 0;
+int width_alignment_factor  = -1;
+int height_alignment_factor = -1;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 framerate = AMFConstructRate(avctx->framerate.num, 
avctx->framerate.den);
@@ -482,6 +491,77 @@ FF_ENABLE_DEPRECATION_WARNINGS
 buffer->pVtbl->Release(buffer);
 var.pInterface->pVtbl->Release(var.pInterface);
 
+//processing crop informaiton according to alignment
+if (ctx->encoder->pVtbl->GetProperty(ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL, &var) != AMF_OK)
+{
+// assume older driver and Navi3x
+width_alignment_factor = 64;
+}
+else
+{
+width_alignment_factor = (int)var.int64Value;
+}
+
+if (ctx->encoder->pVtbl->GetProperty(ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL, &var) != AMF_OK)
+{
+// assume older driver and Navi3x
+height_alignment_factor = 16;
+}
+else
+{
+height_alignment_factor = (int)var.int64Value;
+}
+
+if (width_alignment_factor != -1 &&  height_alignment_factor != -1)
+{
+if (avctx->width % width_alignment_factor != 0)
+{
+crop_right = width_alignment_factor - (avctx->width & 
(width_alignment_factor - 1));
+}
+
+if (avctx->height % height_alignment_factor != 0)
+{
+crop_bottom = height_alignment_factor - (avctx->height & 
(height_alignment_factor - 1));
+}
+
+//There is specia processing for crop_bottom equal to 8 in hardware 
+if (crop_bottom == 8)
+{
+crop_bottom = 2;
+}
+}
+
+if (crop_right != 0 || crop_bottom != 0)
+{
+sd_crop = av_realloc_array(avctx->coded_side_data, 
avctx->nb_coded_side_data + 1, sizeof(*sd_crop));
+if (!sd_crop)
+{
+av_log(ctx, AV_LOG_WARNING, "Can't allocate memory for amf av1 
encoder crop information\n");
+return AVERROR(ENOMEM);
+}
+
+sd_crop->data = (uint8_t*)av_mallocz(sizeof(uint32_t) * 4);
+if (!sd_crop->data)
+{
+av_log(ctx, AV_LOG_WARNING, "Can't allocate memory for amf av1 
encoder crop information\n");
+return AVERROR(ENOMEM);
+}
+
+crop = (uint32_t*)sd_crop->data;
+
+//top, bottom, left,right
+*crop++ = 0;
+*crop++ = crop_bottom;
+*crop++ = 0;
+*crop   = crop_right;
+
+avctx->nb_coded_side_data++;
+
+avctx->coded_side_data = sd_crop;
+avctx->coded_side_data[avctx->nb_coded_side_data - 1].type = 
AV_PKT_DATA_FRAME_CROPPING;
+avctx->coded_side_data[avctx->nb_coded_side_data - 1].size = 
sizeof(uint32_t) * 4;
+}
+
 return 0;
 }
 
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/amf_enc: av1 cropping support

2024-07-25 Thread Araz Iusubov
---
 libavcodec/amfenc.c |  6 
 libavcodec/amfenc.h |  3 ++
 libavcodec/amfenc_av1.c | 64 -
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 061859f85c..93925854e0 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -402,6 +402,12 @@ int av_cold ff_amf_encode_close(AVCodecContext *avctx)
 dlclose(ctx->library);
 ctx->library = NULL;
 }
+
+if (ctx->crop) 
+{
+av_freep(ctx->crop);
+}
+
 ctx->trace = NULL;
 ctx->debug = NULL;
 ctx->factory = NULL;
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..abcf465063 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -81,6 +81,9 @@ typedef struct AmfContext {
 
 int log_to_dbg;
 
+//handle crop
+uint32_t*crop;
+
 // Static options, have to be set before Init() call
 int usage;
 int profile;
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index d40c71cb33..e9bc26a770 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -19,9 +19,13 @@
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
+#include "libavutil/intreadwrite.h"
 #include "amfenc.h"
 #include "codec_internal.h"
 
+#define AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL
L"Av1WidthAlignmentFactor"  // amf_int64; default = 1
+#define AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL   
L"Av1HeightAlignmentFactor" // amf_int64; default = 1
+
 #define OFFSET(x) offsetof(AmfContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
@@ -167,7 +171,12 @@ static av_cold int amf_encode_init_av1(AVCodecContext* 
avctx)
 AMFRate framerate;
 AMFSize framesize = AMFConstructSize(avctx->width, 
avctx->height);
 
-
+//for av1 alignment and crop
+AVPacketSideData*   sd_crop = NULL;
+uint32_tcrop_right  = 0;
+uint32_tcrop_bottom = 0;
+int width_alignment_factor  = -1;
+int height_alignment_factor = -1;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 framerate = AMFConstructRate(avctx->framerate.num, 
avctx->framerate.den);
@@ -482,6 +491,59 @@ FF_ENABLE_DEPRECATION_WARNINGS
 buffer->pVtbl->Release(buffer);
 var.pInterface->pVtbl->Release(var.pInterface);
 
+//processing crop informaiton according to alignment
+if (ctx->encoder->pVtbl->GetProperty(ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_CAP_WIDTH_ALIGNMENT_FACTOR_LOCAL, &var) != AMF_OK)
+// assume older driver and Navi3x
+width_alignment_factor = 64;
+else
+width_alignment_factor = (int)var.int64Value;
+
+if (ctx->encoder->pVtbl->GetProperty(ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_CAP_HEIGHT_ALIGNMENT_FACTOR_LOCAL, &var) != AMF_OK)
+// assume older driver and Navi3x
+height_alignment_factor = 16;
+else
+height_alignment_factor = (int)var.int64Value;
+
+if (width_alignment_factor != -1 &&  height_alignment_factor != -1) {
+if (avctx->width % width_alignment_factor != 0)
+crop_right = width_alignment_factor - (avctx->width & 
(width_alignment_factor - 1));
+
+if (avctx->height % height_alignment_factor != 0)
+crop_bottom = height_alignment_factor - (avctx->height & 
(height_alignment_factor - 1));
+
+//There is specia processing for crop_bottom equal to 8 in hardware 
+if (crop_bottom == 8)
+crop_bottom = 2;
+}
+
+if (crop_right != 0 || crop_bottom != 0) {
+ctx->crop = av_mallocz(sizeof(uint32_t) * 4);
+if (!ctx->crop) {
+av_log(ctx, AV_LOG_WARNING, "Can't allocate memory for amf av1 
encoder crop information\n");
+return AVERROR(ENOMEM);
+}
+
+sd_crop = av_realloc_array(avctx->coded_side_data, 
avctx->nb_coded_side_data + 1, sizeof(*sd_crop));
+if (!sd_crop) {
+av_log(ctx, AV_LOG_WARNING, "Can't allocate memory for amf av1 
encoder crop information\n");
+av_freep(ctx->crop);
+return AVERROR(ENOMEM);
+}
+
+avctx->coded_side_data = sd_crop;
+avctx->nb_coded_side_data++;
+
+//top, bottom, left,right
+AV_WL32(ctx->crop + 0, 0);
+AV_WL32(ctx->crop + 1, crop_bottom);
+AV_WL32(ctx->crop + 2, 0);
+AV_WL32(ctx->crop + 3, crop_right);
+
+avctx->coded_side_data[avctx->nb_coded_side_data - 1].type = 
AV_PKT_DATA_FRAME_CROPPING;
+avctx->coded_side_data[avctx->nb_coded_side_data - 1].data = 
(uint8_t*)ctx->crop;
+avctx->coded_side_data[avctx->nb_coded_side_data - 1].size = 
sizeof(uint32_t) * 4;
+}
+
 return 0;
 }
 
-- 
2.45.2.windows.1


[FFmpeg-devel] [PATCH 1/4, v2] avcodec/amfenc: Fixes the color information in the output.

2024-08-01 Thread Araz Iusubov
From: Michael Fabian 'Xaymar' Dirks 

added 10 bit support for amf hevc.

before:

command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file.mkv -an -c:v h264_amf res.dx11_hw_h264.mkv
output -  Format of input frames context (p010le) is not supported by AMF.
command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v hevc_amf res.dx11_hw_hevc.mkv
output -  Format of input frames context (p010le) is not supported by AMF.

after:

command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v h264_amf res.dx11_hw_h264.mkv
output -  10-bit input video is not supported by AMF H264 encoder
command - ffmpeg.exe -hide_banner -y -hwaccel d3d11va -hwaccel_output_format 
d3d11 -i test_10bit_file -an -c:v hevc_amf res.dx11_hw_hevc.mkv
output -  10bit file

v2 - lost line returned in ff_amf_pix_fmts
v3 - fixes after review
v4 - extract duplicated code, fix incorrect processing of 10-bit input for h264
v5 - non-functional changes after review

Co-authored-by: Evgeny Pavlov 
Co-authored-by: Araz Iusubov 
---
 libavcodec/amfenc.c  | 37 +
 libavcodec/amfenc.h  |  3 +++
 libavcodec/amfenc_h264.c | 24 
 libavcodec/amfenc_hevc.c | 31 ++-
 4 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 061859f85c..0bd15dd812 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -60,6 +60,7 @@ const enum AVPixelFormat ff_amf_pix_fmts[] = {
 #if CONFIG_DXVA2
 AV_PIX_FMT_DXVA2_VLD,
 #endif
+AV_PIX_FMT_P010,
 AV_PIX_FMT_NONE
 };
 
@@ -72,6 +73,7 @@ static const FormatMap format_map[] =
 {
 { AV_PIX_FMT_NONE,   AMF_SURFACE_UNKNOWN },
 { AV_PIX_FMT_NV12,   AMF_SURFACE_NV12 },
+{ AV_PIX_FMT_P010,   AMF_SURFACE_P010 },
 { AV_PIX_FMT_BGR0,   AMF_SURFACE_BGRA },
 { AV_PIX_FMT_RGB0,   AMF_SURFACE_RGBA },
 { AV_PIX_FMT_GRAY8,  AMF_SURFACE_GRAY8 },
@@ -785,6 +787,41 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 return ret;
 }
 
+int ff_amf_get_color_profile(AVCodecContext *avctx)
+{
+amf_int64 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+if (avctx->color_range == AVCOL_RANGE_JPEG) {
+/// Color Space for Full (JPEG) Range
+switch (avctx->colorspace) {
+case AVCOL_SPC_SMPTE170M:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+break;
+case AVCOL_SPC_BT709:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+break;
+case AVCOL_SPC_BT2020_NCL:
+case AVCOL_SPC_BT2020_CL:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+break;
+}
+} else {
+/// Color Space for Limited (MPEG) range
+switch (avctx->colorspace) {
+case AVCOL_SPC_SMPTE170M:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+break;
+case AVCOL_SPC_BT709:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+break;
+case AVCOL_SPC_BT2020_NCL:
+case AVCOL_SPC_BT2020_CL:
+color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+break;
+}
+}
+return color_profile;
+}
+
 const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[] = {
 #if CONFIG_D3D11VA
 HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA),
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..62736ef579 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -21,6 +21,7 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -170,6 +171,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt);
 */
 extern const enum AVPixelFormat ff_amf_pix_fmts[];
 
+int ff_amf_get_color_profile(AVCodecContext *avctx);
+
 /**
 * Error handling helper
 */
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 32baa8e91a..7caeca748d 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -200,6 +200,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext 
*avctx)
 AMFRate  framerate;
 AMFSize  framesize = 
AMFConstructSize(avctx->width, avctx->height);
 int  deblocking_filter = (avctx->flags & 
AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+amf_int64color_profile;
+enum AVPixelFormat pix_fmt;
 
 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
 framerate = AMFConstructRate(avctx->framerate.num, 
avctx->framerate.den);
@@ -270,10 +272,24 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, 
AMF_VIDE

[FFmpeg-devel] [PATCH 2/4,v2] avcodec/amfenc: HDR metadata.

2024-08-01 Thread Araz Iusubov
From: nyanmisaka 

v2: fixes for indentation
---
 libavcodec/amfenc.c | 83 +
 1 file changed, 83 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 0bd15dd812..068bb53002 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -36,6 +36,57 @@
 #include "amfenc.h"
 #include "encode.h"
 #include "internal.h"
+#include "libavutil/mastering_display_metadata.h"
+
+static int amf_save_hdr_metadata(AVCodecContext *avctx, const AVFrame *frame, 
AMFHDRMetadata *hdrmeta)
+{
+AVFrameSideData*sd_display;
+AVFrameSideData*sd_light;
+AVMasteringDisplayMetadata *display_meta;
+AVContentLightMetadata *light_meta;
+
+sd_display = av_frame_get_side_data(frame, 
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+if (sd_display) {
+display_meta = (AVMasteringDisplayMetadata *)sd_display->data;
+if (display_meta->has_luminance) {
+const unsigned int luma_den = 1;
+hdrmeta->maxMasteringLuminance =
+(amf_uint32)(luma_den * av_q2d(display_meta->max_luminance));
+hdrmeta->minMasteringLuminance =
+FFMIN((amf_uint32)(luma_den * 
av_q2d(display_meta->min_luminance)), hdrmeta->maxMasteringLuminance);
+}
+if (display_meta->has_primaries) {
+const unsigned int chroma_den = 5;
+hdrmeta->redPrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[0][0])), chroma_den);
+hdrmeta->redPrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[0][1])), chroma_den);
+hdrmeta->greenPrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[1][0])), chroma_den);
+hdrmeta->greenPrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[1][1])), chroma_den);
+hdrmeta->bluePrimary[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[2][0])), chroma_den);
+hdrmeta->bluePrimary[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->display_primaries[2][1])), chroma_den);
+hdrmeta->whitePoint[0] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->white_point[0])), chroma_den);
+hdrmeta->whitePoint[1] =
+FFMIN((amf_uint16)(chroma_den * 
av_q2d(display_meta->white_point[1])), chroma_den);
+}
+
+sd_light = av_frame_get_side_data(frame, 
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+if (sd_light) {
+light_meta = (AVContentLightMetadata *)sd_light->data;
+if (light_meta) {
+hdrmeta->maxContentLightLevel = (amf_uint16)light_meta->MaxCLL;
+hdrmeta->maxFrameAverageLightLevel = 
(amf_uint16)light_meta->MaxFALL;
+}
+}
+return 0;
+}
+return 1;
+}
 
 #if CONFIG_D3D11VA
 #include 
@@ -683,6 +734,26 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
 }
 
+// HDR10 metadata
+if (frame->color_trc == AVCOL_TRC_SMPTE2084) {
+AMFBuffer * hdrmeta_buffer = NULL;
+res = ctx->context->pVtbl->AllocBuffer(ctx->context, 
AMF_MEMORY_HOST, sizeof(AMFHDRMetadata), &hdrmeta_buffer);
+if (res == AMF_OK) {
+AMFHDRMetadata * hdrmeta = 
(AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
+if (amf_save_hdr_metadata(avctx, frame, hdrmeta) == 0) {
+switch (avctx->codec->id) {
+case AV_CODEC_ID_H264:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+case AV_CODEC_ID_HEVC:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+}
+res = amf_set_property_buffer(surface, 
L"av_frame_hdrmeta", hdrmeta_buffer);
+AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"SetProperty failed for \"av_frame_hdrmeta\" with error %d\n", res);
+}
+hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
+}
+}
+
 surface->pVtbl->SetPts(surface, frame->pts);
 AMF_ASSIGN_PROPERTY_INT64(res, surface, PTS_PROP, frame->pts);
 
@@ -746,6 +817,18 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 }
 res_resubmit = AMF_OK;
 if (ctx->delayed_surface != NULL) { // try to resubmit frame
+if (ctx->delayed_surface->pVtbl->HasProperty(ctx->delayed_surface, 
L"av_frame_hdrmeta")) {
+AMFBuffer

[FFmpeg-devel] [PATCH 3/4, v2] avcodec/amfenc: add 10 bit encoding in av1_amf

2024-08-01 Thread Araz Iusubov
From: Evgeny Pavlov 

v2: refactored after review

Signed-off-by: Evgeny Pavlov 
Co-authored-by: Dmitrii Ovchinnikov 
Co-authored-by: Araz Iusubov 
---
 libavcodec/amfenc.c |  2 ++
 libavcodec/amfenc_av1.c | 28 +++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 068bb53002..49dd91c4e0 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -746,6 +746,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer); break;
 case AV_CODEC_ID_HEVC:
 AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer); break;
+case AV_CODEC_ID_AV1:
+AMF_ASSIGN_PROPERTY_INTERFACE(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_INPUT_HDR_METADATA, hdrmeta_buffer); break;
 }
 res = amf_set_property_buffer(surface, 
L"av_frame_hdrmeta", hdrmeta_buffer);
 AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"SetProperty failed for \"av_frame_hdrmeta\" with error %d\n", res);
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 62b9af9da0..e960e5ec81 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -170,7 +170,9 @@ static av_cold int amf_encode_init_av1(AVCodecContext* 
avctx)
 AMFGuid guid;
 AMFRate framerate;
 AMFSize framesize = AMFConstructSize(avctx->width, 
avctx->height);
-
+amf_int64   color_depth;
+amf_int64   color_profile;
+enumAVPixelFormat pix_fmt;
 
 //for av1 alignment and crop
 uint32_tcrop_right  = 0;
@@ -220,6 +222,30 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_PROFILE, profile);
 }
 
+/// Color profile
+color_profile = ff_amf_get_color_profile(avctx);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+
+/// Color Depth
+pix_fmt = avctx->hw_frames_ctx ? 
((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
+: avctx->pix_fmt;
+color_depth = AMF_COLOR_BIT_DEPTH_8;
+if (pix_fmt == AV_PIX_FMT_P010) {
+color_depth = AMF_COLOR_BIT_DEPTH_10;
+}
+
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
+/// Color Transfer Characteristics (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
+/// Color Primaries (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
+} else {
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
+}
+
 profile_level = avctx->level;
 if (profile_level == AV_LEVEL_UNKNOWN) {
 profile_level = ctx->level;
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/4, v2] avcodec/amfenc: GPU driver version check

2024-08-01 Thread Araz Iusubov
Implemented gpu driver check.
10-bit patch works incorrectly on driver version lower than 23.30.

---
 libavcodec/amfenc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 49dd91c4e0..41eaef9758 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -415,6 +415,10 @@ static int amf_init_encoder(AVCodecContext *avctx)
 else
 pix_fmt = avctx->pix_fmt;
 
+if (pix_fmt == AV_PIX_FMT_P010) {
+AMF_RETURN_IF_FALSE(ctx, ctx->version >= AMF_MAKE_FULL_VERSION(1, 4, 
32, 0), AVERROR_UNKNOWN, "10-bit encoder is not supported by AMD GPU drivers 
versions lower than 23.30.\n");
+}
+
 ctx->format = amf_av_to_amf_format(pix_fmt);
 AMF_RETURN_IF_FALSE(ctx, ctx->format != AMF_SURFACE_UNKNOWN, 
AVERROR(EINVAL),
 "Format %s is not supported\n", 
av_get_pix_fmt_name(pix_fmt));
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH, v2] avcodec/amfenc: increase precision of Sleep() on Windows

2024-08-19 Thread Araz Iusubov
From: Evgeny Pavlov 

This commit increase precision of Sleep() function on Windows.
This fix reduces the sleep time on Windows to improve AMF encoding
performance on low resolution input videos.

Fix for issue #10622

We evaluated CreateWaitableTimerExW with
CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag. In fact, this function has
the same precision level as the Sleep() function.

Usually changing the time resolution will only affect the current
process and will not impact other processes, thus it will not cause a
global effect on the current system. Here is an info from
documentation on timeBeginPeriod
https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod

"Prior to Windows 10, version 2004, this function affects a global
Windows setting. For all processes Windows uses the lowest value (that
is, highest resolution) requested by any process. Starting with
Windows 10, version 2004, this function no longer affects global timer
resolution. For processes which call this function, Windows uses the
lowest value (that is, highest resolution) requested by any process.
For processes which have not called this function, Windows does not
guarantee a higher resolution than the default system resolution."

We provide the following measurement to show performance improvements
with this patch.

1. Performance tests show that this high precision sleep will improve
performance, especially for low resolution sequences, it can get about
20% improvement.

Frames Per Second (FPS) being encoded by the hardware encoder (Navi 31
RX7900XT ):

Source Type: H.264 ,  Output Type: H.264
(Sorry for bad formatting)
No. |   Sequence Resolution | No. of Frames|FPS Before patch|
FPS after patch   | Difference| Improvement %
|---|--||---|---|--
1   |   480x360 | 8290 |2030|
 2365| 335   | 16.5%
2   |   720x576 | 8290 |1440|
 1790| 350   | 24.3%
3 | 1280x720| 8290 |1120|
 1190| 70| 6.3%
4   |   1920x1080   | 8290 |692 |
 714 | 22| 3.2%
5   |   3840x2160   | 8290 |200 |
 200 | 0 | 0.0%

The sample ffmpeg command line:
$ ffmpeg.exe -y -hwaccel d3d11va -hwaccel_output_format d3d11 -i
input.mp4 -c:v h264_amf out.mp4
where input.mp4 should be changed to corresponding resolution input
H.264 format bitstream.

2. The power tests show an increase in power is within limit scope.

The purpose of the power test is to examine the increase in CPU power
consumption due to the improvement in CPU time resolution after using
this patch. We were testing a product from AMD called Phoenix, which
we refer to as an APU. It combines a general-purpose AMD CPU and a 3D
integrated graphics processing unit (IGPU) on a single die. Only the
APU has a DAP connector to the board's power rails.

We got the power test data shown below:

|| 480x360   |  720x576   | 1280x720 |
1920x1080 | 3840x2160 | average
||---||--|---|---|
|CPU  power change   |  1.93%|  2.43% | -1.69%   | 3.49%
  | 2.92% | 1.82%
|APU power total change  |  0.86%|  1.34% | -0.62%   | 1.54%
  | -0.58%| 0.51

When using a high precision clock by applying the patch, the average
power consumption for CPU increases 1.82%, and the APU total increases
0.51%. We can see the power increase in power not very significant.

Signed-off-by: Evgeny Pavlov 
---
 libavcodec/amfenc.c | 31 +++
 libavcodec/amfenc.h |  3 +++
 2 files changed, 34 insertions(+)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 061859f85c..55e24856e8 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -42,7 +42,12 @@
 #endif
 
 #ifdef _WIN32
+#include 
 #include "compat/w32dlfcn.h"
+
+typedef MMRESULT (*timeapi_fun)(UINT uPeriod);
+#define WINMM_DLL "winmm.dll"
+
 #else
 #include 
 #endif
@@ -113,6 +118,9 @@ static int amf_load_library(AVCodecContext *avctx)
 AMFInit_Fn init_fun;
 AMFQueryVersion_Fn version_fun;
 AMF_RESULT res;
+#ifdef _WIN32
+timeapi_fun time_begin_fun;
+#endif
 
 ctx->delayed_frame = av_frame_alloc();
 if (!ctx->delayed_frame) {
@@ -145,6 +153,16 @@ static int amf_load_library(AVCodecContext *avctx)
 AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "GetTrace() 
failed with error %d\n", res);
 res = ctx->factory->pVtbl->GetDebug(ctx->factory, &ctx->debug);
 AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "GetDebug() 
failed with error %d\n", res);
+
+#ifdef _WIN32
+// Increase precision of Sleep() function on Windows platform
+ctx->winmm_

[FFmpeg-devel] [PATCH, v3] avcodec/amfenc: increase precision of Sleep() on Windows

2024-10-11 Thread Araz Iusubov
From: Cameron Gutman 

This commit increase precision of Sleep() function on Windows.
This fix reduces the sleep time on Windows to improve AMF encoding
performance on low resolution input videos.

Fix for issue #10622

Co-authored-by: Araz Iusubov 
---
 libavcodec/amfenc.c  | 21 ++---
 libavcodec/amfenc.h  |  3 +++
 libavcodec/amfenc_av1.c  |  5 +
 libavcodec/amfenc_h264.c |  5 +
 libavcodec/amfenc_hevc.c |  5 +
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 225fb9df27..03d75031f5 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -426,6 +426,8 @@ static int amf_init_encoder(AVCodecContext *avctx)
 res = ctx->factory->pVtbl->CreateComponent(ctx->factory, ctx->context, 
codec_id, &ctx->encoder);
 AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND, 
"CreateComponent(%ls) failed with error %d\n", codec_id, res);
 
+ctx->submitted_frame = 0;
+
 return 0;
 }
 
@@ -541,7 +543,6 @@ static int amf_copy_buffer(AVCodecContext *avctx, AVPacket 
*pkt, AMFBuffer *buff
 if ((ctx->max_b_frames > 0 || ((ctx->pa_adaptive_mini_gop == 1) ? true : 
false)) && ctx->dts_delay == 0) {
 int64_t timestamp_last = AV_NOPTS_VALUE;
 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);
@@ -826,6 +827,13 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 
 av_frame_unref(frame);
 ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
+
+if (ctx->submitted_frame == 0)
+{
+ctx->use_b_frame = (ctx->max_b_frames > 0 || 
((ctx->pa_adaptive_mini_gop == 1) ? true : false));
+}
+ctx->submitted_frame++;
+
 if (ret < 0)
 return ret;
 }
@@ -835,7 +843,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 do {
 block_and_wait = 0;
 // poll data
-if (!avpkt->data && !avpkt->buf) {
+if (!avpkt->data && !avpkt->buf && (ctx->use_b_frame ? 
(ctx->submitted_frame >= 2) : true) ) {
 res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder, &data);
 if (data) {
 // copy data to packet
@@ -845,6 +853,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 data->pVtbl->QueryInterface(data, &guid, (void**)&buffer); // 
query for buffer interface
 ret = amf_copy_buffer(avctx, avpkt, buffer);
 
+ctx->submitted_frame++;
 buffer->pVtbl->Release(buffer);
 
 if (data->pVtbl->HasProperty(data, L"av_frame_ref")) {
@@ -884,6 +893,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 av_frame_unref(ctx->delayed_frame);
 AMF_RETURN_IF_FALSE(ctx, res_resubmit == AMF_OK, 
AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", res_resubmit);
 
+ctx->submitted_frame++;
 ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
 if (ret < 0)
 return ret;
@@ -902,7 +912,12 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket 
*avpkt)
 if (query_output_data_flag == 0) {
 if (res_resubmit == AMF_INPUT_FULL || ctx->delayed_drain || 
(ctx->eof && res_query != AMF_EOF) || (ctx->hwsurfaces_in_queue >= 
ctx->hwsurfaces_in_queue_max)) {
 block_and_wait = 1;
-av_usleep(1000);
+
+// Only sleep if the driver doesn't support waiting in 
QueryOutput()
+// or if we already have output data so we will skip calling 
it.
+if (!ctx->query_timeout_supported || avpkt->data || 
avpkt->buf) {
+av_usleep(1000);
+}
 }
 }
 } while (block_and_wait);
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 0f2abcbd82..d83ee5bf1c 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -68,6 +68,7 @@ typedef struct AmfContext {
 
 int hwsurfaces_in_queue;
 int hwsurfaces_in_queue_max;
+int query_timeout_supported;
 
 // helpers to handle async calls
 int delayed_drain;
@@ -77,6 +78,8 @@ typedef struct AmfContext {
 // shift dts back by max_b_frames in timing
 AVFifo *timestamp_list;
 int64_t dts_delay;

[FFmpeg-devel] [PATCH] avcodec/amfenc: Color information update

2024-10-31 Thread Araz Iusubov
Processing of transfer characteristic SMPTE2084 and 8-bit depth added on AMF 
side and will appear in one of upcoming releases.

---
 libavcodec/amfenc_av1.c  | 13 -
 libavcodec/amfenc_hevc.c | 13 -
 2 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index b40d54f70c..fc28287a48 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -252,15 +252,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
-if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
-/// Color Transfer Characteristics (AMF matches ISO/IEC)
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
-/// Color Primaries (AMF matches ISO/IEC)
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
-} else {
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
-}
+/// Color Transfer Characteristics (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, avctx->color_trc);
+/// Color Primaries (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, avctx->color_primaries);
 
 profile_level = avctx->level;
 if (profile_level == AV_LEVEL_UNKNOWN) {
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index f9f6f8adb3..8ceaee0851 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -254,15 +254,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 color_depth = AMF_COLOR_BIT_DEPTH_10;
 }
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, color_depth);
-if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
-/// Color Transfer Characteristics (AMF matches ISO/IEC)
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
-/// Color Primaries (AMF matches ISO/IEC)
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
-} else {
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, 
AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
-}
+/// Color Transfer Characteristics (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, avctx->color_trc);
+/// Color Primaries (AMF matches ISO/IEC)
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, avctx->color_primaries);
 
 // Picture control properties
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/amfenc: GOP size check

2024-10-28 Thread Araz Iusubov
АFix for the error with an invalid GOP size parameter.
---
 libavcodec/amfenc_av1.c  | 4 +++-
 libavcodec/amfenc_h264.c | 4 +++-
 libavcodec/amfenc_hevc.c | 4 +++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index b40d54f70c..8920389180 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -281,7 +281,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
 }
 
 // Picture control properties
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size);
+if (avctx->gop_size != -1) {
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size);
+}
 
 // Setup header insertion mode only if this option was defined explicitly
 if (ctx->header_insertion_mode != -1) {
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 959be9eab6..cc473c5056 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -512,7 +512,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, 
AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, !!deblocking_filter);
 
 // Keyframe Interval
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_IDR_PERIOD, 
avctx->gop_size);
+if (avctx->gop_size != -1) {
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_IDR_PERIOD, avctx->gop_size);
+}
 
 // Header Insertion Spacing
 if (ctx->header_spacing >= 0)
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index f9f6f8adb3..c3b60ff6f4 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -266,7 +266,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 // Picture control properties
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
-AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, avctx->gop_size);
+if (avctx->gop_size != -1) {
+AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, avctx->gop_size);
+}
 if (avctx->slices > 1) {
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_SLICES_PER_FRAME, avctx->slices);
 }
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/amfenc: DX12 Reference-only feature support

2025-01-30 Thread Araz Iusubov
The Reference-Only feature in DirectX 12 is a memory optimization 
technique designed for video decoding scenarios.
This feature requires that reference resources must be allocated with 
the D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY resource flag. 
Reference textures must also be separated from output textures. 
This feature is not supported in the current version of ffmpeg. 
Since AMD GPU uses this feature in Direct 12 decoder, 
ffmpeg does not support AMD GPU Direct 12 decoding.
To properly support the Reference-Only feature, 
two parallel resource pools must be configured and managed:
General Resource Pool: 
Contains resources used for output decoded frames. 
Defined in AVHWFramesContext and manages the final decoded textures. 
Reference-Only Resource Pool: 
Intended for storing reference frame resources. 
Resources created with the 
D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY flag 
are allocated to AVBufferPool.

---
 libavcodec/d3d12va_decode.c   | 58 ---
 libavutil/hwcontext_d3d12va.c | 65 ---
 2 files changed, 115 insertions(+), 8 deletions(-)

diff --git a/libavcodec/d3d12va_decode.c b/libavcodec/d3d12va_decode.c
index 3b8978635e..8916f94d10 100644
--- a/libavcodec/d3d12va_decode.c
+++ b/libavcodec/d3d12va_decode.c
@@ -51,11 +51,19 @@ unsigned ff_d3d12va_get_surface_index(const AVCodecContext 
*avctx,
   D3D12VADecodeContext *ctx, const AVFrame 
*frame,
   int curr)
 {
+AVHWFramesContext  *frames_ctx   = D3D12VA_FRAMES_CONTEXT(avctx);
+AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx;
+
 AVD3D12VAFrame *f;
 ID3D12Resource *res;
 unsigned i;
 
-f = (AVD3D12VAFrame *)frame->data[0];
+if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) 
{
+f = (AVD3D12VAFrame*)frame->data[1];
+} else {
+f = (AVD3D12VAFrame*)frame->data[0];
+}
+
 if (!f)
 goto fail;
 
@@ -250,6 +258,11 @@ static int d3d12va_create_decoder(AVCodecContext *avctx)
 return AVERROR_PATCHWELCOME;
 }
 
+if (feature.ConfigurationFlags & 
D3D12_VIDEO_DECODE_CONFIGURATION_FLAG_REFERENCE_ONLY_ALLOCATIONS_REQUIRED) {
+frames_hwctx->flags |= 
(D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY | 
D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE);
+av_log(avctx, AV_LOG_INFO, "Reference-Only Allocations are required 
for this configuration.\n");
+}
+
 desc = (D3D12_VIDEO_DECODER_DESC) {
 .NodeMask = 0,
 .Configuration = ctx->cfg,
@@ -440,8 +453,19 @@ int ff_d3d12va_common_end_frame(AVCodecContext *avctx, 
AVFrame *frame,
 D3D12VADecodeContext   *ctx   = D3D12VA_DECODE_CONTEXT(avctx);
 ID3D12Resource *buffer= NULL;
 ID3D12CommandAllocator *command_allocator = NULL;
-AVD3D12VAFrame *f = (AVD3D12VAFrame 
*)frame->data[0];
-ID3D12Resource *resource  = (ID3D12Resource *)f->texture;
+AVHWFramesContext  *frames_ctx= D3D12VA_FRAMES_CONTEXT(avctx);
+AVD3D12VAFramesContext *frames_hwctx  = frames_ctx->hwctx;
+AVD3D12VAFrame *f = NULL;
+AVD3D12VAFrame *output_data   = NULL;
+
+if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) 
{
+f   = (AVD3D12VAFrame*)frame->data[1];
+output_data = (AVD3D12VAFrame*)frame->data[0];
+} else {
+f   = (AVD3D12VAFrame*)frame->data[0];
+}
+
+ID3D12Resource* resource = (ID3D12Resource*)f->texture;
 
 ID3D12VideoDecodeCommandList *cmd_list = ctx->command_list;
 D3D12_RESOURCE_BARRIER barriers[32] = { 0 };
@@ -469,6 +493,14 @@ int ff_d3d12va_common_end_frame(AVCodecContext *avctx, 
AVFrame *frame,
 .pOutputTexture2D= resource,
 };
 
+if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) 
{
+output_args.pOutputTexture2D = output_data->texture;
+
+output_args.ConversionArguments.Enable   = 1;
+output_args.ConversionArguments.pReferenceTexture2D  = resource;
+output_args.ConversionArguments.ReferenceSubresource = 0;
+}
+
 UINT num_barrier = 1;
 barriers[0] = (D3D12_RESOURCE_BARRIER) {
 .Type  = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
@@ -481,6 +513,20 @@ int ff_d3d12va_common_end_frame(AVCodecContext *avctx, 
AVFrame *frame,
 },
 };
 
+if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) 
{
+barriers[1] = (D3D12_RESOURCE_BARRIER) {
+.Type  = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
+.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
+.Transition = {
+.pResource   = output_data->texture,
+.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
+.StateBefore = D3D12_RESOURCE_STATE_COMMON,
+

[FFmpeg-devel] [PATCH] avcodec/amfenc: Fix max rate control log message

2025-01-16 Thread Araz Iusubov
---
 libavcodec/amfenc_av1.c  | 2 +-
 libavcodec/amfenc_h264.c | 2 +-
 libavcodec/amfenc_hevc.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index bc6ad3d7fb..b21011ef23 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -374,7 +374,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->rc_max_rate);
 }
 else if (ctx->rate_control_mode == 
AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
-av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR 
but rc_max_rate is not set\n");
+av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate 
is not set, default max_rate will be applied.\n");
 }
 if (avctx->bit_rate > 0) {
 ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR;
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 78bd70eb7a..18b1ca48c9 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -395,7 +395,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 if (avctx->rc_max_rate) {
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->rc_max_rate);
 } else if (ctx->rate_control_mode == 
AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
-av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR 
but rc_max_rate is not set\n");
+av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate 
is not set, default max_rate will be applied.\n");
 }
 
 if (ctx->latency != -1) {
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 0907db945c..42f823e512 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -369,7 +369,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 if (avctx->rc_max_rate) {
 AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, 
AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, avctx->rc_max_rate);
 } else if (ctx->rate_control_mode == 
AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
-av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR 
but rc_max_rate is not set\n");
+av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate 
is not set, default max_rate will be applied.\n");
 }
 
 if (ctx->latency != -1) {
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH, v2] avcodec/d3d12va_decode: enable reference-only mode

2025-03-18 Thread Araz Iusubov
The Reference-Only feature in DirectX 12 is a memory optimization
technique designed for video decoding scenarios.
This feature requires that reference resources must be allocated with
the D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY resource flag.
Reference textures must also be separated from output textures.
This feature is not supported in the current version of ffmpeg. 
Since AMD GPU uses this feature in Direct 12 decoder, 
ffmpeg does not support AMD GPU Direct 12 decoding.

---
 libavcodec/d3d12va_decode.c | 165 +---
 libavcodec/d3d12va_decode.h |  13 +++
 2 files changed, 166 insertions(+), 12 deletions(-)

diff --git a/libavcodec/d3d12va_decode.c b/libavcodec/d3d12va_decode.c
index 3b8978635e..b9df266e37 100644
--- a/libavcodec/d3d12va_decode.c
+++ b/libavcodec/d3d12va_decode.c
@@ -41,6 +41,102 @@ typedef struct HelperObjects {
 uint64_t fence_value;
 } HelperObjects;

+typedef struct ReferenceFrame {
+ID3D12Resource *resource;
+intused;
+ID3D12Resource *output_resource;
+} ReferenceFrame;
+
+static ID3D12Resource *get_reference_only_resource(AVCodecContext *avctx, 
ID3D12Resource *output_resource)
+{
+D3D12VADecodeContext   *ctx  = D3D12VA_DECODE_CONTEXT(avctx);
+AVHWFramesContext  *frames_ctx   = D3D12VA_FRAMES_CONTEXT(avctx);
+AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx;
+AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx;
+int i = 0;
+ID3D12Resource *resource = NULL;
+ReferenceFrame *reference_only_map = ctx->reference_only_map;
+if (reference_only_map == NULL) {
+av_log(avctx, AV_LOG_ERROR, "Reference frames are not allocated!\n");
+return NULL;
+}
+
+// find unused resource
+for (i = 0; i < ctx->max_num_ref; i++) {
+if (!reference_only_map[i].used && reference_only_map[i].resource != 
NULL) {
+reference_only_map[i].used = 1;
+resource = reference_only_map[i].resource;
+reference_only_map[i].output_resource = output_resource;
+return resource;
+}
+}
+
+// find space to allocate
+for (i = 0; i < ctx->max_num_ref; i++) {
+if (reference_only_map[i].resource == NULL)
+break;
+}
+
+if (i == ctx->max_num_ref) {
+av_log(avctx, AV_LOG_ERROR, "No space for new Reference frame!\n");
+return NULL;
+}
+
+// allocate frame
+D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
+D3D12_RESOURCE_DESC desc;
+output_resource->lpVtbl->GetDesc(output_resource, &desc);
+desc.Flags = D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY | 
D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
+
+if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, 
&props, D3D12_HEAP_FLAG_NONE, &desc,
+D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void 
**)&reference_only_map[i].resource))) {
+av_log(ctx, AV_LOG_ERROR, "Failed to create D3D12 Reference 
Resource!\n");
+return NULL;
+}
+
+reference_only_map[i].used = 1;
+resource = reference_only_map[i].resource;
+reference_only_map[i].output_resource = output_resource;
+
+return resource;
+}
+
+static void free_reference_only_resources(AVCodecContext *avctx)
+{
+D3D12VADecodeContext *ctx = D3D12VA_DECODE_CONTEXT(avctx);
+int i;
+ReferenceFrame *reference_only_map = ctx->reference_only_map;
+if (reference_only_map != NULL) {
+for (i = 0; i < ctx->max_num_ref; i++) {
+if (reference_only_map[i].resource != NULL) {
+D3D12_OBJECT_RELEASE(reference_only_map[i].resource);
+}
+}
+av_freep(&ctx->reference_only_map);
+av_freep(&ctx->ref_only_resources);
+}
+}
+
+static void prepare_reference_only_resources(AVCodecContext *avctx)
+{
+D3D12VADecodeContext *ctx = D3D12VA_DECODE_CONTEXT(avctx);
+int i, j;
+ReferenceFrame *reference_only_map = ctx->reference_only_map;
+if (reference_only_map == NULL)
+return;
+memset(ctx->ref_only_resources, 0, ctx->max_num_ref * 
sizeof(*(ctx->ref_only_resources)));
+for (j = 0; j < ctx->max_num_ref; j++) {
+for (i = 0; i < ctx->max_num_ref; i++) {
+if (reference_only_map[j].used && 
reference_only_map[j].output_resource == ctx->ref_resources[i]) {
+ctx->ref_only_resources[i] = reference_only_map[j].resource;
+break;
+}
+}
+if (i == ctx->max_num_ref)
+reference_only_map[j].used = 0;
+}
+}
+
 int ff_d3d12va_get_suitable_max_bitstream_size(AVCodecContext *avctx)
 {
 AVHWFramesContext *frames_ctx = D3D12VA_FRAMES_CONTEXT(avctx);
@@ -250,6 +346,18 @@ static int d3d12va_create_decoder(AVCodecContext *avctx)
 return AVERROR_PATCHWELCOME;
 }

+ctx->reference_only_map = NULL;
+ctx->ref_only_resources = NULL;
+if (feature.ConfigurationFlags & 
D3D12_VIDEO_DECODE_CONF

[FFmpeg-devel] [PATCH] avcodec/d3d12va_encode: texture array support for HEVC

2025-05-06 Thread Araz Iusubov
This patch adds support for the texture array feature
used by AMD boards in the D3D12 HEVC encoder.
In texture array mode, a single texture array is shared for all
reference and reconstructed pictures using different subresources.
The implementation ensures compatibility
and has been successfully tested on AMD, Intel, and NVIDIA GPUs.

---
 libavcodec/d3d12va_encode.c  | 241 +--
 libavcodec/d3d12va_encode.h  |  29 
 libavcodec/d3d12va_encode_hevc.c |   5 +-
 3 files changed, 231 insertions(+), 44 deletions(-)

diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c
index 4d738200fe..580d2ea383 100644
--- a/libavcodec/d3d12va_encode.c
+++ b/libavcodec/d3d12va_encode.c
@@ -264,6 +264,11 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 
 av_log(avctx, AV_LOG_DEBUG, "Input surface is %p.\n", 
pic->input_surface->texture);
 
+if (ctx->is_texture_array) {
+base_pic->recon_image->data[0] = ctx->texture_array_frame;
+pic->subresource_index = (ctx->subresource_used_index++) % 
ctx->max_subresource_array_size;
+}
+
 pic->recon_surface = (AVD3D12VAFrame *)base_pic->recon_image->data[0];
 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %p.\n",
pic->recon_surface->texture);
@@ -325,11 +330,28 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 goto fail;
 }
 
+if (ctx->is_texture_array) {
+d3d12_refs.pSubresources = av_calloc(d3d12_refs.NumTexture2Ds,
+
sizeof(*d3d12_refs.pSubresources));
+if (!d3d12_refs.pSubresources) {
+err = AVERROR(ENOMEM);
+goto fail;
+}
+}
+
 i = 0;
-for (j = 0; j < base_pic->nb_refs[0]; j++)
-d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->recon_surface->texture;
-for (j = 0; j < base_pic->nb_refs[1]; j++)
-d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->recon_surface->texture;
+for (j = 0; j < base_pic->nb_refs[0]; j++) {
+d3d12_refs.ppTexture2Ds[i]  = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->recon_surface->texture;
+if (ctx->is_texture_array)
+d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->subresource_index;
+i++;
+}
+for (j = 0; j < base_pic->nb_refs[1]; j++) {
+d3d12_refs.ppTexture2Ds[i]  = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->recon_surface->texture;
+if (ctx->is_texture_array)
+d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->subresource_index;
+i++;
+}
 }
 
 input_args.PictureControlDesc.IntraRefreshFrameIndex  = 0;
@@ -343,7 +365,11 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 output_args.Bitstream.pBuffer= 
pic->output_buffer;
 output_args.Bitstream.FrameStartOffset   = 
pic->aligned_header_size;
 output_args.ReconstructedPicture.pReconstructedPicture   = 
pic->recon_surface->texture;
-output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
+if (ctx->is_texture_array) {
+output_args.ReconstructedPicture.ReconstructedPictureSubresource = 
pic->subresource_index;
+} else {
+output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
+}
 output_args.EncoderOutputMetadata.pBuffer= 
pic->encoded_metadata;
 output_args.EncoderOutputMetadata.Offset = 0;
 
@@ -381,35 +407,87 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 },  \
 }
 
+#define TRANSITION_BARRIER_SUBRESOURCE(res, subres,before, after)   \
+(D3D12_RESOURCE_BARRIER) {  \
+.Type  = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,\
+.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,  \
+.Transition = { \
+.pResource   = res, \
+.Subresource = subres,  \
+.StateBefore = before,  \
+.StateAfter  = after,   \
+},  \
+}
+
 barriers[0] = TRANSITION_BARRIER(pic->input_surface->texture,
  D3D12_RESOURCE_STATE_COMMON,
  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
 barriers[1] = TRANSITION_BARRIER(pic->output_buffer,
  D3D12_RESOURCE_STATE_COMMON,
  

[FFmpeg-devel] [PATCH] avcodec/amfenc: add smart access video option

2025-03-11 Thread Araz Iusubov
From: Evgeny Pavlov 

This commit adds option for enabling SmartAccess Video (SAV)
in AMF encoders. SAV is an AMD hardware-specific feature which
enables the parallelization of encode and decode streams across
multiple Video Codec Engine (VCN) hardware instances.

---
 libavcodec/amfenc.h  |  1 +
 libavcodec/amfenc_av1.c  | 17 +
 libavcodec/amfenc_h264.c | 18 ++
 libavcodec/amfenc_hevc.c | 18 ++
 4 files changed, 54 insertions(+)

diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 3f42c4cd94..aec3a3f9ec 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -72,6 +72,7 @@ typedef struct AMFEncoderContext {
 int b_frame_delta_qp;
 int ref_b_frame_delta_qp;
 int bit_depth;
+int smart_access_video;
 
 // Dynamic options, can be set after Init() call
 
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 05ad2b8897..8c5fa9dfbc 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -133,6 +133,8 @@ static const AVOption options[] = {
 { "1080p",  "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082   }, 0, 0, VE, 
.unit = "align" },
 { "none",   "", 0, AV_OPT_TYPE_CONST, {.i64 = 
AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS  }, 0, 0, VE, 
.unit = "align" },
 
+{ "smart_access_video", "Enable Smart Access Video",
OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1  }, -1, 1, 
VE},
+
 //Pre Analysis options
 { "preanalysis","Enable preanalysis",  
 OFFSET(preanalysis),   
 AV_OPT_TYPE_BOOL,   {.i64 = -1 }, -1, 1, VE },
 
@@ -326,6 +328,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
 av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak VBR\n");
 }
 }
+if (ctx->smart_access_video != -1) {
+AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
+if (res != AMF_OK) {
+av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not 
supported by AMF.\n");
+if (ctx->smart_access_video != 0)
+return AVERROR(ENOSYS);
+} else {
+av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is 
set.\n", ctx->smart_access_video);
+// Set low latency mode if Smart Access Video is enabled
+if (ctx->smart_access_video != 0) {
+AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, 
AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE, 
AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY);
+av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low 
latency mode.\n");
+}
+}
+}
 
 // Pre-Pass, Pre-Analysis, Two-Pass
 if (ctx->rate_control_mode == 
AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP) {
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 4291f0ea64..2f906f3273 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -139,6 +139,8 @@ static const AVOption options[] = {
 { "forced_idr", "Force I frames to be IDR frames",  
OFFSET(forced_idr)   , AV_OPT_TYPE_BOOL,  { .i64 = 0  }, 0, 1, VE },
 { "aud","Inserts AU Delimiter NAL unit",OFFSET(aud)
  , AV_OPT_TYPE_BOOL,  { .i64 = -1 }, -1, 1, VE },
 
+{ "smart_access_video", "Enable Smart Access Video",
OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1  }, -1, 1, VE},
+
 //Pre Analysis options
 { "preanalysis","Enable preanalysis",  
 OFFSET(preanalysis),   
 AV_OPT_TYPE_BOOL,   {.i64 = -1 }, -1, 1, VE },
 
@@ -399,6 +401,22 @@ FF_ENABLE_DEPRECATION_WARNINGS
 AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, 
AMF_VIDEO_ENCODER_LOWLATENCY_MODE, ((ctx->latency == 0) ? false : true));
 }
 
+if (ctx->smart_access_video != -1) {
+AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, 
AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
+if (res != AMF_OK) {
+av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not 
supported by AMF.\n");
+if (ctx->smart_access_video != 0)
+return AVERROR(ENOSYS);
+} else {
+av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is 
set.\n", ctx->smart_access_video);
+// Set low latency mode if Smart Access Video is enabled
+if (ctx->smart_access_video != 0) {
+AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, 
AMF_VIDEO_ENCODER_LOWLATENCY_MODE, true);
+av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low 
latency mode.\n");
+}
+}
+  

[FFmpeg-devel] [PATCH] avcodec/d3d12va_decode: enable reference-only decoder mode

2025-02-21 Thread Araz Iusubov
The Reference-Only feature in DirectX 12 is a memory optimization
technique designed for video decoding scenarios.
This feature requires that reference resources must be allocated with
the D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY resource flag.
Reference textures must also be separated from output textures.
This feature is not supported in the current version of ffmpeg. 
Since AMD GPU uses this feature in Direct 12 decoder, 
ffmpeg does not support AMD GPU Direct 12 decoding.

---
 libavcodec/d3d12va_decode.c | 176 +---
 libavcodec/d3d12va_decode.h |  13 +++
 2 files changed, 176 insertions(+), 13 deletions(-)

diff --git a/libavcodec/d3d12va_decode.c b/libavcodec/d3d12va_decode.c
index 3b8978635e..c51234c256 100644
--- a/libavcodec/d3d12va_decode.c
+++ b/libavcodec/d3d12va_decode.c
@@ -41,6 +41,111 @@ typedef struct HelperObjects {
 uint64_t fence_value;
 } HelperObjects;
 
+typedef struct ReferenceFrame {
+ID3D12Resource *resource;
+intused;
+ID3D12Resource *output_resource;
+} ReferenceFrame;
+
+static ID3D12Resource *get_reference_only_resource(AVCodecContext *avctx, 
ID3D12Resource *output_resource)
+{
+D3D12VADecodeContext   *ctx  = D3D12VA_DECODE_CONTEXT(avctx);
+AVHWFramesContext  *frames_ctx   = D3D12VA_FRAMES_CONTEXT(avctx);
+AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx;
+AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx;
+int i;
+ID3D12Resource *resource = NULL;
+ReferenceFrame *reference_only_map = (ReferenceFrame 
*)(ctx->reference_only_map);
+if(reference_only_map == NULL){
+av_log(avctx, AV_LOG_ERROR, "Reference frames are not allocated!\n");
+return NULL;
+}
+
+// find unused resource
+for (i = 0; i < ctx->max_num_ref; i++) {
+if(!reference_only_map[i].used && reference_only_map[i].resource != 
NULL) {
+reference_only_map[i].used = 1;
+resource = reference_only_map[i].resource;
+reference_only_map[i].output_resource = output_resource;
+break;
+}
+}
+if(resource == NULL){
+// find space to allocate
+for (i = 0; i < ctx->max_num_ref; i++) {
+if(reference_only_map[i].resource == NULL) {
+break;
+}
+}
+}
+if(i == ctx->max_num_ref){
+av_log(avctx, AV_LOG_ERROR, "No space for new Reference frame!\n");
+}else{
+// allocate frame 
+D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
+D3D12_RESOURCE_DESC desc = {
+.Dimension= D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+.Alignment= 0,
+.Width= avctx->coded_width,
+.Height   = avctx->coded_height,
+.DepthOrArraySize = 1,
+.MipLevels= 1,
+.Format   = frames_hwctx->format,
+.SampleDesc   = {.Count = 1, .Quality = 0 },
+.Layout   = D3D12_TEXTURE_LAYOUT_UNKNOWN,
+.Flags= 
D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY | 
D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE,
+};
+
+if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, 
&props, D3D12_HEAP_FLAG_NONE, &desc,
+D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void 
**)&reference_only_map[i].resource))) {
+av_log(ctx, AV_LOG_ERROR, "Could not create the texture\n");
+}
+resource = reference_only_map[i].resource;
+reference_only_map[i].used = 1;
+reference_only_map[i].output_resource = output_resource;
+}
+// return it
+return resource;
+}
+
+static void free_reference_only_resources(AVCodecContext *avctx)
+{
+D3D12VADecodeContext   *ctx  = D3D12VA_DECODE_CONTEXT(avctx);
+int i;
+ReferenceFrame *reference_only_map = (ReferenceFrame 
*)(ctx->reference_only_map);
+if(reference_only_map != NULL){
+for (i = 0; i < ctx->max_num_ref; i++) {
+if(reference_only_map[i].resource != NULL) {
+D3D12_OBJECT_RELEASE(reference_only_map[i].resource);
+}
+}
+av_freep(&ctx->reference_only_map);
+av_freep(&ctx->ref_only_resources);
+}
+}
+
+static void prepare_reference_only_resources(AVCodecContext *avctx)
+{
+D3D12VADecodeContext   *ctx  = D3D12VA_DECODE_CONTEXT(avctx);
+int i, j;
+ReferenceFrame *reference_only_map = (ReferenceFrame 
*)(ctx->reference_only_map);
+if(reference_only_map == NULL){
+return;
+}
+memset(ctx->ref_only_resources, 0, ctx->max_num_ref * 
sizeof(*(ctx->ref_only_resources)));
+for (j = 0; j < ctx->max_num_ref; j++) {
+for (i = 0; i < ctx->max_num_ref; i++) {
+if(reference_only_map[j].used && 
reference_only_map[j].output_resource == ctx->ref_resources[i]) {
+ctx->ref_only_resources[i] = ref

[FFmpeg-devel] [PATCH, v2] avcodec/d3d12va_encode: texture array support for HEVC

2025-05-16 Thread Araz Iusubov
This patch adds support for the texture array feature
used by AMD boards in the D3D12 HEVC encoder.
In texture array mode, a single texture array is shared for all
reference and reconstructed pictures using different subresources.
The implementation ensures compatibility
and has been successfully tested on AMD, Intel, and NVIDIA GPUs.

v2 updates: 
1. The reference to MaxL1ReferencesForB for the H.264 codec 
was updated to use the corresponding H.264 field instead of the HEVC one.
2. Max_subresource_array_size calculation was adjusted 
by removing the D3D12VA_VIDEO_ENC_ASYNC_DEPTH offset.

---
 libavcodec/d3d12va_encode.c  | 241 +--
 libavcodec/d3d12va_encode.h  |  29 
 libavcodec/d3d12va_encode_hevc.c |   5 +-
 3 files changed, 231 insertions(+), 44 deletions(-)

diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c
index 4d738200fe..d428ad1fd8 100644
--- a/libavcodec/d3d12va_encode.c
+++ b/libavcodec/d3d12va_encode.c
@@ -264,6 +264,11 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 
 av_log(avctx, AV_LOG_DEBUG, "Input surface is %p.\n", 
pic->input_surface->texture);
 
+if (ctx->is_texture_array) {
+base_pic->recon_image->data[0] = ctx->texture_array_frame;
+pic->subresource_index = (ctx->subresource_used_index++) % 
ctx->max_subresource_array_size;
+}
+
 pic->recon_surface = (AVD3D12VAFrame *)base_pic->recon_image->data[0];
 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %p.\n",
pic->recon_surface->texture);
@@ -325,11 +330,28 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 goto fail;
 }
 
+if (ctx->is_texture_array) {
+d3d12_refs.pSubresources = av_calloc(d3d12_refs.NumTexture2Ds,
+
sizeof(*d3d12_refs.pSubresources));
+if (!d3d12_refs.pSubresources) {
+err = AVERROR(ENOMEM);
+goto fail;
+}
+}
+
 i = 0;
-for (j = 0; j < base_pic->nb_refs[0]; j++)
-d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->recon_surface->texture;
-for (j = 0; j < base_pic->nb_refs[1]; j++)
-d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->recon_surface->texture;
+for (j = 0; j < base_pic->nb_refs[0]; j++) {
+d3d12_refs.ppTexture2Ds[i]  = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->recon_surface->texture;
+if (ctx->is_texture_array)
+d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->subresource_index;
+i++;
+}
+for (j = 0; j < base_pic->nb_refs[1]; j++) {
+d3d12_refs.ppTexture2Ds[i]  = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->recon_surface->texture;
+if (ctx->is_texture_array)
+d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->subresource_index;
+i++;
+}
 }
 
 input_args.PictureControlDesc.IntraRefreshFrameIndex  = 0;
@@ -343,7 +365,11 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 output_args.Bitstream.pBuffer= 
pic->output_buffer;
 output_args.Bitstream.FrameStartOffset   = 
pic->aligned_header_size;
 output_args.ReconstructedPicture.pReconstructedPicture   = 
pic->recon_surface->texture;
-output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
+if (ctx->is_texture_array) {
+output_args.ReconstructedPicture.ReconstructedPictureSubresource = 
pic->subresource_index;
+} else {
+output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
+}
 output_args.EncoderOutputMetadata.pBuffer= 
pic->encoded_metadata;
 output_args.EncoderOutputMetadata.Offset = 0;
 
@@ -381,35 +407,87 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 },  \
 }
 
+#define TRANSITION_BARRIER_SUBRESOURCE(res, subres,before, after)   \
+(D3D12_RESOURCE_BARRIER) {  \
+.Type  = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,\
+.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,  \
+.Transition = { \
+.pResource   = res, \
+.Subresource = subres,  \
+.StateBefore = before,  \
+.StateAfter  = after,   \
+},  \
+}
+
 barriers[0] = TRANSITION_BARRIER(pic->input_surface->texture,
  

[FFmpeg-devel] [PATCH, v3] avcodec/d3d12va_encode: texture array support for HEVC

2025-05-24 Thread Araz Iusubov
This patch adds support for the texture array feature
used by AMD boards in the D3D12 HEVC encoder.
In texture array mode, a single texture array is shared for all
reference and reconstructed pictures using different subresources.
The implementation ensures compatibility
and has been successfully tested on AMD, Intel, and NVIDIA GPUs.

v2 updates: 
1. The reference to MaxL1ReferencesForB for the H.264 codec 
was updated to use the corresponding H.264 field instead of the HEVC one.
2. Max_subresource_array_size calculation was adjusted 
by removing the D3D12VA_VIDEO_ENC_ASYNC_DEPTH offset.

v3 updates:
1. Fixed a type mismatch by explicitly casting AVD3D12VAFrame* to 
(uint8_t*) when assigning to data[0].
2. Adjusted logging format specifier for HRESULT to use `%lx`.

---
 libavcodec/d3d12va_encode.c  | 241 +--
 libavcodec/d3d12va_encode.h  |  29 
 libavcodec/d3d12va_encode_hevc.c |   5 +-
 3 files changed, 231 insertions(+), 44 deletions(-)

diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c
index 4d738200fe..85e79b2e14 100644
--- a/libavcodec/d3d12va_encode.c
+++ b/libavcodec/d3d12va_encode.c
@@ -264,6 +264,11 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 
 av_log(avctx, AV_LOG_DEBUG, "Input surface is %p.\n", 
pic->input_surface->texture);
 
+if (ctx->is_texture_array) {
+base_pic->recon_image->data[0] = (uint8_t *)ctx->texture_array_frame;
+pic->subresource_index = (ctx->subresource_used_index++) % 
ctx->max_subresource_array_size;
+}
+
 pic->recon_surface = (AVD3D12VAFrame *)base_pic->recon_image->data[0];
 av_log(avctx, AV_LOG_DEBUG, "Recon surface is %p.\n",
pic->recon_surface->texture);
@@ -325,11 +330,28 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 goto fail;
 }
 
+if (ctx->is_texture_array) {
+d3d12_refs.pSubresources = av_calloc(d3d12_refs.NumTexture2Ds,
+
sizeof(*d3d12_refs.pSubresources));
+if (!d3d12_refs.pSubresources) {
+err = AVERROR(ENOMEM);
+goto fail;
+}
+}
+
 i = 0;
-for (j = 0; j < base_pic->nb_refs[0]; j++)
-d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->recon_surface->texture;
-for (j = 0; j < base_pic->nb_refs[1]; j++)
-d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->recon_surface->texture;
+for (j = 0; j < base_pic->nb_refs[0]; j++) {
+d3d12_refs.ppTexture2Ds[i]  = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->recon_surface->texture;
+if (ctx->is_texture_array)
+d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture 
*)base_pic->refs[0][j]->priv)->subresource_index;
+i++;
+}
+for (j = 0; j < base_pic->nb_refs[1]; j++) {
+d3d12_refs.ppTexture2Ds[i]  = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->recon_surface->texture;
+if (ctx->is_texture_array)
+d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture 
*)base_pic->refs[1][j]->priv)->subresource_index;
+i++;
+}
 }
 
 input_args.PictureControlDesc.IntraRefreshFrameIndex  = 0;
@@ -343,7 +365,11 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 output_args.Bitstream.pBuffer= 
pic->output_buffer;
 output_args.Bitstream.FrameStartOffset   = 
pic->aligned_header_size;
 output_args.ReconstructedPicture.pReconstructedPicture   = 
pic->recon_surface->texture;
-output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
+if (ctx->is_texture_array) {
+output_args.ReconstructedPicture.ReconstructedPictureSubresource = 
pic->subresource_index;
+} else {
+output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0;
+}
 output_args.EncoderOutputMetadata.pBuffer= 
pic->encoded_metadata;
 output_args.EncoderOutputMetadata.Offset = 0;
 
@@ -381,35 +407,87 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
 },  \
 }
 
+#define TRANSITION_BARRIER_SUBRESOURCE(res, subres,before, after)   \
+(D3D12_RESOURCE_BARRIER) {  \
+.Type  = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,\
+.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,  \
+.Transition = { \
+.pResource   = res, \
+.Subresource = subres,  \
+.StateBefore = before,  \
+.StateAfter  = after,  

[FFmpeg-devel] [PATCH] avcodec/d3d12va_encode: fix l0 reference count limit

2025-06-04 Thread Araz Iusubov
Prevents potential null pointer dereference when querying 
MaxL1ReferencesForB from codec-specific support structures 
during GOP structure initialization.

---
 libavcodec/d3d12va_encode.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c
index 4d738200fe..e39d4d1c29 100644
--- a/libavcodec/d3d12va_encode.c
+++ b/libavcodec/d3d12va_encode.c
@@ -1088,13 +1088,15 @@ static int 
d3d12va_encode_init_gop_structure(AVCodecContext *avctx)
 switch (ctx->codec->d3d12_codec) {
 case D3D12_VIDEO_ENCODER_CODEC_H264:
 ref_l0 = 
FFMIN(support.PictureSupport.pH264Support->MaxL0ReferencesForP,
-   
support.PictureSupport.pH264Support->MaxL1ReferencesForB);
+   
support.PictureSupport.pH264Support->MaxL1ReferencesForB ?
+   
support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB : UINT_MAX);
 ref_l1 = 
support.PictureSupport.pH264Support->MaxL1ReferencesForB;
 break;
 
 case D3D12_VIDEO_ENCODER_CODEC_HEVC:
 ref_l0 = 
FFMIN(support.PictureSupport.pHEVCSupport->MaxL0ReferencesForP,
-   
support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB);
+   
support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB ?
+   
support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB : UINT_MAX);
 ref_l1 = 
support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB;
 break;
 
-- 
2.45.2.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".