summaryrefslogtreecommitdiff
path: root/sys/decklink
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2021-04-23 18:05:06 +0300
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-04-26 15:03:34 +0000
commit56af02f9c8c3ccc4dfbdf64bfb76276e94a2ca98 (patch)
treec1c8080c53fc32c8a377c0dbe49ee554564ca3ad /sys/decklink
parent4b47b96ae16493b83e3995b436fb6cc737b56afa (diff)
downloadgstreamer-plugins-bad-56af02f9c8c3ccc4dfbdf64bfb76276e94a2ca98.tar.gz
decklinkvideosrc: Automatically detect widescreen vs. normal NTSC/PAL
Based on the AFD aspect ratio flag the source can detect (in mode=auto) whether this NTSC/PAL mode is actually a normal or a widescreen one and select the caps according to that. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2193>
Diffstat (limited to 'sys/decklink')
-rw-r--r--sys/decklink/gstdecklinkvideosrc.cpp72
-rw-r--r--sys/decklink/gstdecklinkvideosrc.h1
2 files changed, 52 insertions, 21 deletions
diff --git a/sys/decklink/gstdecklinkvideosrc.cpp b/sys/decklink/gstdecklinkvideosrc.cpp
index 41de397d7..bf71e384c 100644
--- a/sys/decklink/gstdecklinkvideosrc.cpp
+++ b/sys/decklink/gstdecklinkvideosrc.cpp
@@ -666,6 +666,7 @@ gst_decklink_video_src_start (GstDecklinkVideoSrc * self)
self->skipped_last = 0;
self->skip_from_timestamp = GST_CLOCK_TIME_NONE;
self->skip_to_timestamp = GST_CLOCK_TIME_NONE;
+ self->aspect_ratio_flag = -1;
return TRUE;
}
@@ -1014,6 +1015,8 @@ extract_vbi_line (GstDecklinkVideoSrc * self, GstBuffer ** buffer,
continue;
}
+ self->aspect_ratio_flag = (gstanc.data[0] >> 2) & 0x1;
+
afd = (GstVideoAFDValue) ((gstanc.data[0] >> 3) & 0xf);
is_letterbox = ((gstanc.data[3] >> 4) & 0x3) == 0;
bar1 = GST_READ_UINT16_BE (&gstanc.data[4]);
@@ -1246,9 +1249,55 @@ retry:
// If we're not flushing, we should have a valid frame from the queue
g_assert (f.frame != NULL);
+ // Create output buffer
+ f.frame->GetBytes ((gpointer *) & data);
+ data_size = f.frame->GetHeight() * f.frame->GetRowBytes();
+
+ vf = (VideoFrame *) g_malloc0 (sizeof (VideoFrame));
+
+ *buffer =
+ gst_buffer_new_wrapped_full ((GstMemoryFlags) GST_MEMORY_FLAG_READONLY,
+ (gpointer) data, data_size, 0, data_size, vf,
+ (GDestroyNotify) video_frame_free);
+
+ vf->frame = f.frame;
+ f.frame->AddRef ();
+ vf->input = self->input->input;
+ vf->input->AddRef ();
+
+ // If we have a format that supports VANC and we are asked to extract CC,
+ // then do it here.
+ if ((self->output_cc || self->output_afd_bar)
+ && self->signal_state != SIGNAL_STATE_LOST)
+ extract_vbi (self, buffer, vf);
+
if (!gst_pad_has_current_caps (GST_BASE_SRC_PAD (self))) {
caps_changed = TRUE;
}
+ // If there was AFD information with the aspect ratio flag set and the mode
+ // is auto then we have to switch from normal NTSC/PAL to the widescreen
+ // variants
+ if (self->aspect_ratio_flag == 1 && self->mode == GST_DECKLINK_MODE_AUTO) {
+ switch (f.mode) {
+ case GST_DECKLINK_MODE_NTSC:
+ f.mode = GST_DECKLINK_MODE_NTSC_WIDESCREEN;
+ break;
+ case GST_DECKLINK_MODE_NTSC_P:
+ f.mode = GST_DECKLINK_MODE_NTSC_P_WIDESCREEN;
+ break;
+ case GST_DECKLINK_MODE_NTSC2398:
+ f.mode = GST_DECKLINK_MODE_NTSC2398_WIDESCREEN;
+ break;
+ case GST_DECKLINK_MODE_PAL:
+ f.mode = GST_DECKLINK_MODE_PAL_WIDESCREEN;
+ break;
+ case GST_DECKLINK_MODE_PAL_P:
+ f.mode = GST_DECKLINK_MODE_PAL_P_WIDESCREEN;
+ break;
+ default:
+ break;
+ }
+ }
if (self->caps_mode != f.mode) {
if (self->mode == GST_DECKLINK_MODE_AUTO
@@ -1263,6 +1312,7 @@ retry:
("Invalid mode in captured frame"),
("Mode set to %d but captured %d", self->caps_mode, f.mode));
capture_frame_clear (&f);
+ gst_clear_buffer (buffer);
return GST_FLOW_NOT_NEGOTIATED;
}
}
@@ -1279,6 +1329,7 @@ retry:
("Invalid pixel format in captured frame"),
("Format set to %d but captured %d", self->caps_format, f.format));
capture_frame_clear (&f);
+ gst_clear_buffer (buffer);
return GST_FLOW_NOT_NEGOTIATED;
}
}
@@ -1328,27 +1379,6 @@ retry:
}
}
- f.frame->GetBytes ((gpointer *) & data);
- data_size = self->info.size;
-
- vf = (VideoFrame *) g_malloc0 (sizeof (VideoFrame));
-
- *buffer =
- gst_buffer_new_wrapped_full ((GstMemoryFlags) GST_MEMORY_FLAG_READONLY,
- (gpointer) data, data_size, 0, data_size, vf,
- (GDestroyNotify) video_frame_free);
-
- vf->frame = f.frame;
- f.frame->AddRef ();
- vf->input = self->input->input;
- vf->input->AddRef ();
-
- // If we have a format that supports VANC and we are asked to extract CC,
- // then do it here.
- if ((self->output_cc || self->output_afd_bar)
- && self->signal_state != SIGNAL_STATE_LOST)
- extract_vbi (self, buffer, vf);
-
if (f.no_signal)
GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
GST_BUFFER_TIMESTAMP (*buffer) = f.timestamp;
diff --git a/sys/decklink/gstdecklinkvideosrc.h b/sys/decklink/gstdecklinkvideosrc.h
index edd52d334..5e9876687 100644
--- a/sys/decklink/gstdecklinkvideosrc.h
+++ b/sys/decklink/gstdecklinkvideosrc.h
@@ -58,6 +58,7 @@ struct _GstDecklinkVideoSrc
GstDecklinkModeEnum mode;
GstDecklinkModeEnum caps_mode;
+ gint aspect_ratio_flag; /* -1 when unknown, 0 not set, 1 set */
BMDPixelFormat caps_format;
GstDecklinkConnectionEnum connection;
gint device_number;