Skip to content

Commit 5c4f724

Browse files
Merge pull request #2 from SeaOtocinclus/export-D90536530
Better detection for supported pixel formats
2 parents 105c90d + caa4a95 commit 5c4f724

File tree

1 file changed

+47
-12
lines changed

1 file changed

+47
-12
lines changed

xprs/xprsDecoder.cpp

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ XprsResult CVideoDecoder::init(bool disableHwAcceleration) {
6969
}
7070

7171
#ifdef __APPLE__
72+
73+
// kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange and
74+
// kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange were introduced in macOS 15.0 / iOS 18.0 SDK
75+
#if (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 150000) || \
76+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 180000) || \
77+
(defined(__TV_OS_VERSION_MAX_ALLOWED) && __TV_OS_VERSION_MAX_ALLOWED >= 180000) || \
78+
(defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED >= 110000)
79+
#define XPRS_HAS_422_BIPLANAR_FORMATS 1
80+
#define XPRS_HAS_444_BIPLANAR_FORMATS 1
81+
#else
82+
#define XPRS_HAS_422_BIPLANAR_FORMATS 0
83+
#define XPRS_HAS_444_BIPLANAR_FORMATS 0
84+
#endif
85+
7286
static PixelFormat convertVideoToolboxPixelFormat(OSType videotoolboxFormat) {
7387
switch (videotoolboxFormat) {
7488
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
@@ -79,12 +93,16 @@ static PixelFormat convertVideoToolboxPixelFormat(OSType videotoolboxFormat) {
7993
case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
8094
case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange:
8195
return PixelFormat::NV1210LE;
96+
#if XPRS_HAS_422_BIPLANAR_FORMATS
8297
case kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange:
8398
case kCVPixelFormatType_422YpCbCr8BiPlanarFullRange:
8499
return PixelFormat::YUV422P;
100+
#endif
101+
#if XPRS_HAS_444_BIPLANAR_FORMATS
85102
case kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange:
86103
case kCVPixelFormatType_444YpCbCr8BiPlanarFullRange:
87104
return PixelFormat::YUV444P;
105+
#endif
88106
default:
89107
return PixelFormat::UNKNOWN;
90108
}
@@ -113,11 +131,16 @@ void CVideoDecoder::convertAVFrame(const AVFrame* avframe, Frame& frameOut) {
113131
if (pixelFormat != kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange &&
114132
pixelFormat != kCVPixelFormatType_420YpCbCr8BiPlanarFullRange &&
115133
pixelFormat != kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange &&
116-
pixelFormat != kCVPixelFormatType_420YpCbCr10BiPlanarFullRange &&
117-
pixelFormat != kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange &&
118-
pixelFormat != kCVPixelFormatType_422YpCbCr8BiPlanarFullRange &&
119-
pixelFormat != kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange &&
120-
pixelFormat != kCVPixelFormatType_444YpCbCr8BiPlanarFullRange) {
134+
pixelFormat != kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
135+
#if XPRS_HAS_422_BIPLANAR_FORMATS
136+
&& pixelFormat != kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange &&
137+
pixelFormat != kCVPixelFormatType_422YpCbCr8BiPlanarFullRange
138+
#endif
139+
#if XPRS_HAS_444_BIPLANAR_FORMATS
140+
&& pixelFormat != kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange &&
141+
pixelFormat != kCVPixelFormatType_444YpCbCr8BiPlanarFullRange
142+
#endif
143+
) {
121144
return;
122145
}
123146

@@ -135,17 +158,24 @@ void CVideoDecoder::convertAVFrame(const AVFrame* avframe, Frame& frameOut) {
135158
// Default to 420 format
136159
size_t uvHeight = height / 2;
137160
size_t frameSize = width * height * 3 / 2;
161+
#if XPRS_HAS_422_BIPLANAR_FORMATS
138162
if (pixelFormat == kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange ||
139163
pixelFormat == kCVPixelFormatType_422YpCbCr8BiPlanarFullRange) {
140164
// 422 doubles vertical chroma samples compared to 420
141165
frameSize = width * height * 2;
142166
uvHeight = height;
143-
} else if (
144-
pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange ||
145-
pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarFullRange) {
167+
} else
168+
#endif
169+
#if XPRS_HAS_444_BIPLANAR_FORMATS
170+
if (pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange ||
171+
pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarFullRange) {
146172
// 444 doubles both vertical and horizontal chroma samples compared to 420
147173
frameSize = width * height * 3;
148174
uvHeight = height;
175+
} else
176+
#endif
177+
{
178+
// 420 format - use default values above
149179
}
150180
frameSize *= bytes;
151181
if (_buffer.size() < frameSize) {
@@ -160,6 +190,7 @@ void CVideoDecoder::convertAVFrame(const AVFrame* avframe, Frame& frameOut) {
160190
}
161191

162192
// Convert biplanar 422 and 444 to triplanar
193+
#if XPRS_HAS_422_BIPLANAR_FORMATS
163194
if (pixelFormat == kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange ||
164195
pixelFormat == kCVPixelFormatType_422YpCbCr8BiPlanarFullRange) {
165196
uint8_t* uvPlane = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
@@ -179,9 +210,11 @@ void CVideoDecoder::convertAVFrame(const AVFrame* avframe, Frame& frameOut) {
179210
frameOut.planes[2] = vPlane;
180211
frameOut.stride[2] = width / 2;
181212

182-
} else if (
183-
pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange ||
184-
pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarFullRange) {
213+
} else
214+
#endif
215+
#if XPRS_HAS_444_BIPLANAR_FORMATS
216+
if (pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange ||
217+
pixelFormat == kCVPixelFormatType_444YpCbCr8BiPlanarFullRange) {
185218
uint8_t* uvPlane = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
186219
uint8_t* uPlane = _buffer.data() + width * height;
187220
uint8_t* vPlane = uPlane + (width * height);
@@ -197,7 +230,9 @@ void CVideoDecoder::convertAVFrame(const AVFrame* avframe, Frame& frameOut) {
197230
frameOut.stride[1] = width;
198231
frameOut.planes[2] = vPlane;
199232
frameOut.stride[2] = width;
200-
} else {
233+
} else
234+
#endif
235+
{
201236
// Copy the UV plane for NV12
202237
uint8_t* uvPlane = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
203238
for (size_t y = 0; y < uvHeight; y++) {

0 commit comments

Comments
 (0)