decklinkvideosink: Made "auto" mode work according to caps

When the mode of decklinkvideosink is set to "auto", the sink claims to
support the full set of caps that it can support for all modes. Then, every
time new caps are set, the sink will automatically find the correct mode for
these caps and set it.

Caveat: We have no way to know whether a specific mode will actually work for
your hardware. Therefore, if you try sending 4K video to a 1080 screen, it
will silently fail, we have no way to know that in advance. Manually setting
that mode at least gave the user a way to double-check what they are doing.

https://bugzilla.gnome.org/show_bug.cgi?id=759600
This commit is contained in:
Vivia Nikolaidou 2015-12-17 17:26:29 +02:00 committed by Sebastian Dröge
parent 40d0c1aec0
commit fafc8e564c
4 changed files with 36 additions and 5 deletions

View file

@ -358,6 +358,24 @@ gst_decklink_mode_get_template_caps (void)
return caps;
}
const GstDecklinkMode *
gst_decklink_find_mode_for_caps (GstCaps * caps)
{
int i;
GstCaps *mode_caps;
for (i = 1; i < (int) G_N_ELEMENTS (modes); i++) {
mode_caps = gst_decklink_mode_get_caps ((GstDecklinkModeEnum) i);
if (gst_caps_can_intersect (caps, mode_caps)) {
gst_caps_unref (mode_caps);
return gst_decklink_get_mode ((GstDecklinkModeEnum) i);
}
gst_caps_unref (mode_caps);
}
return NULL;
}
#define GST_TYPE_DECKLINK_CLOCK \
(gst_decklink_clock_get_type())
#define GST_DECKLINK_CLOCK(obj) \

View file

@ -192,4 +192,6 @@ GstClock * gst_decklink_output_get_audio_clock (GstDecklinkOutput * out
GstDecklinkInput * gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio);
void gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio);
const GstDecklinkMode * gst_decklink_find_mode_for_caps (GstCaps * caps);
#endif

View file

@ -688,8 +688,7 @@ gst_decklink_audio_src_stop (GstDecklinkAudioSrc * self)
{
GST_DEBUG_OBJECT (self, "Stopping");
g_queue_foreach (&self->current_packets, (GFunc) capture_packet_free,
NULL);
g_queue_foreach (&self->current_packets, (GFunc) capture_packet_free, NULL);
g_queue_clear (&self->current_packets);
if (self->input && self->input->audio_enabled) {

View file

@ -292,8 +292,17 @@ gst_decklink_video_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
self->output->output->SetScheduledFrameCompletionCallback (new
GStreamerVideoOutputCallback (self));
mode = gst_decklink_get_mode (self->mode);
g_assert (mode != NULL);
if (self->mode == GST_DECKLINK_MODE_AUTO) {
mode = gst_decklink_find_mode_for_caps (caps);
if (mode == NULL) {
GST_WARNING_OBJECT (self,
"Failed to find compatible mode for caps %" GST_PTR_FORMAT, caps);
return FALSE;
}
} else {
mode = gst_decklink_get_mode (self->mode);
g_assert (mode != NULL);
};
ret = self->output->output->EnableVideoOutput (mode->mode,
bmdVideoOutputFlagDefault);
@ -318,7 +327,10 @@ gst_decklink_video_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
GstDecklinkVideoSink *self = GST_DECKLINK_VIDEO_SINK_CAST (bsink);
GstCaps *mode_caps, *caps;
mode_caps = gst_decklink_mode_get_caps (self->mode);
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_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);