Unified · Split
| @@ -51,10 +51,12 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame) · 50 unmodified lines | ||
| 51 | 51 | case kCVPixelFormatType_422YpCbCr8: vt->tmp_frame->format = AV_PIX_FMT_UYVY422; break; |
| 52 | 52 | case kCVPixelFormatType_32BGRA: vt->tmp_frame->format = AV_PIX_FMT_BGRA; break; |
| 53 | 53 | #ifdef kCFCoreFoundationVersionNumber10_7 |
| 54 | − case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break; | |
| 54 | + case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: | |
| 55 | + case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break; | |
| 55 | 56 | #endif |
| 56 | 57 | #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE |
| 57 | − case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_P010; break; | |
| 58 | + case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: | |
| 59 | + case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_P010; break; | |
| 58 | 60 | #endif |
| 59 | 61 | default: |
| 60 | 62 | av_log(NULL, AV_LOG_ERROR, |
| @@ -1084,8 +1084,9 @@ static int videotoolbox_common_init(AVCodecContext *avctx) · 1083 unmodified lines | ||
| 1084 | 1084 | goto fail; |
| 1085 | 1085 | } |
| 1086 | 1086 | |
| 1087 | + bool full_range = avctx->color_range == AVCOL_RANGE_JPEG; | |
| 1087 | 1088 | vtctx->vt_ctx->cv_pix_fmt_type = |
| 1088 | − av_map_videotoolbox_format_from_pixfmt(hw_frames->sw_format); | |
| 1089 | + av_map_videotoolbox_format_from_pixfmt2(hw_frames->sw_format, full_range); | |
| 1089 | 1090 | if (!vtctx->vt_ctx->cv_pix_fmt_type) { |
| 1090 | 1091 | av_log(avctx, AV_LOG_ERROR, "Unknown sw_format.\n"); |
| 1091 | 1092 | err = AVERROR(EINVAL); |
| @@ -1208,14 +1209,15 @@ const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = { · 116 unmodified lines | ||
| 1208 | 1209 | .priv_data_size = sizeof(VTContext), |
| 1209 | 1210 | }; |
| 1210 | 1211 | |
| 1211 | −static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt) | |
| 1212 | +static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt, | |
| 1213 | + bool full_range) | |
| 1212 | 1214 | { |
| 1213 | 1215 | AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret)); |
| 1214 | 1216 | |
| 1215 | 1217 | if (ret) { |
| 1216 | 1218 | ret->output_callback = videotoolbox_decoder_callback; |
| 1217 | 1219 | |
| 1218 | − OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt(pix_fmt); | |
| 1220 | + OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(pix_fmt, full_range); | |
| 1219 | 1221 | if (cv_pix_fmt_type == 0) { |
| 1220 | 1222 | cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; |
| 1221 | 1223 | } |
| @@ -1227,7 +1229,7 @@ static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AV · 5 unmodified lines | ||
| 1227 | 1229 | |
| 1228 | 1230 | AVVideotoolboxContext *av_videotoolbox_alloc_context(void) |
| 1229 | 1231 | { |
| 1230 | − return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE); | |
| 1232 | + return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false); | |
| 1231 | 1233 | } |
| 1232 | 1234 | |
| 1233 | 1235 | int av_videotoolbox_default_init(AVCodecContext *avctx) |
| @@ -1237,7 +1239,9 @@ int av_videotoolbox_default_init(AVCodecContext *avctx) · 3 unmodified lines | ||
| 1237 | 1239 | |
| 1238 | 1240 | int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx) |
| 1239 | 1241 | { |
| 1240 | − avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context_with_pix_fmt(videotoolbox_best_pixel_format(avctx)); | |
| 1242 | + enum AVPixelFormat pix_fmt = videotoolbox_best_pixel_format(avctx); | |
| 1243 | + bool full_range = avctx->color_range == AVCOL_RANGE_JPEG; | |
| 1244 | + avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context_with_pix_fmt(pix_fmt, full_range); | |
| 1241 | 1245 | if (!avctx->hwaccel_context) |
| 1242 | 1246 | return AVERROR(ENOMEM); |
| 1243 | 1247 | return videotoolbox_start(avctx); |
| @@ -34,16 +34,19 @@ · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | static const struct { |
| 36 | 36 | uint32_t cv_fmt; |
| 37 | + bool full_range; | |
| 37 | 38 | enum AVPixelFormat pix_fmt; |
| 38 | 39 | } cv_pix_fmts[] = { |
| 39 | − { kCVPixelFormatType_420YpCbCr8Planar, AV_PIX_FMT_YUV420P }, | |
| 40 | − { kCVPixelFormatType_422YpCbCr8, AV_PIX_FMT_UYVY422 }, | |
| 41 | − { kCVPixelFormatType_32BGRA, AV_PIX_FMT_BGRA }, | |
| 40 | + { kCVPixelFormatType_420YpCbCr8Planar, false, AV_PIX_FMT_YUV420P }, | |
| 41 | + { kCVPixelFormatType_422YpCbCr8, false, AV_PIX_FMT_UYVY422 }, | |
| 42 | + { kCVPixelFormatType_32BGRA, false, AV_PIX_FMT_BGRA }, | |
| 42 | 43 | #ifdef kCFCoreFoundationVersionNumber10_7 |
| 43 | − { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, AV_PIX_FMT_NV12 }, | |
| 44 | + { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, false, AV_PIX_FMT_NV12 }, | |
| 45 | + { kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, true, AV_PIX_FMT_NV12 }, | |
| 44 | 46 | #endif |
| 45 | 47 | #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE |
| 46 | − { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, AV_PIX_FMT_P010 }, | |
| 48 | + { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, false, AV_PIX_FMT_P010 }, | |
| 49 | + { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange, true, AV_PIX_FMT_P010 }, | |
| 47 | 50 | #endif |
| 48 | 51 | }; |
| 49 | 52 | |
| @@ -58,10 +61,15 @@ enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt) · 8 unmodified lines | ||
| 58 | 61 | } |
| 59 | 62 | |
| 60 | 63 | uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt) |
| 64 | +{ | |
| 65 | + return av_map_videotoolbox_format_from_pixfmt2(pix_fmt, false); | |
| 66 | +} | |
| 67 | + | |
| 68 | +uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range) | |
| 61 | 69 | { |
| 62 | 70 | int i; |
| 63 | 71 | for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { |
| 64 | − if (cv_pix_fmts[i].pix_fmt == pix_fmt) | |
| 72 | + if (cv_pix_fmts[i].pix_fmt == pix_fmt && cv_pix_fmts[i].full_range == full_range) | |
| 65 | 73 | return cv_pix_fmts[i].cv_fmt; |
| 66 | 74 | } |
| 67 | 75 | return 0; |
| @@ -51,4 +51,10 @@ enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt); · 50 unmodified lines | ||
| 51 | 51 | */ |
| 52 | 52 | uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt); |
| 53 | 53 | |
| 54 | +/** | |
| 55 | + * Same as av_map_videotoolbox_format_from_pixfmt function, but can map and | |
| 56 | + * return full range pixel formats via a flag. | |
| 57 | + */ | |
| 58 | +uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range); | |
| 59 | + | |
| 54 | 60 | #endif /* AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H */ |