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.

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

Reply via email to