[FFmpeg-devel] [PATCH] libavutil/hwcontext_qsv: Make qsv hardware transfers thread safe

2024-04-17 Thread Mark Samuelson
The QSV hardware context currently uses pthreads to lock initilization,
which is not available on windows builds.  Instead, use the AVMutex
object.  Also lock uses of the realigned_upload_frame and
realigned_download_frame objects, so multiple threads do not attempt
to write to them at the same time.
---
 
Here is a new patch addressing your comments
Fixed the nested calls to ff_mutex_lock
Fixed the two accidental tabs
Fixed the two violations of K style
Fixed the two incidents of mixing declaration and code


 libavutil/hwcontext_qsv.c | 93 +++
 1 file changed, 56 insertions(+), 37 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index c7c7878644..ed462d440a 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -23,10 +23,7 @@
 #include 
 
 #include "config.h"
-
-#if HAVE_PTHREADS
-#include 
-#endif
+#include "thread.h"
 
 #define COBJMACROS
 #if CONFIG_VAAPI
@@ -98,9 +95,7 @@ typedef struct QSVFramesContext {
 atomic_int session_download_init;
 mfxSession session_upload;
 atomic_int session_upload_init;
-#if HAVE_PTHREADS
-pthread_mutex_t session_lock;
-#endif
+AVMutex session_lock;
 
 AVBufferRef *child_frames_ref;
 mfxFrameSurface1 *surfaces_internal;
@@ -354,9 +349,7 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx)
 s->session_upload = NULL;
 s->session_upload_init = 0;
 
-#if HAVE_PTHREADS
-pthread_mutex_destroy(>session_lock);
-#endif
+ff_mutex_destroy(>session_lock);
 
 av_freep(>mem_ids);
 #if QSV_HAVE_OPAQUE
@@ -1302,9 +1295,7 @@ static int qsv_frames_init(AVHWFramesContext *ctx)
 s->session_download_init = 0;
 s->session_upload_init   = 0;
 
-#if HAVE_PTHREADS
-pthread_mutex_init(>session_lock, NULL);
-#endif
+ff_mutex_init(>session_lock, NULL);
 
 return 0;
 }
@@ -1629,24 +1620,20 @@ static int 
qsv_internal_session_check_init(AVHWFramesContext *ctx, int upload)
 if (atomic_load(inited))
 return 0;
 
-#if HAVE_PTHREADS
-pthread_mutex_lock(>session_lock);
-#endif
+ff_mutex_lock(>session_lock);
 
 if (!atomic_load(inited)) {
 ret = qsv_init_internal_session(ctx, session, upload);
 atomic_store(inited, 1);
 }
 
-#if HAVE_PTHREADS
-pthread_mutex_unlock(>session_lock);
-#endif
+ff_mutex_unlock(>session_lock);
 
 return ret;
 }
 
-static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
-  const AVFrame *src)
+static int qsv_transfer_data_from_internal(AVHWFramesContext *ctx, AVFrame 
*dst,
+   const AVFrame *src, int realigned)
 {
 QSVFramesContext  *s = ctx->hwctx;
 mfxFrameSurface1 out = {{ 0 }};
@@ -1658,17 +1645,11 @@ static int qsv_transfer_data_from(AVHWFramesContext 
*ctx, AVFrame *dst,
 /* download to temp frame if the output is not padded as libmfx requires */
 AVFrame *tmp_frame = >realigned_download_frame;
 AVFrame *dst_frame;
-int realigned = 0;
-
-ret = qsv_internal_session_check_init(ctx, 0);
-if (ret < 0)
-return ret;
 
 /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 
16.
  * Height must be a multiple of 16 for progressive frame sequence and a
  * multiple of 32 otherwise.", so allign all frames to 16 before 
downloading. */
-if (dst->height & 15 || dst->linesize[0] & 15) {
-realigned = 1;
+if (realigned) {
 if (tmp_frame->format != dst->format ||
 tmp_frame->width  != FFALIGN(dst->linesize[0], 16) ||
 tmp_frame->height != FFALIGN(dst->height, 16)) {
@@ -1728,8 +1709,30 @@ static int qsv_transfer_data_from(AVHWFramesContext 
*ctx, AVFrame *dst,
 return 0;
 }
 
-static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst,
-const AVFrame *src)
+static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
+  const AVFrame *src)
+{
+QSVFramesContext *s = ctx->hwctx;
+int realigned = 0;
+int ret = 0;
+
+ret = qsv_internal_session_check_init(ctx, 0);
+if (ret < 0)
+return ret;
+
+if (dst->height & 15 || dst->linesize[0] & 15) {
+realigned = 1;
+ff_mutex_lock(>session_lock);
+}
+ret = qsv_transfer_data_from_internal(ctx, dst, src, realigned);
+if (realigned)
+ff_mutex_unlock(>session_lock);
+
+return ret;
+}
+
+static int qsv_transfer_data_to_internal(AVHWFramesContext *ctx, AVFrame *dst,
+ const AVFrame *src, int realigned)
 {
 QSVFramesContext   *s = ctx->hwctx;
 mfxFrameSurface1   in = {{ 0 }};
@@ -1742,17 +1745,11 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 /* make a copy if the input is not padded as libmfx requires */
 AVFrame *tmp_frame = >realigned_upload_frame;
 const AVFrame *src_frame;
-int realigned = 0;

[FFmpeg-devel] [PATCH] libavutil/hwcontext_qsv: Make qsv hardware transfers thread safe

2024-04-13 Thread Mark Samuelson
The QSV hardware context currently uses pthreads to lock initilization,
which is not available on windows builds.  Instead, use the AVMutex
object.  Also lock uses of the realigned_upload_frame and
realigned_download_frame objects, so multiple threads do not attempt
to write to them at the same time.
---
 libavutil/hwcontext_qsv.c | 75 ---
 1 file changed, 46 insertions(+), 29 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index c7c7878644..92bab134e4 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -23,10 +23,7 @@
 #include 
 
 #include "config.h"
-
-#if HAVE_PTHREADS
-#include 
-#endif
+#include "thread.h"
 
 #define COBJMACROS
 #if CONFIG_VAAPI
@@ -98,9 +95,7 @@ typedef struct QSVFramesContext {
 atomic_int session_download_init;
 mfxSession session_upload;
 atomic_int session_upload_init;
-#if HAVE_PTHREADS
-pthread_mutex_t session_lock;
-#endif
+AVMutex session_lock;
 
 AVBufferRef *child_frames_ref;
 mfxFrameSurface1 *surfaces_internal;
@@ -354,9 +349,7 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx)
 s->session_upload = NULL;
 s->session_upload_init = 0;
 
-#if HAVE_PTHREADS
-pthread_mutex_destroy(>session_lock);
-#endif
+ff_mutex_destroy(>session_lock);
 
 av_freep(>mem_ids);
 #if QSV_HAVE_OPAQUE
@@ -1302,9 +1295,7 @@ static int qsv_frames_init(AVHWFramesContext *ctx)
 s->session_download_init = 0;
 s->session_upload_init   = 0;
 
-#if HAVE_PTHREADS
-pthread_mutex_init(>session_lock, NULL);
-#endif
+ff_mutex_init(>session_lock, NULL);
 
 return 0;
 }
@@ -1629,24 +1620,20 @@ static int 
qsv_internal_session_check_init(AVHWFramesContext *ctx, int upload)
 if (atomic_load(inited))
 return 0;
 
-#if HAVE_PTHREADS
-pthread_mutex_lock(>session_lock);
-#endif
+ff_mutex_lock(>session_lock);
 
 if (!atomic_load(inited)) {
 ret = qsv_init_internal_session(ctx, session, upload);
 atomic_store(inited, 1);
 }
 
-#if HAVE_PTHREADS
-pthread_mutex_unlock(>session_lock);
-#endif
+ff_mutex_unlock(>session_lock);
 
 return ret;
 }
 
-static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
-  const AVFrame *src)
+static int qsv_transfer_data_from_internal(AVHWFramesContext *ctx, AVFrame 
*dst,
+   const AVFrame *src, int realigned)
 {
 QSVFramesContext  *s = ctx->hwctx;
 mfxFrameSurface1 out = {{ 0 }};
@@ -1658,7 +1645,6 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, 
AVFrame *dst,
 /* download to temp frame if the output is not padded as libmfx requires */
 AVFrame *tmp_frame = >realigned_download_frame;
 AVFrame *dst_frame;
-int realigned = 0;
 
 ret = qsv_internal_session_check_init(ctx, 0);
 if (ret < 0)
@@ -1667,8 +1653,7 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, 
AVFrame *dst,
 /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 
16.
  * Height must be a multiple of 16 for progressive frame sequence and a
  * multiple of 32 otherwise.", so allign all frames to 16 before 
downloading. */
-if (dst->height & 15 || dst->linesize[0] & 15) {
-realigned = 1;
+if (realigned) {
 if (tmp_frame->format != dst->format ||
 tmp_frame->width  != FFALIGN(dst->linesize[0], 16) ||
 tmp_frame->height != FFALIGN(dst->height, 16)) {
@@ -1728,8 +1713,25 @@ static int qsv_transfer_data_from(AVHWFramesContext 
*ctx, AVFrame *dst,
 return 0;
 }
 
-static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst,
-const AVFrame *src)
+static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
+  const AVFrame *src)
+{
+   QSVFramesContext *s = ctx->hwctx;
+int realigned = 0;
+if (dst->height & 15 || dst->linesize[0] & 15)
+{
+realigned = 1;
+ff_mutex_lock(>session_lock);
+}
+int ret = qsv_transfer_data_from_internal(ctx, dst, src, realigned);
+if (realigned)
+ff_mutex_unlock(>session_lock);
+
+return ret;
+}
+
+static int qsv_transfer_data_to_internal(AVHWFramesContext *ctx, AVFrame *dst,
+const AVFrame *src, int realigned)
 {
 QSVFramesContext   *s = ctx->hwctx;
 mfxFrameSurface1   in = {{ 0 }};
@@ -1742,7 +1744,6 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 /* make a copy if the input is not padded as libmfx requires */
 AVFrame *tmp_frame = >realigned_upload_frame;
 const AVFrame *src_frame;
-int realigned = 0;
 
 ret = qsv_internal_session_check_init(ctx, 1);
 if (ret < 0)
@@ -1751,8 +1752,7 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 
16.

Re: [FFmpeg-devel] [PATCH] avcodec/mfenc: expose more properties of the media foundation encoder

2024-04-01 Thread Mark Samuelson
On Mon, Apr 1, 2024 at 10:06 AM Mark Thompson  wrote:

> > On 28/03/2024 12:34, Mark Samuelson wrote:
> > > Thank you for the notes, here is a new patch that incorporates your
> suggestions.  You are right, the default value of 12 for gop_size is
> suprising, I didn't know about it before now.
> > >
> > > ---
> > >   libavcodec/mf_utils.h |  5 +
> > >   libavcodec/mfenc.c| 33 +++--
> > >   2 files changed, 32 insertions(+), 6 deletions(-)
> >
> > Patch looks good.
> >
> > I did a bit of testing with the Microsoft H.264 MFT: GOP size and
> compression level work as expected, and VBV parameters seem to be doing
> something sensible.
> >
> > Under what conditions are you expecting global_quality ->
> AVEncVideoEncodeQP to do anything, though?  When I set it alone the output
> was always identical regardless of what value I set > it to.  (Including
> with "-rate_control quality".)
> >
> > Thanks,
> >
> > - Mark
>

I have also had issues making the Media Foundation encoder respect that
value.  I put it in there so that I could easily test it, because I was
having issues with the existing opt_enc_quality -> AVEncCommonQuality.  I
figured it was better to leave it in so people can experiment with it.

>
> > > diff --git a/libavcodec/mf_utils.h b/libavcodec/mf_utils.h
> > > index aebfb9ad21..387c005f38 100644
> > > --- a/libavcodec/mf_utils.h
> > > +++ b/libavcodec/mf_utils.h
> > > @@ -97,6 +97,11 @@ DEFINE_GUID(ff_CODECAPI_AVEncH264CABACEnable,
> 0xee6cad62, 0xd305, 0x4248, 0xa
> > >   DEFINE_GUID(ff_CODECAPI_AVEncVideoForceKeyFrame, 0x398c1b98, 0x8353,
> 0x475a, 0x9e, 0xf2, 0x8f, 0x26, 0x5d, 0x26, 0x3, 0x45);
> > >   DEFINE_GUID(ff_CODECAPI_AVEncMPVDefaultBPictureCount, 0x8d390aac,
> 0xdc5c, 0x4200, 0xb5, 0x7f, 0x81, 0x4d, 0x04, 0xba, 0xba, 0xb2);
> > >   DEFINE_GUID(ff_CODECAPI_AVScenarioInfo,
> 0xb28a6e64,0x3ff9,0x446a,0x8a,0x4b,0x0d,0x7a,0x53,0x41,0x32,0x36);
> > > +DEFINE_GUID(ff_CODECAPI_AVEncCommonBufferSize, 0x0db96574, 0xb6a4,
> 0x4c8b, 0x81, 0x06, 0x37, 0x73, 0xde, 0x03, 0x10, 0xcd);
> > > +DEFINE_GUID(ff_CODECAPI_AVEncCommonMaxBitRate, 0x9651eae4, 0x39b9,
> 0x4ebf, 0x85, 0xef, 0xd7, 0xf4, 0x44, 0xec, 0x74, 0x65);
> > > +DEFINE_GUID(ff_CODECAPI_AVEncCommonQualityVsSpeed, 0x98332df8,
> 0x03cd, 0x476b, 0x89, 0xfa, 0x3f, 0x9e, 0x44, 0x2d, 0xec, 0x9f);
> > > +DEFINE_GUID(ff_CODECAPI_AVEncMPVGOPSize, 0x95f31b26, 0x95a4, 0x41aa,
> 0x93, 0x03, 0x24, 0x6a, 0x7f, 0xc6, 0xee, 0xf1);
> > > +DEFINE_GUID(ff_CODECAPI_AVEncVideoEncodeQP, 0x2cb5696b, 0x23fb,
> 0x4ce1, 0xa0, 0xf9, 0xef, 0x5b, 0x90, 0xfd, 0x55, 0xca);
> > >
> > >   DEFINE_GUID(ff_MF_SA_D3D11_BINDFLAGS, 0xeacf97ad, 0x065c, 0x4408,
> 0xbe, 0xe3, 0xfd, 0xcb, 0xfd, 0x12, 0x8b, 0xe2);
> > >   DEFINE_GUID(ff_MF_SA_D3D11_USAGE, 0xe85fe442, 0x2ca3, 0x486e, 0xa9,
> 0xc7, 0x10, 0x9d, 0xda, 0x60, 0x98, 0x80);
> > > diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c
> > > index 9225692c51..cad531bd7d 100644
> > > --- a/libavcodec/mfenc.c
> > > +++ b/libavcodec/mfenc.c
> > > @@ -695,6 +695,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
> > >   if (c->opt_enc_quality >= 0)
> > >   ICodecAPI_SetValue(c->codec_api,
> _CODECAPI_AVEncCommonQuality, FF_VAL_VT_UI4(c->opt_enc_quality));
> > >
> > > +if (avctx->rc_max_rate > 0)
> > > +ICodecAPI_SetValue(c->codec_api,
> _CODECAPI_AVEncCommonMaxBitRate, FF_VAL_VT_UI4(avctx->rc_max_rate));
> > > +
> > > +if (avctx->gop_size > 0)
> > > +ICodecAPI_SetValue(c->codec_api,
> _CODECAPI_AVEncMPVGOPSize, FF_VAL_VT_UI4(avctx->gop_size));
> > > +
> > > +if(avctx->rc_buffer_size > 0)
> > > +ICodecAPI_SetValue(c->codec_api,
> _CODECAPI_AVEncCommonBufferSize, FF_VAL_VT_UI4(avctx->rc_buffer_size));
> > > +
> > > +if(avctx->compression_level >= 0)
> > > +ICodecAPI_SetValue(c->codec_api,
> _CODECAPI_AVEncCommonQualityVsSpeed,
> FF_VAL_VT_UI4(avctx->compression_level));
> > > +
> > > +if(avctx->global_quality > 0)
> > > +ICodecAPI_SetValue(c->codec_api,
> _CODECAPI_AVEncVideoEncodeQP, FF_VAL_VT_UI4(avctx->global_quality ));
> > > +
> > >   // Always set the number of b-frames. Qualcomm's HEVC
> encoder on SD835
> > >   // defaults this to 1, and that setting is buggy with many
> of the
> > >   /

[FFmpeg-devel] [PATCH] avcodec/mfenc: expose more properties of the media foundation encoder

2024-03-28 Thread Mark Samuelson
Thank you for the notes, here is a new patch that incorporates your 
suggestions.  You are right, the default value of 12 for gop_size is suprising, 
I didn't know about it before now.

---
 libavcodec/mf_utils.h |  5 +
 libavcodec/mfenc.c| 33 +++--
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/libavcodec/mf_utils.h b/libavcodec/mf_utils.h
index aebfb9ad21..387c005f38 100644
--- a/libavcodec/mf_utils.h
+++ b/libavcodec/mf_utils.h
@@ -97,6 +97,11 @@ DEFINE_GUID(ff_CODECAPI_AVEncH264CABACEnable,0xee6cad62, 
0xd305, 0x4248, 0xa
 DEFINE_GUID(ff_CODECAPI_AVEncVideoForceKeyFrame, 0x398c1b98, 0x8353, 0x475a, 
0x9e, 0xf2, 0x8f, 0x26, 0x5d, 0x26, 0x3, 0x45);
 DEFINE_GUID(ff_CODECAPI_AVEncMPVDefaultBPictureCount, 0x8d390aac, 0xdc5c, 
0x4200, 0xb5, 0x7f, 0x81, 0x4d, 0x04, 0xba, 0xba, 0xb2);
 DEFINE_GUID(ff_CODECAPI_AVScenarioInfo, 
0xb28a6e64,0x3ff9,0x446a,0x8a,0x4b,0x0d,0x7a,0x53,0x41,0x32,0x36);
+DEFINE_GUID(ff_CODECAPI_AVEncCommonBufferSize, 0x0db96574, 0xb6a4, 0x4c8b, 
0x81, 0x06, 0x37, 0x73, 0xde, 0x03, 0x10, 0xcd);
+DEFINE_GUID(ff_CODECAPI_AVEncCommonMaxBitRate, 0x9651eae4, 0x39b9, 0x4ebf, 
0x85, 0xef, 0xd7, 0xf4, 0x44, 0xec, 0x74, 0x65);
+DEFINE_GUID(ff_CODECAPI_AVEncCommonQualityVsSpeed, 0x98332df8, 0x03cd, 0x476b, 
0x89, 0xfa, 0x3f, 0x9e, 0x44, 0x2d, 0xec, 0x9f);
+DEFINE_GUID(ff_CODECAPI_AVEncMPVGOPSize, 0x95f31b26, 0x95a4, 0x41aa, 0x93, 
0x03, 0x24, 0x6a, 0x7f, 0xc6, 0xee, 0xf1);
+DEFINE_GUID(ff_CODECAPI_AVEncVideoEncodeQP, 0x2cb5696b, 0x23fb, 0x4ce1, 0xa0, 
0xf9, 0xef, 0x5b, 0x90, 0xfd, 0x55, 0xca);
 
 DEFINE_GUID(ff_MF_SA_D3D11_BINDFLAGS, 0xeacf97ad, 0x065c, 0x4408, 0xbe, 0xe3, 
0xfd, 0xcb, 0xfd, 0x12, 0x8b, 0xe2);
 DEFINE_GUID(ff_MF_SA_D3D11_USAGE, 0xe85fe442, 0x2ca3, 0x486e, 0xa9, 0xc7, 
0x10, 0x9d, 0xda, 0x60, 0x98, 0x80);
diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c
index 9225692c51..cad531bd7d 100644
--- a/libavcodec/mfenc.c
+++ b/libavcodec/mfenc.c
@@ -695,6 +695,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
 if (c->opt_enc_quality >= 0)
 ICodecAPI_SetValue(c->codec_api, _CODECAPI_AVEncCommonQuality, 
FF_VAL_VT_UI4(c->opt_enc_quality));
 
+if (avctx->rc_max_rate > 0)
+ICodecAPI_SetValue(c->codec_api, 
_CODECAPI_AVEncCommonMaxBitRate, FF_VAL_VT_UI4(avctx->rc_max_rate));
+
+if (avctx->gop_size > 0)
+ICodecAPI_SetValue(c->codec_api, _CODECAPI_AVEncMPVGOPSize, 
FF_VAL_VT_UI4(avctx->gop_size));
+
+if(avctx->rc_buffer_size > 0)
+ICodecAPI_SetValue(c->codec_api, 
_CODECAPI_AVEncCommonBufferSize, FF_VAL_VT_UI4(avctx->rc_buffer_size));
+
+if(avctx->compression_level >= 0)
+ICodecAPI_SetValue(c->codec_api, 
_CODECAPI_AVEncCommonQualityVsSpeed, 
FF_VAL_VT_UI4(avctx->compression_level));
+
+if(avctx->global_quality > 0)
+ICodecAPI_SetValue(c->codec_api, _CODECAPI_AVEncVideoEncodeQP, 
FF_VAL_VT_UI4(avctx->global_quality ));
+
 // Always set the number of b-frames. Qualcomm's HEVC encoder on SD835
 // defaults this to 1, and that setting is buggy with many of the
 // rate control modes. (0 or 2 b-frames works fine with most rate
@@ -1223,7 +1238,7 @@ static int mf_init(AVCodecContext *avctx)
 
 #define OFFSET(x) offsetof(MFContext, x)
 
-#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS) \
+#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS) \
 static const AVClass ff_ ## NAME ## _mf_encoder_class = {  
\
 .class_name = #NAME "_mf", 
\
 .item_name  = av_default_item_name,
\
@@ -1243,6 +1258,7 @@ static int mf_init(AVCodecContext *avctx)
 FMTS   
\
 CAPS   
\
 .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,   
\
+   .defaults   = DEFAULTS, 
   \
 };
 
 #define AFMTS \
@@ -1252,9 +1268,9 @@ static int mf_init(AVCodecContext *avctx)
 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID |   
\
   AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
 
-MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS);
-MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS);
-MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS);
+MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS, NULL);
+MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS, NULL);
+MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS, NULL);
 
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption venc_opts[] = {
@@ -1283,6 +1299,11 @@ static const AVOption venc_opts[] = {
 {NULL}
 };
 
+static const FFCodecDefault defaults[] = {
+{ "g", "0" },
+{ NULL },
+};
+
 #define VFMTS \
 

[FFmpeg-devel] [PATCH] avcodec/mfenc: expose more properties of the media foundation encoder

2024-03-26 Thread Mark Samuelson
---
 libavcodec/mf_utils.h |  5 +
 libavcodec/mfenc.c| 19 +++
 2 files changed, 24 insertions(+)

diff --git a/libavcodec/mf_utils.h b/libavcodec/mf_utils.h
index aebfb9ad21..387c005f38 100644
--- a/libavcodec/mf_utils.h
+++ b/libavcodec/mf_utils.h
@@ -97,6 +97,11 @@ DEFINE_GUID(ff_CODECAPI_AVEncH264CABACEnable,0xee6cad62, 
0xd305, 0x4248, 0xa
 DEFINE_GUID(ff_CODECAPI_AVEncVideoForceKeyFrame, 0x398c1b98, 0x8353, 0x475a, 
0x9e, 0xf2, 0x8f, 0x26, 0x5d, 0x26, 0x3, 0x45);
 DEFINE_GUID(ff_CODECAPI_AVEncMPVDefaultBPictureCount, 0x8d390aac, 0xdc5c, 
0x4200, 0xb5, 0x7f, 0x81, 0x4d, 0x04, 0xba, 0xba, 0xb2);
 DEFINE_GUID(ff_CODECAPI_AVScenarioInfo, 
0xb28a6e64,0x3ff9,0x446a,0x8a,0x4b,0x0d,0x7a,0x53,0x41,0x32,0x36);
+DEFINE_GUID(ff_CODECAPI_AVEncCommonBufferSize, 0x0db96574, 0xb6a4, 0x4c8b, 
0x81, 0x06, 0x37, 0x73, 0xde, 0x03, 0x10, 0xcd);
+DEFINE_GUID(ff_CODECAPI_AVEncCommonMaxBitRate, 0x9651eae4, 0x39b9, 0x4ebf, 
0x85, 0xef, 0xd7, 0xf4, 0x44, 0xec, 0x74, 0x65);
+DEFINE_GUID(ff_CODECAPI_AVEncCommonQualityVsSpeed, 0x98332df8, 0x03cd, 0x476b, 
0x89, 0xfa, 0x3f, 0x9e, 0x44, 0x2d, 0xec, 0x9f);
+DEFINE_GUID(ff_CODECAPI_AVEncMPVGOPSize, 0x95f31b26, 0x95a4, 0x41aa, 0x93, 
0x03, 0x24, 0x6a, 0x7f, 0xc6, 0xee, 0xf1);
+DEFINE_GUID(ff_CODECAPI_AVEncVideoEncodeQP, 0x2cb5696b, 0x23fb, 0x4ce1, 0xa0, 
0xf9, 0xef, 0x5b, 0x90, 0xfd, 0x55, 0xca);
 
 DEFINE_GUID(ff_MF_SA_D3D11_BINDFLAGS, 0xeacf97ad, 0x065c, 0x4408, 0xbe, 0xe3, 
0xfd, 0xcb, 0xfd, 0x12, 0x8b, 0xe2);
 DEFINE_GUID(ff_MF_SA_D3D11_USAGE, 0xe85fe442, 0x2ca3, 0x486e, 0xa9, 0xc7, 
0x10, 0x9d, 0xda, 0x60, 0x98, 0x80);
diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c
index 9225692c51..36f64a93b8 100644
--- a/libavcodec/mfenc.c
+++ b/libavcodec/mfenc.c
@@ -54,6 +54,8 @@ typedef struct MFContext {
 int opt_enc_quality;
 int opt_enc_scenario;
 int opt_enc_hw;
+int opt_enc_bufferSize;
+int opt_enc_encodeQP;
 } MFContext;
 
 static int mf_choose_output_type(AVCodecContext *avctx);
@@ -695,6 +697,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
 if (c->opt_enc_quality >= 0)
 ICodecAPI_SetValue(c->codec_api, _CODECAPI_AVEncCommonQuality, 
FF_VAL_VT_UI4(c->opt_enc_quality));
 
+if (avctx->rc_max_rate > 0)
+ICodecAPI_SetValue(c->codec_api, 
_CODECAPI_AVEncCommonMaxBitRate, FF_VAL_VT_UI4(avctx->rc_max_rate));
+
+if (avctx->gop_size > 0)
+ICodecAPI_SetValue(c->codec_api, _CODECAPI_AVEncMPVGOPSize, 
FF_VAL_VT_UI4(avctx->gop_size));
+
+if(c->opt_enc_bufferSize > 0)
+ICodecAPI_SetValue(c->codec_api, 
_CODECAPI_AVEncCommonBufferSize, FF_VAL_VT_UI4(c->opt_enc_bufferSize));
+
+if(avctx->compression_level >= 0)
+ICodecAPI_SetValue(c->codec_api, 
_CODECAPI_AVEncCommonQualityVsSpeed, 
FF_VAL_VT_UI4(avctx->compression_level));
+
+if(c->opt_enc_encodeQP > 15)
+ICodecAPI_SetValue(c->codec_api, _CODECAPI_AVEncVideoEncodeQP, 
FF_VAL_VT_UI4(c->opt_enc_encodeQP));
+
 // Always set the number of b-frames. Qualcomm's HEVC encoder on SD835
 // defaults this to 1, and that setting is buggy with many of the
 // rate control modes. (0 or 2 b-frames works fine with most rate
@@ -1280,6 +1297,8 @@ static const AVOption venc_opts[] = {
 
 {"quality",   "Quality", OFFSET(opt_enc_quality), AV_OPT_TYPE_INT, 
{.i64 = -1}, -1, 100, VE},
 {"hw_encoding",   "Force hardware encoding", OFFSET(opt_enc_hw), 
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE},
+{"buffer_size", "BufferSize", OFFSET(opt_enc_bufferSize), AV_OPT_TYPE_INT, 
{.i64 = 0}, 0, INT_MAX, VE},
+{"encodeQP", "QualityQP", OFFSET(opt_enc_encodeQP), AV_OPT_TYPE_INT, {.i64 
= 15}, 15, 51, VE},
 {NULL}
 };
 
-- 
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".