[FFmpeg-devel,v2,1/2] avcodec/videotoolbox: add support for 10bit pixel format

Submitted by der richter on April 13, 2019, 10:19 a.m.

Details

Message ID 20190413101959.43275-1-der.richter@gmx.de
State New
Headers show

Commit Message

der richter April 13, 2019, 10:19 a.m.
From: fumoboy007 <fumoboy007@me.com>

this patch was originally posted on issue #7704 and was slightly
adjusted to check for the availability of the pixel format.
---
 configure                          |  2 ++
 fftools/ffmpeg_videotoolbox.c      |  3 +++
 libavcodec/videotoolbox.c          | 32 +++++++++++++++++++++++++-----
 libavutil/hwcontext_videotoolbox.c |  3 +++
 4 files changed, 35 insertions(+), 5 deletions(-)

--
2.21.0

Comments

Aman Gupta April 13, 2019, 1:30 p.m.
On Sat, Apr 13, 2019 at 3:25 AM der richter <der.richter@gmx.de> wrote:

> From: fumoboy007 <fumoboy007@me.com>
>
> this patch was originally posted on issue #7704 and was slightly
> adjusted to check for the availability of the pixel format.
> ---
>  configure                          |  2 ++
>  fftools/ffmpeg_videotoolbox.c      |  3 +++
>  libavcodec/videotoolbox.c          | 32 +++++++++++++++++++++++++-----
>  libavutil/hwcontext_videotoolbox.c |  3 +++
>  4 files changed, 35 insertions(+), 5 deletions(-)
>
> diff --git a/configure b/configure
> index 331393f8d5..a89da70aab 100755
> --- a/configure
> +++ b/configure
> @@ -2253,6 +2253,7 @@ TOOLCHAIN_FEATURES="
>
>  TYPES_LIST="
>      kCMVideoCodecType_HEVC
> +    kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
>      socklen_t
>      struct_addrinfo
>      struct_group_source_req
> @@ -6012,6 +6013,7 @@ enabled avfoundation && {
>  enabled videotoolbox && {
>      check_lib coreservices CoreServices/CoreServices.h
> UTGetOSTypeFromString "-framework CoreServices"
>      check_func_headers CoreMedia/CMFormatDescription.h
> kCMVideoCodecType_HEVC "-framework CoreMedia"
> +    check_func_headers CoreVideo/CVPixelBuffer.h
> kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
>  }
>
>  check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
> diff --git a/fftools/ffmpeg_videotoolbox.c b/fftools/ffmpeg_videotoolbox.c
> index b820aec017..ad6174d3c7 100644
> --- a/fftools/ffmpeg_videotoolbox.c
> +++ b/fftools/ffmpeg_videotoolbox.c
> @@ -52,6 +52,9 @@ static int videotoolbox_retrieve_data(AVCodecContext *s,
> AVFrame *frame)
>      case kCVPixelFormatType_32BGRA:           vt->tmp_frame->format =
> AV_PIX_FMT_BGRA; break;
>  #ifdef kCFCoreFoundationVersionNumber10_7
>      case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
> vt->tmp_frame->format = AV_PIX_FMT_NV12; break;
> +#endif
> +#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
> +    case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
> vt->tmp_frame->format = AV_PIX_FMT_P010; break;
>  #endif
>      default:
>          av_log(NULL, AV_LOG_ERROR,
> diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
> index fb3501f413..021afd411b 100644
> --- a/libavcodec/videotoolbox.c
> +++ b/libavcodec/videotoolbox.c
> @@ -26,6 +26,7 @@
>  #include "vt_internal.h"
>  #include "libavutil/avutil.h"
>  #include "libavutil/hwcontext.h"
> +#include "libavutil/pixdesc.h"
>  #include "bytestream.h"
>  #include "decode.h"
>  #include "h264dec.h"
> @@ -1020,6 +1021,17 @@ static int videotoolbox_uninit(AVCodecContext
> *avctx)
>      return 0;
>  }
>
> +static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext
> *avctx) {
> +    const AVPixFmtDescriptor *descriptor =
> av_pix_fmt_desc_get(avctx->pix_fmt);
> +    if (!descriptor)
> +        return AV_PIX_FMT_NV12; // same as av_videotoolbox_alloc_context()
> +
> +    int depth = descriptor->comp[0].depth;
> +    if (depth > 8) {
> +        return AV_PIX_FMT_P010;
> +    }


Need a final fall-through return before the end of the function.


> +}
> +
>  static int videotoolbox_common_init(AVCodecContext *avctx)
>  {
>      VTContext *vtctx = avctx->internal->hwaccel_priv_data;
> @@ -1053,7 +1065,7 @@ static int videotoolbox_common_init(AVCodecContext
> *avctx)
>
>          hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
>          hw_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
> -        hw_frames->sw_format = AV_PIX_FMT_NV12; // same as
> av_videotoolbox_alloc_context()
> +        hw_frames->sw_format = videotoolbox_best_pixel_format(avctx);
>          hw_frames->width = avctx->width;
>          hw_frames->height = avctx->height;
>
> @@ -1097,7 +1109,7 @@ static int videotoolbox_frame_params(AVCodecContext
> *avctx,
>      frames_ctx->format            = AV_PIX_FMT_VIDEOTOOLBOX;
>      frames_ctx->width             = avctx->coded_width;
>      frames_ctx->height            = avctx->coded_height;
> -    frames_ctx->sw_format         = AV_PIX_FMT_NV12;
> +    frames_ctx->sw_format         = videotoolbox_best_pixel_format(avctx);
>
>      return 0;
>  }
> @@ -1194,18 +1206,28 @@ const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
>      .priv_data_size = sizeof(VTContext),
>  };
>
> -AVVideotoolboxContext *av_videotoolbox_alloc_context(void)
> +static AVVideotoolboxContext
> *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt)
>  {
>      AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));
>
>      if (ret) {
>          ret->output_callback = videotoolbox_decoder_callback;
> -        ret->cv_pix_fmt_type =
> kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
> +
> +        OSType cv_pix_fmt_type =
> av_map_videotoolbox_format_from_pixfmt(pix_fmt);
> +        if (cv_pix_fmt_type == 0) {
> +            cv_pix_fmt_type =
> kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
> +        }
> +        ret->cv_pix_fmt_type = cv_pix_fmt_type;
>      }
>
>      return ret;
>  }
>
> +AVVideotoolboxContext *av_videotoolbox_alloc_context(void)
> +{
> +    return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE);
> +}
> +
>  int av_videotoolbox_default_init(AVCodecContext *avctx)
>  {
>      return av_videotoolbox_default_init2(avctx, NULL);
> @@ -1213,7 +1235,7 @@ int av_videotoolbox_default_init(AVCodecContext
> *avctx)
>
>  int av_videotoolbox_default_init2(AVCodecContext *avctx,
> AVVideotoolboxContext *vtctx)
>  {
> -    avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context();
> +    avctx->hwaccel_context = vtctx ?:
> av_videotoolbox_alloc_context_with_pix_fmt(videotoolbox_best_pixel_format(avctx));
>      if (!avctx->hwaccel_context)
>          return AVERROR(ENOMEM);
>      return videotoolbox_start(avctx);
> diff --git a/libavutil/hwcontext_videotoolbox.c
> b/libavutil/hwcontext_videotoolbox.c
> index cc00f1f2f2..6eac2c0774 100644
> --- a/libavutil/hwcontext_videotoolbox.c
> +++ b/libavutil/hwcontext_videotoolbox.c
> @@ -42,6 +42,9 @@ static const struct {
>  #ifdef kCFCoreFoundationVersionNumber10_7
>      { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,  AV_PIX_FMT_NV12 },
>  #endif
> +#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
> +    { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, AV_PIX_FMT_P010 },
> +#endif
>  };
>
>  enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt)
> --
> 2.21.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

Patch hide | download patch | download mbox

diff --git a/configure b/configure
index 331393f8d5..a89da70aab 100755
--- a/configure
+++ b/configure
@@ -2253,6 +2253,7 @@  TOOLCHAIN_FEATURES="

 TYPES_LIST="
     kCMVideoCodecType_HEVC
+    kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
     socklen_t
     struct_addrinfo
     struct_group_source_req
@@ -6012,6 +6013,7 @@  enabled avfoundation && {
 enabled videotoolbox && {
     check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices"
     check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia"
+    check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
 }

 check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
diff --git a/fftools/ffmpeg_videotoolbox.c b/fftools/ffmpeg_videotoolbox.c
index b820aec017..ad6174d3c7 100644
--- a/fftools/ffmpeg_videotoolbox.c
+++ b/fftools/ffmpeg_videotoolbox.c
@@ -52,6 +52,9 @@  static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame)
     case kCVPixelFormatType_32BGRA:           vt->tmp_frame->format = AV_PIX_FMT_BGRA; break;
 #ifdef kCFCoreFoundationVersionNumber10_7
     case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break;
+#endif
+#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
+    case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_P010; break;
 #endif
     default:
         av_log(NULL, AV_LOG_ERROR,
diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
index fb3501f413..021afd411b 100644
--- a/libavcodec/videotoolbox.c
+++ b/libavcodec/videotoolbox.c
@@ -26,6 +26,7 @@ 
 #include "vt_internal.h"
 #include "libavutil/avutil.h"
 #include "libavutil/hwcontext.h"
+#include "libavutil/pixdesc.h"
 #include "bytestream.h"
 #include "decode.h"
 #include "h264dec.h"
@@ -1020,6 +1021,17 @@  static int videotoolbox_uninit(AVCodecContext *avctx)
     return 0;
 }

+static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext *avctx) {
+    const AVPixFmtDescriptor *descriptor = av_pix_fmt_desc_get(avctx->pix_fmt);
+    if (!descriptor)
+        return AV_PIX_FMT_NV12; // same as av_videotoolbox_alloc_context()
+
+    int depth = descriptor->comp[0].depth;
+    if (depth > 8) {
+        return AV_PIX_FMT_P010;
+    }
+}
+
 static int videotoolbox_common_init(AVCodecContext *avctx)
 {
     VTContext *vtctx = avctx->internal->hwaccel_priv_data;
@@ -1053,7 +1065,7 @@  static int videotoolbox_common_init(AVCodecContext *avctx)

         hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
         hw_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
-        hw_frames->sw_format = AV_PIX_FMT_NV12; // same as av_videotoolbox_alloc_context()
+        hw_frames->sw_format = videotoolbox_best_pixel_format(avctx);
         hw_frames->width = avctx->width;
         hw_frames->height = avctx->height;

@@ -1097,7 +1109,7 @@  static int videotoolbox_frame_params(AVCodecContext *avctx,
     frames_ctx->format            = AV_PIX_FMT_VIDEOTOOLBOX;
     frames_ctx->width             = avctx->coded_width;
     frames_ctx->height            = avctx->coded_height;
-    frames_ctx->sw_format         = AV_PIX_FMT_NV12;
+    frames_ctx->sw_format         = videotoolbox_best_pixel_format(avctx);

     return 0;
 }
@@ -1194,18 +1206,28 @@  const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
     .priv_data_size = sizeof(VTContext),
 };

-AVVideotoolboxContext *av_videotoolbox_alloc_context(void)
+static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt)
 {
     AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));

     if (ret) {
         ret->output_callback = videotoolbox_decoder_callback;
-        ret->cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
+
+        OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt(pix_fmt);
+        if (cv_pix_fmt_type == 0) {
+            cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
+        }
+        ret->cv_pix_fmt_type = cv_pix_fmt_type;
     }

     return ret;
 }

+AVVideotoolboxContext *av_videotoolbox_alloc_context(void)
+{
+    return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE);
+}
+
 int av_videotoolbox_default_init(AVCodecContext *avctx)
 {
     return av_videotoolbox_default_init2(avctx, NULL);
@@ -1213,7 +1235,7 @@  int av_videotoolbox_default_init(AVCodecContext *avctx)

 int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx)
 {
-    avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context();
+    avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context_with_pix_fmt(videotoolbox_best_pixel_format(avctx));
     if (!avctx->hwaccel_context)
         return AVERROR(ENOMEM);
     return videotoolbox_start(avctx);
diff --git a/libavutil/hwcontext_videotoolbox.c b/libavutil/hwcontext_videotoolbox.c
index cc00f1f2f2..6eac2c0774 100644
--- a/libavutil/hwcontext_videotoolbox.c
+++ b/libavutil/hwcontext_videotoolbox.c
@@ -42,6 +42,9 @@  static const struct {
 #ifdef kCFCoreFoundationVersionNumber10_7
     { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,  AV_PIX_FMT_NV12 },
 #endif
+#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
+    { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, AV_PIX_FMT_P010 },
+#endif
 };

 enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt)