}
GType
+gst_decklink_video_format_get_type (void)
+{
+ static gsize id = 0;
+ static const GEnumValue types[] = {
+ {GST_DECKLINK_VIDEO_FORMAT_AUTO, "auto", "Auto"},
+ {GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV, "8bit-yuv", "bmdFormat8BitYUV"},
+ {GST_DECKLINK_VIDEO_FORMAT_10BIT_YUV, "10bit-yuv", "bmdFormat10BitYUV"},
+ {GST_DECKLINK_VIDEO_FORMAT_8BIT_ARGB, "8bit-argb", "bmdFormat8BitARGB"},
+ {GST_DECKLINK_VIDEO_FORMAT_8BIT_BGRA, "8bit-bgra", "bmdFormat8BitBGRA"},
+ /*
+ {GST_DECKLINK_VIDEO_FORMAT_10BIT_RGB, "10bit-rgb", "bmdFormat10BitRGB"},
+ {GST_DECKLINK_VIDEO_FORMAT_12BIT_RGB, "12bit-rgb", "bmdFormat12BitRGB"},
+ {GST_DECKLINK_VIDEO_FORMAT_12BIT_RGBLE, "12bit-rgble", "bmdFormat12BitRGBLE"},
+ {GST_DECKLINK_VIDEO_FORMAT_10BIT_RGBXLE, "10bit-rgbxle", "bmdFormat10BitRGBXLE"},
+ {GST_DECKLINK_VIDEO_FORMAT_10BIT_RGBX, "10bit-rgbx", "bmdFormat10BitRGBX"},
+ */
+ {0, NULL, NULL}
+ };
+
+ if (g_once_init_enter (&id)) {
+ GType tmp = g_enum_register_static ("GstDecklinkVideoFormat", types);
+ g_once_init_leave (&id, tmp);
+ }
+
+ return (GType) id;
+}
+
+GType
gst_decklink_audio_connection_get_type (void)
{
static gsize id = 0;
{bmdMode4K2160p60, 3840, 2160, 60, 1, false, UHD}
};
+static const struct
+{
+ BMDPixelFormat format;
+ gint bpp;
+ GstVideoFormat vformat;
+} formats[] = {
+ /* *INDENT-OFF* */
+ {bmdFormat8BitYUV, 2, GST_VIDEO_FORMAT_UYVY}, /* auto */
+ {bmdFormat8BitYUV, 2, GST_VIDEO_FORMAT_UYVY},
+ {bmdFormat10BitYUV, 4, GST_VIDEO_FORMAT_v210},
+ {bmdFormat8BitARGB, 4, GST_VIDEO_FORMAT_ARGB},
+ {bmdFormat8BitBGRA, 4, GST_VIDEO_FORMAT_BGRA},
+/* Not yet supported
+ {bmdFormat10BitRGB, FIXME, FIXME},
+ {bmdFormat12BitRGB, FIXME, FIXME},
+ {bmdFormat12BitRGBLE, FIXME, FIXME},
+ {bmdFormat10BitRGBXLE, FIXME, FIXME},
+ {bmdFormat10BitRGBX, FIXME, FIXME} */
+ /* *INDENT-ON* */
+};
+
const GstDecklinkMode *
gst_decklink_get_mode (GstDecklinkModeEnum e)
{
return displayMode;
}
+const BMDPixelFormat
+gst_decklink_pixel_format_from_type (GstDecklinkVideoFormat t)
+{
+ return formats[t].format;
+}
+
+const gint
+gst_decklink_bpp_from_type (GstDecklinkVideoFormat t)
+{
+ return formats[t].bpp;
+}
+
+const GstDecklinkVideoFormat
+gst_decklink_type_from_video_format (GstVideoFormat f)
+{
+ guint i;
+
+ for (i = 1; i < G_N_ELEMENTS (formats); i++) {
+ if (formats[i].vformat == f)
+ return (GstDecklinkVideoFormat) i;
+ }
+ g_assert_not_reached ();
+ return GST_DECKLINK_VIDEO_FORMAT_AUTO;
+}
+
static const BMDVideoConnection connections[] = {
0, /* auto */
bmdVideoConnectionSDI,
return connections[e];
}
+static gboolean
+gst_decklink_caps_get_pixel_format (GstCaps * caps, BMDPixelFormat * format)
+{
+ GstVideoInfo vinfo;
+ GstVideoFormat f;
+
+ if (gst_video_info_from_caps (&vinfo, caps) == FALSE) {
+ GST_ERROR ("Could not get video info from caps: %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+
+ f = vinfo.finfo->format;
+ return gst_decklink_type_from_video_format (f);
+}
+
static GstStructure *
gst_decklink_mode_get_structure (GstDecklinkModeEnum e, BMDPixelFormat f)
{
GstCaps *caps;
caps = gst_caps_new_empty ();
- gst_caps_append_structure (caps, gst_decklink_mode_get_structure (e, f));
+ caps =
+ gst_caps_merge_structure (caps, gst_decklink_mode_get_structure (e, f));
return caps;
}
GstCaps *
-gst_decklink_mode_get_template_caps (void)
+gst_decklink_mode_get_caps_all_formats (GstDecklinkModeEnum e)
+{
+ GstCaps *caps;
+ guint i;
+
+ caps = gst_caps_new_empty ();
+ for (i = 1; i < G_N_ELEMENTS (formats); i++)
+ caps =
+ gst_caps_merge_structure (caps, gst_decklink_mode_get_structure (e,
+ formats[i].format));
+
+ return caps;
+}
+
+GstCaps *
+gst_decklink_pixel_format_get_caps (BMDPixelFormat f)
{
int i;
GstCaps *caps;
caps = gst_caps_new_empty ();
for (i = 1; i < (int) G_N_ELEMENTS (modes); 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);
+ s = gst_decklink_mode_get_structure ((GstDecklinkModeEnum) i, f);
+ caps = gst_caps_merge_structure (caps, s);
}
return caps;
}
+GstCaps *
+gst_decklink_mode_get_template_caps (void)
+{
+ int i;
+ GstCaps *caps;
+
+ caps = gst_caps_new_empty ();
+ for (i = 1; i < (int) G_N_ELEMENTS (modes); i++)
+ caps =
+ gst_caps_merge (caps,
+ gst_decklink_mode_get_caps_all_formats ((GstDecklinkModeEnum) i));
+
+ return caps;
+}
+
const GstDecklinkMode *
-gst_decklink_find_mode_for_caps (GstCaps * caps)
+gst_decklink_find_mode_and_format_for_caps (GstCaps * caps,
+ BMDPixelFormat * format)
{
int i;
GstCaps *mode_caps;
+ g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
+ if (!gst_decklink_caps_get_pixel_format (caps, format))
+ return NULL;
+
for (i = 1; i < (int) G_N_ELEMENTS (modes); i++) {
- mode_caps =
- gst_decklink_mode_get_caps ((GstDecklinkModeEnum) i, bmdFormat8BitYUV);
+ mode_caps = gst_decklink_mode_get_caps ((GstDecklinkModeEnum) i, *format);
if (gst_caps_can_intersect (caps, mode_caps)) {
gst_caps_unref (mode_caps);
return gst_decklink_get_mode ((GstDecklinkModeEnum) i);
return NULL;
}
+const GstDecklinkMode *
+gst_decklink_find_mode_for_caps (GstCaps * caps)
+{
+ BMDPixelFormat format;
+
+ return gst_decklink_find_mode_and_format_for_caps (caps, &format);
+}
+
#define GST_TYPE_DECKLINK_CLOCK \
(gst_decklink_clock_get_type())
#define GST_DECKLINK_CLOCK(obj) \
#define _GST_DECKLINK_H_
#include <gst/gst.h>
+#include <gst/video/video.h>
#ifdef G_OS_UNIX
#include "linux/DeckLinkAPI.h"
#endif
#define GST_TYPE_DECKLINK_AUDIO_CONNECTION (gst_decklink_audio_connection_get_type ())
GType gst_decklink_audio_connection_get_type (void);
+typedef enum {
+ GST_DECKLINK_VIDEO_FORMAT_AUTO,
+ GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV, /* bmdFormat8BitYUV */
+ GST_DECKLINK_VIDEO_FORMAT_10BIT_YUV, /* bmdFormat10BitYUV */
+ GST_DECKLINK_VIDEO_FORMAT_8BIT_ARGB, /* bmdFormat8BitARGB */
+ GST_DECKLINK_VIDEO_FORMAT_8BIT_BGRA, /* bmdFormat8BitBGRA */
+ GST_DECKLINK_VIDEO_FORMAT_10BIT_RGB, /* bmdFormat10BitRGB */
+ GST_DECKLINK_VIDEO_FORMAT_12BIT_RGB, /* bmdFormat12BitRGB */
+ GST_DECKLINK_VIDEO_FORMAT_12BIT_RGBLE, /* bmdFormat12BitRGBLE */
+ GST_DECKLINK_VIDEO_FORMAT_10BIT_RGBXLE, /* bmdFormat10BitRGBXLE */
+ GST_DECKLINK_VIDEO_FORMAT_10BIT_RGBX, /* bmdFormat10BitRGBX */
+} GstDecklinkVideoFormat;
+#define GST_TYPE_DECKLINK_VIDEO_FORMAT (gst_decklink_video_format_get_type ())
+GType gst_decklink_video_format_get_type (void);
+
+const BMDPixelFormat gst_decklink_pixel_format_from_type (GstDecklinkVideoFormat t);
+const gint gst_decklink_bpp_from_type (GstDecklinkVideoFormat t);
+const GstDecklinkVideoFormat gst_decklink_type_from_video_format (GstVideoFormat f);
+
typedef struct _GstDecklinkMode GstDecklinkMode;
struct _GstDecklinkMode {
BMDDisplayMode mode;
void gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio);
const GstDecklinkMode * gst_decklink_find_mode_for_caps (GstCaps * caps);
+const GstDecklinkMode * gst_decklink_find_mode_and_format_for_caps (GstCaps * caps, BMDPixelFormat * format);
+GstCaps * gst_decklink_mode_get_caps_all_formats (GstDecklinkModeEnum e);
+GstCaps * gst_decklink_pixel_format_get_caps (BMDPixelFormat f);
#endif
{
PROP_0,
PROP_MODE,
- PROP_DEVICE_NUMBER
+ PROP_DEVICE_NUMBER,
+ PROP_VIDEO_FORMAT
};
static void gst_decklink_video_sink_set_property (GObject * object,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT)));
+ g_object_class_install_property (gobject_class, PROP_VIDEO_FORMAT,
+ g_param_spec_enum ("video-format", "Video format",
+ "Video format type to use for playback",
+ GST_TYPE_DECKLINK_VIDEO_FORMAT, GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ G_PARAM_CONSTRUCT)));
+
templ_caps = gst_decklink_mode_get_template_caps ();
templ_caps = gst_caps_make_writable (templ_caps);
/* For output we support any framerate and only really care about timestamps */
{
self->mode = GST_DECKLINK_MODE_NTSC;
self->device_number = 0;
+ self->video_format = GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV;
gst_base_sink_set_max_lateness (GST_BASE_SINK_CAST (self), 20 * GST_MSECOND);
gst_base_sink_set_qos_enabled (GST_BASE_SINK_CAST (self), TRUE);
case PROP_DEVICE_NUMBER:
self->device_number = g_value_get_int (value);
break;
+ case PROP_VIDEO_FORMAT:
+ self->video_format = (GstDecklinkVideoFormat) g_value_get_enum (value);
+ switch (self->video_format) {
+ case GST_DECKLINK_VIDEO_FORMAT_AUTO:
+ case GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV:
+ case GST_DECKLINK_VIDEO_FORMAT_10BIT_YUV:
+ case GST_DECKLINK_VIDEO_FORMAT_8BIT_ARGB:
+ case GST_DECKLINK_VIDEO_FORMAT_8BIT_BGRA:
+ break;
+ default:
+ GST_ELEMENT_WARNING (GST_ELEMENT (self), CORE, NOT_IMPLEMENTED,
+ ("Format %d not supported", self->video_format), (NULL));
+ break;
+ }
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
case PROP_DEVICE_NUMBER:
g_value_set_int (value, self->device_number);
break;
+ case PROP_VIDEO_FORMAT:
+ g_value_set_enum (value, self->video_format);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
GStreamerVideoOutputCallback (self));
if (self->mode == GST_DECKLINK_MODE_AUTO) {
- mode = gst_decklink_find_mode_for_caps (caps);
+ BMDPixelFormat f;
+ mode = gst_decklink_find_mode_and_format_for_caps (caps, &f);
if (mode == NULL) {
GST_WARNING_OBJECT (self,
"Failed to find compatible mode for caps %" GST_PTR_FORMAT, caps);
return FALSE;
}
+ if (self->video_format != GST_DECKLINK_VIDEO_FORMAT_AUTO &&
+ gst_decklink_pixel_format_from_type (self->video_format) != f) {
+ GST_WARNING_OBJECT (self, "Failed to set pixel format to %d",
+ self->video_format);
+ return FALSE;
+ }
} else {
+ /* We don't have to give the format in EnableVideoOutput. Therefore,
+ * even if it's AUTO, we have it stored in self->info and set it in
+ * gst_decklink_video_sink_prepare */
mode = gst_decklink_get_mode (self->mode);
g_assert (mode != NULL);
};
GstDecklinkVideoSink *self = GST_DECKLINK_VIDEO_SINK_CAST (bsink);
GstCaps *mode_caps, *caps;
- if (self->mode == GST_DECKLINK_MODE_AUTO)
+ if (self->mode == GST_DECKLINK_MODE_AUTO
+ && self->video_format == GST_DECKLINK_VIDEO_FORMAT_AUTO)
mode_caps = gst_decklink_mode_get_template_caps ();
+ else if (self->video_format == GST_DECKLINK_VIDEO_FORMAT_AUTO)
+ mode_caps = gst_decklink_mode_get_caps_all_formats (self->mode);
+ else if (self->mode == GST_DECKLINK_MODE_AUTO)
+ mode_caps =
+ gst_decklink_pixel_format_get_caps (gst_decklink_pixel_format_from_type
+ (self->video_format));
else
- mode_caps = gst_decklink_mode_get_caps (self->mode, bmdFormat8BitYUV);
+ mode_caps =
+ gst_decklink_mode_get_caps (self->mode,
+ gst_decklink_pixel_format_from_type (self->video_format));
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);
GstClockTime latency, render_delay;
GstClockTimeDiff ts_offset;
gint i;
+ GstDecklinkVideoFormat caps_format;
+ BMDPixelFormat format;
+ gint bpp;
GST_DEBUG_OBJECT (self, "Preparing buffer %p", buffer);
return GST_FLOW_ERROR;
}
+ caps_format = gst_decklink_type_from_video_format (self->info.finfo->format);
+ format = gst_decklink_pixel_format_from_type (caps_format);
+ bpp = gst_decklink_bpp_from_type (caps_format);
+
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
if (duration == GST_CLOCK_TIME_NONE) {
running_time = 0;
ret = self->output->output->CreateVideoFrame (self->info.width,
- self->info.height, self->info.stride[0], bmdFormat8BitYUV,
- bmdFrameFlagDefault, &frame);
+ self->info.height, self->info.stride[0], format, bmdFrameFlagDefault,
+ &frame);
if (ret != S_OK) {
GST_ELEMENT_ERROR (self, STREAM, FAILED,
(NULL), ("Failed to create video frame: 0x%08x", ret));
frame->GetBytes ((void **) &outdata);
indata = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
for (i = 0; i < self->info.height; i++) {
- memcpy (outdata, indata, GST_VIDEO_FRAME_WIDTH (&vframe) * 2);
+ memcpy (outdata, indata, GST_VIDEO_FRAME_WIDTH (&vframe) * bpp);
indata += GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0);
outdata += frame->GetRowBytes ();
}
GstDecklinkModeEnum mode;
gint device_number;
+ GstDecklinkVideoFormat video_format;
GstVideoInfo info;
PROP_MODE,
PROP_CONNECTION,
PROP_DEVICE_NUMBER,
- PROP_BUFFER_SIZE
+ PROP_BUFFER_SIZE,
+ PROP_VIDEO_FORMAT
};
typedef struct
G_MAXINT, DEFAULT_BUFFER_SIZE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+ g_object_class_install_property (gobject_class, PROP_VIDEO_FORMAT,
+ g_param_spec_enum ("video-format", "Video format",
+ "Video format type to use for input (Only use auto for mode=auto)",
+ GST_TYPE_DECKLINK_VIDEO_FORMAT, GST_DECKLINK_VIDEO_FORMAT_AUTO,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ G_PARAM_CONSTRUCT)));
+
templ_caps = gst_decklink_mode_get_template_caps ();
gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps));
self->connection = DEFAULT_CONNECTION;
self->device_number = 0;
self->buffer_size = DEFAULT_BUFFER_SIZE;
+ self->video_format = GST_DECKLINK_VIDEO_FORMAT_AUTO;
gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
switch (property_id) {
case PROP_MODE:
self->mode = (GstDecklinkModeEnum) g_value_get_enum (value);
+ /* setting the default value for caps_mode here: if mode==auto then we
+ * configure caps_mode from the caps, if mode!=auto we set caps_mode to
+ * the same value as the mode. so self->caps_mode is essentially
+ * self->mode with mode=auto filtered into whatever we got from the
+ * negotiation */
+ if (self->mode != GST_DECKLINK_MODE_AUTO)
+ self->caps_mode = self->mode;
break;
case PROP_CONNECTION:
self->connection = (GstDecklinkConnectionEnum) g_value_get_enum (value);
case PROP_BUFFER_SIZE:
self->buffer_size = g_value_get_uint (value);
break;
+ case PROP_VIDEO_FORMAT:
+ self->video_format = (GstDecklinkVideoFormat) g_value_get_enum (value);
+ switch (self->video_format) {
+ case GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV:
+ case GST_DECKLINK_VIDEO_FORMAT_10BIT_YUV:
+ case GST_DECKLINK_VIDEO_FORMAT_8BIT_ARGB:
+ case GST_DECKLINK_VIDEO_FORMAT_8BIT_BGRA:
+ self->caps_format =
+ gst_decklink_pixel_format_from_type (self->video_format);
+ case GST_DECKLINK_VIDEO_FORMAT_AUTO:
+ break;
+ default:
+ GST_ELEMENT_WARNING (GST_ELEMENT (self), CORE, NOT_IMPLEMENTED,
+ ("Format %d not supported", self->video_format), (NULL));
+ break;
+ }
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
case PROP_BUFFER_SIZE:
g_value_set_uint (value, self->buffer_size);
break;
+ case PROP_VIDEO_FORMAT:
+ g_value_set_enum (value, self->video_format);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
const GstDecklinkMode *mode;
BMDVideoInputFlags flags;
HRESULT ret;
+ BMDPixelFormat format;
GST_DEBUG_OBJECT (self, "Setting caps %" GST_PTR_FORMAT, caps);
mode = gst_decklink_get_mode (self->mode);
g_assert (mode != NULL);
- ret = self->input->input->EnableVideoInput (mode->mode,
- bmdFormat8BitYUV, flags);
+ format = self->caps_format;
+ ret = self->input->input->EnableVideoInput (mode->mode, format, flags);
if (ret != S_OK) {
GST_WARNING_OBJECT (self, "Failed to enable video input");
return FALSE;
{
GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (bsrc);
GstCaps *mode_caps, *caps;
+ BMDPixelFormat format;
+ GstDecklinkModeEnum mode;
g_mutex_lock (&self->lock);
- if (self->caps_mode != GST_DECKLINK_MODE_AUTO)
- mode_caps = gst_decklink_mode_get_caps (self->caps_mode, self->caps_format);
- else
- mode_caps = gst_decklink_mode_get_caps (self->mode, self->caps_format);
+ mode = self->caps_mode;
+ format = self->caps_format;
g_mutex_unlock (&self->lock);
+ mode_caps = gst_decklink_mode_get_caps (mode, format);
+
if (filter) {
caps =
gst_caps_intersect_full (filter, mode_caps, GST_CAPS_INTERSECT_FIRST);
VideoFrame *vf;
CaptureFrame *f;
GstCaps *caps;
+ gboolean caps_changed = FALSE;
g_mutex_lock (&self->lock);
while (g_queue_is_empty (&self->current_frames) && !self->flushing) {
}
g_mutex_lock (&self->lock);
- 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);
+ if (self->caps_mode != f->mode) {
+ if (self->mode == GST_DECKLINK_MODE_AUTO) {
+ GST_DEBUG_OBJECT (self, "Mode changed from %d to %d", self->caps_mode,
+ f->mode);
+ caps_changed = TRUE;
+ self->caps_mode = f->mode;
+ } else {
+ g_mutex_unlock (&self->lock);
+ if (f)
+ capture_frame_free (f);
+ GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
+ ("Invalid mode in captured frame"),
+ ("Mode set to %d but captured %d", self->caps_mode, f->mode));
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+ }
+ if (self->caps_format != f->format) {
+ if (self->video_format == GST_DECKLINK_VIDEO_FORMAT_AUTO) {
+ GST_DEBUG_OBJECT (self, "Format changed from %d to %d", self->caps_format,
+ f->format);
+ caps_changed = TRUE;
+ self->caps_format = f->format;
+ } else {
+ g_mutex_unlock (&self->lock);
+ if (f)
+ capture_frame_free (f);
+ GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
+ ("Invalid pixel format in captured frame"),
+ ("Format set to %d but captured %d", self->caps_format, f->format));
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+ }
+
+ g_mutex_unlock (&self->lock);
+ if (caps_changed) {
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),
gst_message_new_latency (GST_OBJECT_CAST (self)));
gst_caps_unref (caps);
- } else {
- g_mutex_unlock (&self->lock);
+
}
f->frame->GetBytes ((gpointer *) & data);
const GstDecklinkMode *mode;
g_mutex_lock (&self->lock);
- if (self->caps_mode != GST_DECKLINK_MODE_AUTO)
- mode = gst_decklink_get_mode (self->caps_mode);
- else
- mode = gst_decklink_get_mode (self->mode);
+ mode = gst_decklink_get_mode (self->caps_mode);
g_mutex_unlock (&self->lock);
min = gst_util_uint64_scale_ceil (GST_SECOND, mode->fps_d, mode->fps_n);
ret = GST_STATE_CHANGE_FAILURE;
goto out;
}
+ if (self->mode == GST_DECKLINK_MODE_AUTO &&
+ self->video_format != GST_DECKLINK_VIDEO_FORMAT_AUTO) {
+ GST_WARNING_OBJECT (self, "Warning: mode=auto and format!=auto may \
+ not work");
+ }
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
g_mutex_lock (&self->input->lock);
gint device_number;
GstVideoInfo info;
+ GstDecklinkVideoFormat video_format;
GstDecklinkInput *input;