Commit 028342bc authored by Nirbheek Chauhan's avatar Nirbheek Chauhan 🐜
Browse files

FIXME: vtdec: Support outputting ARGB64 hackily

kCVPixelFormatType_64ARGB is actually BE, but GST_VIDEO_FORMAT_ARGB64
is LE, so we need to byte-swap each component manually. This is very
hacky, and the correct solution is to add GST_VIDEO_FORMAT_ARGB64_BE
and add converters for it in videoconvert.

Likely due to this byte-swapping, we black frames when outputting to
glimagesink, so disable gl features when outputting ARGB64.

This is the same thing that is done in the old ProRes decoder element,
so it should be fine for now.
parent 5925ba39
Pipeline #477181 canceled with stages
in 1 minute and 11 seconds
......@@ -115,7 +115,7 @@ const CFStringRef
CFSTR ("RequireHardwareAcceleratedVideoDecoder");
#endif
#define VIDEO_SRC_CAPS_FORMATS "{ NV12, AYUV64 }"
#define VIDEO_SRC_CAPS_FORMATS "{ NV12, AYUV64, ARGB64 }"
#define VIDEO_SRC_CAPS_NATIVE \
GST_VIDEO_CAPS_MAKE(VIDEO_SRC_CAPS_FORMATS) ";" \
......@@ -270,7 +270,7 @@ alpha_and_high_bit_depth_video_format (GstStructure * s)
for (i = 0; i < size; i++) {
const GValue *value = gst_value_list_get_value (list, i);
const char *fmt = g_value_get_string (value);
if (g_strcmp0 (fmt, "AYUV64") == 0)
if (g_strcmp0 (fmt, "AYUV64") == 0 || g_strcmp0 (fmt, "ARGB64") == 0)
return gst_video_format_from_string (fmt);
}
return GST_VIDEO_FORMAT_UNKNOWN;
......@@ -340,9 +340,14 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder)
format = GST_VIDEO_FORMAT_NV12;
}
features = gst_caps_get_features (caps, 0);
if (features)
features = gst_caps_features_copy (features);
if (format == GST_VIDEO_FORMAT_ARGB64) {
/* FIXME: We get black frames with this, needs figuring out */
GST_FIXME_OBJECT (vtdec, "Disabling GLMemory / Vulkan with ARGB64");
} else {
features = gst_caps_get_features (caps, 0);
if (features)
features = gst_caps_features_copy (features);
}
output_state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (vtdec),
format, vtdec->video_info.width, vtdec->video_info.height,
......@@ -641,6 +646,9 @@ gst_vtdec_create_session (GstVtdec * vtdec, GstVideoFormat format,
case GST_VIDEO_FORMAT_NV12:
cv_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
break;
case GST_VIDEO_FORMAT_ARGB64:
cv_format = kCVPixelFormatType_64ARGB;
break;
case GST_VIDEO_FORMAT_AYUV64:
cv_format = kCVPixelFormatType_4444AYpCbCr16;
break;
......@@ -925,6 +933,47 @@ gst_vtdec_session_output_callback (void *decompression_output_ref_con,
GST_WARNING_OBJECT (vtdec, "Output state not configured, release buffer");
frame->flags &= VTDEC_FRAME_FLAG_SKIP;
} else {
GstVideoFormat format = GST_VIDEO_FORMAT_INFO_FORMAT (state->info.finfo);
/* TODO: have to reshuffle component values to native endianness. This is
* essentially an extra memcpy, and will not work at all if the decoded
* CVPixelBuffer is in GPU memory. Need to add new pixel formats for BE/LE
* endianness and let OpenGL handle it. */
if (format == GST_VIDEO_FORMAT_ARGB64 && G_BYTE_ORDER == G_LITTLE_ENDIAN) {
guint16 *pixel;
guint8 *base_address;
guint height, width, y, x;
size_t row_bytes;
CVPixelBufferRef pixbuf = (CVPixelBufferRef) image_buffer;
if (CVPixelBufferIsPlanar (pixbuf)) {
/* TODO: handle planer decoded pixbufs */
GST_ERROR_OBJECT (vtdec, "Error decoding frame, planar pro-res");
frame->flags |= VTDEC_FRAME_FLAG_ERROR;
CVBufferRelease (image_buffer);
goto out;
}
CVPixelBufferLockBaseAddress (pixbuf, 0);
height = CVPixelBufferGetHeight (pixbuf);
width = CVPixelBufferGetWidth (pixbuf);
base_address = CVPixelBufferGetBaseAddress (pixbuf);
g_assert_nonnull (base_address);
row_bytes = CVPixelBufferGetBytesPerRow (pixbuf);
g_assert_cmpint (row_bytes, >, 0);
g_assert_cmpint (CVPixelBufferGetPixelFormatType (pixbuf), ==, kCVPixelFormatType_64ARGB);
for (y = 0; y < height; ++y) {
pixel = (guint16*) (base_address + y * row_bytes);
for (x = 0; x < width * 4; ++x, ++pixel) {
*pixel = GUINT16_SWAP_LE_BE (*pixel);
}
}
CVPixelBufferUnlockBaseAddress (pixbuf, 0);
}
buf =
gst_core_video_buffer_new (image_buffer, &state->info,
vtdec->texture_cache);
......
Supports Markdown
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