Signed-off-by: Aman Gupta <aman@tmm1.net>tags/n4.3
| @@ -51,10 +51,12 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame) | |||||
| case kCVPixelFormatType_422YpCbCr8: vt->tmp_frame->format = AV_PIX_FMT_UYVY422; break; | case kCVPixelFormatType_422YpCbCr8: vt->tmp_frame->format = AV_PIX_FMT_UYVY422; break; | ||||
| 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: | |||||
| case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break; | |||||
| #endif | #endif | ||||
| #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE | #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE | ||||
| case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_P010; break; | |||||
| case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: | |||||
| case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange: 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, | ||||
| @@ -1084,8 +1084,9 @@ static int videotoolbox_common_init(AVCodecContext *avctx) | |||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| bool full_range = avctx->color_range == AVCOL_RANGE_JPEG; | |||||
| vtctx->vt_ctx->cv_pix_fmt_type = | vtctx->vt_ctx->cv_pix_fmt_type = | ||||
| av_map_videotoolbox_format_from_pixfmt(hw_frames->sw_format); | |||||
| av_map_videotoolbox_format_from_pixfmt2(hw_frames->sw_format, full_range); | |||||
| if (!vtctx->vt_ctx->cv_pix_fmt_type) { | if (!vtctx->vt_ctx->cv_pix_fmt_type) { | ||||
| av_log(avctx, AV_LOG_ERROR, "Unknown sw_format.\n"); | av_log(avctx, AV_LOG_ERROR, "Unknown sw_format.\n"); | ||||
| err = AVERROR(EINVAL); | err = AVERROR(EINVAL); | ||||
| @@ -1208,14 +1209,15 @@ const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = { | |||||
| .priv_data_size = sizeof(VTContext), | .priv_data_size = sizeof(VTContext), | ||||
| }; | }; | ||||
| static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt) | |||||
| static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt, | |||||
| bool full_range) | |||||
| { | { | ||||
| 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; | ||||
| OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt(pix_fmt); | |||||
| OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(pix_fmt, full_range); | |||||
| if (cv_pix_fmt_type == 0) { | if (cv_pix_fmt_type == 0) { | ||||
| cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; | cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; | ||||
| } | } | ||||
| @@ -1227,7 +1229,7 @@ static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AV | |||||
| AVVideotoolboxContext *av_videotoolbox_alloc_context(void) | AVVideotoolboxContext *av_videotoolbox_alloc_context(void) | ||||
| { | { | ||||
| return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE); | |||||
| return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false); | |||||
| } | } | ||||
| int av_videotoolbox_default_init(AVCodecContext *avctx) | int av_videotoolbox_default_init(AVCodecContext *avctx) | ||||
| @@ -1237,7 +1239,9 @@ 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_with_pix_fmt(videotoolbox_best_pixel_format(avctx)); | |||||
| enum AVPixelFormat pix_fmt = videotoolbox_best_pixel_format(avctx); | |||||
| bool full_range = avctx->color_range == AVCOL_RANGE_JPEG; | |||||
| avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context_with_pix_fmt(pix_fmt, full_range); | |||||
| if (!avctx->hwaccel_context) | if (!avctx->hwaccel_context) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| return videotoolbox_start(avctx); | return videotoolbox_start(avctx); | ||||
| @@ -34,16 +34,19 @@ | |||||
| static const struct { | static const struct { | ||||
| uint32_t cv_fmt; | uint32_t cv_fmt; | ||||
| bool full_range; | |||||
| enum AVPixelFormat pix_fmt; | enum AVPixelFormat pix_fmt; | ||||
| } cv_pix_fmts[] = { | } cv_pix_fmts[] = { | ||||
| { kCVPixelFormatType_420YpCbCr8Planar, AV_PIX_FMT_YUV420P }, | |||||
| { kCVPixelFormatType_422YpCbCr8, AV_PIX_FMT_UYVY422 }, | |||||
| { kCVPixelFormatType_32BGRA, AV_PIX_FMT_BGRA }, | |||||
| { kCVPixelFormatType_420YpCbCr8Planar, false, AV_PIX_FMT_YUV420P }, | |||||
| { kCVPixelFormatType_422YpCbCr8, false, AV_PIX_FMT_UYVY422 }, | |||||
| { kCVPixelFormatType_32BGRA, false, AV_PIX_FMT_BGRA }, | |||||
| #ifdef kCFCoreFoundationVersionNumber10_7 | #ifdef kCFCoreFoundationVersionNumber10_7 | ||||
| { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, AV_PIX_FMT_NV12 }, | |||||
| { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, false, AV_PIX_FMT_NV12 }, | |||||
| { kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, true, AV_PIX_FMT_NV12 }, | |||||
| #endif | #endif | ||||
| #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE | #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE | ||||
| { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, AV_PIX_FMT_P010 }, | |||||
| { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, false, AV_PIX_FMT_P010 }, | |||||
| { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange, true, AV_PIX_FMT_P010 }, | |||||
| #endif | #endif | ||||
| }; | }; | ||||
| @@ -58,10 +61,15 @@ enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt) | |||||
| } | } | ||||
| uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt) | uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt) | ||||
| { | |||||
| return av_map_videotoolbox_format_from_pixfmt2(pix_fmt, false); | |||||
| } | |||||
| uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range) | |||||
| { | { | ||||
| int i; | int i; | ||||
| for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { | for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { | ||||
| if (cv_pix_fmts[i].pix_fmt == pix_fmt) | |||||
| if (cv_pix_fmts[i].pix_fmt == pix_fmt && cv_pix_fmts[i].full_range == full_range) | |||||
| return cv_pix_fmts[i].cv_fmt; | return cv_pix_fmts[i].cv_fmt; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -51,4 +51,10 @@ enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt); | |||||
| */ | */ | ||||
| uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt); | uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt); | ||||
| /** | |||||
| * Same as av_map_videotoolbox_format_from_pixfmt function, but can map and | |||||
| * return full range pixel formats via a flag. | |||||
| */ | |||||
| uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range); | |||||
| #endif /* AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H */ | #endif /* AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H */ | ||||