[vlc-commits] [Git][videolan/vlc][master] 3 commits: amf_frc: don't use a staging texture to pass the input texture

Steve Lhomme (@robUx4) gitlab at videolan.org
Mon Oct 14 10:12:25 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
b25d56b2 by Steve Lhomme at 2024-10-14T09:52:23+00:00
amf_frc: don't use a staging texture to pass the input texture

There is a trick to set the slice array number on the D3D resource before
submission.

- - - - -
bf7ce015 by Steve Lhomme at 2024-10-14T09:52:23+00:00
amf_frc: lock D3D11 context on QueryOutput()

- - - - -
f7537d88 by Steve Lhomme at 2024-10-14T09:52:23+00:00
amf_frc: release the amfOutput when it's not used anymore

Its lifecycle may not be tied to the D3D11 texture.

- - - - -


1 changed file:

- modules/video_filter/amf_frc.c


Changes:

=====================================
modules/video_filter/amf_frc.c
=====================================
@@ -24,6 +24,8 @@
 
 #include <assert.h>
 
+static GUID  AMFVLCTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, {0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf} };
+
 static const char *const ppsz_filter_options[] = {
     "frc-indicator", NULL
 };
@@ -44,7 +46,6 @@ struct filter_sys_t
 {
     struct vlc_amf_context         amf;
     AMFComponent                   *amf_frc;
-    AMFSurface                     *amfInput;
     const d3d_format_t             *cfg;
 
     enum AMF_FRC_MODE_TYPE         mode;
@@ -52,11 +53,49 @@ struct filter_sys_t
     date_t                         next_output_pts;
 };
 
-static picture_t *PictureFromTexture(filter_t *filter, d3d11_device_t *d3d_dev, ID3D11Texture2D *out)
+struct d3d11amf_pic_context
+{
+    struct d3d11_pic_context  ctx;
+    AMFData                   *data;
+};
+
+#define D3D11AMF_PICCONTEXT_FROM_PICCTX(pic_ctx)  \
+    container_of((pic_ctx), struct d3d11amf_pic_context, ctx.s)
+
+
+static void d3d11amf_pic_context_destroy(picture_context_t *ctx)
+{
+    struct d3d11amf_pic_context *pic_ctx = D3D11AMF_PICCONTEXT_FROM_PICCTX(ctx);
+    struct AMFData *data = pic_ctx->data;
+    static_assert(offsetof(struct d3d11amf_pic_context, ctx.s) == 0,
+        "Cast assumption failure");
+    d3d11_pic_context_destroy(ctx);
+    data->pVtbl->Release(data);
+}
+
+static picture_context_t *d3d11amf_pic_context_copy(picture_context_t *ctx)
+{
+    struct d3d11amf_pic_context *src_ctx = D3D11AMF_PICCONTEXT_FROM_PICCTX(ctx);
+    struct d3d11amf_pic_context *pic_ctx = malloc(sizeof(*pic_ctx));
+    if (unlikely(pic_ctx==NULL))
+        return NULL;
+    *pic_ctx = *src_ctx;
+    vlc_video_context_Hold(pic_ctx->ctx.s.vctx);
+    pic_ctx->data->pVtbl->Acquire(pic_ctx->data);
+    for (int i=0;i<DXGI_MAX_SHADER_VIEW; i++)
+    {
+        pic_ctx->ctx.picsys.resource[i]  = src_ctx->ctx.picsys.resource[i];
+        pic_ctx->ctx.picsys.renderSrc[i] = src_ctx->ctx.picsys.renderSrc[i];
+    }
+    AcquireD3D11PictureSys(&pic_ctx->ctx.picsys);
+    return &pic_ctx->ctx.s;
+}
+
+static picture_t *PictureFromTexture(filter_t *filter, d3d11_device_t *d3d_dev, ID3D11Texture2D *out, AMFData* data)
 {
     struct filter_sys_t *sys = filter->p_sys;
 
-    struct d3d11_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
+    struct d3d11amf_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
     if (unlikely(pic_ctx == NULL))
         return NULL;
 
@@ -66,19 +105,20 @@ static picture_t *PictureFromTexture(filter_t *filter, d3d11_device_t *d3d_dev,
         msg_Err(filter, "Failed to map create the temporary picture.");
         goto done;
     }
-    p_dst->context = &pic_ctx->s;
+    p_dst->context = &pic_ctx->ctx.s;
 
     D3D11_PictureAttach(p_dst, out, sys->cfg);
 
     if (unlikely(D3D11_AllocateResourceView(vlc_object_logger(filter), d3d_dev->d3ddevice, sys->cfg,
-                                            pic_ctx->picsys.texture, 0, pic_ctx->picsys.renderSrc) != VLC_SUCCESS))
+                                            pic_ctx->ctx.picsys.texture, 0, pic_ctx->ctx.picsys.renderSrc) != VLC_SUCCESS))
         goto done;
 
-    pic_ctx->s = (picture_context_t) {
-        d3d11_pic_context_destroy, d3d11_pic_context_copy,
+    pic_ctx->ctx.s = (picture_context_t) {
+        d3d11amf_pic_context_destroy, d3d11amf_pic_context_copy,
         vlc_video_context_Hold(filter->vctx_out),
     };
-    pic_ctx->picsys.sharedHandle = INVALID_HANDLE_VALUE;
+    pic_ctx->ctx.picsys.sharedHandle = INVALID_HANDLE_VALUE;
+    pic_ctx->data = data;
 
     return p_dst;
 done:
@@ -95,39 +135,23 @@ static picture_t * Filter(filter_t *filter, picture_t *p_pic)
     picture_sys_d3d11_t *src_sys = ActiveD3D11PictureSys(p_pic);
 
     AMF_RESULT res;
-    AMFSurface *submitSurface;
-
-    AMFPlane *packedStaging = sys->amfInput->pVtbl->GetPlane(sys->amfInput, AMF_PLANE_PACKED);
-    ID3D11Resource *amfStaging = packedStaging->pVtbl->GetNative(packedStaging);
-
-#ifndef NDEBUG
-    ID3D11Texture2D *staging = (ID3D11Texture2D *)amfStaging;
-    D3D11_TEXTURE2D_DESC stagingDesc, inputDesc;
-    ID3D11Texture2D_GetDesc(staging, &stagingDesc);
-    ID3D11Texture2D_GetDesc(src_sys->texture[KNOWN_DXGI_INDEX], &inputDesc);
-    assert(stagingDesc.Width == inputDesc.Width);
-    assert(stagingDesc.Height == inputDesc.Height);
-    assert(stagingDesc.Format == inputDesc.Format);
-#endif
+    AMFSurface *submitSurface = NULL;
 
     d3d11_decoder_device_t *dev_sys = GetD3D11OpaqueContext( filter->vctx_in );
 
-#if 0
-    if (src_sys->slice_index == 0)
-    sys->amf.Context->pVtbl->CreateSurfaceFromDX11Native(sys->amf.Context, )
-#endif
-    // copy source into staging as it may not be shared and we can't select a slice
-    d3d11_device_lock( &dev_sys->d3d_dev );
-    ID3D11DeviceContext_CopySubresourceRegion(dev_sys->d3d_dev.d3dcontext, amfStaging,
-                                            0,
-                                            0, 0, 0,
-                                            src_sys->resource[KNOWN_DXGI_INDEX],
-                                            src_sys->slice_index,
-                                            NULL);
-    d3d11_device_unlock( &dev_sys->d3d_dev );
-    submitSurface = sys->amfInput;
+    res = sys->amf.Context->pVtbl->CreateSurfaceFromDX11Native(sys->amf.Context, (void*)src_sys->resource[KNOWN_DXGI_INDEX], &submitSurface, NULL);
+    if (res != AMF_OK)
+    {
+        msg_Err(filter, "filter surface allocation failed (err=%d)", res);
+        if (submitSurface)
+            submitSurface->pVtbl->Release(submitSurface);
+        return p_pic;
+    }
+    amf_int subResourceIndex = src_sys->slice_index;
+    ID3D11Resource_SetPrivateData(src_sys->resource[KNOWN_DXGI_INDEX], &AMFVLCTextureArrayIndexGUID, sizeof(subResourceIndex), &subResourceIndex);
 
     res = sys->amf_frc->pVtbl->SubmitInput(sys->amf_frc, (AMFData*)submitSurface);
+    submitSurface->pVtbl->Release(submitSurface);
     if (res == AMF_INPUT_FULL)
     {
         msg_Dbg(filter, "filter input full, skip this frame");
@@ -143,7 +167,9 @@ static picture_t * Filter(filter_t *filter, picture_t *p_pic)
     bool got_output = sys->mode != FRC_x2_PRESENT;
     do {
         AMFData *amfOutput = NULL;
+        d3d11_device_lock( &dev_sys->d3d_dev ); // may consider to connect with AMFContext::LockDX11()/UnlockDX11()
         res = sys->amf_frc->pVtbl->QueryOutput(sys->amf_frc, &amfOutput);
+        d3d11_device_unlock( &dev_sys->d3d_dev );
         if (res != AMF_OK && res != AMF_REPEAT)
         {
             msg_Err(filter, "filter gave no output (err=%d)", res);
@@ -155,10 +181,12 @@ static picture_t * Filter(filter_t *filter, picture_t *p_pic)
 
         assert(amfOutput->pVtbl->GetMemoryType(amfOutput) == AMF_MEMORY_DX11);
         ID3D11Texture2D *out = packed->pVtbl->GetNative(packed);
-        picture_t *dst = PictureFromTexture(filter, &dev_sys->d3d_dev, out);
-        amfOutput->pVtbl->Release(amfOutput);
+        picture_t *dst = PictureFromTexture(filter, &dev_sys->d3d_dev, out, amfOutput);
         if (dst == NULL)
+        {
+            amfOutput->pVtbl->Release(amfOutput);
             break;
+        }
 
         picture_CopyProperties(dst, p_pic);
         if (!got_output)
@@ -192,7 +220,6 @@ static picture_t * Filter(filter_t *filter, picture_t *p_pic)
 static void D3D11CloseAMFFRC(filter_t *filter)
 {
     struct filter_sys_t *sys = filter->p_sys;
-    sys->amfInput->pVtbl->Release(sys->amfInput);
     sys->amf_frc->pVtbl->Release(sys->amf_frc);
     vlc_video_context_Release(filter->vctx_out);
 }
@@ -323,14 +350,6 @@ static int D3D11CreateAMFFRC(filter_t *filter)
     if (res != AMF_OK)
         goto error;
 
-    res = sys->amf.Context->pVtbl->AllocSurface(sys->amf.Context, AMF_MEMORY_DX11,
-                                                amf_fmt,
-                                                filter->fmt_in.video.i_width,
-                                                filter->fmt_in.video.i_height,
-                                                &sys->amfInput);
-    if (res != AMF_OK)
-        goto error;
-
     sys->cfg = cfg;
     static const struct vlc_filter_operations filter_ops =
     {
@@ -358,8 +377,6 @@ static int D3D11CreateAMFFRC(filter_t *filter)
 
     return VLC_SUCCESS;
 error:
-    if (sys->amfInput)
-        sys->amfInput->pVtbl->Release(sys->amfInput);
     if (sys->amf_frc != NULL)
         sys->amf_frc->pVtbl->Release(sys->amf_frc);
     vlc_AMFReleaseContext(&sys->amf);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fc8ad0661ccde3c428773e2fc11c6be12ba34c2f...f7537d8835691d28115a6288a5212cc9e26f2d8f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fc8ad0661ccde3c428773e2fc11c6be12ba34c2f...f7537d8835691d28115a6288a5212cc9e26f2d8f
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list