Re: [FFmpeg-devel] [PATCH 6/7] avcodec: allow multiple hwaccels for the same codec/pixfmt

2017-10-03 Thread wm4
On Tue, 3 Oct 2017 15:58:32 +0200
Timo Rothenpieler  wrote:

> > -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;

Also this is actually completely broken. It's trivially fixed, but if
anyone actually wants to try the patches, here's an updated set:

https://github.com/wm4/FFmpeg/tree/libav-cuvid
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 6/7] avcodec: allow multiple hwaccels for the same codec/pixfmt

2017-10-03 Thread Philip Langdale
On Tue,  3 Oct 2017 15:15:17 +0200
wm4  wrote:

> 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
> + */
> +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  = ##_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

Looks fine. Nothing beyond what Timo said.


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


Re: [FFmpeg-devel] [PATCH 6/7] avcodec: allow multiple hwaccels for the same codec/pixfmt

2017-10-03 Thread wm4
On Tue, 3 Oct 2017 15:58:32 +0200
Timo Rothenpieler  wrote:

> 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?

Fixed locally with:

/**
 * Some hwaccels are ambiguous if only the id and pix_fmt fields are used.
 * If non-NULL, the associated AVCodec must have
 * FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS set.
 */
const AVClass *decoder_class;

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


Re: [FFmpeg-devel] [PATCH 6/7] avcodec: allow multiple hwaccels for the same codec/pixfmt

2017-10-03 Thread Timo Rothenpieler

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  = ##_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





smime.p7s
Description: S/MIME Cryptographic Signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 6/7] avcodec: allow multiple hwaccels for the same codec/pixfmt

2017-10-03 Thread 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
+ */
+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  = ##_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
-- 
2.14.1

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