From fe13e5f211d2e5d01e65d0e45dc628f172f299fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 7 Jul 2021 12:28:38 +0300 Subject: [PATCH] Add support for AFD/Bar VANC in the source element and widescreen NTSC/PAL --- gstajacommon.cpp | 19 +++++++++++++- gstajasrc.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/gstajacommon.cpp b/gstajacommon.cpp index aebda17516..dadcbb7a50 100644 --- a/gstajacommon.cpp +++ b/gstajacommon.cpp @@ -174,7 +174,24 @@ GstCaps *gst_ntv2_supported_caps(NTV2DeviceID device_id) { ::NTV2DeviceCanDoVideoFormat(device_id, format.aja_format)) || (format.quad_format != NTV2_FORMAT_UNKNOWN && ::NTV2DeviceCanDoVideoFormat(device_id, format.quad_format))) { - gst_caps_append(caps, gst_aja_video_format_to_caps(format.gst_format)); + GstCaps *tmp = gst_aja_video_format_to_caps(format.gst_format); + + // Widescreen PAL/NTSC + if (format.gst_format == GST_AJA_VIDEO_FORMAT_525_2398 || + format.gst_format == GST_AJA_VIDEO_FORMAT_525_2400 || + format.gst_format == GST_AJA_VIDEO_FORMAT_525_5994) { + GstCaps *tmp2 = gst_caps_copy(tmp); + gst_caps_set_simple(tmp2, "pixel-aspect-ratio", GST_TYPE_FRACTION, 40, + 33, NULL); + gst_caps_append(tmp, tmp2); + } else if (format.gst_format == GST_AJA_VIDEO_FORMAT_625_5000) { + GstCaps *tmp2 = gst_caps_copy(tmp); + gst_caps_set_simple(tmp2, "pixel-aspect-ratio", GST_TYPE_FRACTION, 16, + 11, NULL); + gst_caps_append(tmp, tmp2); + } + + gst_caps_append(caps, tmp); } } } diff --git a/gstajasrc.cpp b/gstajasrc.cpp index 7b22fd4374..91c1e1295e 100644 --- a/gstajasrc.cpp +++ b/gstajasrc.cpp @@ -1406,6 +1406,8 @@ static GstFlowReturn gst_aja_src_create(GstPushSrc *psrc, GstBuffer **buffer) { // // See AJA SDK support ticket #4844. guint32 n_vanc_packets = anc_packets.CountAncillaryData(); + bool aspect_ratio_flag = false; + bool have_afd_bar = false; for (guint32 i = 0; i < n_vanc_packets; i++) { AJAAncillaryData *packet = anc_packets.GetAncillaryDataAtIndex(i); @@ -1413,14 +1415,46 @@ static GstFlowReturn gst_aja_src_create(GstPushSrc *psrc, GstBuffer **buffer) { packet->GetSID() == AJAAncillaryData_CEA708_SID && packet->GetPayloadData() && packet->GetPayloadByteCount() && AJA_SUCCESS(packet->ParsePayloadData())) { + GST_TRACE_OBJECT( + self, "Found CEA708 CDP VANC of %" G_GSIZE_FORMAT " bytes at line %u", + packet->GetPayloadByteCount(), packet->GetLocationLineNumber()); gst_buffer_add_video_caption_meta( *buffer, GST_VIDEO_CAPTION_TYPE_CEA708_CDP, packet->GetPayloadData(), packet->GetPayloadByteCount()); + } else if (packet->GetDID() == 0x41 && packet->GetSID() == 0x05 && + packet->GetPayloadData() && packet->GetPayloadByteCount() == 8) { + const guint8 *data = packet->GetPayloadData(); + + have_afd_bar = true; + aspect_ratio_flag = (data[0] >> 2) & 0x1; + + GstVideoAFDValue afd = (GstVideoAFDValue)((data[0] >> 3) & 0xf); + gboolean is_letterbox = ((data[3] >> 4) & 0x3) == 0; + guint16 bar1 = GST_READ_UINT16_BE(&data[4]); + guint16 bar2 = GST_READ_UINT16_BE(&data[6]); + + GST_TRACE_OBJECT(self, + "Found AFD/Bar VANC at line %u: AR %u, AFD %u, " + "letterbox %u, bar1 %u, bar2 %u", + packet->GetLocationLineNumber(), aspect_ratio_flag, afd, + is_letterbox, bar1, bar2); + + const NTV2Standard standard( + ::GetNTV2StandardFromVideoFormat(item.detected_format)); + const NTV2SmpteLineNumber smpte_line_num_info = + ::GetSmpteLineNumber(standard); + bool field2 = + packet->GetLocationLineNumber() > + smpte_line_num_info.GetLastLine( + smpte_line_num_info.firstFieldTop ? NTV2_FIELD0 : NTV2_FIELD1); + + gst_buffer_add_video_afd_meta(*buffer, field2 ? 1 : 0, + GST_VIDEO_AFD_SPEC_SMPTE_ST2016_1, afd); + gst_buffer_add_video_bar_meta(*buffer, field2 ? 1 : 0, is_letterbox, bar1, + bar2); } } - // TODO: Add AFD/Bar meta - bool caps_changed = false; CNTV2VPID vpid(item.vpid); @@ -1464,6 +1498,17 @@ static GstFlowReturn gst_aja_src_create(GstPushSrc *psrc, GstBuffer **buffer) { break; } + if (!have_afd_bar && vpid.GetImageAspect16x9()) aspect_ratio_flag = true; + + // Widescreen PAL/NTSC + if (aspect_ratio_flag && info.height == 486) { + info.par_n = 40; + info.par_d = 33; + } else if (aspect_ratio_flag && info.height == 576) { + info.par_n = 16; + info.par_d = 11; + } + if (!gst_pad_has_current_caps(GST_BASE_SRC_PAD(self)) || !gst_video_info_is_equal(&info, &self->current_info)) { self->current_info = info; @@ -1474,6 +1519,15 @@ static GstFlowReturn gst_aja_src_create(GstPushSrc *psrc, GstBuffer **buffer) { GstVideoInfo info; if (gst_video_info_from_ntv2_video_format(&info, item.detected_format)) { + // Widescreen PAL/NTSC + if (aspect_ratio_flag && info.height == 486) { + info.par_n = 40; + info.par_d = 33; + } else if (aspect_ratio_flag && info.height == 576) { + info.par_n = 16; + info.par_d = 11; + } + if (!gst_pad_has_current_caps(GST_BASE_SRC_PAD(self)) || !gst_video_info_is_equal(&info, &self->current_info)) { self->current_info = info; @@ -1481,6 +1535,16 @@ static GstFlowReturn gst_aja_src_create(GstPushSrc *psrc, GstBuffer **buffer) { } } else if (!gst_pad_has_current_caps(GST_BASE_SRC_PAD(self))) { self->current_info = self->configured_info; + + // Widescreen PAL/NTSC + if (aspect_ratio_flag && self->current_info.height == 486) { + self->current_info.par_n = 40; + self->current_info.par_d = 33; + } else if (aspect_ratio_flag && self->current_info.height == 576) { + self->current_info.par_n = 16; + self->current_info.par_d = 11; + } + caps_changed = true; } }