Commit 2a9d461a authored by Akemi's avatar Akemi Committed by Aman Gupta

avcodec/videotoolbox: add support for full range pixel formats

Signed-off-by: 's avatarAman Gupta <aman@tmm1.net>
parent 787c56b9
...@@ -51,10 +51,12 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame) ...@@ -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) ...@@ -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 = { ...@@ -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 ...@@ -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) ...@@ -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 @@ ...@@ -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_420YpCbCr8Planar, false, AV_PIX_FMT_YUV420P },
{ kCVPixelFormatType_422YpCbCr8, AV_PIX_FMT_UYVY422 }, { kCVPixelFormatType_422YpCbCr8, false, AV_PIX_FMT_UYVY422 },
{ kCVPixelFormatType_32BGRA, AV_PIX_FMT_BGRA }, { 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) ...@@ -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); ...@@ -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 */
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