Message ID | 20190413101959.43275-1-der.richter@gmx.de |
---|---|
State | Superseded |
Headers | show |
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".
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)
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