decklink: Add a default profile id

This causes no changes to the profile but keeps the existing settings.
The profile can also be changed from e.g. the card's configuration
application and in that case probably should be left alone.

The default is the new value as it keeps the profile setting as it is,
which is consistent with the previous behaviour in 1.18.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1721>
This commit is contained in:
Sebastian Dröge 2020-10-25 13:30:55 +02:00
parent d1df412d70
commit 56b2130300
7 changed files with 56 additions and 63 deletions

View file

@ -8089,7 +8089,7 @@
"construct": true,
"construct-only": false,
"controllable": false,
"default": "one-sub-device-full (0)",
"default": "default (0)",
"mutable": "null",
"readable": true,
"type": "GstDecklinkProfileId",
@ -8262,7 +8262,7 @@
"construct": true,
"construct-only": false,
"controllable": false,
"default": "one-sub-device-full (0)",
"default": "default (0)",
"mutable": "null",
"readable": true,
"type": "GstDecklinkProfileId",
@ -8673,30 +8673,35 @@
"GstDecklinkProfileId": {
"kind": "enum",
"values": [
{
"desc": "Default, don't change profile",
"name": "default",
"value": "0"
},
{
"desc": "One sub-device, Full-Duplex",
"name": "one-sub-device-full",
"value": "0"
"value": "1"
},
{
"desc": "One sub-device, Half-Duplex",
"name": "one-sub-device-half",
"value": "1"
"value": "2"
},
{
"desc": "Two sub-devices, Full-Duplex",
"name": "two-sub-devices-full",
"value": "2"
"value": "3"
},
{
"desc": "Two sub-devices, Half-Duplex",
"name": "two-sub-devices-half",
"value": "3"
"value": "4"
},
{
"desc": "Four sub-devices, Half-Duplex",
"name": "four-sub-devices-half",
"value": "4"
"value": "5"
}
]
},

View file

@ -158,6 +158,7 @@ gst_decklink_video_format_get_type (void)
/**
* GstDecklinkProfileId:
* @GST_DECKLINK_PROFILE_ID_DEFAULT: Don't change the profile
* @GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX: Equivalent to bmdProfileOneSubDeviceFullDuplex
* @GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_HALF_DUPLEX: Equivalent to bmdProfileOneSubDeviceHalfDuplex
* @GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_FULL_DUPLEX: Equivalent to bmdProfileTwoSubDevicesFullDuplex
@ -173,6 +174,7 @@ gst_decklink_profile_id_get_type (void)
{
static gsize id = 0;
static const GEnumValue types[] = {
{GST_DECKLINK_PROFILE_ID_DEFAULT, "Default, don't change profile", "default"},
{GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX, "One sub-device, Full-Duplex", "one-sub-device-full"},
{GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_HALF_DUPLEX, "One sub-device, Half-Duplex", "one-sub-device-half"},
{GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_FULL_DUPLEX, "Two sub-devices, Full-Duplex", "two-sub-devices-full"},
@ -366,20 +368,6 @@ static const struct
/* *INDENT-ON* */
};
static const struct
{
BMDProfileID profile;
GstDecklinkProfileId gstprofile;
} profiles[] = {
/* *INDENT-OFF* */
{bmdProfileOneSubDeviceFullDuplex, GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX},
{bmdProfileOneSubDeviceHalfDuplex, GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_HALF_DUPLEX},
{bmdProfileTwoSubDevicesFullDuplex, GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_FULL_DUPLEX},
{bmdProfileTwoSubDevicesHalfDuplex, GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_HALF_DUPLEX},
{bmdProfileFourSubDevicesHalfDuplex, GST_DECKLINK_PROFILE_ID_FOUR_SUB_DEVICES_HALF_DUPLEX},
/* *INDENT-ON* */
};
enum ProfileSetOperationResult
{
PROFILE_SET_UNSUPPORTED,
@ -614,25 +602,6 @@ gst_decklink_timecode_format_to_enum (BMDTimecodeFormat f)
return GST_DECKLINK_TIMECODE_FORMAT_RP188ANY;
}
const BMDProfileID
gst_decklink_profile_id_from_enum (GstDecklinkProfileId p)
{
return profiles[p].profile;
}
const GstDecklinkProfileId
gst_decklink_profile_id_to_enum (BMDProfileID p)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (profiles); i++) {
if (profiles[i].profile == p)
return profiles[i].gstprofile;
}
g_assert_not_reached ();
return GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX;
}
const BMDKeyerMode
gst_decklink_keyer_mode_from_enum (GstDecklinkKeyerMode m)
{
@ -885,7 +854,7 @@ struct _Device
};
static ProfileSetOperationResult gst_decklink_configure_profile (Device * device,
BMDProfileID profile_id);
GstDecklinkProfileId profile_id);
class GStreamerDecklinkInputCallback:public IDeckLinkInputCallback
{
@ -1826,20 +1795,46 @@ gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio)
}
static ProfileSetOperationResult
gst_decklink_configure_profile (Device * device, BMDProfileID profile_id)
gst_decklink_configure_profile (Device * device, GstDecklinkProfileId profile_id)
{
HRESULT res;
if (profile_id == GST_DECKLINK_PROFILE_ID_DEFAULT)
return PROFILE_SET_SUCCESS;
GstDecklinkInput *input = &device->input;
IDeckLink *decklink = input->device;
IDeckLinkProfileManager *manager = NULL;
if (decklink->QueryInterface(IID_IDeckLinkProfileManager, (void **)&manager) == S_OK) {
BMDProfileID bmd_profile_id;
switch (profile_id) {
case GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX:
bmd_profile_id = bmdProfileOneSubDeviceFullDuplex;
break;
case GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_HALF_DUPLEX:
bmd_profile_id = bmdProfileOneSubDeviceHalfDuplex;
break;
case GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_FULL_DUPLEX:
bmd_profile_id = bmdProfileTwoSubDevicesFullDuplex;
break;
case GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_HALF_DUPLEX:
bmd_profile_id = bmdProfileTwoSubDevicesHalfDuplex;
break;
case GST_DECKLINK_PROFILE_ID_FOUR_SUB_DEVICES_HALF_DUPLEX:
bmd_profile_id = bmdProfileFourSubDevicesHalfDuplex;
break;
default:
case GST_DECKLINK_PROFILE_ID_DEFAULT:
g_assert_not_reached ();
break;
}
IDeckLinkProfile *profile = NULL;
res = manager->GetProfile(profile_id, &profile);
res = manager->GetProfile(bmd_profile_id, &profile);
if (res == S_OK) {
if (res == S_OK && profile) {
res = profile->SetActive();
profile->Release();
}
@ -1854,9 +1849,7 @@ gst_decklink_configure_profile (Device * device, BMDProfileID profile_id)
GST_ERROR("Failed to set profile.\n");
return PROFILE_SET_FAILURE;
}
}
else {
} else {
GST_DEBUG("Device has only one profile.\n");
return PROFILE_SET_UNSUPPORTED;
}

View file

@ -161,6 +161,7 @@ typedef enum {
GType gst_decklink_video_format_get_type (void);
typedef enum {
GST_DECKLINK_PROFILE_ID_DEFAULT,
GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX, /* bmdProfileOneSubDeviceFullDuplex */
GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_HALF_DUPLEX, /* bmdProfileOneSubDeviceHalfDuplex */
GST_DECKLINK_PROFILE_ID_TWO_SUB_DEVICES_FULL_DUPLEX, /* bmdProfileTwoSubDevicesFullDuplex */

View file

@ -360,7 +360,7 @@ gst_decklink_video_sink_class_init (GstDecklinkVideoSinkClass * klass)
"same profile group."
"DeckLink Duo 2 support configuration of the duplex mode of "
"individual sub-devices.",
GST_TYPE_DECKLINK_PROFILE_ID, GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX,
GST_TYPE_DECKLINK_PROFILE_ID, GST_DECKLINK_PROFILE_ID_DEFAULT,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT)));
@ -428,7 +428,7 @@ gst_decklink_video_sink_init (GstDecklinkVideoSink * self)
self->mode = GST_DECKLINK_MODE_NTSC;
self->device_number = 0;
self->video_format = GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV;
self->profile_id = bmdProfileOneSubDeviceFullDuplex;
self->profile_id = GST_DECKLINK_PROFILE_ID_DEFAULT;
/* VITC is legacy, we should expect RP188 in modern use cases */
self->timecode_format = bmdTimecodeRP188Any;
self->caption_line = 0;
@ -467,9 +467,7 @@ gst_decklink_video_sink_set_property (GObject * object, guint property_id,
}
break;
case PROP_PROFILE_ID:
self->profile_id =
gst_decklink_profile_id_from_enum ((GstDecklinkProfileId)
g_value_get_enum (value));
self->profile_id = (GstDecklinkProfileId) g_value_get_enum (value);
break;
case PROP_TIMECODE_FORMAT:
self->timecode_format =
@ -513,8 +511,7 @@ gst_decklink_video_sink_get_property (GObject * object, guint property_id,
g_value_set_enum (value, self->video_format);
break;
case PROP_PROFILE_ID:
g_value_set_enum (value,
gst_decklink_profile_id_to_enum (self->profile_id));
g_value_set_enum (value, self->profile_id);
break;
case PROP_TIMECODE_FORMAT:
g_value_set_enum (value,

View file

@ -52,7 +52,7 @@ struct _GstDecklinkVideoSink
GstDecklinkModeEnum mode;
gint device_number;
GstDecklinkVideoFormat video_format;
BMDProfileID profile_id;
GstDecklinkProfileId profile_id;
BMDTimecodeFormat timecode_format;
BMDKeyerMode keyer_mode;
gint keyer_level;

View file

@ -317,7 +317,7 @@ gst_decklink_video_src_class_init (GstDecklinkVideoSrcClass * klass)
"same profile group."
"DeckLink Duo 2 support configuration of the duplex mode of "
"individual sub-devices.",
GST_TYPE_DECKLINK_PROFILE_ID, GST_DECKLINK_PROFILE_ID_ONE_SUB_DEVICE_FULL_DUPLEX,
GST_TYPE_DECKLINK_PROFILE_ID, GST_DECKLINK_PROFILE_ID_DEFAULT,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT)));
@ -393,7 +393,7 @@ gst_decklink_video_src_init (GstDecklinkVideoSrc * self)
self->device_number = 0;
self->buffer_size = DEFAULT_BUFFER_SIZE;
self->video_format = GST_DECKLINK_VIDEO_FORMAT_AUTO;
self->profile_id = bmdProfileOneSubDeviceFullDuplex;
self->profile_id = GST_DECKLINK_PROFILE_ID_DEFAULT;
self->timecode_format = bmdTimecodeRP188Any;
self->signal_state = SIGNAL_STATE_UNKNOWN;
self->output_stream_time = DEFAULT_OUTPUT_STREAM_TIME;
@ -469,9 +469,7 @@ gst_decklink_video_src_set_property (GObject * object, guint property_id,
}
break;
case PROP_PROFILE_ID:
self->profile_id =
gst_decklink_profile_id_from_enum ((GstDecklinkProfileId)
g_value_get_enum (value));
self->profile_id = (GstDecklinkProfileId) g_value_get_enum (value);
break;
case PROP_TIMECODE_FORMAT:
self->timecode_format =
@ -522,8 +520,7 @@ gst_decklink_video_src_get_property (GObject * object, guint property_id,
g_value_set_enum (value, self->video_format);
break;
case PROP_PROFILE_ID:
g_value_set_enum (value,
gst_decklink_profile_id_to_enum (self->profile_id));
g_value_set_enum (value, self->profile_id);
break;
case PROP_TIMECODE_FORMAT:
g_value_set_enum (value,

View file

@ -71,7 +71,7 @@ struct _GstDecklinkVideoSrc
GstVideoInfo info;
GstDecklinkVideoFormat video_format;
BMDProfileID profile_id;
GstDecklinkProfileId profile_id;
BMDTimecodeFormat timecode_format;
GstDecklinkInput *input;