summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJulien Moutte <julien@ctondemand.com>2016-01-13 22:05:49 +0100
committerJulien Moutte <julien@ctondemand.com>2016-01-22 16:11:08 +0100
commit3ea431c5b5425806b7139025b6f233999563594d (patch)
tree8958c3fdc069cf8c3c411c3bf42406720f365e68 /sys
parent8c57341241d98b7f4f0154199b1ba3ad9a1a95bf (diff)
decklinkvideosrc: implement RGB capture support
Combine mode and format to generate caps and support the flags from VideoChanged callback to support RGB capture. https://bugzilla.gnome.org/show_bug.cgi?id=760594
Diffstat (limited to 'sys')
-rw-r--r--sys/decklink/gstdecklink.cpp63
-rw-r--r--sys/decklink/gstdecklink.h3
-rw-r--r--sys/decklink/gstdecklinkvideosink.cpp2
-rw-r--r--sys/decklink/gstdecklinkvideosrc.cpp17
-rw-r--r--sys/decklink/gstdecklinkvideosrc.h1
5 files changed, 63 insertions, 23 deletions
diff --git a/sys/decklink/gstdecklink.cpp b/sys/decklink/gstdecklink.cpp
index c0d1128b0..64637f1d9 100644
--- a/sys/decklink/gstdecklink.cpp
+++ b/sys/decklink/gstdecklink.cpp
@@ -316,28 +316,53 @@ gst_decklink_get_connection (GstDecklinkConnectionEnum e)
}
static GstStructure *
-gst_decklink_mode_get_structure (GstDecklinkModeEnum e)
+gst_decklink_mode_get_structure (GstDecklinkModeEnum e, BMDPixelFormat f)
{
const GstDecklinkMode *mode = &modes[e];
-
- return gst_structure_new ("video/x-raw",
- "format", G_TYPE_STRING, "UYVY",
+ GstStructure *s = gst_structure_new ("video/x-raw",
"width", G_TYPE_INT, mode->width,
"height", G_TYPE_INT, mode->height,
- "framerate", GST_TYPE_FRACTION, mode->fps_n, mode->fps_d,
- "interlace-mode", G_TYPE_STRING,
- mode->interlaced ? "interleaved" : "progressive", "pixel-aspect-ratio",
- GST_TYPE_FRACTION, mode->par_n, mode->par_d, "colorimetry", G_TYPE_STRING,
- mode->colorimetry, "chroma-site", G_TYPE_STRING, "mpeg2", NULL);
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, mode->par_n, mode->par_d,
+ "interlace-mode", G_TYPE_STRING, mode->interlaced ? "interleaved" : "progressive",
+ "framerate", GST_TYPE_FRACTION, mode->fps_n, mode->fps_d, NULL);
+
+ switch (f) {
+ case bmdFormat8BitYUV: /* '2vuy' */
+ gst_structure_set (s, "format", G_TYPE_STRING, "UYVY",
+ "colorimetry", G_TYPE_STRING, mode->colorimetry,
+ "chroma-site", G_TYPE_STRING, "mpeg2", NULL);
+ break;
+ case bmdFormat10BitYUV: /* 'v210' */
+ gst_structure_set (s, "format", G_TYPE_STRING, "v210", NULL);
+ break;
+ case bmdFormat8BitARGB: /* 'ARGB' */
+ gst_structure_set (s, "format", G_TYPE_STRING, "ARGB", NULL);
+ break;
+ case bmdFormat8BitBGRA: /* 'BGRA' */
+ gst_structure_set (s, "format", G_TYPE_STRING, "BGRA", NULL);
+ break;
+ case bmdFormat10BitRGB: /* 'r210' Big-endian RGB 10-bit per component with SMPTE video levels (64-960). Packed as 2:10:10:10 */
+ case bmdFormat12BitRGB: /* 'R12B' Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component */
+ case bmdFormat12BitRGBLE: /* 'R12L' Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component */
+ case bmdFormat10BitRGBXLE: /* 'R10l' Little-endian 10-bit RGB with SMPTE video levels (64-940) */
+ case bmdFormat10BitRGBX: /* 'R10b' Big-endian 10-bit RGB with SMPTE video levels (64-940) */
+ default:
+ GST_WARNING ("format not supported %d", f);
+ gst_structure_free (s);
+ s = NULL;
+ break;
+ }
+
+ return s;
}
GstCaps *
-gst_decklink_mode_get_caps (GstDecklinkModeEnum e)
+gst_decklink_mode_get_caps (GstDecklinkModeEnum e, BMDPixelFormat f)
{
GstCaps *caps;
caps = gst_caps_new_empty ();
- gst_caps_append_structure (caps, gst_decklink_mode_get_structure (e));
+ gst_caps_append_structure (caps, gst_decklink_mode_get_structure (e, f));
return caps;
}
@@ -351,7 +376,9 @@ gst_decklink_mode_get_template_caps (void)
caps = gst_caps_new_empty ();
for (i = 1; i < (int) G_N_ELEMENTS (modes); i++) {
- s = gst_decklink_mode_get_structure ((GstDecklinkModeEnum) i);
+ s = gst_decklink_mode_get_structure ((GstDecklinkModeEnum) i, bmdFormat8BitYUV);
+ gst_caps_append_structure (caps, s);
+ s = gst_decklink_mode_get_structure ((GstDecklinkModeEnum) i, bmdFormat8BitARGB);
gst_caps_append_structure (caps, s);
}
@@ -365,7 +392,7 @@ gst_decklink_find_mode_for_caps (GstCaps * caps)
GstCaps *mode_caps;
for (i = 1; i < (int) G_N_ELEMENTS (modes); i++) {
- mode_caps = gst_decklink_mode_get_caps ((GstDecklinkModeEnum) i);
+ mode_caps = gst_decklink_mode_get_caps ((GstDecklinkModeEnum) i, bmdFormat8BitYUV);
if (gst_caps_can_intersect (caps, mode_caps)) {
gst_caps_unref (mode_caps);
return gst_decklink_get_mode ((GstDecklinkModeEnum) i);
@@ -470,19 +497,25 @@ public:
virtual HRESULT STDMETHODCALLTYPE
VideoInputFormatChanged (BMDVideoInputFormatChangedEvents,
- IDeckLinkDisplayMode * mode, BMDDetectedVideoInputFormatFlags)
+ IDeckLinkDisplayMode * mode, BMDDetectedVideoInputFormatFlags formatFlags)
{
+ BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
+
GST_INFO ("Video input format changed");
+ if (formatFlags & bmdDetectedVideoInputRGB444)
+ pixelFormat = bmdFormat8BitARGB;
+
g_mutex_lock (&m_input->lock);
m_input->input->PauseStreams ();
m_input->input->EnableVideoInput (mode->GetDisplayMode (),
- bmdFormat8BitYUV, bmdVideoInputEnableFormatDetection);
+ pixelFormat, bmdVideoInputEnableFormatDetection);
m_input->input->FlushStreams ();
m_input->input->StartStreams ();
m_input->mode =
gst_decklink_get_mode (gst_decklink_get_mode_enum_from_bmd
(mode->GetDisplayMode ()));
+ m_input->format = pixelFormat;
g_mutex_unlock (&m_input->lock);
return S_OK;
diff --git a/sys/decklink/gstdecklink.h b/sys/decklink/gstdecklink.h
index 493b48e5c..6c32feef6 100644
--- a/sys/decklink/gstdecklink.h
+++ b/sys/decklink/gstdecklink.h
@@ -126,7 +126,7 @@ struct _GstDecklinkMode {
const GstDecklinkMode * gst_decklink_get_mode (GstDecklinkModeEnum e);
const GstDecklinkModeEnum gst_decklink_get_mode_enum_from_bmd (BMDDisplayMode mode);
const BMDVideoConnection gst_decklink_get_connection (GstDecklinkConnectionEnum e);
-GstCaps * gst_decklink_mode_get_caps (GstDecklinkModeEnum e);
+GstCaps * gst_decklink_mode_get_caps (GstDecklinkModeEnum e, BMDPixelFormat f);
GstCaps * gst_decklink_mode_get_template_caps (void);
typedef struct _GstDecklinkOutput GstDecklinkOutput;
@@ -172,6 +172,7 @@ struct _GstDecklinkInput {
void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime capture_duration);
/* Configured mode or NULL */
const GstDecklinkMode *mode;
+ BMDPixelFormat format;
/* Set by the audio source */
void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time);
diff --git a/sys/decklink/gstdecklinkvideosink.cpp b/sys/decklink/gstdecklinkvideosink.cpp
index 7111cb1c5..eebeff328 100644
--- a/sys/decklink/gstdecklinkvideosink.cpp
+++ b/sys/decklink/gstdecklinkvideosink.cpp
@@ -330,7 +330,7 @@ gst_decklink_video_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
if (self->mode == GST_DECKLINK_MODE_AUTO)
mode_caps = gst_decklink_mode_get_template_caps ();
else
- mode_caps = gst_decklink_mode_get_caps (self->mode);
+ mode_caps = gst_decklink_mode_get_caps (self->mode, bmdFormat8BitYUV);
mode_caps = gst_caps_make_writable (mode_caps);
/* For output we support any framerate and only really care about timestamps */
gst_caps_map_in_place (mode_caps, reset_framerate, NULL);
diff --git a/sys/decklink/gstdecklinkvideosrc.cpp b/sys/decklink/gstdecklinkvideosrc.cpp
index 915393eaf..2b304f912 100644
--- a/sys/decklink/gstdecklinkvideosrc.cpp
+++ b/sys/decklink/gstdecklinkvideosrc.cpp
@@ -47,6 +47,7 @@ typedef struct
IDeckLinkVideoInputFrame *frame;
GstClockTime capture_time, capture_duration;
GstDecklinkModeEnum mode;
+ BMDPixelFormat format;
} CaptureFrame;
static void
@@ -178,6 +179,7 @@ gst_decklink_video_src_init (GstDecklinkVideoSrc * self)
{
self->mode = DEFAULT_MODE;
self->caps_mode = GST_DECKLINK_MODE_AUTO;
+ self->caps_format = bmdFormat8BitYUV;
self->connection = DEFAULT_CONNECTION;
self->device_number = 0;
self->buffer_size = DEFAULT_BUFFER_SIZE;
@@ -352,9 +354,9 @@ gst_decklink_video_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
g_mutex_lock (&self->lock);
if (self->caps_mode != GST_DECKLINK_MODE_AUTO)
- mode_caps = gst_decklink_mode_get_caps (self->caps_mode);
+ mode_caps = gst_decklink_mode_get_caps (self->caps_mode, self->caps_format);
else
- mode_caps = gst_decklink_mode_get_caps (self->mode);
+ mode_caps = gst_decklink_mode_get_caps (self->mode, self->caps_format);
g_mutex_unlock (&self->lock);
if (filter) {
@@ -481,6 +483,7 @@ gst_decklink_video_src_got_frame (GstElement * element,
f->capture_time = capture_time;
f->capture_duration = capture_duration;
f->mode = mode;
+ f->format = frame->GetPixelFormat ();
frame->AddRef ();
g_queue_push_tail (&self->current_frames, f);
g_cond_signal (&self->cond);
@@ -515,12 +518,14 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
}
g_mutex_lock (&self->lock);
- if (self->mode == GST_DECKLINK_MODE_AUTO && self->caps_mode != f->mode) {
- GST_DEBUG_OBJECT (self, "Mode changed from %d to %d", self->caps_mode,
- f->mode);
+ if (self->mode == GST_DECKLINK_MODE_AUTO &&
+ (self->caps_mode != f->mode || self->caps_format != f->format)) {
+ GST_DEBUG_OBJECT (self, "Mode/Format changed from %d/%d to %d/%d",
+ self->caps_mode, self->caps_format, f->mode, f->format);
self->caps_mode = f->mode;
+ self->caps_format = f->format;
g_mutex_unlock (&self->lock);
- caps = gst_decklink_mode_get_caps (f->mode);
+ caps = gst_decklink_mode_get_caps (f->mode, f->format);
gst_video_info_from_caps (&self->info, caps);
gst_base_src_set_caps (GST_BASE_SRC_CAST (bsrc), caps);
gst_element_post_message (GST_ELEMENT_CAST (self),
diff --git a/sys/decklink/gstdecklinkvideosrc.h b/sys/decklink/gstdecklinkvideosrc.h
index 6cb5bb9d3..b83495f0c 100644
--- a/sys/decklink/gstdecklinkvideosrc.h
+++ b/sys/decklink/gstdecklinkvideosrc.h
@@ -52,6 +52,7 @@ struct _GstDecklinkVideoSrc
GstDecklinkModeEnum mode;
GstDecklinkModeEnum caps_mode;
+ BMDPixelFormat caps_format;
GstDecklinkConnectionEnum connection;
gint device_number;