applemedia: Consolidate GstVideoFormat <-> CVPixelFormat conversion

In the process we have changed the color value range from video-range
to full-range, which is probably what people want in the first place.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4135>
This commit is contained in:
Nirbheek Chauhan 2023-03-09 09:14:47 +05:30 committed by GStreamer Marge Bot
parent 6b103061ec
commit 2d6da02653
5 changed files with 23 additions and 82 deletions

View file

@ -68,6 +68,10 @@ gst_video_format_to_cvpixelformat (GstVideoFormat fmt)
return kCVPixelFormatType_422YpCbCr8_yuvs; return kCVPixelFormatType_422YpCbCr8_yuvs;
/* Alpha YUV */ /* Alpha YUV */
case GST_VIDEO_FORMAT_AYUV64: case GST_VIDEO_FORMAT_AYUV64:
/* This is fine for now because Apple only ships LE devices */
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
#error "AYUV64 is NE but kCVPixelFormatType_4444AYpCbCr16 is LE"
#endif
return kCVPixelFormatType_4444AYpCbCr16; return kCVPixelFormatType_4444AYpCbCr16;
/* RGB formats */ /* RGB formats */
case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ARGB:

View file

@ -24,6 +24,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
// kCVPixelFormatType_64RGBALE is only available for 11.3 +.
// See https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_64rgbale
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < 110300
#define kCVPixelFormatType_64RGBALE 'l64r'
#endif
#define GST_APPLEMEDIA_HAVE_64RGBALE __builtin_available(macOS 11.3, *)
#define GST_CVPIXELFORMAT_FOURCC_ARGS(fourcc) \ #define GST_CVPIXELFORMAT_FOURCC_ARGS(fourcc) \
__GST_PRINT_CHAR(((fourcc) >> 24) & 0xff), \ __GST_PRINT_CHAR(((fourcc) >> 24) & 0xff), \
__GST_PRINT_CHAR(((fourcc) >> 16) & 0xff), \ __GST_PRINT_CHAR(((fourcc) >> 16) & 0xff), \

View file

@ -57,6 +57,7 @@
#include <gst/gl/gstglcontext.h> #include <gst/gl/gstglcontext.h>
#include "vtdec.h" #include "vtdec.h"
#include "vtutil.h" #include "vtutil.h"
#include "helpers.h"
#include "corevideobuffer.h" #include "corevideobuffer.h"
#include "coremediabuffer.h" #include "coremediabuffer.h"
#include "videotexturecache-gl.h" #include "videotexturecache-gl.h"
@ -169,7 +170,7 @@ gst_vtdec_class_init (GstVtdecClass * klass)
{ {
GstCaps *caps = gst_caps_from_string (VIDEO_SRC_CAPS); GstCaps *caps = gst_caps_from_string (VIDEO_SRC_CAPS);
/* RGBA64_LE is kCVPixelFormatType_64RGBALE, only available on macOS 11.3+ */ /* RGBA64_LE is kCVPixelFormatType_64RGBALE, only available on macOS 11.3+ */
if (GST_VTUTIL_HAVE_64RGBALE) if (GST_APPLEMEDIA_HAVE_64RGBALE)
caps = gst_vtutil_caps_append_video_format (caps, "RGBA64_LE"); caps = gst_vtutil_caps_append_video_format (caps, "RGBA64_LE");
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps));
@ -299,7 +300,7 @@ get_preferred_video_format (GstStructure * s, gboolean prores)
return vfmt; return vfmt;
break; break;
case GST_VIDEO_FORMAT_RGBA64_LE: case GST_VIDEO_FORMAT_RGBA64_LE:
if (GST_VTUTIL_HAVE_64RGBALE) { if (GST_APPLEMEDIA_HAVE_64RGBALE) {
if (prores) if (prores)
return vfmt; return vfmt;
} else { } else {
@ -678,36 +679,10 @@ gst_vtdec_create_session (GstVtdec * vtdec, GstVideoFormat format,
VTDecompressionOutputCallbackRecord callback; VTDecompressionOutputCallbackRecord callback;
CFMutableDictionaryRef videoDecoderSpecification; CFMutableDictionaryRef videoDecoderSpecification;
OSStatus status; OSStatus status;
guint32 cv_format = 0; guint32 cv_format = gst_video_format_to_cvpixelformat (format);
g_return_val_if_fail (vtdec->session == NULL, FALSE); g_return_val_if_fail (vtdec->session == NULL, FALSE);
switch (format) {
case GST_VIDEO_FORMAT_NV12:
cv_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
break;
case GST_VIDEO_FORMAT_AYUV64:
/* This is fine for now because Apple only ships LE devices */
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
#error "AYUV64 is NE but kCVPixelFormatType_4444AYpCbCr16 is LE"
#endif
cv_format = kCVPixelFormatType_4444AYpCbCr16;
break;
case GST_VIDEO_FORMAT_ARGB64_BE:
cv_format = kCVPixelFormatType_64ARGB;
break;
case GST_VIDEO_FORMAT_RGBA64_LE:
if (GST_VTUTIL_HAVE_64RGBALE)
cv_format = kCVPixelFormatType_64RGBALE;
else
/* Codepath will never be hit on macOS older than Big Sur (11.3) */
g_warn_if_reached ();
break;
default:
g_warn_if_reached ();
break;
}
videoDecoderSpecification = videoDecoderSpecification =
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks, CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks); &kCFTypeDictionaryValueCallBacks);

View file

@ -69,6 +69,7 @@
#include "coremediabuffer.h" #include "coremediabuffer.h"
#include "corevideobuffer.h" #include "corevideobuffer.h"
#include "vtutil.h" #include "vtutil.h"
#include "helpers.h"
#include <gst/pbutils/codec-utils.h> #include <gst/pbutils/codec-utils.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
@ -258,7 +259,7 @@ gst_vtenc_base_init (GstVTEncClass * klass)
if (enable_argb) { if (enable_argb) {
caps = gst_vtutil_caps_append_video_format (caps, "ARGB64_BE"); caps = gst_vtutil_caps_append_video_format (caps, "ARGB64_BE");
/* RGBA64_LE is kCVPixelFormatType_64RGBALE, only available on macOS 11.3+ */ /* RGBA64_LE is kCVPixelFormatType_64RGBALE, only available on macOS 11.3+ */
if (GST_VTUTIL_HAVE_64RGBALE) if (GST_APPLEMEDIA_HAVE_64RGBALE)
caps = gst_vtutil_caps_append_video_format (caps, "RGBA64_LE"); caps = gst_vtutil_caps_append_video_format (caps, "RGBA64_LE");
} }
#endif #endif
@ -1644,25 +1645,15 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstVideoCodecFrame * frame)
if (pbuf == NULL) { if (pbuf == NULL) {
GstVideoFrame inframe, outframe; GstVideoFrame inframe, outframe;
GstBuffer *outbuf; GstBuffer *outbuf;
OSType pixel_format_type;
CVReturn cv_ret; CVReturn cv_ret;
OSType pixel_format_type =
gst_video_format_to_cvpixelformat (GST_VIDEO_INFO_FORMAT
(&self->video_info));
/* FIXME: iOS has special stride requirements that we don't know yet. /* FIXME: iOS has special stride requirements that we don't know yet.
* Copy into a newly allocated pixelbuffer for now. Probably makes * Copy into a newly allocated pixelbuffer for now. Probably makes
* sense to create a buffer pool around these at some point. * sense to create a buffer pool around these at some point.
*/ */
switch (GST_VIDEO_INFO_FORMAT (&self->video_info)) {
case GST_VIDEO_FORMAT_I420:
pixel_format_type = kCVPixelFormatType_420YpCbCr8Planar;
break;
case GST_VIDEO_FORMAT_NV12:
pixel_format_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
break;
default:
g_assert_not_reached ();
}
if (!gst_video_frame_map (&inframe, &self->video_info, frame->input_buffer, if (!gst_video_frame_map (&inframe, &self->video_info, frame->input_buffer,
GST_MAP_READ)) { GST_MAP_READ)) {
GST_ERROR_OBJECT (self, "failed to map input buffer"); GST_ERROR_OBJECT (self, "failed to map input buffer");
@ -1714,12 +1705,14 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstVideoCodecFrame * frame)
} }
{ {
OSType pixel_format_type =
gst_video_format_to_cvpixelformat (GST_VIDEO_INFO_FORMAT
(&self->video_info));
const size_t num_planes = GST_VIDEO_FRAME_N_PLANES (&vframe->videoframe); const size_t num_planes = GST_VIDEO_FRAME_N_PLANES (&vframe->videoframe);
void *plane_base_addresses[GST_VIDEO_MAX_PLANES]; void *plane_base_addresses[GST_VIDEO_MAX_PLANES];
size_t plane_widths[GST_VIDEO_MAX_PLANES]; size_t plane_widths[GST_VIDEO_MAX_PLANES];
size_t plane_heights[GST_VIDEO_MAX_PLANES]; size_t plane_heights[GST_VIDEO_MAX_PLANES];
size_t plane_bytes_per_row[GST_VIDEO_MAX_PLANES]; size_t plane_bytes_per_row[GST_VIDEO_MAX_PLANES];
OSType pixel_format_type;
size_t i; size_t i;
for (i = 0; i < num_planes; i++) { for (i = 0; i < num_planes; i++) {
@ -1733,37 +1726,6 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstVideoCodecFrame * frame)
GST_VIDEO_FRAME_COMP_STRIDE (&vframe->videoframe, i); GST_VIDEO_FRAME_COMP_STRIDE (&vframe->videoframe, i);
} }
switch (GST_VIDEO_INFO_FORMAT (&self->video_info)) {
case GST_VIDEO_FORMAT_ARGB64_BE:
pixel_format_type = kCVPixelFormatType_64ARGB;
break;
case GST_VIDEO_FORMAT_AYUV64:
/* This is fine for now because Apple only ships LE devices */
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
#error "AYUV64 is NE but kCVPixelFormatType_4444AYpCbCr16 is LE"
#endif
pixel_format_type = kCVPixelFormatType_4444AYpCbCr16;
break;
case GST_VIDEO_FORMAT_RGBA64_LE:
if (GST_VTUTIL_HAVE_64RGBALE)
pixel_format_type = kCVPixelFormatType_64RGBALE;
else
/* Codepath will never be hit on macOS older than Big Sur (11.3) */
g_assert_not_reached ();
break;
case GST_VIDEO_FORMAT_I420:
pixel_format_type = kCVPixelFormatType_420YpCbCr8Planar;
break;
case GST_VIDEO_FORMAT_NV12:
pixel_format_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
break;
case GST_VIDEO_FORMAT_UYVY:
pixel_format_type = kCVPixelFormatType_422YpCbCr8;
break;
default:
g_assert_not_reached ();
}
cv_ret = CVPixelBufferCreateWithPlanarBytes (NULL, cv_ret = CVPixelBufferCreateWithPlanarBytes (NULL,
self->negotiated_width, self->negotiated_height, self->negotiated_width, self->negotiated_height,
pixel_format_type, pixel_format_type,

View file

@ -30,13 +30,6 @@
* each variant, so we use a dummy type for details->format_id */ * each variant, so we use a dummy type for details->format_id */
#define GST_kCMVideoCodecType_Some_AppleProRes 1 #define GST_kCMVideoCodecType_Some_AppleProRes 1
// kCVPixelFormatType_64RGBALE is only available for 11.3 +.
// See https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_64rgbale
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < 110300
#define kCVPixelFormatType_64RGBALE 'l64r'
#endif
#define GST_VTUTIL_HAVE_64RGBALE __builtin_available(macOS 11.3, *)
G_BEGIN_DECLS G_BEGIN_DECLS
gchar * gst_vtutil_object_to_string (CFTypeRef obj); gchar * gst_vtutil_object_to_string (CFTypeRef obj);