On Thu, 24 Sep 2015 09:15:22 +0200
Steve Lhomme <[email protected]> wrote:

> On Mon, Sep 21, 2015 at 3:32 PM, wm4 <[email protected]> wrote:
> > On Wed, 16 Sep 2015 13:27:42 +0200
> > Steve Lhomme <[email protected]> wrote:
> >
> >> From: Steve Lhomme <[email protected]>
> >>
> >> --
> >> now with an allocation function for the structure
> >> updated with APIchanges addition (minus an extra line)
> >> ---
> >>  doc/APIchanges       |  4 ++++
> >>  libavcodec/Makefile  |  2 +-
> >>  libavcodec/d3d11va.c | 33 +++++++++++++++++++++++++++++++++
> >>  libavcodec/d3d11va.h | 18 ++++++++++++++++--
> >>  libavcodec/dxva2.c   | 15 +++++++++++++--
> >>  libavcodec/version.h |  2 +-
> >>  6 files changed, 68 insertions(+), 6 deletions(-)
> >>  create mode 100644 libavcodec/d3d11va.c
> >>
> >> diff --git a/doc/APIchanges b/doc/APIchanges
> >> index fb9d305..42caad7 100644
> >> --- a/doc/APIchanges
> >> +++ b/doc/APIchanges
> >> @@ -13,6 +13,10 @@ libavutil:     2015-08-28
> >>
> >>  API changes, most recent first:
> >>
> >> +2015-xx-xx - xxxxxxx - lavc 57.2.0 - d3d11va.h
> >> +  Add av_d3d11va_alloc_context(). This function must from now on be used 
> >> for
> >> +  allocating AVD3D11VAContext.
> >> +
> >>  2015-xx-xx - lavu 55.0.0
> >>    xxxxxxx - Change type of AVPixFmtDescriptor.flags from uint8_t to 
> >> uint64_t.
> >>    xxxxxxx - Change type of AVComponentDescriptor fields from uint16_t to 
> >> int
> >> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> >> index 5cdef9c..f163a79 100644
> >> --- a/libavcodec/Makefile
> >> +++ b/libavcodec/Makefile
> >> @@ -581,7 +581,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER)       += adpcm.o 
> >> adpcm_data.o
> >>  OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o adpcm_data.o
> >>
> >>  # hardware accelerators
> >> -OBJS-$(CONFIG_D3D11VA)                    += dxva2.o
> >> +OBJS-$(CONFIG_D3D11VA)                    += d3d11va.o dxva2.o
> >>  OBJS-$(CONFIG_DXVA2)                      += dxva2.o
> >>  OBJS-$(CONFIG_VAAPI)                      += vaapi.o
> >>  OBJS-$(CONFIG_VDA)                        += vda.o
> >> diff --git a/libavcodec/d3d11va.c b/libavcodec/d3d11va.c
> >> new file mode 100644
> >> index 0000000..d24730a
> >> --- /dev/null
> >> +++ b/libavcodec/d3d11va.c
> >> @@ -0,0 +1,33 @@
> >> +/*
> >> + * Direct3D11 HW acceleration
> >> + *
> >> + * copyright (c) 2015 Steve Lhomme
> >> + *
> >> + * This file is part of Libav.
> >> + *
> >> + * Libav is free software; you can redistribute it and/or
> >> + * modify it under the terms of the GNU Lesser General Public
> >> + * License as published by the Free Software Foundation; either
> >> + * version 2.1 of the License, or (at your option) any later version.
> >> + *
> >> + * Libav is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> + * Lesser General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU Lesser General Public
> >> + * License along with Libav; if not, write to the Free Software
> >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
> >> 02110-1301 USA
> >> + */
> >> +
> >> +#include "config.h"
> >> +#include "libavutil/mem.h"
> >> +
> >> +#include "d3d11va.h"
> >> +
> >> +AVD3D11VAContext *av_d3d11va_alloc_context(void)
> >> +{
> >> +    AVD3D11VAContext* res = av_mallocz(sizeof(AVD3D11VAContext));
> >> +    res->context_mutex = INVALID_HANDLE_VALUE;
> >> +    return res;
> >> +}
> >> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
> >> index f5777c2..9264ec6 100644
> >> --- a/libavcodec/d3d11va.h
> >> +++ b/libavcodec/d3d11va.h
> >> @@ -53,8 +53,10 @@
> >>   * to the Direct3D11 Libav HWAccel implementation.
> >>   *
> >>   * The application must make it available as 
> >> AVCodecContext.hwaccel_context.
> >> + *
> >> + * Use av_d3d11va_alloc_context() exclusively to allocate an 
> >> AVD3D11VAContext.
> >>   */
> >> -struct AVD3D11VAContext {
> >> +typedef struct AVD3D11VAContext {
> >>      /**
> >>       * D3D11 decoder object
> >>       */
> >> @@ -89,7 +91,19 @@ struct AVD3D11VAContext {
> >>       * Private to the Libav AVHWAccel implementation
> >>       */
> >>      unsigned report_id;
> >> -};
> >> +
> >> +    /**
> >> +      * Mutex to access video_context
> >> +      */
> >> +    HANDLE  context_mutex;
> >> +} AVD3D11VAContext;
> >> +
> >> +/**
> >> + * Allocate an AVD3D11VAContext.
> >> + *
> >> + * @return Newly-allocated AVD3D11VAContext or NULL on failure.
> >> + */
> >> +AVD3D11VAContext *av_d3d11va_alloc_context(void);
> >>
> >>  /**
> >>   * @}
> >> diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
> >> index 6a7dd53..8b0e686 100644
> >> --- a/libavcodec/dxva2.c
> >> +++ b/libavcodec/dxva2.c
> >> @@ -144,10 +144,13 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> >> AVFrame *frame,
> >>
> >>      do {
> >>  #if CONFIG_D3D11VA
> >> -        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
> >> +        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> >> +            if (D3D11VA_CONTEXT(ctx)->context_mutex != 
> >> INVALID_HANDLE_VALUE)
> >> +                
> >> WaitForSingleObjectEx(D3D11VA_CONTEXT(ctx)->context_mutex, INFINITE, 
> >> FALSE);
> >>              hr = 
> >> ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, 
> >> D3D11VA_CONTEXT(ctx)->decoder,
> >>                                                        
> >> ff_dxva2_get_surface(frame),
> >>                                                        0, NULL);
> >> +        }
> >>  #endif
> >>  #if CONFIG_DXVA2
> >>          if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
> >> @@ -161,6 +164,11 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> >> AVFrame *frame,
> >>
> >>      if (FAILED(hr)) {
> >>          av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%lx\n", hr);
> >> +#if CONFIG_D3D11VA
> >> +        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
> >> +            if (D3D11VA_CONTEXT(ctx)->context_mutex != 
> >> INVALID_HANDLE_VALUE)
> >> +                ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
> >> +#endif
> >>          return -1;
> >>      }
> >>
> >> @@ -260,8 +268,11 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> >> AVFrame *frame,
> >>
> >>  end:
> >>  #if CONFIG_D3D11VA
> >> -    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
> >> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> >>          hr = 
> >> ID3D11VideoContext_DecoderEndFrame(D3D11VA_CONTEXT(ctx)->video_context, 
> >> D3D11VA_CONTEXT(ctx)->decoder);
> >> +        if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
> >> +            ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
> >> +    }
> >>  #endif
> >>  #if CONFIG_DXVA2
> >>      if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
> >> diff --git a/libavcodec/version.h b/libavcodec/version.h
> >> index 45b99ca..ecd6e1d 100644
> >> --- a/libavcodec/version.h
> >> +++ b/libavcodec/version.h
> >> @@ -29,7 +29,7 @@
> >>  #include "libavutil/version.h"
> >>
> >>  #define LIBAVCODEC_VERSION_MAJOR 57
> >> -#define LIBAVCODEC_VERSION_MINOR  1
> >> +#define LIBAVCODEC_VERSION_MINOR  2
> >>  #define LIBAVCODEC_VERSION_MICRO  0
> >>
> >>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> >
> > Maybe I missed all the discussion, but why are you not using a critical
> > section? These should be faster. (Although it might not matter at all.)
> 
> You're right, I overlooked this. Mutex may be overkill for this. I'll
> try a version with a CRITICAL_SECTION.
> 
> > I'm also wondering why it's needed at all, and why the lazy allocation
> > works (instead of being a race condition), and why the user has to
> > allocate this explicitly. Is it intended that the user can set the
> > mutex that's used?
> 
> It is needed because the ID3D11VideoContext cannot be accessed by
> multiple threads at once. It works on desktop but not on Windows Phone
> 8.1. It detects the multiple accesses and returns an error.
> 
> The allocation/init is left to the user for more flexibility. In the
> case of VLC it's allocated by the vout which needs it. And since the
> decoder and the vout don't talk directly, it's left to the vout to
> take care of it.

Makes sense. But couldn't the caller just put locking around all
libavcodec entrypoints? I do this for vaapi.

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to