Am 03.10.2017 um 15:15 schrieb wm4:
Currently, AVHWAccels are looked up using a (codec_id, pixfmt) tuple.
This means it's impossible to have 2 decoders for the same codec and
using the same opaque hardware pixel format.

This breaks merging Libav's CUVID hwaccel. FFmpeg has its own CUVID
support, but it's a full stream decoder, using NVIDIA's codec parser.
The Libav one is a true hwaccel, which is based on the builtin software
decoders.

Fix this by introducing another field to disambiguate AVHWAccels, and
use it for our CUVID decoders. FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS makes
this mechanism backwards compatible and optional.
---
  libavcodec/Makefile   |  1 +
  libavcodec/avcodec.h  |  5 +++++
  libavcodec/cuviddec.c |  2 ++
  libavcodec/decode.c   | 12 ++++++++----
  libavcodec/internal.h |  5 +++++
  5 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index fa3ab8f08a..3e0d654541 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -820,6 +820,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_CUVID)                      += cuvid.o
  OBJS-$(CONFIG_D3D11VA)                    += dxva2.o
  OBJS-$(CONFIG_DXVA2)                      += dxva2.o
  OBJS-$(CONFIG_VAAPI)                      += vaapi_decode.o
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 52cc5b0ca0..ecc49e5643 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -4000,6 +4000,11 @@ typedef struct AVHWAccel {
       * Internal hwaccel capabilities.
       */
      int caps_internal;
+
+    /**
+     * Some hwaccels are ambiguous if only

This seems to be truncated?

+     */
+    const AVClass *decoder_class;
  } AVHWAccel;
/**
diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index 2ba8e00c6a..6370348639 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -1106,6 +1106,7 @@ static const AVOption options[] = {
          .type           = AVMEDIA_TYPE_VIDEO, \
          .id             = AV_CODEC_ID_##X, \
          .pix_fmt        = AV_PIX_FMT_CUDA, \
+        .decoder_class  = &x##_cuvid_class, \
      }; \
      AVCodec ff_##x##_cuvid_decoder = { \
          .name           = #x "_cuvid", \
@@ -1120,6 +1121,7 @@ static const AVOption options[] = {
          .receive_frame  = cuvid_output_frame, \
          .flush          = cuvid_flush, \
          .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
+        .caps_internal  = FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS, \
          .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
                                                          AV_PIX_FMT_NV12, \
                                                          AV_PIX_FMT_P010, \
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 668ef9667f..7060f6a3b7 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1152,15 +1152,19 @@ enum AVPixelFormat avcodec_default_get_format(struct 
AVCodecContext *s, const en
      return fmt[0];
  }
-static AVHWAccel *find_hwaccel(enum AVCodecID codec_id,
+static AVHWAccel *find_hwaccel(AVCodecContext *avctx,
                                 enum AVPixelFormat pix_fmt)
  {
      AVHWAccel *hwaccel = NULL;
+    const AVClass *av_class =
+        (avctx->codec->caps_internal & FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS)
+        ? avctx->av_class : NULL;
- while ((hwaccel = av_hwaccel_next(hwaccel)))
-        if (hwaccel->id == codec_id
+    while ((hwaccel = av_hwaccel_next(hwaccel))) {
+        if (hwaccel->decoder_class == av_class && hwaccel->id == 
avctx->codec_id
              && hwaccel->pix_fmt == pix_fmt)
              return hwaccel;
+    }
      return NULL;
  }
@@ -1168,7 +1172,7 @@ static int setup_hwaccel(AVCodecContext *avctx,
                           const enum AVPixelFormat fmt,
                           const char *name)
  {
-    AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt);
+    AVHWAccel *hwa = find_hwaccel(avctx, fmt);
      int ret        = 0;
if (!hwa) {
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index faa923c11f..0177ea6521 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -69,6 +69,11 @@
   */
  #define FF_CODEC_CAP_SLICE_THREAD_HAS_MF    (1 << 5)
+/**
+ * Allow only AVHWAccels which have a matching decoder_class field.
+ */
+#define FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS  (1 << 6)
+
  #ifdef TRACE
  #   define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__)
  #else


Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to