Commit 036b4b0f authored by fumoboy007's avatar fumoboy007 Committed by Jan Ekström

avcodec/videotoolbox: add support for 10bit pixel format

this patch was originally posted on issue #7704 and was slightly
adjusted to check for the availability of the pixel format.
parent c3aa4844
...@@ -2253,6 +2253,7 @@ TOOLCHAIN_FEATURES=" ...@@ -2253,6 +2253,7 @@ TOOLCHAIN_FEATURES="
TYPES_LIST=" TYPES_LIST="
kCMVideoCodecType_HEVC kCMVideoCodecType_HEVC
kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
socklen_t socklen_t
struct_addrinfo struct_addrinfo
struct_group_source_req struct_group_source_req
...@@ -6014,6 +6015,7 @@ enabled avfoundation && { ...@@ -6014,6 +6015,7 @@ enabled avfoundation && {
enabled videotoolbox && { enabled videotoolbox && {
check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices" check_lib coreservices CoreServices/CoreServices.h UTGetOSTypeFromString "-framework CoreServices"
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia" 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 check_struct "sys/time.h sys/resource.h" "struct rusage" ru_maxrss
......
...@@ -52,6 +52,9 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame) ...@@ -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; case kCVPixelFormatType_32BGRA: vt->tmp_frame->format = AV_PIX_FMT_BGRA; break;
#ifdef kCFCoreFoundationVersionNumber10_7 #ifdef kCFCoreFoundationVersionNumber10_7
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break; 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 #endif
default: default:
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "vt_internal.h" #include "vt_internal.h"
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#include "libavutil/hwcontext.h" #include "libavutil/hwcontext.h"
#include "libavutil/pixdesc.h"
#include "bytestream.h" #include "bytestream.h"
#include "decode.h" #include "decode.h"
#include "h264dec.h" #include "h264dec.h"
...@@ -1020,6 +1021,19 @@ static int videotoolbox_uninit(AVCodecContext *avctx) ...@@ -1020,6 +1021,19 @@ static int videotoolbox_uninit(AVCodecContext *avctx)
return 0; 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;
}
return AV_PIX_FMT_NV12;
}
static int videotoolbox_common_init(AVCodecContext *avctx) static int videotoolbox_common_init(AVCodecContext *avctx)
{ {
VTContext *vtctx = avctx->internal->hwaccel_priv_data; VTContext *vtctx = avctx->internal->hwaccel_priv_data;
...@@ -1053,7 +1067,7 @@ static int videotoolbox_common_init(AVCodecContext *avctx) ...@@ -1053,7 +1067,7 @@ static int videotoolbox_common_init(AVCodecContext *avctx)
hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data; hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
hw_frames->format = AV_PIX_FMT_VIDEOTOOLBOX; 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->width = avctx->width;
hw_frames->height = avctx->height; hw_frames->height = avctx->height;
...@@ -1097,7 +1111,7 @@ static int videotoolbox_frame_params(AVCodecContext *avctx, ...@@ -1097,7 +1111,7 @@ static int videotoolbox_frame_params(AVCodecContext *avctx,
frames_ctx->format = AV_PIX_FMT_VIDEOTOOLBOX; frames_ctx->format = AV_PIX_FMT_VIDEOTOOLBOX;
frames_ctx->width = avctx->coded_width; frames_ctx->width = avctx->coded_width;
frames_ctx->height = avctx->coded_height; 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; return 0;
} }
...@@ -1194,18 +1208,28 @@ const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = { ...@@ -1194,18 +1208,28 @@ const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
.priv_data_size = sizeof(VTContext), .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)); AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));
if (ret) { if (ret) {
ret->output_callback = videotoolbox_decoder_callback; 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; 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) int av_videotoolbox_default_init(AVCodecContext *avctx)
{ {
return av_videotoolbox_default_init2(avctx, NULL); return av_videotoolbox_default_init2(avctx, NULL);
...@@ -1213,7 +1237,7 @@ int av_videotoolbox_default_init(AVCodecContext *avctx) ...@@ -1213,7 +1237,7 @@ int av_videotoolbox_default_init(AVCodecContext *avctx)
int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx) 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) if (!avctx->hwaccel_context)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
return videotoolbox_start(avctx); return videotoolbox_start(avctx);
......
...@@ -42,6 +42,9 @@ static const struct { ...@@ -42,6 +42,9 @@ static const struct {
#ifdef kCFCoreFoundationVersionNumber10_7 #ifdef kCFCoreFoundationVersionNumber10_7
{ kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, AV_PIX_FMT_NV12 }, { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, AV_PIX_FMT_NV12 },
#endif #endif
#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
{ kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, AV_PIX_FMT_P010 },
#endif
}; };
enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt) enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment