mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
avcodec/videotoolbox: add support for full range pixel formats
Signed-off-by: Aman Gupta <aman@tmm1.net>
This commit is contained in:
parent
787c56b9e9
commit
2a9d461abc
@ -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_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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user