Commit 483c92f9 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 9b773b56
Pipeline #477184 waiting for manual action with stages
in 1 minute and 32 seconds
......@@ -117,7 +117,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) ";" \
......@@ -269,6 +269,7 @@ get_preferred_video_format (GstStructure * s, gboolean prores)
return vfmt;
break;
case GST_VIDEO_FORMAT_AYUV64:
case GST_VIDEO_FORMAT_ARGB64:
if (prores)
return vfmt;
break;
......@@ -347,9 +348,14 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder)
}
}
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,
......@@ -648,6 +654,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:
/* This is fine for now because Apple only ships LE devices */
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
......@@ -936,6 +945,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);
......@@ -955,6 +1005,7 @@ gst_vtdec_session_output_callback (void *decompression_output_ref_con,
}
}
out:
g_async_queue_push_sorted (vtdec->reorder_queue, frame,
sort_frames_by_pts, NULL);
}
......
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