diff --git a/.indent_cpp_list b/.indent_cpp_list index e84f1e7815..276506df84 100644 --- a/.indent_cpp_list +++ b/.indent_cpp_list @@ -14,6 +14,7 @@ subprojects/gst-plugins-bad/sys/d3d11 subprojects/gst-plugins-bad/sys/d3d12 subprojects/gst-plugins-bad/sys/dwrite subprojects/gst-plugins-bad/sys/hip +^(subprojects/gst-plugins-bad/sys/decklink2/)+(\w)+([^/])+(cpp$) subprojects/gst-plugins-bad/sys/mediafoundation subprojects/gst-plugins-bad/sys/nvcodec ^(subprojects/gst-plugins-bad/sys/qsv/)+(\w)+([^/])+(cpp$) diff --git a/subprojects/gst-libav/ext/libav/gstavdemux.c b/subprojects/gst-libav/ext/libav/gstavdemux.c index d530c2743d..ea0462a9c7 100644 --- a/subprojects/gst-libav/ext/libav/gstavdemux.c +++ b/subprojects/gst-libav/ext/libav/gstavdemux.c @@ -648,7 +648,7 @@ gst_ffmpegdemux_perform_seek (GstFFMpegDemux * demux, GstEvent * event) /* and restart the task in case it got paused explicitely or by * the FLUSH_START event we pushed out. */ gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop, - demux->sinkpad, NULL); + gst_object_ref (demux->sinkpad), gst_object_unref); /* and release the lock again so we can continue streaming */ GST_PAD_STREAM_UNLOCK (demux->sinkpad); @@ -1965,7 +1965,7 @@ gst_ffmpegdemux_sink_activate_pull (GstPad * sinkpad, GstObject * parent, if (active) { demux->seekable = TRUE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop, - demux, NULL); + gst_object_ref (demux), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); demux->seekable = FALSE; diff --git a/subprojects/gst-libav/ext/libav/gstavviddec.c b/subprojects/gst-libav/ext/libav/gstavviddec.c index e21f3e1558..3a5a88cd5a 100644 --- a/subprojects/gst-libav/ext/libav/gstavviddec.c +++ b/subprojects/gst-libav/ext/libav/gstavviddec.c @@ -2136,9 +2136,10 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec, GstVideoInfo *info = &ffmpegdec->output_state->info; if (vmeta->width != GST_VIDEO_INFO_WIDTH (info) || vmeta->height != GST_VIDEO_INFO_HEIGHT (info)) { - g_error ("video meta uses %dx%d instead of %dx%d", + GST_ERROR_OBJECT (ffmpegdec, "video meta uses %dx%d instead of %dx%d", vmeta->width, vmeta->height, GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info)); + GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (output_frame); } } } diff --git a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json index 340a28ca36..ffbbfc0890 100644 --- a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json @@ -18811,6 +18811,18 @@ "type": "gboolean", "writable": true }, + "ignore-flushing": { + "blurb": "Whether to ignore GST_FLOW_FLUSHING", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, "ignore-notlinked": { "blurb": "Whether to ignore GST_FLOW_NOT_LINKED", "conditionally-available": false, @@ -21406,6 +21418,1264 @@ "tracers": {}, "url": "Unknown package origin" }, + "decklink2": { + "description": "Blackmagic Decklink plugin", + "elements": { + "decklink2combiner": { + "author": "Seungha Yang ", + "description": "Combines video and audio frames", + "hierarchy": [ + "GstDeckLink2Combiner", + "GstAggregator", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Combiner", + "pad-templates": { + "audio": { + "caps": "audio/x-raw:\n format: { S16LE, S32LE }\n rate: 48000\n channels: { (int)2, (int)8, (int)16 }\n layout: interleaved\n", + "direction": "sink", + "presence": "always", + "type": "GstAggregatorPad" + }, + "src": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n", + "direction": "src", + "presence": "always", + "type": "GstAggregatorPad" + }, + "video": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n", + "direction": "sink", + "presence": "always", + "type": "GstAggregatorPad" + } + }, + "rank": "none" + }, + "decklink2demux": { + "author": "Seungha Yang ", + "description": "Decklink2 Demux", + "hierarchy": [ + "GstDeckLink2Demux", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Video/Audio/Demuxer/Hardware", + "pad-templates": { + "audio": { + "caps": "audio/x-raw:\n format: { S16LE, S32LE }\n rate: 48000\n channels: { (int)2, (int)8, (int)16 }\n layout: interleaved\n", + "direction": "src", + "presence": "sometimes" + }, + "sink": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n", + "direction": "sink", + "presence": "always" + }, + "video": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n", + "direction": "src", + "presence": "always" + } + }, + "rank": "none" + }, + "decklink2sink": { + "author": "Seungha Yang ", + "description": "Decklink2 Sink", + "hierarchy": [ + "GstDeckLink2Sink", + "GstBaseSink", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Video/Audio/Sink/Hardware", + "pad-templates": { + "sink": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n audio-channels: { (int)0, (int)2, (int)8, (int)16 }\n", + "direction": "sink", + "presence": "always" + } + }, + "properties": { + "afd-bar-line": { + "blurb": "Line number to use for inserting AFD/Bar data (0 = disabled)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "10000", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "cc-line": { + "blurb": "Line number to use for inserting closed captions (0 = disabled)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "22", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "device-number": { + "blurb": "Output device instance to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "2147483647", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "keyer-level": { + "blurb": "Keyer level", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "255", + "max": "255", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "keyer-mode": { + "blurb": "Keyer mode to be enabled", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "off (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2KeyerMode", + "writable": true + }, + "mapping-format": { + "blurb": "3G-SDI Mapping Format (Level A/B)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "default (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2MappingFormat", + "writable": true + }, + "max-buffered-frames": { + "blurb": "Max number of frames to buffer before dropping", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "14", + "max": "16", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "min-buffered-frames": { + "blurb": "Min number of frames to buffer before duplicating", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "3", + "max": "16", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "mode": { + "blurb": "Video Mode to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (1769303659)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2Mode", + "writable": true + }, + "n-preroll-frames": { + "blurb": "How many frames to preroll before starting scheduled playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "7", + "max": "16", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "persistent-id": { + "blurb": "Output device instance to use. Higher priority than \"device-number\".", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "18446744073709551615", + "max": "9223372036854775807", + "min": "-1", + "mutable": "ready", + "readable": true, + "type": "gint64", + "writable": true + }, + "profile": { + "blurb": "Certain DeckLink devices such as the DeckLink 8K Pro, the DeckLink Quad 2 and the DeckLink Duo 2 support multiple profiles to configure the capture and playback behavior of its sub-devices.For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2 sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile is shared between all 4 sub-devices. Any sub-devices that share a profile are considered to be part of the same profile group.DeckLink Duo 2 support configuration of the duplex mode of individual sub-devices.", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "default (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2ProfileId", + "writable": true + }, + "timecode-format": { + "blurb": "Timecode format type to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "rp188any (1919955256)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2TimecodeFormat", + "writable": true + }, + "video-format": { + "blurb": "Video format type to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "8bit-yuv (846624121)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2VideoFormat", + "writable": true + } + }, + "rank": "none" + }, + "decklink2src": { + "author": "Seungha Yang ", + "description": "Decklink2 Source", + "hierarchy": [ + "GstDeckLink2Src", + "GstPushSrc", + "GstBaseSrc", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "klass": "Video/Audio/Source/Hardware", + "pad-templates": { + "src": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "audio-channels": { + "blurb": "Audio Channels", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "2 (2)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2AudioChannels", + "writable": true + }, + "audio-connection": { + "blurb": "Audio input connection to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2AudioConnection", + "writable": true + }, + "buffer-size": { + "blurb": "Size of internal buffer in number of video frames", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "5", + "max": "16", + "min": "1", + "mutable": "ready", + "readable": true, + "type": "guint", + "writable": true + }, + "device-number": { + "blurb": "Output device instance to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "2147483647", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "mode": { + "blurb": "Video Mode to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (1769303659)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2Mode", + "writable": true + }, + "output-afd-bar": { + "blurb": "Extract and output AFD/Bar as GstMeta (if present)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "ready", + "readable": true, + "type": "gboolean", + "writable": true + }, + "output-cc": { + "blurb": "Extract and output CC as GstMeta (if present)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "ready", + "readable": true, + "type": "gboolean", + "writable": true + }, + "persistent-id": { + "blurb": "Output device instance to use. Higher priority than \"device-number\".", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "18446744073709551615", + "max": "9223372036854775807", + "min": "-1", + "mutable": "ready", + "readable": true, + "type": "gint64", + "writable": true + }, + "profile": { + "blurb": "Certain DeckLink devices such as the DeckLink 8K Pro, the DeckLink Quad 2 and the DeckLink Duo 2 support multiple profiles to configure the capture and playback behavior of its sub-devices.For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2 sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile is shared between all 4 sub-devices. Any sub-devices that share a profile are considered to be part of the same profile group.DeckLink Duo 2 support configuration of the duplex mode of individual sub-devices.", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "default (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2ProfileId", + "writable": true + }, + "signal": { + "blurb": "True if there is a valid input signal available", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": false + }, + "timecode-format": { + "blurb": "Timecode format type to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "rp188any (1919955256)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2TimecodeFormat", + "writable": true + }, + "video-connection": { + "blurb": "Video input connection to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2VideoConnection", + "writable": true + }, + "video-format": { + "blurb": "Video format type to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "8bit-yuv (846624121)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2VideoFormat", + "writable": true + } + }, + "rank": "none" + }, + "decklink2srcbin": { + "author": "Seungha Yang ", + "description": "Decklink2 Source Bin", + "hierarchy": [ + "GstDeckLink2SrcBin", + "GstBin", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstChildProxy" + ], + "klass": "Video/Audio/Source/Hardware", + "pad-templates": { + "audio": { + "caps": "audio/x-raw:\n format: { S16LE, S32LE }\n rate: 48000\n channels: { (int)2, (int)8, (int)16 }\n layout: interleaved\n", + "direction": "src", + "presence": "sometimes" + }, + "video": { + "caps": "video/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 10/11\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 12/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: interleaved\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 486\npixel-aspect-ratio: 40/33\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 720\n height: 576\npixel-aspect-ratio: 16/11\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1920\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: interleaved\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 1280\n height: 720\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1556\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 2048\n height: 1080\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 3840\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 4096\n height: 2160\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 7680\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 24/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 25/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 30/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 50/1\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60000/1001\n format: { UYVY, v210, ARGB, BGRA }\nvideo/x-raw:\n width: 8192\n height: 4320\npixel-aspect-ratio: 1/1\n interlace-mode: progressive\n framerate: 60/1\n format: { UYVY, v210, ARGB, BGRA }\n", + "direction": "src", + "presence": "always" + } + }, + "properties": { + "audio-channels": { + "blurb": "Audio Channels", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "2 (2)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2AudioChannels", + "writable": true + }, + "audio-connection": { + "blurb": "Audio input connection to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2AudioConnection", + "writable": true + }, + "buffer-size": { + "blurb": "Size of internal buffer in number of video frames", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "5", + "max": "16", + "min": "1", + "mutable": "ready", + "readable": true, + "type": "guint", + "writable": true + }, + "device-number": { + "blurb": "Output device instance to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "2147483647", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "gint", + "writable": true + }, + "mode": { + "blurb": "Video Mode to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (1769303659)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2Mode", + "writable": true + }, + "output-afd-bar": { + "blurb": "Extract and output AFD/Bar as GstMeta (if present)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "ready", + "readable": true, + "type": "gboolean", + "writable": true + }, + "output-cc": { + "blurb": "Extract and output CC as GstMeta (if present)", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "ready", + "readable": true, + "type": "gboolean", + "writable": true + }, + "persistent-id": { + "blurb": "Output device instance to use. Higher priority than \"device-number\".", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "18446744073709551615", + "max": "9223372036854775807", + "min": "-1", + "mutable": "ready", + "readable": true, + "type": "gint64", + "writable": true + }, + "profile": { + "blurb": "Certain DeckLink devices such as the DeckLink 8K Pro, the DeckLink Quad 2 and the DeckLink Duo 2 support multiple profiles to configure the capture and playback behavior of its sub-devices.For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2 sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile is shared between all 4 sub-devices. Any sub-devices that share a profile are considered to be part of the same profile group.DeckLink Duo 2 support configuration of the duplex mode of individual sub-devices.", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "default (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2ProfileId", + "writable": true + }, + "signal": { + "blurb": "True if there is a valid input signal available", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": false + }, + "timecode-format": { + "blurb": "Timecode format type to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "rp188any (1919955256)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2TimecodeFormat", + "writable": true + }, + "video-connection": { + "blurb": "Video input connection to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (0)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2VideoConnection", + "writable": true + }, + "video-format": { + "blurb": "Video format type to use for playback", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "8bit-yuv (846624121)", + "mutable": "ready", + "readable": true, + "type": "GstDeckLink2VideoFormat", + "writable": true + } + }, + "rank": "none" + } + }, + "filename": "gstdecklink2", + "license": "LGPL", + "other-types": { + "GstDeckLink2AudioChannels": { + "kind": "enum", + "values": [ + { + "desc": "Disabled", + "name": "disabled", + "value": "-1" + }, + { + "desc": "2 Channels", + "name": "2", + "value": "2" + }, + { + "desc": "8 Channels", + "name": "8", + "value": "8" + }, + { + "desc": "16 Channels", + "name": "16", + "value": "16" + }, + { + "desc": "Maximum channels supported", + "name": "max", + "value": "0" + } + ] + }, + "GstDeckLink2AudioConnection": { + "kind": "enum", + "values": [ + { + "desc": "Auto", + "name": "auto", + "value": "0" + }, + { + "desc": "SDI/HDMI embedded audio", + "name": "embedded", + "value": "1" + }, + { + "desc": "AES/EBU", + "name": "aes", + "value": "2" + }, + { + "desc": "Analog", + "name": "analog", + "value": "4" + }, + { + "desc": "Analog (XLR)", + "name": "analog-xlr", + "value": "8" + }, + { + "desc": "Analog (RCA)", + "name": "analog-rca", + "value": "16" + } + ] + }, + "GstDeckLink2KeyerMode": { + "kind": "enum", + "values": [ + { + "desc": "Off", + "name": "off", + "value": "0" + }, + { + "desc": "Internal", + "name": "internal", + "value": "1" + }, + { + "desc": "External", + "name": "external", + "value": "2" + } + ] + }, + "GstDeckLink2MappingFormat": { + "kind": "enum", + "values": [ + { + "desc": "Default, don't change mapping format", + "name": "default", + "value": "0" + }, + { + "desc": "Level A", + "name": "level-a", + "value": "1" + }, + { + "desc": "Level B", + "name": "level-b", + "value": "2" + } + ] + }, + "GstDeckLink2Mode": { + "kind": "enum", + "values": [ + { + "desc": "Automatic detection", + "name": "auto", + "value": "1769303659" + }, + { + "desc": "NTSC SD 60i", + "name": "ntsc", + "value": "1853125475" + }, + { + "desc": "NTSC SD 60i (24 fps)", + "name": "ntsc2398", + "value": "1853108787" + }, + { + "desc": "PAL SD 50i", + "name": "pal", + "value": "1885432864" + }, + { + "desc": "NTSC SD 60p", + "name": "ntsc-p", + "value": "1853125488" + }, + { + "desc": "PAL SD 50p", + "name": "pal-p", + "value": "1885432944" + }, + { + "desc": "NTSC SD 60i Widescreen", + "name": "ntsc-widescreen", + "value": "1314149187" + }, + { + "desc": "NTSC SD 60i Widescreen (24 fps)", + "name": "ntsc2398-widescreen", + "value": "1314140723" + }, + { + "desc": "PAL SD 50i Widescreen", + "name": "pal-widescreen", + "value": "1346456608" + }, + { + "desc": "NTSC SD 60p Widescreen", + "name": "ntsc-p-widescreen", + "value": "1314149200" + }, + { + "desc": "PAL SD 50p Widescreen", + "name": "pal-p-widescreen", + "value": "1346456656" + }, + { + "desc": "HD1080 23.98p", + "name": "1080p2398", + "value": "842231923" + }, + { + "desc": "HD1080 24p", + "name": "1080p24", + "value": "842297459" + }, + { + "desc": "HD1080 25p", + "name": "1080p25", + "value": "1215312437" + }, + { + "desc": "HD1080 29.97p", + "name": "1080p2997", + "value": "1215312441" + }, + { + "desc": "HD1080 30p", + "name": "1080p30", + "value": "1215312688" + }, + { + "desc": "HD1080 50p", + "name": "1080p50", + "value": "1215313200" + }, + { + "desc": "HD1080 59.94p", + "name": "1080p5994", + "value": "1215313209" + }, + { + "desc": "HD1080 60p", + "name": "1080p60", + "value": "1215313456" + }, + { + "desc": "HD1080 50i", + "name": "1080i50", + "value": "1214854448" + }, + { + "desc": "HD1080 59.94i", + "name": "1080i5994", + "value": "1214854457" + }, + { + "desc": "HD1080 60i", + "name": "1080i60", + "value": "1214854704" + }, + { + "desc": "HD720 50p", + "name": "720p50", + "value": "1752184112" + }, + { + "desc": "HD720 59.94p", + "name": "720p5994", + "value": "1752184121" + }, + { + "desc": "HD720 60p", + "name": "720p60", + "value": "1752184368" + }, + { + "desc": "2k 23.98p", + "name": "1556p2398", + "value": "845886003" + }, + { + "desc": "2k 24p", + "name": "1556p24", + "value": "845886004" + }, + { + "desc": "2k 25p", + "name": "1556p25", + "value": "845886005" + }, + { + "desc": "2k dci 23.98p", + "name": "2kdcip2398", + "value": "845427251" + }, + { + "desc": "2k dci 24p", + "name": "2kdcip24", + "value": "845427252" + }, + { + "desc": "2k dci 25p", + "name": "2kdcip25", + "value": "845427253" + }, + { + "desc": "2k dci 29.97p", + "name": "2kdcip2997", + "value": "845427257" + }, + { + "desc": "2k dci 30p", + "name": "2kdcip30", + "value": "845427504" + }, + { + "desc": "2k dci 50p", + "name": "2kdcip50", + "value": "845428016" + }, + { + "desc": "2k dci 59.94p", + "name": "2kdcip5994", + "value": "845428025" + }, + { + "desc": "2k dci 60p", + "name": "2kdcip60", + "value": "845428272" + }, + { + "desc": "4k 23.98p", + "name": "2160p2398", + "value": "879440435" + }, + { + "desc": "4k 24p", + "name": "2160p24", + "value": "879440436" + }, + { + "desc": "4k 25p", + "name": "2160p25", + "value": "879440437" + }, + { + "desc": "4k 29.97p", + "name": "2160p2997", + "value": "879440441" + }, + { + "desc": "4k 30p", + "name": "2160p30", + "value": "879440688" + }, + { + "desc": "4k 50p", + "name": "2160p50", + "value": "879441200" + }, + { + "desc": "4k 59.94p", + "name": "2160p5994", + "value": "879441209" + }, + { + "desc": "4k 60p", + "name": "2160p60", + "value": "879441456" + }, + { + "desc": "4k dci 23.98p", + "name": "4kdcip2398", + "value": "878981683" + }, + { + "desc": "4k dci 24p", + "name": "4kdcip24", + "value": "878981684" + }, + { + "desc": "4k dci 25p", + "name": "4kdcip25", + "value": "878981685" + }, + { + "desc": "4k dci 29.97p", + "name": "4kdcip2997", + "value": "878981689" + }, + { + "desc": "4k dci 30p", + "name": "4kdcip30", + "value": "878981936" + }, + { + "desc": "4k dci 50p", + "name": "4kdcip50", + "value": "878982448" + }, + { + "desc": "4k dci 59.94p", + "name": "4kdcip5994", + "value": "878982457" + }, + { + "desc": "4k dci 60p", + "name": "4kdcip60", + "value": "878982704" + }, + { + "desc": "8k 23.98p", + "name": "8kp2398", + "value": "946549299" + }, + { + "desc": "8k 24p", + "name": "8kp24", + "value": "946549300" + }, + { + "desc": "8k 25p", + "name": "8kp25", + "value": "946549301" + }, + { + "desc": "8k 29.97p", + "name": "8kp2997", + "value": "946549305" + }, + { + "desc": "8k 30p", + "name": "8kp30", + "value": "946549552" + }, + { + "desc": "8k 50p", + "name": "8kp50", + "value": "946550064" + }, + { + "desc": "8k 59.94p", + "name": "8kp5994", + "value": "946550073" + }, + { + "desc": "8k 60p", + "name": "8kp60", + "value": "946550320" + }, + { + "desc": "8k dci 23.98p", + "name": "8kdcip2398", + "value": "946090547" + }, + { + "desc": "8k dci 24p", + "name": "8kdcip24", + "value": "946090548" + }, + { + "desc": "8k dci 25p", + "name": "8kdcip25", + "value": "946090549" + }, + { + "desc": "8k dci 29.97p", + "name": "8kdcip2997", + "value": "946090553" + }, + { + "desc": "8k dci 30p", + "name": "8kdcip30", + "value": "946090800" + }, + { + "desc": "8k dci 50p", + "name": "8kdcip50", + "value": "946091312" + }, + { + "desc": "8k dci 59.94p", + "name": "8kdcip5994", + "value": "946091321" + }, + { + "desc": "8k dci 60p", + "name": "8kdcip60", + "value": "946091568" + } + ] + }, + "GstDeckLink2ProfileId": { + "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": "828663396" + }, + { + "desc": "One sub-device, Half-Duplex", + "name": "one-sub-device-half", + "value": "828663908" + }, + { + "desc": "Two sub-devices, Full-Duplex", + "name": "two-sub-devices-full", + "value": "845440612" + }, + { + "desc": "Two sub-devices, Half-Duplex", + "name": "two-sub-devices-half", + "value": "845441124" + }, + { + "desc": "Four sub-devices, Half-Duplex", + "name": "four-sub-devices-half", + "value": "878995556" + } + ] + }, + "GstDeckLink2TimecodeFormat": { + "kind": "enum", + "values": [ + { + "desc": "bmdTimecodeRP188VITC1", + "name": "rp188vitc1", + "value": "1919972913" + }, + { + "desc": "bmdTimecodeRP188VITC2", + "name": "rp188vitc2", + "value": "1919955250" + }, + { + "desc": "bmdTimecodeRP188LTC", + "name": "rp188ltc", + "value": "1919970420" + }, + { + "desc": "bmdTimecodeRP188Any", + "name": "rp188any", + "value": "1919955256" + }, + { + "desc": "bmdTimecodeVITC", + "name": "vitc", + "value": "1986622563" + }, + { + "desc": "bmdTimecodeVITCField2", + "name": "vitcfield2", + "value": "1986622514" + }, + { + "desc": "bmdTimecodeSerial", + "name": "serial", + "value": "1936028265" + } + ] + }, + "GstDeckLink2VideoConnection": { + "kind": "enum", + "values": [ + { + "desc": "Auto", + "name": "auto", + "value": "0" + }, + { + "desc": "SDI", + "name": "sdi", + "value": "1" + }, + { + "desc": "HDMI", + "name": "hdmi", + "value": "2" + }, + { + "desc": "Optical SDI", + "name": "optical-sdi", + "value": "4" + }, + { + "desc": "Component", + "name": "component", + "value": "8" + }, + { + "desc": "Composite", + "name": "composite", + "value": "16" + }, + { + "desc": "S-Video", + "name": "svideo", + "value": "32" + } + ] + }, + "GstDeckLink2VideoFormat": { + "kind": "enum", + "values": [ + { + "desc": "Auto", + "name": "auto", + "value": "0" + }, + { + "desc": "bmdFormat8BitYUV", + "name": "8bit-yuv", + "value": "846624121" + }, + { + "desc": "bmdFormat10BitYUV", + "name": "10bit-yuv", + "value": "1983000880" + }, + { + "desc": "bmdFormat8BitARGB", + "name": "8bit-argb", + "value": "32" + }, + { + "desc": "bmdFormat8BitBGRA", + "name": "8bit-bgra", + "value": "1111970369" + } + ] + } + }, + "package": "GStreamer Bad Plug-ins", + "source": "gst-plugins-bad", + "tracers": {}, + "url": "Unknown package origin" + }, "directfb": { "description": "DirectFB video output plugin", "elements": { diff --git a/subprojects/gst-plugins-bad/ext/dtls/gstdtlsenc.c b/subprojects/gst-plugins-bad/ext/dtls/gstdtlsenc.c index 4f2b38e584..e4fafca7ae 100644 --- a/subprojects/gst-plugins-bad/ext/dtls/gstdtlsenc.c +++ b/subprojects/gst-plugins-bad/ext/dtls/gstdtlsenc.c @@ -477,8 +477,8 @@ src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, self->src_ret = GST_FLOW_OK; self->send_initial_events = TRUE; success = - gst_pad_start_task (pad, (GstTaskFunction) src_task_loop, self->src, - NULL); + gst_pad_start_task (pad, (GstTaskFunction) src_task_loop, + gst_object_ref (self->src), gst_object_unref); if (!success) { GST_WARNING_OBJECT (self, "failed to activate pad task"); } diff --git a/subprojects/gst-plugins-bad/ext/gme/gstgme.c b/subprojects/gst-plugins-bad/ext/gme/gstgme.c index 15d9476ba0..e8f7f76bbd 100644 --- a/subprojects/gst-plugins-bad/ext/gme/gstgme.c +++ b/subprojects/gst-plugins-bad/ext/gme/gstgme.c @@ -258,7 +258,7 @@ gst_gme_dec_src_event (GstPad * pad, GstObject * parent, GstEvent * event) gme->seeking = TRUE; gst_pad_start_task (gme->srcpad, (GstTaskFunction) gst_gme_play, - gme->srcpad, NULL); + gst_object_ref (gme->srcpad), gst_object_unref); GST_PAD_STREAM_UNLOCK (gme->srcpad); result = TRUE; @@ -461,8 +461,8 @@ gme_setup (GstGmeDec * gme) gst_segment_init (&seg, GST_FORMAT_TIME); gst_pad_push_event (gme->srcpad, gst_event_new_segment (&seg)); - gst_pad_start_task (gme->srcpad, (GstTaskFunction) gst_gme_play, gme->srcpad, - NULL); + gst_pad_start_task (gme->srcpad, (GstTaskFunction) gst_gme_play, + gst_object_ref (gme->srcpad), gst_object_unref); gme->initialized = TRUE; gme->seeking = FALSE; diff --git a/subprojects/gst-plugins-bad/ext/modplug/gstmodplug.cc b/subprojects/gst-plugins-bad/ext/modplug/gstmodplug.cc index 4ced9f1cf5..34998829e5 100644 --- a/subprojects/gst-plugins-bad/ext/modplug/gstmodplug.cc +++ b/subprojects/gst-plugins-bad/ext/modplug/gstmodplug.cc @@ -392,7 +392,7 @@ gst_modplug_do_seek (GstModPlug * modplug, GstEvent * event) gst_util_uint64_scale_int (cur, modplug->frequency, GST_SECOND); gst_pad_start_task (modplug->sinkpad, - (GstTaskFunction) gst_modplug_loop, modplug, NULL); + (GstTaskFunction) gst_modplug_loop, gst_object_ref (modplug), gst_object_unref); GST_PAD_STREAM_UNLOCK (modplug->sinkpad); @@ -586,7 +586,7 @@ gst_modplug_sinkpad_activate_mode (GstPad * pad, GstObject * parent, case GST_PAD_MODE_PULL: if (active) { res = gst_pad_start_task (pad, (GstTaskFunction) gst_modplug_loop, - modplug, NULL); + gst_object_ref (modplug), gst_object_unref); } else { res = gst_pad_stop_task (pad); } diff --git a/subprojects/gst-plugins-bad/ext/mpeg2enc/gstmpeg2enc.cc b/subprojects/gst-plugins-bad/ext/mpeg2enc/gstmpeg2enc.cc index 73c8d8021b..1699a8b32c 100644 --- a/subprojects/gst-plugins-bad/ext/mpeg2enc/gstmpeg2enc.cc +++ b/subprojects/gst-plugins-bad/ext/mpeg2enc/gstmpeg2enc.cc @@ -717,7 +717,7 @@ gst_mpeg2enc_handle_frame (GstVideoEncoder * video_encoder, if (!enc->started) { GST_DEBUG_OBJECT (video_encoder, "handle_frame: START task"); gst_pad_start_task (video_encoder->srcpad, - (GstTaskFunction) gst_mpeg2enc_loop, enc, NULL); + (GstTaskFunction) gst_mpeg2enc_loop, gst_object_ref (enc), gst_object_unref); enc->started = TRUE; } diff --git a/subprojects/gst-plugins-bad/ext/mplex/gstmplex.cc b/subprojects/gst-plugins-bad/ext/mplex/gstmplex.cc index 6e2e5e4dbe..b5806c4df7 100644 --- a/subprojects/gst-plugins-bad/ext/mplex/gstmplex.cc +++ b/subprojects/gst-plugins-bad/ext/mplex/gstmplex.cc @@ -533,8 +533,8 @@ gst_mplex_start_task (GstMplex * mplex) if (G_UNLIKELY (mplex->srcresult == GST_FLOW_CUSTOM_SUCCESS) && mplex->job->video_tracks == mplex->num_vpads && mplex->job->audio_tracks == mplex->num_apads) { - gst_pad_start_task (mplex->srcpad, (GstTaskFunction) gst_mplex_loop, mplex, - NULL); + gst_pad_start_task (mplex->srcpad, (GstTaskFunction) gst_mplex_loop, gst_object_ref (mplex), + gst_object_unref); mplex->srcresult = GST_FLOW_OK; } } diff --git a/subprojects/gst-plugins-bad/ext/musepack/gstmusepackdec.c b/subprojects/gst-plugins-bad/ext/musepack/gstmusepackdec.c index de449294ca..3d02800d8b 100644 --- a/subprojects/gst-plugins-bad/ext/musepack/gstmusepackdec.c +++ b/subprojects/gst-plugins-bad/ext/musepack/gstmusepackdec.c @@ -233,7 +233,8 @@ gst_musepackdec_handle_seek_event (GstMusepackDec * dec, GstEvent * event) GST_DEBUG_OBJECT (dec, "seek successful"); gst_pad_start_task (dec->sinkpad, - (GstTaskFunction) gst_musepackdec_loop, dec->sinkpad, NULL); + (GstTaskFunction) gst_musepackdec_loop, gst_object_ref (dec->sinkpad), + gst_object_unref); GST_PAD_STREAM_UNLOCK (dec->sinkpad); @@ -473,7 +474,8 @@ gst_musepackdec_sink_activate_mode (GstPad * sinkpad, GstObject * parent, case GST_PAD_MODE_PULL: if (active) { result = gst_pad_start_task (sinkpad, - (GstTaskFunction) gst_musepackdec_loop, sinkpad, NULL); + (GstTaskFunction) gst_musepackdec_loop, gst_object_ref (sinkpad), + gst_object_unref); } else { result = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-bad/ext/openjpeg/gstopenjpegdec.c b/subprojects/gst-plugins-bad/ext/openjpeg/gstopenjpegdec.c index 950b06d9bf..05ed9da0e7 100644 --- a/subprojects/gst-plugins-bad/ext/openjpeg/gstopenjpegdec.c +++ b/subprojects/gst-plugins-bad/ext/openjpeg/gstopenjpegdec.c @@ -1534,7 +1534,8 @@ gst_openjpeg_dec_decode_frame_multiple (GstVideoDecoder * decoder, if (!self->started) { GST_DEBUG_OBJECT (self, "Starting task"); gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_openjpeg_dec_loop, decoder, NULL); + (GstTaskFunction) gst_openjpeg_dec_loop, gst_object_ref (decoder), + gst_object_unref); self->started = TRUE; } /* Make sure to release the base class stream lock, otherwise diff --git a/subprojects/gst-plugins-bad/ext/resindvd/gstmpegdemux.c b/subprojects/gst-plugins-bad/ext/resindvd/gstmpegdemux.c index 02ce48a53f..c3e66bbeb5 100644 --- a/subprojects/gst-plugins-bad/ext/resindvd/gstmpegdemux.c +++ b/subprojects/gst-plugins-bad/ext/resindvd/gstmpegdemux.c @@ -2136,7 +2136,7 @@ gst_flups_demux_sink_activate_pull (GstPad * sinkpad, GstObject * parent, GST_DEBUG ("pull mode activated"); demux->random_access = TRUE; return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flups_demux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { demux->random_access = FALSE; return gst_pad_stop_task (sinkpad); diff --git a/subprojects/gst-plugins-bad/ext/sctp/gstsctpdec.c b/subprojects/gst-plugins-bad/ext/sctp/gstsctpdec.c index 7603912a87..e3a9086b11 100644 --- a/subprojects/gst-plugins-bad/ext/sctp/gstsctpdec.c +++ b/subprojects/gst-plugins-bad/ext/sctp/gstsctpdec.c @@ -406,7 +406,8 @@ flush_srcpad (const GValue * item, gpointer user_data) } else { gst_data_queue_set_flushing (sctpdec_pad->packet_queue, FALSE); gst_pad_start_task (GST_PAD (sctpdec_pad), - (GstTaskFunction) gst_sctp_data_srcpad_loop, sctpdec_pad, NULL); + (GstTaskFunction) gst_sctp_data_srcpad_loop, + gst_object_ref (sctpdec_pad), gst_object_unref); } } @@ -552,8 +553,8 @@ gst_sctp_dec_src_event (GstPad * pad, GstSctpDec * self, GstEvent * event) /* Unflush and start task again */ gst_data_queue_set_flushing (sctpdec_pad->packet_queue, FALSE); - gst_pad_start_task (pad, (GstTaskFunction) gst_sctp_data_srcpad_loop, pad, - NULL); + gst_pad_start_task (pad, (GstTaskFunction) gst_sctp_data_srcpad_loop, + gst_object_ref (pad), gst_object_unref); return gst_pad_event_default (pad, GST_OBJECT (self), event); } @@ -634,7 +635,7 @@ get_pad_for_stream_id (GstSctpDec * self, guint16 stream_id) GST_OBJECT_UNLOCK (self); gst_pad_start_task (new_pad, (GstTaskFunction) gst_sctp_data_srcpad_loop, - new_pad, NULL); + gst_object_ref (new_pad), gst_object_unref); gst_object_ref (new_pad); diff --git a/subprojects/gst-plugins-bad/ext/sctp/gstsctpenc.c b/subprojects/gst-plugins-bad/ext/sctp/gstsctpenc.c index c8b66be0cd..981a56af4c 100644 --- a/subprojects/gst-plugins-bad/ext/sctp/gstsctpenc.c +++ b/subprojects/gst-plugins-bad/ext/sctp/gstsctpenc.c @@ -397,7 +397,8 @@ gst_sctp_enc_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_READY_TO_PAUSED: if (ret != GST_STATE_CHANGE_FAILURE) gst_pad_start_task (self->src_pad, - (GstTaskFunction) gst_sctp_enc_srcpad_loop, self->src_pad, NULL); + (GstTaskFunction) gst_sctp_enc_srcpad_loop, + gst_object_ref (self->src_pad), gst_object_unref); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; @@ -820,7 +821,8 @@ gst_sctp_enc_src_event (GstPad * pad, GstObject * parent, GstEvent * event) self->src_ret = GST_FLOW_OK; GST_OBJECT_UNLOCK (self); gst_pad_start_task (self->src_pad, - (GstTaskFunction) gst_sctp_enc_srcpad_loop, self->src_pad, NULL); + (GstTaskFunction) gst_sctp_enc_srcpad_loop, + gst_object_ref (self->src_pad), gst_object_unref); ret = gst_pad_event_default (pad, parent, event); break; diff --git a/subprojects/gst-plugins-bad/ext/sndfile/gstsfdec.c b/subprojects/gst-plugins-bad/ext/sndfile/gstsfdec.c index 20a61cb5ca..5aaa0998fd 100644 --- a/subprojects/gst-plugins-bad/ext/sndfile/gstsfdec.c +++ b/subprojects/gst-plugins-bad/ext/sndfile/gstsfdec.c @@ -260,7 +260,8 @@ gst_sf_dec_do_seek (GstSFDec * self, GstEvent * event) gst_pad_push_event (self->srcpad, gst_event_new_segment (&seg)); gst_pad_start_task (self->sinkpad, - (GstTaskFunction) gst_sf_dec_loop, self, NULL); + (GstTaskFunction) gst_sf_dec_loop, gst_object_ref (self), + gst_object_unref); GST_PAD_STREAM_UNLOCK (self->sinkpad); @@ -459,7 +460,7 @@ gst_sf_dec_sink_activate_mode (GstPad * sinkpad, GstObject * parent, /* if we have a scheduler we can start the task */ GST_DEBUG_OBJECT (sinkpad, "start task"); res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_sf_dec_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-bad/ext/sndfile/gstsfsink.c b/subprojects/gst-plugins-bad/ext/sndfile/gstsfsink.c index bd1bb9dad4..761b9c9014 100644 --- a/subprojects/gst-plugins-bad/ext/sndfile/gstsfsink.c +++ b/subprojects/gst-plugins-bad/ext/sndfile/gstsfsink.c @@ -455,7 +455,8 @@ gst_sf_sink_activate_pull (GstBaseSink * basesink, gboolean active) if (active) { /* start task */ result = gst_pad_start_task (basesink->sinkpad, - (GstTaskFunction) gst_sf_sink_loop, basesink->sinkpad, NULL); + (GstTaskFunction) gst_sf_sink_loop, gst_object_ref (basesink->sinkpad), + gst_object_unref); } else { /* step 2, make sure streaming finishes */ result = gst_pad_stop_task (basesink->sinkpad); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/audio/gstnonstreamaudiodecoder.c b/subprojects/gst-plugins-bad/gst-libs/gst/audio/gstnonstreamaudiodecoder.c index e8da770d61..5acdc55da6 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/audio/gstnonstreamaudiodecoder.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/audio/gstnonstreamaudiodecoder.c @@ -1486,8 +1486,8 @@ static gboolean gst_nonstream_audio_decoder_start_task (GstNonstreamAudioDecoder * dec) { if (!gst_pad_start_task (dec->srcpad, - (GstTaskFunction) gst_nonstream_audio_decoder_output_task, dec, - NULL)) { + (GstTaskFunction) gst_nonstream_audio_decoder_output_task, + gst_object_ref (dec), gst_object_unref)) { GST_ERROR_OBJECT (dec, "could not start decoder output task"); return FALSE; } else diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmsesrc.c b/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmsesrc.c index 6939514a25..3c9fbbd02f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmsesrc.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/mse/gstmsesrc.c @@ -834,7 +834,8 @@ resume_all_streams (GstMseSrc * self) GstPad *pad = GST_PAD (stream->pad); if (active) { clear_flushing (GST_MSE_SRC_PAD (pad)); - gst_pad_start_task (pad, (GstTaskFunction) pad_task, pad, NULL); + gst_pad_start_task (pad, (GstTaskFunction) pad_task, gst_object_ref (pad), + gst_object_unref); } } } @@ -1111,7 +1112,8 @@ pad_activate_mode (GstMseSrcPad * pad, GstObject * parent, GstPadMode mode, } if (active) { - gst_pad_start_task (GST_PAD (pad), (GstTaskFunction) pad_task, pad, NULL); + gst_pad_start_task (GST_PAD (pad), (GstTaskFunction) pad_task, + gst_object_ref (pad), gst_object_unref); } else { set_flushing_and_signal (pad); gst_media_source_track_flush (pad->track); diff --git a/subprojects/gst-plugins-bad/gst/aiff/aiffparse.c b/subprojects/gst-plugins-bad/gst/aiff/aiffparse.c index 1e8c955b79..8609d86a18 100644 --- a/subprojects/gst-plugins-bad/gst/aiff/aiffparse.c +++ b/subprojects/gst-plugins-bad/gst/aiff/aiffparse.c @@ -526,7 +526,7 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event, aiff->segment_running = TRUE; if (!aiff->streaming) { gst_pad_start_task (aiff->sinkpad, (GstTaskFunction) gst_aiff_parse_loop, - aiff->sinkpad, NULL); + gst_object_ref (aiff->sinkpad), gst_object_unref); } GST_PAD_STREAM_UNLOCK (aiff->sinkpad); @@ -1821,7 +1821,7 @@ gst_aiff_parse_sink_activate_mode (GstPad * sinkpad, GstObject * parent, aiff->segment_running = TRUE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_aiff_parse_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { aiff->segment_running = FALSE; res = gst_pad_stop_task (sinkpad); diff --git a/subprojects/gst-plugins-bad/gst/closedcaption/gstccconverter.c b/subprojects/gst-plugins-bad/gst/closedcaption/gstccconverter.c index 5290253272..9837f912c5 100644 --- a/subprojects/gst-plugins-bad/gst/closedcaption/gstccconverter.c +++ b/subprojects/gst-plugins-bad/gst/closedcaption/gstccconverter.c @@ -1566,14 +1566,20 @@ can_generate_output (GstCCConverter * self) /* compute the relative frame count for each */ if (!gst_util_fraction_multiply (self->in_fps_d, self->in_fps_n, - self->input_frames, 1, &input_frame_n, &input_frame_d)) - /* we should never overflow */ - g_assert_not_reached (); + self->input_frames, 1, &input_frame_n, &input_frame_d)) { + GST_ERROR_OBJECT (self, + "Couldn't get input rate, fps: %d/%d, input frames %d", + self->in_fps_n, self->in_fps_d, self->input_frames); + return FALSE; + } if (!gst_util_fraction_multiply (self->out_fps_d, self->out_fps_n, - self->output_frames, 1, &output_frame_n, &output_frame_d)) - /* we should never overflow */ - g_assert_not_reached (); + self->output_frames, 1, &output_frame_n, &output_frame_d)) { + GST_ERROR_OBJECT (self, + "Couldn't get output rate, fps: %d/%d, output frames %d", + self->out_fps_n, self->out_fps_d, self->output_frames); + return FALSE; + } output_time_cmp = gst_util_fraction_compare (input_frame_n, input_frame_d, output_frame_n, output_frame_d); diff --git a/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.c b/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.c index 8b44df039b..aaae65308b 100644 --- a/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.c +++ b/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.c @@ -45,8 +45,11 @@ enum { PROP_0, PROP_REMOVE_CAPTION_META, + PROP_FORCE_EXPOSE_CAPTION_PAD, }; +#define DEFAULT_FORCE_EXPOSE_CAPTION_PAD FALSE + static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, @@ -112,6 +115,23 @@ gst_cc_extractor_class_init (GstCCExtractorClass * klass) "Remove caption meta from outgoing video buffers", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstCCExtractor:force-expose-caption-pad + * + * Exposes caption pad on the first buffer even if caption meta is not + * attached on the buffer. When this mode is used, user should configure + * ccconverter element so that downstream can handle any caption type update. + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_FORCE_EXPOSE_CAPTION_PAD, + g_param_spec_boolean ("force-expose-caption-pad", + "Force expose caption pad", + "Force expose caption pad on the first buffer", + DEFAULT_FORCE_EXPOSE_CAPTION_PAD, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY | + G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_cc_extractor_change_state); @@ -340,15 +360,9 @@ forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data) } static GstFlowReturn -gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf, - GstVideoCaptionMeta * meta, GstVideoTimeCodeMeta * tc_meta) +gst_cc_extractor_ensure_caption_pad (GstCCExtractor * filter, + GstVideoCaptionType caption_type) { - GstBuffer *outbuf = NULL; - GstFlowReturn flow; - - GST_DEBUG_OBJECT (filter, "Handling meta"); - - /* Check if the meta type matches the configured one */ if (filter->captionpad == NULL) { GST_DEBUG_OBJECT (filter, "Creating new caption pad"); @@ -359,24 +373,55 @@ gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf, GST_DEBUG_FUNCPTR (gst_cc_extractor_iterate_internal_links)); gst_pad_set_active (filter->captionpad, TRUE); - filter->caption_type = meta->caption_type; + /* When force_expose_caption_pad == TRUE */ + if (caption_type == GST_VIDEO_CAPTION_TYPE_UNKNOWN) { + GstCaps *caps = NULL; - gst_pad_sticky_events_foreach (filter->sinkpad, forward_sticky_events, - filter); + /* caption type is unknow at this moment. Adds caption pad first and + * picks one caption type supported by downstream (if it's linked) */ + gst_element_add_pad (GST_ELEMENT (filter), filter->captionpad); + gst_flow_combiner_add_pad (filter->combiner, filter->captionpad); - if (!gst_pad_has_current_caps (filter->captionpad)) { - GST_ERROR_OBJECT (filter, "Unknown/invalid caption type"); - return GST_FLOW_NOT_NEGOTIATED; - } + /* caption pad may be linked on pad-added signal, then query downstream */ + caps = gst_pad_get_allowed_caps (filter->captionpad); + if (!caps || gst_caps_is_any (caps)) { + gst_clear_caps (&caps); + caps = gst_pad_get_pad_template_caps (filter->captionpad); + } + + caps = gst_caps_fixate (caps); + caption_type = gst_video_caption_type_from_caps (caps); + gst_caps_unref (caps); + + if (caption_type == GST_VIDEO_CAPTION_TYPE_UNKNOWN) { + GST_ERROR_OBJECT (filter, "Failed to determine CC type"); + return GST_FLOW_NOT_NEGOTIATED; + } + + filter->caption_type = caption_type; - gst_element_add_pad (GST_ELEMENT (filter), filter->captionpad); - gst_flow_combiner_add_pad (filter->combiner, filter->captionpad); - } else if (meta->caption_type != filter->caption_type) { + gst_pad_sticky_events_foreach (filter->sinkpad, forward_sticky_events, + filter); + } else { + filter->caption_type = caption_type; + + gst_pad_sticky_events_foreach (filter->sinkpad, forward_sticky_events, + filter); + + if (!gst_pad_has_current_caps (filter->captionpad)) { + GST_ERROR_OBJECT (filter, "Unknown/invalid caption type"); + return GST_FLOW_NOT_NEGOTIATED; + } + + gst_element_add_pad (GST_ELEMENT (filter), filter->captionpad); + gst_flow_combiner_add_pad (filter->combiner, filter->captionpad); + } + } else if (caption_type != filter->caption_type) { GstCaps *caption_caps = - create_caps_from_caption_type (meta->caption_type, &filter->video_info); + create_caps_from_caption_type (caption_type, &filter->video_info); GST_DEBUG_OBJECT (filter, "Caption type changed from %d to %d", - filter->caption_type, meta->caption_type); + filter->caption_type, caption_type); if (caption_caps == NULL) { GST_ERROR_OBJECT (filter, "Unknown/invalid caption type"); return GST_FLOW_NOT_NEGOTIATED; @@ -385,9 +430,25 @@ gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf, gst_pad_push_event (filter->captionpad, gst_event_new_caps (caption_caps)); gst_caps_unref (caption_caps); - filter->caption_type = meta->caption_type; + filter->caption_type = caption_type; } + return GST_FLOW_OK; +} + +static GstFlowReturn +gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf, + GstVideoCaptionMeta * meta, GstVideoTimeCodeMeta * tc_meta) +{ + GstBuffer *outbuf = NULL; + GstFlowReturn flow; + + GST_DEBUG_OBJECT (filter, "Handling meta"); + + flow = gst_cc_extractor_ensure_caption_pad (filter, meta->caption_type); + if (flow != GST_FLOW_OK) + return flow; + GST_DEBUG_OBJECT (filter, "Creating new buffer of size %" G_GSIZE_FORMAT " bytes", meta->size); /* Extract caption data into new buffer with identical buffer timestamps */ @@ -428,6 +489,9 @@ gst_cc_extractor_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) gboolean had_cc_meta = FALSE; gpointer iter = NULL; + if (filter->force_expose_caption_pad) + flow = gst_cc_extractor_ensure_caption_pad (filter, filter->caption_type); + tc_meta = gst_buffer_get_video_time_code_meta (buf); while ((cc_meta = @@ -513,6 +577,9 @@ gst_cc_extractor_set_property (GObject * object, guint prop_id, case PROP_REMOVE_CAPTION_META: filter->remove_caption_meta = g_value_get_boolean (value); break; + case PROP_FORCE_EXPOSE_CAPTION_PAD: + filter->force_expose_caption_pad = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -529,6 +596,9 @@ gst_cc_extractor_get_property (GObject * object, guint prop_id, GValue * value, case PROP_REMOVE_CAPTION_META: g_value_set_boolean (value, filter->remove_caption_meta); break; + case PROP_FORCE_EXPOSE_CAPTION_PAD: + g_value_set_boolean (value, filter->force_expose_caption_pad); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.h b/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.h index 36b0ef9bf4..1532b5266f 100644 --- a/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.h +++ b/subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.h @@ -52,6 +52,7 @@ struct _GstCCExtractor GstFlowCombiner *combiner; gboolean remove_caption_meta; + gboolean force_expose_caption_pad; }; struct _GstCCExtractorClass diff --git a/subprojects/gst-plugins-bad/gst/closedcaption/gstline21dec.c b/subprojects/gst-plugins-bad/gst/closedcaption/gstline21dec.c index 4e5b7702c6..661711af27 100644 --- a/subprojects/gst-plugins-bad/gst/closedcaption/gstline21dec.c +++ b/subprojects/gst-plugins-bad/gst/closedcaption/gstline21dec.c @@ -490,6 +490,7 @@ gst_line_21_decoder_scan (GstLine21Decoder * self, GstVideoFrame * frame) gint i; vbi_sliced sliced[52]; gboolean found = FALSE; + gboolean dual_lines = TRUE; guint8 *data; if (self->mode == GST_LINE_21_DECODER_MODE_DROP && @@ -511,13 +512,14 @@ gst_line_21_decoder_scan (GstLine21Decoder * self, GstVideoFrame * frame) for (; i < self->max_line_probes && i < GST_VIDEO_FRAME_HEIGHT (frame); i++) { gint n_lines; data = get_video_data (self, frame, i); - /* Scan until we get n_lines == 2 */ + /* Scan until we get n_lines == 2 (or 1 if only 1 line present) */ n_lines = vbi_raw_decode (&self->zvbi_decoder, data, sliced); GST_DEBUG_OBJECT (self, "i:%d n_lines:%d", i, n_lines); - if (n_lines == 2) { - GST_DEBUG_OBJECT (self, "Found 2 CC lines at offset %d", i); + if (n_lines == 2 || n_lines == 1) { + GST_DEBUG_OBJECT (self, "Found %d CC lines at offset %d", n_lines, i); self->line21_offset = i; found = TRUE; + dual_lines = n_lines == 2; break; } else if (i == self->line21_offset) { /* Otherwise if this was the previously probed line offset, @@ -550,9 +552,11 @@ gst_line_21_decoder_scan (GstLine21Decoder * self, GstVideoFrame * frame) ccdata[0] |= (base_line1 < i ? i - base_line1 : 0) & 0x1f; ccdata[1] = sliced[0].data[0]; ccdata[2] = sliced[0].data[1]; - ccdata[3] |= (base_line2 < i ? i - base_line2 : 0) & 0x1f; - ccdata[4] = sliced[1].data[0]; - ccdata[5] = sliced[1].data[1]; + if (dual_lines) { + ccdata[3] |= (base_line2 < i ? i - base_line2 : 0) & 0x1f; + ccdata[4] = sliced[1].data[0]; + ccdata[5] = sliced[1].data[1]; + } gst_buffer_add_video_caption_meta (frame->buffer, GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A, ccdata, 6); GST_TRACE_OBJECT (self, diff --git a/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.c b/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.c index f9b6a29077..b31b6ef2eb 100644 --- a/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.c +++ b/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.c @@ -53,6 +53,7 @@ enum PROP_IGNORE_EOS, PROP_CONVERT_TO, PROP_POST_WARNINGS, + PROP_IGNORE_FLUSHING, }; static void gst_error_ignore_set_property (GObject * object, guint prop_id, @@ -151,6 +152,16 @@ gst_error_ignore_class_init (GstErrorIgnoreClass * klass) g_param_spec_boolean ("post-warnings", "Post warnings", "Whether to post warnings on first flow conversion", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstErrorIgnore:ignore-flushing: + * + * Since: 1.30 + */ + g_object_class_install_property (object_class, PROP_IGNORE_FLUSHING, + g_param_spec_boolean ("ignore-flushing", + "Ignore GST_FLOW_FLUSHING", "Whether to ignore GST_FLOW_FLUSHING", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -178,6 +189,7 @@ gst_error_ignore_init (GstErrorIgnore * self) self->ignore_notlinked = FALSE; self->ignore_notnegotiated = TRUE; self->ignore_eos = FALSE; + self->ignore_flushing = FALSE; self->convert_to = GST_FLOW_NOT_LINKED; self->post_warnings = TRUE; } @@ -207,6 +219,9 @@ gst_error_ignore_set_property (GObject * object, guint prop_id, case PROP_POST_WARNINGS: self->post_warnings = g_value_get_boolean (value); break; + case PROP_IGNORE_FLUSHING: + self->ignore_flushing = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -238,6 +253,9 @@ gst_error_ignore_get_property (GObject * object, guint prop_id, GValue * value, case PROP_POST_WARNINGS: g_value_set_boolean (value, self->post_warnings); break; + case PROP_IGNORE_FLUSHING: + g_value_set_boolean (value, self->ignore_flushing); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -286,7 +304,8 @@ gst_error_ignore_sink_chain (GstPad * pad, GstObject * parent, if ((ret == GST_FLOW_ERROR && self->ignore_error) || (ret == GST_FLOW_NOT_LINKED && self->ignore_notlinked) || (ret == GST_FLOW_EOS && self->ignore_eos) || - (ret == GST_FLOW_NOT_NEGOTIATED && self->ignore_notnegotiated)) { + (ret == GST_FLOW_NOT_NEGOTIATED && self->ignore_notnegotiated) || + (ret == GST_FLOW_FLUSHING && self->ignore_flushing)) { if (warn) { GST_ELEMENT_WARNING (self, STREAM, FAILED, diff --git a/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.h b/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.h index bc2aba6149..55f1aeefa1 100644 --- a/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.h +++ b/subprojects/gst-plugins-bad/gst/debugutils/gsterrorignore.h @@ -46,6 +46,7 @@ struct _GstErrorIgnore { gboolean ignore_notnegotiated; gboolean ignore_eos; gboolean post_warnings; + gboolean ignore_flushing; GstFlowReturn convert_to; }; diff --git a/subprojects/gst-plugins-bad/gst/meson.build b/subprojects/gst-plugins-bad/gst/meson.build index 92a2529b8e..24bd198cc7 100644 --- a/subprojects/gst-plugins-bad/gst/meson.build +++ b/subprojects/gst-plugins-bad/gst/meson.build @@ -12,6 +12,7 @@ foreach plugin : ['accurip', 'adpcmdec', 'adpcmenc', 'aiff', 'asfmux', 'rawparse', 'removesilence', 'rist', 'rtmp2', 'rtp', 'sdp', 'segmentclip', 'siren', 'smooth', 'speed', 'subenc', 'switchbin', 'tensordecoders', 'timecode', 'transcode', 'unixfd', 'videofilters', + 'streamselector', 'videoframe_audiolevel', 'videoparsers', 'videosignal', 'vmnc'] subdir(plugin) diff --git a/subprojects/gst-plugins-bad/gst/midi/midiparse.c b/subprojects/gst-plugins-bad/gst/midi/midiparse.c index 413b6f0157..2bbf796015 100644 --- a/subprojects/gst-plugins-bad/gst/midi/midiparse.c +++ b/subprojects/gst-plugins-bad/gst/midi/midiparse.c @@ -373,7 +373,8 @@ gst_midi_parse_perform_seek (GstMidiParse * midiparse, GstEvent * event) * the FLUSH_START event we pushed out. */ tres = gst_pad_start_task (midiparse->sinkpad, - (GstTaskFunction) gst_midi_parse_loop, midiparse->sinkpad, NULL); + (GstTaskFunction) gst_midi_parse_loop, + gst_object_ref (midiparse->sinkpad), gst_object_unref); if (res && !tres) res = FALSE; @@ -454,7 +455,7 @@ gst_midi_parse_activatemode (GstPad * pad, GstObject * parent, case GST_PAD_MODE_PULL: if (active) { res = gst_pad_start_task (pad, (GstTaskFunction) gst_midi_parse_loop, - pad, NULL); + gst_object_ref (pad), gst_object_unref); } else { res = gst_pad_stop_task (pad); } @@ -1384,7 +1385,8 @@ gst_midi_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) midiparse->state = GST_MIDI_PARSE_STATE_PARSE; /* now start the parsing task */ res = gst_pad_start_task (midiparse->sinkpad, - (GstTaskFunction) gst_midi_parse_loop, midiparse->sinkpad, NULL); + (GstTaskFunction) gst_midi_parse_loop, + gst_object_ref (midiparse->sinkpad), gst_object_unref); /* don't forward the event */ gst_event_unref (event); break; diff --git a/subprojects/gst-plugins-bad/gst/mpegdemux/gstmpegdemux.c b/subprojects/gst-plugins-bad/gst/mpegdemux/gstmpegdemux.c index 091a6e4d6d..0cce0bea2f 100644 --- a/subprojects/gst-plugins-bad/gst/mpegdemux/gstmpegdemux.c +++ b/subprojects/gst-plugins-bad/gst/mpegdemux/gstmpegdemux.c @@ -1416,7 +1416,8 @@ gst_ps_demux_handle_seek_pull (GstPsDemux * demux, GstEvent * event) demux->segment_seqnum = seek_seqnum; gst_pad_start_task (demux->sinkpad, - (GstTaskFunction) gst_ps_demux_loop, demux->sinkpad, NULL); + (GstTaskFunction) gst_ps_demux_loop, gst_object_ref (demux->sinkpad), + gst_object_unref); GST_PAD_STREAM_UNLOCK (demux->sinkpad); @@ -3154,7 +3155,8 @@ gst_ps_demux_sink_activate_pull (GstPad * sinkpad, GstObject * parent, GST_DEBUG ("pull mode activated"); demux->random_access = TRUE; return gst_pad_start_task (sinkpad, - (GstTaskFunction) gst_ps_demux_loop, sinkpad, NULL); + (GstTaskFunction) gst_ps_demux_loop, gst_object_ref (sinkpad), + gst_object_unref); } else { demux->random_access = FALSE; return gst_pad_stop_task (sinkpad); diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c index e6bc57b2ec..4ecfad1546 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c @@ -2016,8 +2016,8 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad, flush_event = NULL; } - gst_pad_start_task (base->sinkpad, (GstTaskFunction) mpegts_base_loop, base, - NULL); + gst_pad_start_task (base->sinkpad, (GstTaskFunction) mpegts_base_loop, + gst_object_ref (base), gst_object_unref); GST_PAD_STREAM_UNLOCK (base->sinkpad); return ret == GST_FLOW_OK; @@ -2074,8 +2074,8 @@ mpegts_base_sink_activate_mode (GstPad * pad, GstObject * parent, base->packetizer->calculate_skew = FALSE; gst_segment_init (&base->segment, GST_FORMAT_BYTES); res = - gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, base, - NULL); + gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, + gst_object_ref (base), gst_object_unref); } else res = gst_pad_stop_task (pad); break; diff --git a/subprojects/gst-plugins-bad/gst/mxf/mxfdemux.c b/subprojects/gst-plugins-bad/gst/mxf/mxfdemux.c index b2e0d3454b..7b84df1941 100644 --- a/subprojects/gst-plugins-bad/gst/mxf/mxfdemux.c +++ b/subprojects/gst-plugins-bad/gst/mxf/mxfdemux.c @@ -5872,7 +5872,8 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) demux->seqnum = seqnum; gst_pad_start_task (demux->sinkpad, - (GstTaskFunction) gst_mxf_demux_loop, demux->sinkpad, NULL); + (GstTaskFunction) gst_mxf_demux_loop, gst_object_ref (demux->sinkpad), + gst_object_unref); GST_PAD_STREAM_UNLOCK (demux->sinkpad); @@ -5887,7 +5888,8 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) unresolved_metadata: { gst_pad_start_task (demux->sinkpad, - (GstTaskFunction) gst_mxf_demux_loop, demux->sinkpad, NULL); + (GstTaskFunction) gst_mxf_demux_loop, gst_object_ref (demux->sinkpad), + gst_object_unref); GST_PAD_STREAM_UNLOCK (demux->sinkpad); GST_WARNING_OBJECT (demux, "metadata can't be resolved"); return FALSE; @@ -5904,7 +5906,8 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) gst_mxf_demux_push_src_event (demux, e); } gst_pad_start_task (demux->sinkpad, - (GstTaskFunction) gst_mxf_demux_loop, demux->sinkpad, NULL); + (GstTaskFunction) gst_mxf_demux_loop, gst_object_ref (demux->sinkpad), + gst_object_unref); GST_PAD_STREAM_UNLOCK (demux->sinkpad); GST_WARNING_OBJECT (demux, "Requested seek position is not valid"); return FALSE; @@ -6114,7 +6117,7 @@ gst_mxf_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, if (active) { demux->random_access = TRUE; return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_mxf_demux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { demux->random_access = FALSE; return gst_pad_stop_task (sinkpad); diff --git a/subprojects/gst-plugins-bad/gst/netsim/gstnetsim.c b/subprojects/gst-plugins-bad/gst/netsim/gstnetsim.c index 48c6c64fda..0b550ab65e 100644 --- a/subprojects/gst-plugins-bad/gst/netsim/gstnetsim.c +++ b/subprojects/gst-plugins-bad/gst/netsim/gstnetsim.c @@ -165,7 +165,8 @@ gst_net_sim_src_activatemode (GstPad * pad, GstObject * parent, GST_TRACE_OBJECT (netsim, "ACT: Starting task on srcpad"); result = gst_pad_start_task (netsim->srcpad, - (GstTaskFunction) gst_net_sim_loop, netsim, NULL); + (GstTaskFunction) gst_net_sim_loop, gst_object_ref (netsim), + gst_object_unref); GST_TRACE_OBJECT (netsim, "ACT: Wait for task to start"); g_assert (!netsim->running); diff --git a/subprojects/gst-plugins-bad/gst/rist/gstristrtxsend.c b/subprojects/gst-plugins-bad/gst/rist/gstristrtxsend.c index e3083f24e0..aacdb5a0fc 100644 --- a/subprojects/gst-plugins-bad/gst/rist/gstristrtxsend.c +++ b/subprojects/gst-plugins-bad/gst/rist/gstristrtxsend.c @@ -490,7 +490,8 @@ gst_rist_rtx_send_sink_event (GstPad * pad, GstObject * parent, gst_pad_push_event (rtx->srcpad, event); gst_rist_rtx_send_set_flushing (rtx, FALSE); gst_pad_start_task (rtx->srcpad, - (GstTaskFunction) gst_rist_rtx_send_src_loop, rtx, NULL); + (GstTaskFunction) gst_rist_rtx_send_src_loop, gst_object_ref (rtx), + gst_object_unref); return TRUE; case GST_EVENT_EOS: GST_INFO_OBJECT (rtx, "Got EOS - enqueueing it"); @@ -717,7 +718,8 @@ gst_rist_rtx_send_activate_mode (GstPad * pad, GstObject * parent, if (active) { gst_rist_rtx_send_set_flushing (rtx, FALSE); ret = gst_pad_start_task (rtx->srcpad, - (GstTaskFunction) gst_rist_rtx_send_src_loop, rtx, NULL); + (GstTaskFunction) gst_rist_rtx_send_src_loop, gst_object_ref (rtx), + gst_object_unref); } else { gst_rist_rtx_send_set_flushing (rtx, TRUE); ret = gst_pad_stop_task (rtx->srcpad); diff --git a/subprojects/gst-plugins-bad/gst/streamselector/gststreamselector.c b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselector.c new file mode 100644 index 0000000000..84d7d93e69 --- /dev/null +++ b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselector.c @@ -0,0 +1,847 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:element-streamselector + * @title: streamselector + * + * Direct one out of N input streams to the output pad. + * + * Since: 1.24 + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gststreamselector.h" + +GST_DEBUG_CATEGORY_STATIC (stream_selector_debug); +#define GST_CAT_DEFAULT stream_selector_debug + +enum +{ + PROP_PAD_0, + PROP_PAD_ACTIVE, +}; + +struct _GstStreamSelectorPad +{ + GstAggregatorPad parent; + + GstCaps *caps; + GstEvent *tag_event; + gboolean active; + gboolean discont; + GstClockTime duration; +}; + +static void gst_stream_selector_pad_dispose (GObject * object); +static void gst_stream_selector_pad_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_stream_selector_pad_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static GstFlowReturn gst_stream_selector_pad_flush (GstAggregatorPad * pad, + GstAggregator * agg); +static void gst_stream_selector_set_active_pad (GstStreamSelector * self, + GstStreamSelectorPad * pad, gboolean active); + +#define gst_stream_selector_pad_parent_class pad_parent_class +G_DEFINE_TYPE (GstStreamSelectorPad, gst_stream_selector_pad, + GST_TYPE_AGGREGATOR_PAD); + +static void +gst_stream_selector_pad_class_init (GstStreamSelectorPadClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstAggregatorPadClass *aggpad_class = GST_AGGREGATOR_PAD_CLASS (klass); + + object_class->dispose = gst_stream_selector_pad_dispose; + object_class->set_property = gst_stream_selector_pad_set_property; + object_class->get_property = gst_stream_selector_pad_get_property; + + g_object_class_install_property (object_class, + PROP_PAD_ACTIVE, g_param_spec_boolean ("active", + "Active", "Active state of the pad", FALSE, + GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + aggpad_class->flush = GST_DEBUG_FUNCPTR (gst_stream_selector_pad_flush); +} + +static void +gst_stream_selector_pad_init (GstStreamSelectorPad * self) +{ + self->duration = GST_CLOCK_TIME_NONE; +} + +static void +gst_stream_selector_pad_dispose (GObject * object) +{ + GstStreamSelectorPad *self = GST_STREAM_SELECTOR_PAD (object); + + gst_clear_caps (&self->caps); + + G_OBJECT_CLASS (pad_parent_class)->dispose (object); +} + +static void +gst_stream_selector_pad_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstStreamSelectorPad *pad = GST_STREAM_SELECTOR_PAD (object); + GstStreamSelector *self = (GstStreamSelector *) + gst_object_get_parent (GST_OBJECT_CAST (object)); + + if (!self) { + GST_WARNING_OBJECT (pad, "No parent"); + return; + } + + switch (prop_id) { + case PROP_PAD_ACTIVE: + gst_stream_selector_set_active_pad (self, + pad, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + + gst_object_unref (self); +} + +static void +gst_stream_selector_pad_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstStreamSelectorPad *pad = GST_STREAM_SELECTOR_PAD (object); + + switch (prop_id) { + case PROP_PAD_ACTIVE: + g_value_set_boolean (value, pad->active); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstFlowReturn +gst_stream_selector_pad_flush (GstAggregatorPad * pad, GstAggregator * agg) +{ + GstStreamSelectorPad *self = GST_STREAM_SELECTOR_PAD (pad); + + gst_clear_event (&self->tag_event); + + return GST_FLOW_OK; +} + +static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink_%u", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +enum +{ + PROP_0, + PROP_IGNORE_INACTIVE_PADS, +}; + +struct _GstStreamSelector +{ + GstAggregator parent; + + /* Current active pad, updated on aggregate() */ + GstStreamSelectorPad *active_pad; +}; + +static void gst_stream_selector_child_proxy_init (gpointer g_iface, + gpointer iface_data); +static void gst_stream_selector_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_stream_selector_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static GstPad *gst_stream_selector_request_new_pad (GstElement * elem, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps); +static void gst_stream_selector_release_pad (GstElement * elem, GstPad * pad); +static gboolean gst_stream_selector_start (GstAggregator * agg); +static gboolean gst_stream_selector_stop (GstAggregator * agg); +static gboolean gst_stream_selector_sink_query (GstAggregator * agg, + GstAggregatorPad * pad, GstQuery * query); +static gboolean gst_stream_selector_sink_event (GstAggregator * agg, + GstAggregatorPad * pad, GstEvent * event); +static gboolean gst_stream_selector_src_query (GstAggregator * agg, + GstQuery * query); +static GstFlowReturn gst_stream_selector_aggregate (GstAggregator * agg, + gboolean timeout); + +#define gst_stream_selector_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstStreamSelector, gst_stream_selector, + GST_TYPE_AGGREGATOR, G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY, + gst_stream_selector_child_proxy_init)); +GST_ELEMENT_REGISTER_DEFINE (streamselector, "streamselector", + GST_RANK_NONE, GST_TYPE_STREAM_SELECTOR); + +static void +gst_stream_selector_class_init (GstStreamSelectorClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstAggregatorClass *agg_class = GST_AGGREGATOR_CLASS (klass); + + object_class->set_property = gst_stream_selector_set_property; + object_class->get_property = gst_stream_selector_get_property; + + g_object_class_install_property (object_class, + PROP_IGNORE_INACTIVE_PADS, g_param_spec_boolean ("ignore-inactive-pads", + "Ignore inactive pads", + "Avoid timing out waiting for inactive pads", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_stream_selector_request_new_pad); + element_class->release_pad = + GST_DEBUG_FUNCPTR (gst_stream_selector_release_pad); + + gst_element_class_add_static_pad_template_with_gtype (element_class, + &sink_templ, GST_TYPE_STREAM_SELECTOR_PAD); + gst_element_class_add_static_pad_template_with_gtype (element_class, + &src_templ, GST_TYPE_AGGREGATOR_PAD); + + gst_element_class_set_static_metadata (element_class, "Stream Selector", + "Generic", "N-to-1 input stream selector", + "Seungha Yang "); + + agg_class->start = GST_DEBUG_FUNCPTR (gst_stream_selector_start); + agg_class->stop = GST_DEBUG_FUNCPTR (gst_stream_selector_stop); + agg_class->sink_query = GST_DEBUG_FUNCPTR (gst_stream_selector_sink_query); + agg_class->sink_event = GST_DEBUG_FUNCPTR (gst_stream_selector_sink_event); + agg_class->src_query = GST_DEBUG_FUNCPTR (gst_stream_selector_src_query); + agg_class->aggregate = GST_DEBUG_FUNCPTR (gst_stream_selector_aggregate); + agg_class->get_next_time = + GST_DEBUG_FUNCPTR (gst_aggregator_simple_get_next_time); + agg_class->negotiate = NULL; + + gst_type_mark_as_plugin_api (GST_TYPE_STREAM_SELECTOR_PAD, 0); + + GST_DEBUG_CATEGORY_INIT (stream_selector_debug, "streamselector", 0, + "streamselector"); +} + +static void +gst_stream_selector_init (GstStreamSelector * self) +{ +} + +static void +gst_stream_selector_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + switch (prop_id) { + case PROP_IGNORE_INACTIVE_PADS: + gst_aggregator_set_ignore_inactive_pads (GST_AGGREGATOR (object), + g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_stream_selector_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + switch (prop_id) { + case PROP_IGNORE_INACTIVE_PADS: + g_value_set_boolean (value, + gst_aggregator_get_ignore_inactive_pads (GST_AGGREGATOR (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gst_stream_selector_child_proxy_get_child_by_index (GstChildProxy * proxy, + guint index) +{ + GstElement *elem = GST_ELEMENT_CAST (proxy); + GObject *obj = NULL; + + GST_OBJECT_LOCK (elem); + obj = (GObject *) g_list_nth_data (elem->sinkpads, index); + if (obj) + gst_object_ref (obj); + GST_OBJECT_UNLOCK (elem); + + return obj; +} + +static guint +gst_stream_selector_child_proxy_get_children_count (GstChildProxy * proxy) +{ + GstElement *elem = GST_ELEMENT_CAST (proxy); + guint count = 0; + + GST_OBJECT_LOCK (elem); + count = elem->numsinkpads; + GST_OBJECT_UNLOCK (elem); + + return count; +} + +static void +gst_stream_selector_child_proxy_init (gpointer g_iface, gpointer iface_data) +{ + GstChildProxyInterface *iface = (GstChildProxyInterface *) g_iface; + + iface->get_child_by_index = + gst_stream_selector_child_proxy_get_child_by_index; + iface->get_children_count = + gst_stream_selector_child_proxy_get_children_count; +} + +static void +gst_stream_selector_reset (GstAggregator * agg) +{ + GstElement *elem = GST_ELEMENT_CAST (agg); + GstStreamSelector *self = GST_STREAM_SELECTOR (agg); + GList *iter; + + /* Clear all except for active state */ + GST_OBJECT_LOCK (self); + for (iter = elem->sinkpads; iter; iter = g_list_next (iter)) { + GstStreamSelectorPad *pad = GST_STREAM_SELECTOR_PAD (iter->data); + gst_clear_caps (&pad->caps); + gst_clear_event (&pad->tag_event); + pad->discont = FALSE; + } + GST_OBJECT_UNLOCK (self); + + gst_clear_object (&self->active_pad); +} + +static gboolean +gst_stream_selector_start (GstAggregator * agg) +{ + gst_stream_selector_reset (agg); + + return TRUE; +} + +static gboolean +gst_stream_selector_stop (GstAggregator * agg) +{ + gst_stream_selector_reset (agg); + + return TRUE; +} + +static void +gst_stream_selector_update_active_pad_unlocked (GstStreamSelector * self) +{ + GstElement *elem = GST_ELEMENT_CAST (self); + GstPad *first = NULL; + GstPad *active = NULL; + GstStreamSelectorPad *spad; + GList *iter; + + for (iter = elem->sinkpads; iter; iter = g_list_next (iter)) { + GstPad *pad = GST_PAD_CAST (iter->data); + spad = GST_STREAM_SELECTOR_PAD (pad); + + if (!first) + first = pad; + + if (!active && spad->active) + active = pad; + } + + if (!active && first) { + spad = GST_STREAM_SELECTOR_PAD (first); + spad->active = TRUE; + + GST_DEBUG_OBJECT (spad, "New active pad"); + } +} + +static void +gst_stream_selector_update_active_pad (GstStreamSelector * self) +{ + GST_OBJECT_LOCK (self); + gst_stream_selector_update_active_pad_unlocked (self); + GST_OBJECT_UNLOCK (self); +} + +static void +gst_stream_selector_set_active_pad (GstStreamSelector * self, + GstStreamSelectorPad * pad, gboolean active) +{ + GstElement *elem = GST_ELEMENT_CAST (self); + GList *iter; + + GST_OBJECT_LOCK (self); + if (!active) { + pad->active = FALSE; + gst_stream_selector_update_active_pad_unlocked (self); + } else { + for (iter = elem->sinkpads; iter; iter = g_list_next (iter)) { + GstStreamSelectorPad *other = GST_STREAM_SELECTOR_PAD (iter->data); + other->active = FALSE; + } + + pad->active = TRUE; + GST_DEBUG_OBJECT (pad, "New active pad"); + } + + GST_OBJECT_UNLOCK (self); +} + +static GstPad * +gst_stream_selector_get_active_pad_unlocked (GstStreamSelector * self) +{ + GstElement *elem = GST_ELEMENT_CAST (self); + GList *iter; + GstPad *pad = NULL; + + for (iter = elem->sinkpads; iter; iter = g_list_next (iter)) { + GstStreamSelectorPad *spad = GST_STREAM_SELECTOR_PAD (iter->data); + if (spad->active) { + pad = gst_object_ref (spad); + break; + } + } + + return pad; +} + +static GstPad * +gst_stream_selector_get_active_pad (GstStreamSelector * self) +{ + GstPad *pad; + + GST_OBJECT_LOCK (self); + pad = gst_stream_selector_get_active_pad_unlocked (self); + GST_OBJECT_UNLOCK (self); + + return pad; +} + +static GstPad * +gst_stream_selector_request_new_pad (GstElement * elem, GstPadTemplate * templ, + const gchar * name, const GstCaps * caps) +{ + GstStreamSelector *self = GST_STREAM_SELECTOR (elem); + GstPad *pad; + + pad = GST_ELEMENT_CLASS (parent_class)->request_new_pad (elem, templ, name, + caps); + if (!pad) + return NULL; + + gst_stream_selector_update_active_pad (self); + + gst_child_proxy_child_added (GST_CHILD_PROXY (elem), G_OBJECT (pad), + GST_OBJECT_NAME (pad)); + + return pad; +} + +static void +gst_stream_selector_release_pad (GstElement * elem, GstPad * pad) +{ + GstStreamSelector *self = GST_STREAM_SELECTOR (elem); + + gst_child_proxy_child_removed (GST_CHILD_PROXY (elem), + G_OBJECT (pad), GST_OBJECT_NAME (pad)); + + GST_ELEMENT_CLASS (parent_class)->release_pad (elem, pad); + + gst_stream_selector_update_active_pad (self); +} + +static gboolean +gst_stream_selector_sink_query (GstAggregator * agg, GstAggregatorPad * pad, + GstQuery * query) +{ + GstStreamSelector *self = GST_STREAM_SELECTOR (agg); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ALLOCATION: + { + GstPad *active = gst_stream_selector_get_active_pad (self); + if (!active) + break; + + if (active == GST_PAD_CAST (pad)) { + gboolean ret = gst_pad_query_default (active, GST_OBJECT_CAST (self), + query); + gst_object_unref (active); + return ret; + } + gst_object_unref (active); + return FALSE; + } + case GST_QUERY_CAPS: + case GST_QUERY_ACCEPT_CAPS: + return gst_pad_peer_query (agg->srcpad, query); + break; + default: + break; + } + + return GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, pad, query); +} + +static gboolean +gst_stream_selector_sink_event (GstAggregator * agg, GstAggregatorPad * pad, + GstEvent * event) +{ + GstStreamSelector *self = GST_STREAM_SELECTOR (agg); + GstStreamSelectorPad *spad = GST_STREAM_SELECTOR_PAD (pad); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_STREAM_START: + { + gst_clear_caps (&spad->caps); + gst_clear_event (&spad->tag_event); + break; + } + case GST_EVENT_CAPS: + { + GstCaps *caps; + GstPad *active; + GstStructure *s; + gint fps_n, fps_d; + + gst_event_parse_caps (event, &caps); + gst_caps_replace (&spad->caps, caps); + + s = gst_caps_get_structure (caps, 0); + if (gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d) + && fps_n > 0 && fps_d > 0) { + GST_DEBUG_OBJECT (pad, "Framerate %d / %d", fps_n, fps_d); + spad->duration = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n); + } else { + spad->duration = GST_CLOCK_TIME_NONE; + } + + active = gst_stream_selector_get_active_pad (self); + if (active) { + if (active == GST_PAD_CAST (pad)) + gst_aggregator_set_src_caps (agg, caps); + gst_object_unref (active); + } + break; + } + case GST_EVENT_SEGMENT: + { + GstPad *active; + const GstSegment *segment; + + gst_event_parse_segment (event, &segment); + + if (segment->format != GST_FORMAT_TIME) { + GST_ERROR_OBJECT (self, "Non-TIME format segment is not supported"); + return FALSE; + } + + active = gst_stream_selector_get_active_pad (self); + if (!active) + break; + + if (active == GST_PAD_CAST (pad)) { + GST_DEBUG_OBJECT (active, "Pad is active, schedule update segment %" + GST_SEGMENT_FORMAT, segment); + gst_aggregator_update_segment (agg, segment); + } + + gst_object_unref (active); + break; + } + case GST_EVENT_TAG: + { + /* aggregator will drop tag event. Store the tag here and send later + * on aggregate() */ + gst_clear_event (&spad->tag_event); + spad->tag_event = event; + return TRUE; + } + default: + break; + } + + return GST_AGGREGATOR_CLASS (parent_class)->sink_event (agg, pad, event); +} + +static gboolean +gst_stream_selector_src_query (GstAggregator * agg, GstQuery * query) +{ + GstStreamSelector *self = GST_STREAM_SELECTOR (agg); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CAPS: + { + GstPad *active = gst_stream_selector_get_active_pad (self); + if (active) { + gboolean ret = gst_pad_peer_query (active, query); + gst_object_unref (active); + return ret; + } + break; + } + default: + break; + } + + return GST_AGGREGATOR_CLASS (parent_class)->src_query (agg, query); +} + +static GstClockTime +gst_stream_selector_get_pad_running_time (GstStreamSelector * self, + GstAggregatorPad * pad) +{ + GstClockTime running_time = GST_CLOCK_TIME_NONE; + GstClockTime running_time_end = GST_CLOCK_TIME_NONE; + GstClockTime timestamp; + GstBuffer *buf; + + buf = gst_aggregator_pad_peek_buffer (pad); + if (!buf) + return GST_CLOCK_TIME_NONE; + + timestamp = GST_BUFFER_PTS (buf); + if (!GST_CLOCK_TIME_IS_VALID (timestamp)) + timestamp = GST_BUFFER_DTS (buf); + + if (GST_CLOCK_TIME_IS_VALID (timestamp)) { + running_time = gst_segment_to_running_time (&pad->segment, + GST_FORMAT_TIME, timestamp); + } + + if (GST_CLOCK_TIME_IS_VALID (running_time)) { + if (GST_BUFFER_DURATION_IS_VALID (buf)) + running_time_end = running_time + GST_BUFFER_DURATION (buf); + else + running_time_end = running_time; + } + + gst_buffer_unref (buf); + + return running_time_end; +} + +static GstFlowReturn +gst_stream_selector_aggregate (GstAggregator * agg, gboolean timeout) +{ + GstElement *elem = GST_ELEMENT_CAST (agg); + GstStreamSelector *self = GST_STREAM_SELECTOR (agg); + GstBuffer *buf = NULL; + GstStreamSelectorPad *active_pad = NULL; + GstAggregatorPad *active_agg_pad; + GstAggregatorPad *srcpad = GST_AGGREGATOR_PAD_CAST (agg->srcpad); + gboolean active_changed = FALSE; + GList *iter; + GstClockTime running_time = GST_CLOCK_TIME_NONE; + GstClockTime running_time_end = GST_CLOCK_TIME_NONE; + GstClockTime output_running_time = GST_CLOCK_TIME_NONE; + GstClockTime timestamp; + gboolean active_eos = FALSE; + gboolean have_non_eos_pad = FALSE; + GstClockTime advance_dur = GST_CLOCK_TIME_NONE; + + GST_OBJECT_LOCK (self); + active_pad = (GstStreamSelectorPad *) + gst_stream_selector_get_active_pad_unlocked (self); + if (!active_pad) { + GST_WARNING_OBJECT (self, "No current active pad"); + GST_OBJECT_UNLOCK (self); + goto need_data; + } + + if (active_pad != self->active_pad) { + GST_DEBUG_OBJECT (active_pad, "Updated new active pad"); + gst_clear_object (&self->active_pad); + self->active_pad = gst_object_ref (active_pad); + active_changed = TRUE; + } else { + GST_LOG_OBJECT (active_pad, "Current active pad"); + } + + advance_dur = active_pad->duration; + + active_agg_pad = GST_AGGREGATOR_PAD_CAST (active_pad); + + buf = gst_aggregator_pad_pop_buffer (active_agg_pad); + if (!buf && gst_aggregator_pad_is_eos (active_agg_pad)) { + GST_DEBUG_OBJECT (self, "Active pad is EOS"); + active_eos = TRUE; + } + + output_running_time = gst_segment_to_running_time (&srcpad->segment, + GST_FORMAT_TIME, srcpad->segment.position); + + if (buf) { + timestamp = GST_BUFFER_PTS (buf); + if (!GST_CLOCK_TIME_IS_VALID (timestamp)) + timestamp = GST_BUFFER_DTS (buf); + + if (GST_CLOCK_TIME_IS_VALID (timestamp)) { + running_time = gst_segment_to_running_time (&active_agg_pad->segment, + GST_FORMAT_TIME, timestamp); + } + + if (GST_CLOCK_TIME_IS_VALID (running_time)) { + if (GST_BUFFER_DURATION_IS_VALID (buf)) + running_time_end = running_time + GST_BUFFER_DURATION (buf); + else + running_time_end = running_time; + } + + GST_LOG_OBJECT (self, "Current running time %" GST_TIME_FORMAT " - %" + GST_TIME_FORMAT, GST_TIME_ARGS (running_time), + GST_TIME_ARGS (running_time_end)); + } else { + running_time_end = output_running_time; + } + + for (iter = elem->sinkpads; iter; iter = g_list_next (iter)) { + GstAggregatorPad *other_pad = GST_AGGREGATOR_PAD_CAST (iter->data); + GstStreamSelectorPad *other_spad = GST_STREAM_SELECTOR_PAD (other_pad); + GstClockTime other_running_time; + + if (other_spad == active_pad) + continue; + + other_running_time = + gst_stream_selector_get_pad_running_time (self, other_pad); + + /* Drops other pad's buffer if + * - active pad is eos + * - active pad's running time is unknown + * - or other pad's running time is unknown + * - or active pad's running time > other_pad's running time + */ + if (active_eos || !GST_CLOCK_TIME_IS_VALID (running_time_end) || + !GST_CLOCK_TIME_IS_VALID (other_running_time) || + (running_time_end > other_running_time)) { + + GST_LOG_OBJECT (other_pad, "Trying to drop non-active buffer, " + "active-eos %d, active-running-time %" GST_TIME_FORMAT + ", other-running-time %" GST_TIME_FORMAT + ", output-running-time %" GST_TIME_FORMAT, active_eos, + GST_TIME_ARGS (running_time_end), + GST_TIME_ARGS (other_running_time), + GST_TIME_ARGS (output_running_time)); + + if (gst_aggregator_pad_drop_buffer (other_pad)) + other_spad->discont = TRUE; + + if (!gst_aggregator_pad_is_eos (other_pad)) { + if (active_eos) + GST_DEBUG_OBJECT (other_pad, "Other pad is not EOS yet"); + have_non_eos_pad = TRUE; + } + } + } + GST_OBJECT_UNLOCK (self); + + if (active_changed) { + gst_aggregator_set_src_caps (agg, active_pad->caps); + gst_aggregator_update_segment (agg, &active_agg_pad->segment); + } + + if (active_pad->tag_event) { + gst_aggregator_ensure_mandatory_events (agg); + gst_pad_push_event (agg->srcpad, active_pad->tag_event); + active_pad->tag_event = NULL; + } + + if (active_eos) { + gst_object_unref (active_pad); + + if (have_non_eos_pad) { + GST_DEBUG_OBJECT (self, + "Active pad is EOS, waiting for EOS from other pads"); + return GST_AGGREGATOR_FLOW_NEED_DATA; + } + + GST_DEBUG_OBJECT (self, "All pads are EOS"); + + return GST_FLOW_EOS; + } else if (!buf) { + GST_LOG_OBJECT (self, "Active pad is not ready"); + goto need_data; + } + + srcpad->segment.position = + gst_segment_position_from_running_time (&srcpad->segment, + GST_FORMAT_TIME, running_time_end); + + /* Convert gap buffer to event */ + if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP) && + GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DROPPABLE) && + gst_buffer_get_size (buf) == 0) { + GstEvent *gap; + gst_aggregator_ensure_mandatory_events (agg); + + gap = gst_event_new_gap (GST_BUFFER_PTS (buf), GST_BUFFER_DURATION (buf)); + gst_buffer_unref (buf); + + GST_DEBUG_OBJECT (self, "Sending gap event %" GST_PTR_FORMAT, gap); + gst_pad_push_event (agg->srcpad, gap); + gst_object_unref (active_pad); + + return GST_FLOW_OK; + } + + if (active_pad->discont) { + buf = gst_buffer_make_writable (buf); + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); + active_pad->discont = FALSE; + } + + GST_LOG_OBJECT (active_pad, "Finishing buffer %" GST_PTR_FORMAT + ", running time %" GST_TIME_FORMAT, buf, + GST_TIME_ARGS (running_time_end)); + + gst_object_unref (active_pad); + + return gst_aggregator_finish_buffer (agg, buf); + +need_data: + if (srcpad->segment.position != -1) { + if (GST_CLOCK_TIME_IS_VALID (advance_dur)) + srcpad->segment.position += advance_dur; + else + srcpad->segment.position += GST_MSECOND; + } + gst_clear_object (&active_pad); + + return GST_AGGREGATOR_FLOW_NEED_DATA; +} diff --git a/subprojects/gst-plugins-bad/gst/streamselector/gststreamselector.h b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselector.h new file mode 100644 index 0000000000..e270360897 --- /dev/null +++ b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselector.h @@ -0,0 +1,37 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_STREAM_SELECTOR_PAD (gst_stream_selector_pad_get_type()) +G_DECLARE_FINAL_TYPE (GstStreamSelectorPad, gst_stream_selector_pad, + GST, STREAM_SELECTOR_PAD, GstAggregatorPad) + +#define GST_TYPE_STREAM_SELECTOR (gst_stream_selector_get_type()) +G_DECLARE_FINAL_TYPE (GstStreamSelector, gst_stream_selector, + GST, STREAM_SELECTOR, GstAggregator) + +GST_ELEMENT_REGISTER_DECLARE (streamselector); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/gst/streamselector/gststreamselectorbin.c b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselectorbin.c new file mode 100644 index 0000000000..8ef3235fa6 --- /dev/null +++ b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselectorbin.c @@ -0,0 +1,572 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:element-streamselectorbin + * @title: streamselectorbin + * + * Direct one out of N input streams to the output pad. + * + * Since: 1.24 + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gststreamselectorbin.h" +#include + +GST_DEBUG_CATEGORY_STATIC (stream_selector_bin_debug); +#define GST_CAT_DEFAULT stream_selector_bin_debug + +static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink_%u", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static void gst_stream_selector_bin_update_sync (GstStreamSelectorBin * self); + +enum +{ + PROP_PAD_0, + PROP_PAD_ACTIVE, +}; + +struct _GstStreamSelectorBinPad +{ + GstGhostPad parent; + + GstPad *target; + GstStreamSelectorBin *bin; +}; + +static void gst_stream_selector_bin_pad_dispose (GObject * object); +static void gst_stream_selector_bin_pad_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_stream_selector_bin_pad_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +#define gst_stream_selector_bin_pad_parent_class pad_parent_class +G_DEFINE_TYPE (GstStreamSelectorBinPad, gst_stream_selector_bin_pad, + GST_TYPE_GHOST_PAD); + +static void +gst_stream_selector_bin_pad_class_init (GstStreamSelectorBinPadClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gst_stream_selector_bin_pad_dispose; + object_class->set_property = gst_stream_selector_bin_pad_set_property; + object_class->get_property = gst_stream_selector_bin_pad_get_property; + + g_object_class_install_property (object_class, + PROP_PAD_ACTIVE, g_param_spec_boolean ("active", + "Active", "Active state of the pad", FALSE, + GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +gst_stream_selector_bin_pad_init (GstStreamSelectorBinPad * self) +{ +} + +static void +gst_stream_selector_bin_pad_dispose (GObject * object) +{ + GstStreamSelectorBinPad *self = GST_STREAM_SELECTOR_BIN_PAD (object); + + gst_clear_object (&self->target); + + G_OBJECT_CLASS (pad_parent_class)->dispose (object); +} + +static void +gst_stream_selector_bin_pad_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstStreamSelectorBinPad *self = GST_STREAM_SELECTOR_BIN_PAD (object); + + if (self->target) { + g_object_set_property (G_OBJECT (self->target), pspec->name, value); + if (prop_id == PROP_PAD_ACTIVE) + gst_stream_selector_bin_update_sync (self->bin); + } +} + +static void +gst_stream_selector_bin_pad_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstStreamSelectorBinPad *self = GST_STREAM_SELECTOR_BIN_PAD (object); + + if (self->target) + g_object_get_property (G_OBJECT (self->target), pspec->name, value); +} + +typedef enum +{ + GST_STREAM_SELECTOR_BIN_SYNC_MODE_ACTIVE_SEGMENT, + GST_STREAM_SELECTOR_BIN_SYNC_MODE_CLOCK, +} GstStreamSelectorBinSyncMode; + +#define GST_TYPE_STREAM_SELECTOR_BIN_SYNC_MODE (gst_stream_selector_bin_sync_mode_get_type()) +static GType +gst_stream_selector_bin_sync_mode_get_type (void) +{ + static GType type = 0; + static const GEnumValue sync_modes[] = { + {GST_STREAM_SELECTOR_BIN_SYNC_MODE_ACTIVE_SEGMENT, + "Sync using the current active segment", "active-segment"}, + {GST_STREAM_SELECTOR_BIN_SYNC_MODE_CLOCK, "Sync using the clock", "clock"}, + {0, NULL, NULL}, + }; + + if (g_once_init_enter (&type)) { + GType tmp = + g_enum_register_static ("GstStreamSelectorBinSyncMode", sync_modes); + + g_once_init_leave (&type, tmp); + } + + return type; +} + +typedef struct _GstStreamSelectorBinChain +{ + GstStreamSelectorBin *self; + + GstStreamSelectorBinPad *pad; + GstElement *clocksync; +} GstStreamSelectorBinChain; + +struct _GstStreamSelectorBin +{ + GstBin parent; + + GMutex lock; + + GstElement *selector; + GList *input_chains; + gboolean running; + + GstStreamSelectorBinSyncMode sync_mode; + gboolean sync_only_inactive; +}; + +enum +{ + PROP_0, + PROP_SYNC_MODE, + PROP_SYNC_ONLY_INACTIVE, + /* GstAggregator */ + PROP_LATENCY, + PROP_MIN_UPSTREAM_LATENCY, + PROP_START_TIME_SELECTION, + PROP_START_TIME, + PROP_EMIT_SIGNALS, + /* GstStreamSelector */ + PROP_IGNORE_INACTIVE_PADS, +}; + +#define DEFAULT_SYNC_MODE GST_STREAM_SELECTOR_BIN_SYNC_MODE_ACTIVE_SEGMENT +#define DEFAULT_LATENCY 0 +#define DEFAULT_MIN_UPSTREAM_LATENCY 0 +#define DEFAULT_START_TIME_SELECTION GST_AGGREGATOR_START_TIME_SELECTION_ZERO +#define DEFAULT_START_TIME (-1) +#define DEFAULT_EMIT_SIGNALS FALSE +#define DEFAULT_SYNC_ONLY_INACTIVE FALSE + +static void gst_stream_selector_bin_finalize (GObject * object); +static void gst_stream_selector_bin_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_stream_selector_bin_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static GstStateChangeReturn +gst_stream_selector_bin_change_state (GstElement * elem, + GstStateChange transition); +static GstPad *gst_stream_selector_bin_request_new_pad (GstElement * elem, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps); +static void gst_stream_selector_bin_release_pad (GstElement * elem, + GstPad * pad); + +#define gst_stream_selector_bin_parent_class parent_class +G_DEFINE_TYPE (GstStreamSelectorBin, gst_stream_selector_bin, GST_TYPE_BIN); +GST_ELEMENT_REGISTER_DEFINE (streamselectorbin, "streamselectorbin", + GST_RANK_NONE, GST_TYPE_STREAM_SELECTOR_BIN); + +static void +gst_stream_selector_bin_class_init (GstStreamSelectorBinClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + object_class->finalize = gst_stream_selector_bin_finalize; + object_class->set_property = gst_stream_selector_bin_set_property; + object_class->get_property = gst_stream_selector_bin_get_property; + + g_object_class_install_property (object_class, PROP_SYNC_MODE, + g_param_spec_enum ("sync-mode", "Sync mode", + "Behavior in sync-streams mode", + GST_TYPE_STREAM_SELECTOR_BIN_SYNC_MODE, + DEFAULT_SYNC_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_SYNC_ONLY_INACTIVE, + g_param_spec_boolean ("sync-only-inactive", "Sync Only Inactive", + "Synchronize only inactive stream with clock when \"sync-mode=clock\"", + DEFAULT_SYNC_ONLY_INACTIVE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* GstAggregator */ + g_object_class_install_property (object_class, PROP_LATENCY, + g_param_spec_uint64 ("latency", "Buffer latency", + "Additional latency in live mode to allow upstream " + "to take longer to produce buffers for the current " + "position (in nanoseconds)", 0, G_MAXUINT64, + DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_MIN_UPSTREAM_LATENCY, + g_param_spec_uint64 ("min-upstream-latency", "Buffer latency", + "When sources with a higher latency are expected to be plugged " + "in dynamically after the aggregator has started playing, " + "this allows overriding the minimum latency reported by the " + "initial source(s). This is only taken into account when larger " + "than the actually reported minimum latency. (nanoseconds)", + 0, G_MAXUINT64, + DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_START_TIME_SELECTION, + g_param_spec_enum ("start-time-selection", "Start Time Selection", + "Decides which start time is output", + gst_aggregator_start_time_selection_get_type (), + DEFAULT_START_TIME_SELECTION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_START_TIME, + g_param_spec_uint64 ("start-time", "Start Time", + "Start time to use if start-time-selection=set", 0, + G_MAXUINT64, + DEFAULT_START_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_EMIT_SIGNALS, + g_param_spec_boolean ("emit-signals", "Emit signals", + "Send signals", DEFAULT_EMIT_SIGNALS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* GstStreamSelector */ + g_object_class_install_property (object_class, + PROP_IGNORE_INACTIVE_PADS, g_param_spec_boolean ("ignore-inactive-pads", + "Ignore inactive pads", + "Avoid timing out waiting for inactive pads", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_stream_selector_bin_change_state); + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_stream_selector_bin_request_new_pad); + element_class->release_pad = + GST_DEBUG_FUNCPTR (gst_stream_selector_bin_release_pad); + + gst_element_class_add_static_pad_template_with_gtype (element_class, + &sink_templ, GST_TYPE_STREAM_SELECTOR_BIN_PAD); + gst_element_class_add_static_pad_template (element_class, &src_templ); + + gst_element_class_set_static_metadata (element_class, "Stream Selector Bin", + "Generic", "N-to-1 input stream selector", + "Seungha Yang "); + + gst_type_mark_as_plugin_api (GST_TYPE_STREAM_SELECTOR_BIN_PAD, 0); + gst_type_mark_as_plugin_api (GST_TYPE_STREAM_SELECTOR_BIN_SYNC_MODE, 0); + + GST_DEBUG_CATEGORY_INIT (stream_selector_bin_debug, "streamselectorbin", 0, + "streamselectorbin"); +} + +static void +gst_stream_selector_bin_init (GstStreamSelectorBin * self) +{ + GstPad *gpad; + GstPad *srcpad; + + self->selector = gst_element_factory_make ("streamselector", + "stream-selector"); + + gst_bin_add (GST_BIN_CAST (self), self->selector); + + srcpad = gst_element_get_static_pad (GST_ELEMENT_CAST (self->selector), + "src"); + gpad = gst_ghost_pad_new ("src", srcpad); + gst_object_unref (srcpad); + + gst_element_add_pad (GST_ELEMENT_CAST (self), gpad); + + self->sync_mode = DEFAULT_SYNC_MODE; + self->sync_only_inactive = DEFAULT_SYNC_ONLY_INACTIVE; + + g_mutex_init (&self->lock); +} + +static void +gst_stream_selector_bin_finalize (GObject * object) +{ + GstStreamSelectorBin *self = GST_STREAM_SELECTOR_BIN (object); + + if (self->input_chains) + g_list_free_full (self->input_chains, (GDestroyNotify) g_free); + + g_mutex_clear (&self->lock); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_stream_selector_bin_update_sync_unlocked (GstStreamSelectorBin * self) +{ + GList *iter; + if (self->sync_mode != GST_STREAM_SELECTOR_BIN_SYNC_MODE_CLOCK) { + for (iter = self->input_chains; iter; iter = g_list_next (iter)) { + GstStreamSelectorBinChain *chain = iter->data; + g_object_set (chain->clocksync, "sync", FALSE, NULL); + } + } else { + if (self->sync_only_inactive) { + for (iter = self->input_chains; iter; iter = g_list_next (iter)) { + GstStreamSelectorBinChain *chain = iter->data; + gboolean is_active; + g_object_get (chain->pad->target, "active", &is_active, NULL); + g_object_set (chain->clocksync, "sync", !is_active, NULL); + } + } else { + for (iter = self->input_chains; iter; iter = g_list_next (iter)) { + GstStreamSelectorBinChain *chain = iter->data; + g_object_set (chain->clocksync, "sync", TRUE, NULL); + } + } + } +} + +static void +gst_stream_selector_bin_update_sync (GstStreamSelectorBin * self) +{ + g_mutex_lock (&self->lock); + gst_stream_selector_bin_update_sync_unlocked (self); + g_mutex_unlock (&self->lock); +} + +static void +gst_stream_selector_bin_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstStreamSelectorBin *self = GST_STREAM_SELECTOR_BIN (object); + + switch (prop_id) { + case PROP_SYNC_MODE: + { + g_mutex_lock (&self->lock); + self->sync_mode = g_value_get_enum (value); + gst_stream_selector_bin_update_sync_unlocked (self); + g_mutex_unlock (&self->lock); + break; + } + case PROP_SYNC_ONLY_INACTIVE: + { + g_mutex_lock (&self->lock); + self->sync_only_inactive = g_value_get_boolean (value); + gst_stream_selector_bin_update_sync_unlocked (self); + g_mutex_unlock (&self->lock); + break; + } + default: + g_object_set_property (G_OBJECT (self->selector), pspec->name, value); + break; + } +} + +static void +gst_stream_selector_bin_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstStreamSelectorBin *self = GST_STREAM_SELECTOR_BIN (object); + + switch (prop_id) { + case PROP_SYNC_MODE: + g_mutex_lock (&self->lock); + g_value_set_enum (value, self->sync_mode); + g_mutex_unlock (&self->lock); + break; + case PROP_SYNC_ONLY_INACTIVE: + g_mutex_lock (&self->lock); + g_value_set_boolean (value, self->sync_only_inactive); + g_mutex_unlock (&self->lock); + break; + default: + g_object_get_property (G_OBJECT (self->selector), pspec->name, value); + break; + } +} + +static GstStateChangeReturn +gst_stream_selector_bin_change_state (GstElement * elem, + GstStateChange transition) +{ + GstStreamSelectorBin *self = GST_STREAM_SELECTOR_BIN (elem); + GstStateChangeReturn ret; + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + g_mutex_lock (&self->lock); + self->running = TRUE; + g_mutex_unlock (&self->lock); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (elem, transition); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_NULL: + g_mutex_lock (&self->lock); + self->running = FALSE; + g_mutex_unlock (&self->lock); + default: + break; + } + + return ret; +} + +static GstStreamSelectorBinChain * +gst_stream_selector_bin_chain_new (GstStreamSelectorBin * self, + GstPad * selector_pad) +{ + GstStreamSelectorBinChain *chain; + GstStreamSelectorBinPad *binpad; + GstPad *pad; + + chain = g_new0 (GstStreamSelectorBinChain, 1); + chain->self = self; + chain->clocksync = gst_element_factory_make ("clocksync", NULL); + + gst_bin_add (GST_BIN_CAST (self), chain->clocksync); + + pad = gst_element_get_static_pad (chain->clocksync, "src"); + gst_pad_link (pad, selector_pad); + gst_object_unref (pad); + + chain->pad = g_object_new (GST_TYPE_STREAM_SELECTOR_BIN_PAD, + "name", GST_OBJECT_NAME (selector_pad), "direction", GST_PAD_SINK, NULL); + + binpad = GST_STREAM_SELECTOR_BIN_PAD (chain->pad); + binpad->target = selector_pad; + binpad->bin = self; + + pad = gst_element_get_static_pad (chain->clocksync, "sink"); + gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (chain->pad), pad); + gst_object_unref (pad); + + g_mutex_lock (&self->lock); + if (self->running) + gst_pad_set_active (GST_PAD_CAST (chain->pad), TRUE); + g_mutex_unlock (&self->lock); + + gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD_CAST (chain->pad)); + gst_element_sync_state_with_parent (chain->clocksync); + + return chain; +} + +static void +gst_stream_selector_bin_chain_free (GstStreamSelectorBinChain * chain) +{ + GstStreamSelectorBin *self = chain->self; + + gst_element_set_locked_state (chain->clocksync, TRUE); + gst_element_set_state (chain->clocksync, GST_STATE_NULL); + gst_bin_remove (GST_BIN_CAST (chain->self), chain->clocksync); + + gst_element_release_request_pad (self->selector, chain->pad->target); + gst_clear_object (&chain->pad->target); + + g_free (chain); +} + +static GstPad * +gst_stream_selector_bin_request_new_pad (GstElement * elem, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps) +{ + GstStreamSelectorBin *self = GST_STREAM_SELECTOR_BIN (elem); + GstPad *selector_pad; + GstStreamSelectorBinChain *chain; + GstPadTemplate *selector_templ; + + selector_templ = gst_element_get_pad_template (self->selector, "sink_%u"); + selector_pad = + gst_element_request_pad (self->selector, selector_templ, name, caps); + if (!selector_pad) + return NULL; + + chain = gst_stream_selector_bin_chain_new (self, selector_pad); + + g_mutex_lock (&self->lock); + self->input_chains = g_list_append (self->input_chains, chain); + gst_stream_selector_bin_update_sync_unlocked (self); + g_mutex_unlock (&self->lock); + + GST_DEBUG_OBJECT (chain->pad, "Created new pad"); + + return GST_PAD_CAST (chain->pad); +} + +static void +gst_stream_selector_bin_release_pad (GstElement * elem, GstPad * pad) +{ + GstStreamSelectorBin *self = GST_STREAM_SELECTOR_BIN (elem); + GList *iter; + gboolean found = FALSE; + + g_mutex_lock (&self->lock); + for (iter = self->input_chains; iter; iter = g_list_next (iter)) { + GstStreamSelectorBinChain *chain = iter->data; + + if (pad == GST_PAD_CAST (chain->pad)) { + self->input_chains = g_list_delete_link (self->input_chains, iter); + g_mutex_unlock (&self->lock); + + gst_stream_selector_bin_chain_free (chain); + found = TRUE; + break; + } + } + + if (!found) { + g_mutex_unlock (&self->lock); + GST_WARNING_OBJECT (self, "Unknown pad to release %s:%s", + GST_DEBUG_PAD_NAME (pad)); + } + + gst_element_remove_pad (elem, pad); +} diff --git a/subprojects/gst-plugins-bad/gst/streamselector/gststreamselectorbin.h b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselectorbin.h new file mode 100644 index 0000000000..457b09bf98 --- /dev/null +++ b/subprojects/gst-plugins-bad/gst/streamselector/gststreamselectorbin.h @@ -0,0 +1,36 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_STREAM_SELECTOR_BIN_PAD (gst_stream_selector_bin_pad_get_type()) +G_DECLARE_FINAL_TYPE (GstStreamSelectorBinPad, gst_stream_selector_bin_pad, + GST, STREAM_SELECTOR_BIN_PAD, GstGhostPad) + +#define GST_TYPE_STREAM_SELECTOR_BIN (gst_stream_selector_bin_get_type()) +G_DECLARE_FINAL_TYPE (GstStreamSelectorBin, gst_stream_selector_bin, + GST, STREAM_SELECTOR_BIN, GstBin) + +GST_ELEMENT_REGISTER_DECLARE (streamselectorbin); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/gst/streamselector/meson.build b/subprojects/gst-plugins-bad/gst/streamselector/meson.build new file mode 100644 index 0000000000..2ef9799188 --- /dev/null +++ b/subprojects/gst-plugins-bad/gst/streamselector/meson.build @@ -0,0 +1,15 @@ +streamselector_sources = [ + 'gststreamselector.c', + 'gststreamselectorbin.c', + 'plugin.c', +] + +gststreamselector = library('gststreamselector', + streamselector_sources, + c_args : gst_plugins_bad_args, + include_directories : [configinc], + dependencies : [gstbase_dep], + install : true, + install_dir : plugins_install_dir, +) +plugins += [gststreamselector] diff --git a/subprojects/gst-plugins-bad/gst/streamselector/plugin.c b/subprojects/gst-plugins-bad/gst/streamselector/plugin.c new file mode 100644 index 0000000000..b3ad77f185 --- /dev/null +++ b/subprojects/gst-plugins-bad/gst/streamselector/plugin.c @@ -0,0 +1,46 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * plugin-streamselector: + * + * Since: 1.24 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gststreamselector.h" +#include "gststreamselectorbin.h" + +static gboolean +plugin_init (GstPlugin * plugin) +{ + GST_ELEMENT_REGISTER (streamselector, plugin); + GST_ELEMENT_REGISTER (streamselectorbin, plugin); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + streamselector, + "streamselector", + plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/subprojects/gst-plugins-bad/gst/videoparsers/gstmpegvideoparse.c b/subprojects/gst-plugins-bad/gst/videoparsers/gstmpegvideoparse.c index 3c4f7eec67..4b752dcdee 100644 --- a/subprojects/gst-plugins-bad/gst/videoparsers/gstmpegvideoparse.c +++ b/subprojects/gst-plugins-bad/gst/videoparsers/gstmpegvideoparse.c @@ -765,6 +765,7 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) { GstCaps *caps = NULL; GstStructure *s = NULL; + gboolean update_par = FALSE; /* only update if no src caps yet or explicitly triggered */ if (G_LIKELY (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (mpvparse)) && @@ -794,6 +795,7 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) if (mpvparse->sequencehdr.width > 0 && mpvparse->sequencehdr.height > 0) { GstMpegVideoSequenceDisplayExt *seqdispext; gint width, height; + gint upstream_width, upstream_height; width = mpvparse->sequencehdr.width; height = mpvparse->sequencehdr.height; @@ -810,6 +812,15 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) width, height); } } + + /* upstream resolution is different from one we parsed and updated. + * uses parsed par in this case */ + if (s && gst_structure_get_int (s, "width", &upstream_width) && + gst_structure_get_int (s, "height", &upstream_height) && + (upstream_width != width || upstream_height != height)) { + update_par = TRUE; + } + gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL); } @@ -836,7 +847,8 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) /* or pixel-aspect-ratio */ if (mpvparse->sequencehdr.par_w && mpvparse->sequencehdr.par_h > 0 && - (!s || !gst_structure_has_field (s, "pixel-aspect-ratio"))) { + (!s || !gst_structure_has_field (s, "pixel-aspect-ratio") + || update_par)) { gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION, mpvparse->sequencehdr.par_w, mpvparse->sequencehdr.par_h, NULL); } diff --git a/subprojects/gst-plugins-bad/meson.options b/subprojects/gst-plugins-bad/meson.options index 7dd5309aaf..8e14ac1e79 100644 --- a/subprojects/gst-plugins-bad/meson.options +++ b/subprojects/gst-plugins-bad/meson.options @@ -64,6 +64,7 @@ option('segmentclip', type : 'feature', value : 'auto') option('siren', type : 'feature', value : 'auto') option('smooth', type : 'feature', value : 'auto') option('speed', type : 'feature', value : 'auto') +option('streamselector', type : 'feature', value : 'auto') option('subenc', type : 'feature', value : 'auto') option('switchbin', type : 'feature', value : 'auto') option('tensordecoders', type : 'feature', value : 'auto') @@ -109,6 +110,7 @@ option('d3d12', type : 'feature', value : 'auto', description : 'Direct3D12 plug option('dash', type : 'feature', value : 'auto', description : 'DASH demuxer plugin') option('dc1394', type : 'feature', value : 'auto', description : 'libdc1394 IIDC camera source plugin') option('decklink', type : 'feature', value : 'auto', description : 'DeckLink audio/video source/sink plugin') +option('decklink2', type : 'feature', value : 'auto', description : 'DeckLink plugin') option('directfb', type : 'feature', value : 'auto', description : 'DirectFB video sink plugin') option('directsound', type : 'feature', value : 'auto', description : 'Directsound audio source plugin') option('directshow', type : 'feature', value : 'auto', description : 'Directshow audio/video plugins') diff --git a/subprojects/gst-plugins-bad/sys/androidmedia/gstamcaudiodec.c b/subprojects/gst-plugins-bad/sys/androidmedia/gstamcaudiodec.c index 398a6e1bd3..0f7f088f99 100644 --- a/subprojects/gst-plugins-bad/sys/androidmedia/gstamcaudiodec.c +++ b/subprojects/gst-plugins-bad/sys/androidmedia/gstamcaudiodec.c @@ -1005,7 +1005,8 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) self->flushing = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); + (GstTaskFunction) gst_amc_audio_dec_loop, gst_object_ref (decoder), + gst_object_unref); return TRUE; } @@ -1045,7 +1046,8 @@ gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) self->drained = TRUE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); + (GstTaskFunction) gst_amc_audio_dec_loop, gst_object_ref (decoder), + gst_object_unref); GST_DEBUG_OBJECT (self, "Reset decoder"); } diff --git a/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideodec.c b/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideodec.c index 7c5a535d94..2feb79baa3 100644 --- a/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideodec.c +++ b/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideodec.c @@ -2047,7 +2047,8 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder, self->flushing = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL); + (GstTaskFunction) gst_amc_video_dec_loop, gst_object_ref (decoder), + gst_object_unref); return TRUE; } @@ -2085,7 +2086,8 @@ gst_amc_video_dec_flush (GstVideoDecoder * decoder) self->drained = TRUE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL); + (GstTaskFunction) gst_amc_video_dec_loop, gst_object_ref (decoder), + gst_object_unref); GST_DEBUG_OBJECT (self, "Flushed decoder"); diff --git a/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideoenc.c b/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideoenc.c index b2ff33d63b..2d8eb8456e 100644 --- a/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideoenc.c +++ b/subprojects/gst-plugins-bad/sys/androidmedia/gstamcvideoenc.c @@ -1477,7 +1477,8 @@ gst_amc_video_enc_set_format (GstVideoEncoder * encoder, self->flushing = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_video_enc_loop, encoder, NULL); + (GstTaskFunction) gst_amc_video_enc_loop, gst_object_ref (encoder), + gst_object_unref); r = TRUE; @@ -1525,7 +1526,8 @@ gst_amc_video_enc_flush (GstVideoEncoder * encoder) self->drained = TRUE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_video_enc_loop, encoder, NULL); + (GstTaskFunction) gst_amc_video_enc_loop, gst_object_ref (encoder), + gst_object_unref); GST_DEBUG_OBJECT (self, "Flush encoder"); diff --git a/subprojects/gst-plugins-bad/sys/applemedia/avfassetsrc.m b/subprojects/gst-plugins-bad/sys/applemedia/avfassetsrc.m index ff9a23286f..f8a2c51372 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/avfassetsrc.m +++ b/subprojects/gst-plugins-bad/sys/applemedia/avfassetsrc.m @@ -854,14 +854,15 @@ static void gst_avf_asset_src_uri_handler_init (gpointer g_iface, goto exit; } if (AVF_ASSET_READER_HAS_SUPPORTED_AUDIO (self)) { - ret = gst_pad_start_task (self->audiopad, (GstTaskFunction) gst_avf_asset_src_read_audio, self, NULL); + ret = gst_pad_start_task (self->audiopad, (GstTaskFunction) gst_avf_asset_src_read_audio, gst_object_ref (self), gst_object_unref); if (!ret) { GST_ERROR ("Failed to start audio task"); goto exit; } } else if (AVF_ASSET_READER_HAS_AUDIO (self) && self->audiopad) { ret = gst_pad_start_task (self->audiopad, - (GstTaskFunction) gst_avf_asset_src_send_audio_eos, self, NULL); + (GstTaskFunction) gst_avf_asset_src_send_audio_eos, gst_object_ref (self), + gst_object_unref); if (!ret) { GST_ERROR ("Failed to start audio EOS task"); goto exit; @@ -869,14 +870,15 @@ static void gst_avf_asset_src_uri_handler_init (gpointer g_iface, } if (AVF_ASSET_READER_HAS_SUPPORTED_VIDEO (self)) { - ret = gst_pad_start_task (self->videopad, (GstTaskFunction)gst_avf_asset_src_read_video, self, NULL); + ret = gst_pad_start_task (self->videopad, (GstTaskFunction)gst_avf_asset_src_read_video, gst_object_ref (self), gst_object_unref); if (!ret) { GST_ERROR ("Failed to start video task"); goto exit; } } else if (AVF_ASSET_READER_HAS_VIDEO (self) && self->videopad) { ret = gst_pad_start_task (self->videopad, - (GstTaskFunction) gst_avf_asset_src_send_video_eos, self, NULL); + (GstTaskFunction) gst_avf_asset_src_send_video_eos, gst_object_ref (self), + gst_object_unref); if (!ret) { GST_ERROR ("Failed to start video EOS task"); goto exit; diff --git a/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c b/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c index b98cc63705..c04a80c565 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c +++ b/subprojects/gst-plugins-bad/sys/applemedia/vtdec.c @@ -355,7 +355,8 @@ gst_vtdec_start (GstVideoDecoder * decoder) /* Create the output task, but pause it immediately */ vtdec->pause_task = TRUE; if (!gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (decoder), - (GstTaskFunction) gst_vtdec_output_loop, vtdec, NULL)) { + (GstTaskFunction) gst_vtdec_output_loop, gst_object_ref (vtdec), + gst_object_unref)) { GST_ERROR_OBJECT (vtdec, "failed to start output thread"); return FALSE; } diff --git a/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c b/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c index 733e7288a8..b66b7c691d 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c +++ b/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c @@ -870,7 +870,8 @@ gst_vtenc_start (GstVideoEncoder * enc) /* Create the output task, but pause it immediately */ self->pause_task = TRUE; if (!gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (enc), - (GstTaskFunction) gst_vtenc_output_loop, self, NULL)) { + (GstTaskFunction) gst_vtenc_output_loop, gst_object_ref (self), + gst_object_unref)) { GST_ERROR_OBJECT (self, "failed to start output thread"); return FALSE; } diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2combiner.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2combiner.cpp new file mode 100644 index 0000000000..cd4d800721 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2combiner.cpp @@ -0,0 +1,646 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2combiner.h" +#include "gstdecklink2utils.h" +#include + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_combiner_debug); +#define GST_CAT_DEFAULT gst_decklink2_combiner_debug + +static GstStaticPadTemplate audio_template = GST_STATIC_PAD_TEMPLATE ("audio", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-raw, format = (string) { S16LE, S32LE }, " + "rate = (int) 48000, channels = (int) { 2, 8, 16 }, " + "layout = (string) interleaved")); + +struct _GstDeckLink2Combiner +{ + GstAggregator parent; + + GstAggregatorPad *video_pad; + GstAggregatorPad *audio_pad; + + GstCaps *video_caps; + GstCaps *audio_caps; + + GstVideoInfo video_info; + GstAudioInfo audio_info; + + GstClockTime video_start_time; + GstClockTime audio_start_time; + + GstClockTime video_running_time; + GstClockTime audio_running_time; + + guint64 num_video_buffers; + guint64 num_audio_buffers; +}; + +static gboolean gst_decklink2_combiner_sink_event (GstAggregator * agg, + GstAggregatorPad * pad, GstEvent * event); +static gboolean gst_decklink2_combiner_sink_query (GstAggregator * agg, + GstAggregatorPad * aggpad, GstQuery * query); +static GstFlowReturn gst_decklink2_combiner_aggregate (GstAggregator * agg, + gboolean timeout); +static gboolean gst_decklink2_combiner_start (GstAggregator * agg); +static gboolean gst_decklink2_combiner_stop (GstAggregator * agg); +static GstBuffer *gst_decklink2_combiner_clip (GstAggregator * agg, + GstAggregatorPad * aggpad, GstBuffer * buffer); + +#define gst_decklink2_combiner_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Combiner, gst_decklink2_combiner, + GST_TYPE_AGGREGATOR); +GST_ELEMENT_REGISTER_DEFINE (decklink2combiner, "decklink2combiner", + GST_RANK_NONE, GST_TYPE_DECKLINK2_COMBINER); + +static void +gst_decklink2_combiner_class_init (GstDeckLink2CombinerClass * klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstAggregatorClass *agg_class = GST_AGGREGATOR_CLASS (klass); + GstCaps *templ_caps; + + gst_element_class_add_static_pad_template_with_gtype (element_class, + &audio_template, GST_TYPE_AGGREGATOR_PAD); + + templ_caps = gst_decklink2_get_default_template_caps (); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new_with_gtype ("video", GST_PAD_SINK, GST_PAD_ALWAYS, + templ_caps, GST_TYPE_AGGREGATOR_PAD)); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new_with_gtype ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + templ_caps, GST_TYPE_AGGREGATOR_PAD)); + gst_caps_unref (templ_caps); + + gst_element_class_set_static_metadata (element_class, + "DeckLink2 Combiner", + "Combiner", "Combines video and audio frames", + "Seungha Yang "); + + agg_class->sink_event = GST_DEBUG_FUNCPTR (gst_decklink2_combiner_sink_event); + agg_class->sink_query = GST_DEBUG_FUNCPTR (gst_decklink2_combiner_sink_query); + agg_class->aggregate = GST_DEBUG_FUNCPTR (gst_decklink2_combiner_aggregate); + agg_class->start = GST_DEBUG_FUNCPTR (gst_decklink2_combiner_start); + agg_class->stop = GST_DEBUG_FUNCPTR (gst_decklink2_combiner_stop); + agg_class->clip = GST_DEBUG_FUNCPTR (gst_decklink2_combiner_clip); + agg_class->get_next_time = + GST_DEBUG_FUNCPTR (gst_aggregator_simple_get_next_time); + /* No negotiation needed */ + agg_class->negotiate = NULL; + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_combiner_debug, + "decklink2combiner", 0, "decklink2combiner"); +} + +static void +gst_decklink2_combiner_init (GstDeckLink2Combiner * self) +{ + GstPadTemplate *templ; + GstElementClass *klass = GST_ELEMENT_GET_CLASS (self); + + templ = gst_element_class_get_pad_template (klass, "video"); + self->video_pad = (GstAggregatorPad *) + g_object_new (GST_TYPE_AGGREGATOR_PAD, "name", "video", "direction", + GST_PAD_SINK, "template", templ, NULL); + gst_object_unref (templ); + gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD_CAST (self->video_pad)); + + templ = gst_static_pad_template_get (&audio_template); + self->audio_pad = (GstAggregatorPad *) + g_object_new (GST_TYPE_AGGREGATOR_PAD, "name", "audio", "direction", + GST_PAD_SINK, "template", templ, NULL); + gst_object_unref (templ); + gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD_CAST (self->audio_pad)); +} + +static gboolean +gst_decklink2_combiner_sink_event (GstAggregator * agg, + GstAggregatorPad * aggpad, GstEvent * event) +{ + GstDeckLink2Combiner *self = GST_DECKLINK2_COMBINER (agg); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CAPS: + { + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + + GST_DEBUG_OBJECT (self, "Got caps from %s pad %" GST_PTR_FORMAT, + aggpad == self->video_pad ? "video" : "audio", caps); + + if (aggpad == self->video_pad) { + gst_caps_replace (&self->video_caps, caps); + gst_video_info_from_caps (&self->video_info, caps); + } else { + /* FIXME: flush audio if audio info is changed or disallow audio update */ + gst_caps_replace (&self->audio_caps, caps); + gst_audio_info_from_caps (&self->audio_info, caps); + } + + if (self->video_caps) { + gint fps_n, fps_d; + GstClockTime latency; + + caps = gst_caps_copy (self->video_caps); + if (GST_AUDIO_INFO_IS_VALID (&self->audio_info)) { + gst_caps_set_simple (caps, "audio-channels", G_TYPE_INT, + self->audio_info.channels, + "audio-format", G_TYPE_STRING, + gst_audio_format_to_string (self->audio_info.finfo->format), + NULL); + } else { + gst_caps_set_simple (caps, "audio-channels", G_TYPE_INT, 0, NULL); + } + + GST_DEBUG_OBJECT (self, "Set caps %" GST_PTR_FORMAT, caps); + + if (self->video_info.fps_n > 0 && self->video_info.fps_d > 0) { + fps_n = self->video_info.fps_n; + fps_d = self->video_info.fps_d; + } else { + fps_n = 30; + fps_d = 1; + } + + latency = gst_util_uint64_scale_ceil (GST_SECOND, fps_d, fps_n); + gst_aggregator_set_latency (agg, latency, latency); + + gst_aggregator_set_src_caps (agg, caps); + gst_caps_unref (caps); + } + break; + } + case GST_EVENT_SEGMENT: + { + const GstSegment *segment; + + gst_event_parse_segment (event, &segment); + + /* pass through video segment as-is */ + gst_aggregator_update_segment (agg, segment); + break; + } + default: + break; + } + + return GST_AGGREGATOR_CLASS (parent_class)->sink_event (agg, aggpad, event); +} + +static gboolean +gst_decklink2_combiner_sink_query (GstAggregator * agg, + GstAggregatorPad * aggpad, GstQuery * query) +{ + GstDeckLink2Combiner *self = GST_DECKLINK2_COMBINER (agg); + gboolean ret; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CAPS: + { + GstQuery *caps_query; + GstCaps *filter = NULL; + GstStructure *s; + GstCaps *caps = NULL; + GstCaps *templ_caps = gst_pad_get_pad_template_caps (GST_PAD (aggpad)); + + gst_query_parse_caps (query, &filter); + + GST_LOG_OBJECT (aggpad, "Handle query caps with filter %" GST_PTR_FORMAT, + filter); + + if (filter) + caps_query = gst_query_new_caps (filter); + else + caps_query = gst_query_new_caps (templ_caps); + + ret = gst_pad_peer_query (GST_AGGREGATOR_SRC_PAD (agg), caps_query); + gst_query_parse_caps_result (caps_query, &caps); + + GST_LOG_OBJECT (aggpad, "Downstream query caps result %d, %" + GST_PTR_FORMAT, ret, caps); + + if (!caps || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) { + if (filter) { + GstCaps *temp = gst_caps_intersect_full (filter, templ_caps, + GST_CAPS_INTERSECT_FIRST); + gst_query_set_caps_result (query, temp); + gst_caps_unref (temp); + } else { + gst_query_set_caps_result (query, templ_caps); + } + gst_caps_unref (templ_caps); + gst_query_unref (caps_query); + + return TRUE; + } + + caps = gst_caps_copy (caps); + gst_query_unref (caps_query); + + if (aggpad == self->video_pad) { + /* Remove audio related fields */ + for (guint i = 0; i < gst_caps_get_size (caps); i++) { + s = gst_caps_get_structure (caps, i); + gst_structure_remove_field (s, "audio-channels"); + } + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + } else { + GstCaps *audio_caps = gst_caps_copy (templ_caps); + const GValue *ch; + + /* construct caps with updated channels field */ + s = gst_caps_get_structure (caps, 0); + ch = gst_structure_get_value (s, "audio-channels"); + if (ch) + gst_caps_set_value (audio_caps, "channels", ch); + + gst_caps_unref (caps); + + if (filter) { + GstCaps *temp = gst_caps_intersect_full (filter, audio_caps, + GST_CAPS_INTERSECT_FIRST); + gst_query_set_caps_result (query, temp); + gst_caps_unref (temp); + } else { + gst_query_set_caps_result (query, audio_caps); + } + gst_caps_unref (audio_caps); + } + gst_caps_unref (templ_caps); + return TRUE; + } + case GST_QUERY_ACCEPT_CAPS: + GST_DEBUG_OBJECT (aggpad, "Handle accept caps"); + + if (aggpad == self->video_pad) { + ret = gst_pad_peer_query (GST_AGGREGATOR_SRC_PAD (agg), query); + GST_DEBUG_OBJECT (aggpad, "Video accept caps result %d", ret); + } else { + GstQuery *caps_query; + GstCaps *audio_caps; + GstCaps *caps = NULL; + const GValue *ch; + GstStructure *s; + + caps_query = gst_query_new_caps (NULL); + ret = gst_pad_peer_query (GST_AGGREGATOR_SRC_PAD (agg), caps_query); + + gst_query_parse_caps_result (caps_query, &caps); + GST_LOG_OBJECT (aggpad, "Downstream query caps result %d, %" + GST_PTR_FORMAT, ret, caps); + + if (!caps || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) { + gst_query_unref (caps_query); + gst_query_set_accept_caps_result (query, TRUE); + + return TRUE; + } + + audio_caps = gst_static_pad_template_get_caps (&audio_template); + /* construct caps with updated channels field */ + audio_caps = gst_caps_copy (audio_caps); + + s = gst_caps_get_structure (caps, 0); + ch = gst_structure_get_value (s, "audio-channels"); + if (ch) + gst_caps_set_value (audio_caps, "channels", ch); + + gst_query_unref (caps_query); + + gst_query_parse_accept_caps (query, &caps); + gst_query_set_accept_caps_result (query, gst_caps_is_subset (caps, + audio_caps)); + gst_caps_unref (audio_caps); + ret = TRUE; + } + return ret; + default: + break; + } + + return GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, aggpad, query); +} + +static void +gst_decklink2_combiner_reset (GstDeckLink2Combiner * self) +{ + gst_clear_caps (&self->video_caps); + gst_clear_caps (&self->audio_caps); + + gst_video_info_init (&self->video_info); + gst_audio_info_init (&self->audio_info); + + self->video_start_time = GST_CLOCK_TIME_NONE; + self->audio_start_time = GST_CLOCK_TIME_NONE; + self->video_running_time = GST_CLOCK_TIME_NONE; + self->audio_running_time = GST_CLOCK_TIME_NONE; + self->num_video_buffers = 0; + self->num_audio_buffers = 0; +} + +static gboolean +gst_decklink2_combiner_start (GstAggregator * agg) +{ + GstDeckLink2Combiner *self = GST_DECKLINK2_COMBINER (agg); + + gst_decklink2_combiner_reset (self); + + return TRUE; +} + +static gboolean +gst_decklink2_combiner_stop (GstAggregator * agg) +{ + GstDeckLink2Combiner *self = GST_DECKLINK2_COMBINER (agg); + + gst_decklink2_combiner_reset (self); + + return TRUE; +} + +static GstBuffer * +gst_decklink2_combiner_clip (GstAggregator * agg, GstAggregatorPad * aggpad, + GstBuffer * buffer) +{ + GstDeckLink2Combiner *self = GST_DECKLINK2_COMBINER (agg); + GstClockTime pts; + + pts = GST_BUFFER_PTS (buffer); + + if (!GST_CLOCK_TIME_IS_VALID (pts)) { + GST_ERROR_OBJECT (self, "Only buffers with PTS supported"); + return buffer; + } + + if (aggpad == self->video_pad) { + GstClockTime dur; + GstClockTime start, stop, cstart, cstop; + + dur = GST_BUFFER_DURATION (buffer); + if (!GST_CLOCK_TIME_IS_VALID (dur) && + self->video_info.fps_n > 0 && self->video_info.fps_d > 0) { + dur = gst_util_uint64_scale_int (GST_SECOND, self->video_info.fps_d, + self->video_info.fps_n); + } + + start = pts; + if (GST_CLOCK_TIME_IS_VALID (dur)) + stop = start + dur; + else + stop = GST_CLOCK_TIME_NONE; + + if (!gst_segment_clip (&aggpad->segment, GST_FORMAT_TIME, start, stop, + &cstart, &cstop)) { + GST_LOG_OBJECT (self, "Dropping buffer outside segment"); + gst_buffer_unref (buffer); + return NULL; + } + + if (GST_BUFFER_PTS (buffer) != cstart) { + buffer = gst_buffer_make_writable (buffer); + GST_BUFFER_PTS (buffer) = cstart; + } + + if (GST_CLOCK_TIME_IS_VALID (stop) && GST_CLOCK_TIME_IS_VALID (cstop)) { + dur = cstop - cstart; + + if (GST_BUFFER_DURATION (buffer) != dur) + buffer = gst_buffer_make_writable (buffer); + + GST_BUFFER_DURATION (buffer) = dur; + } + } else { + buffer = gst_audio_buffer_clip (buffer, &aggpad->segment, + self->audio_info.rate, self->audio_info.bpf); + } + + return buffer; +} + +static GstFlowReturn +gst_decklink2_combiner_aggregate (GstAggregator * agg, gboolean timeout) +{ + GstDeckLink2Combiner *self = GST_DECKLINK2_COMBINER (agg); + GstBuffer *video_buf = NULL; + GstBuffer *audio_buf = NULL; + GstDeckLink2AudioMeta *meta; + GstClockTime video_running_time = GST_CLOCK_TIME_NONE; + GstClockTime video_running_time_end = GST_CLOCK_TIME_NONE; + GstClockTime audio_running_time, audio_running_time_end; + GstSample *audio_sample; + + if (gst_aggregator_pad_is_eos (self->video_pad) && + gst_aggregator_pad_is_eos (self->audio_pad)) { + GST_DEBUG_OBJECT (self, "All EOS"); + return GST_FLOW_EOS; + } + + video_buf = gst_aggregator_pad_peek_buffer (self->video_pad); + if (!video_buf) { + GST_LOG_OBJECT (self, "Waiting for video"); + goto need_data; + } + + /* Drop empty buffer */ + if (gst_buffer_get_size (video_buf) == 0) { + GST_LOG_OBJECT (self, "Dropping empty video buffer"); + gst_aggregator_pad_drop_buffer (self->video_pad); + goto need_data; + } + + video_running_time = video_running_time_end = + gst_segment_to_running_time (&self->video_pad->segment, + GST_FORMAT_TIME, GST_BUFFER_PTS (video_buf)); + if (GST_BUFFER_DURATION_IS_VALID (video_buf)) { + video_running_time_end += GST_BUFFER_DURATION (video_buf); + } else if (self->video_info.fps_n > 0 && self->video_info.fps_d > 0) { + video_running_time_end += gst_util_uint64_scale_int (GST_SECOND, + self->video_info.fps_d, self->video_info.fps_n); + } else { + /* XXX: shouldn't happen */ + video_running_time_end = video_running_time; + } + + if (!GST_CLOCK_TIME_IS_VALID (self->video_start_time)) { + self->video_start_time = video_running_time; + GST_DEBUG_OBJECT (self, "Video start time %" GST_TIME_FORMAT, + GST_TIME_ARGS (self->video_start_time)); + } + + self->video_running_time = video_running_time_end; + + audio_buf = gst_aggregator_pad_peek_buffer (self->audio_pad); + if (!audio_buf) { + GST_LOG_OBJECT (self, "Waiting for audio buffer"); + goto need_data; + } + + if (gst_buffer_get_size (audio_buf) == 0) { + GST_LOG_OBJECT (self, "Dropping empty audio buffer"); + gst_aggregator_pad_drop_buffer (self->audio_pad); + goto need_data; + } + + audio_running_time = gst_segment_to_running_time (&self->audio_pad->segment, + GST_FORMAT_TIME, GST_BUFFER_PTS (audio_buf)); + if (GST_BUFFER_DURATION_IS_VALID (audio_buf)) { + audio_running_time_end = audio_running_time + + GST_BUFFER_DURATION (audio_buf); + } else { + audio_running_time_end = gst_util_uint64_scale (GST_SECOND, + gst_buffer_get_size (audio_buf), + self->audio_info.rate * self->audio_info.bpf); + audio_running_time_end += audio_running_time; + } + + self->audio_running_time = audio_running_time_end; + + /* Do initial video/audio align */ + if (!GST_CLOCK_TIME_IS_VALID (self->audio_start_time)) { + GST_DEBUG_OBJECT (self, "Initial audio running time %" GST_TIME_FORMAT, + GST_TIME_ARGS (audio_running_time)); + + if (audio_running_time_end <= self->video_start_time) { + GST_DEBUG_OBJECT (self, "audio running-time end %" GST_TIME_FORMAT + " < video-start-time %" GST_TIME_FORMAT, + GST_TIME_ARGS (self->video_start_time), + GST_TIME_ARGS (audio_running_time_end)); + /* completely outside */ + gst_aggregator_pad_drop_buffer (self->audio_pad); + goto need_data; + } else if (audio_running_time < self->video_start_time && + audio_running_time_end >= self->video_start_time) { + /* partial overlap */ + GstClockTime diff; + gsize in_samples, diff_samples; + GstAudioMeta *meta; + GstBuffer *trunc_buf; + + meta = gst_buffer_get_audio_meta (audio_buf); + in_samples = meta ? meta->samples : + gst_buffer_get_size (audio_buf) / self->audio_info.bpf; + + diff = self->video_start_time - audio_running_time; + diff_samples = gst_util_uint64_scale (diff, + self->audio_info.rate, GST_SECOND); + + GST_DEBUG_OBJECT (self, "Truncate initial audio buffer duration %" + GST_TIME_FORMAT, GST_TIME_ARGS (diff)); + + trunc_buf = gst_audio_buffer_truncate ( + (GstBuffer *) g_steal_pointer (&audio_buf), + self->audio_info.bpf, diff_samples, in_samples - diff_samples); + gst_aggregator_pad_drop_buffer (self->audio_pad); + if (!trunc_buf) { + GST_DEBUG_OBJECT (self, "Empty truncated buffer"); + gst_aggregator_pad_drop_buffer (self->audio_pad); + goto need_data; + } + + self->audio_start_time = self->video_start_time; + audio_buf = trunc_buf; + } else if (audio_running_time >= self->video_start_time) { + /* fill silence if needed */ + GstClockTime diff; + gsize diff_samples; + + diff = audio_running_time - self->video_start_time; + if (diff > 0) { + gsize fill_size; + + diff_samples = gst_util_uint64_scale (diff, + self->audio_info.rate, GST_SECOND); + + fill_size = diff_samples * self->audio_info.bpf; + if (fill_size > 0) { + GstBuffer *fill_buf; + GstMapInfo map; + GstMapInfo origin_map; + + GST_DEBUG_OBJECT (self, "Fill initial %" G_GSIZE_FORMAT + " audio samples", diff_samples); + + gst_buffer_map (audio_buf, &origin_map, GST_MAP_READ); + + fill_buf = gst_buffer_new_and_alloc (fill_size + origin_map.size); + gst_buffer_map (fill_buf, &map, GST_MAP_WRITE); + gst_audio_format_info_fill_silence (self->audio_info.finfo, + map.data, fill_size); + memcpy ((guint8 *) map.data + fill_size, + origin_map.data, origin_map.size); + gst_buffer_unmap (fill_buf, &map); + gst_buffer_unmap (audio_buf, &origin_map); + gst_buffer_unref (audio_buf); + audio_buf = fill_buf; + } + } + + self->audio_start_time = self->video_start_time; + gst_aggregator_pad_drop_buffer (self->audio_pad); + } + + self->num_audio_buffers++; + } else { + gst_aggregator_pad_drop_buffer (self->audio_pad); + self->num_audio_buffers++; + } + + gst_aggregator_pad_drop_buffer (self->video_pad); + video_buf = gst_buffer_make_writable (video_buf); + self->num_video_buffers++; + + /* Remove external audio meta if any */ + meta = gst_buffer_get_decklink2_audio_meta (video_buf); + if (meta) { + GST_LOG_OBJECT (self, "Removing old audio meta"); + gst_buffer_remove_meta (video_buf, GST_META_CAST (meta)); + } + + audio_sample = gst_sample_new (audio_buf, self->audio_caps, NULL, NULL); + gst_buffer_unref (audio_buf); + gst_buffer_add_decklink2_audio_meta (video_buf, audio_sample); + gst_sample_unref (audio_sample); + + GST_LOG_OBJECT (self, "Finish buffer %" GST_PTR_FORMAT + ", total video/audio buffers %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ") / %" GST_TIME_FORMAT " (%" + G_GUINT64_FORMAT ")", video_buf, GST_TIME_ARGS (self->video_running_time), + self->num_video_buffers, GST_TIME_ARGS (self->audio_running_time), + self->num_audio_buffers); + + GST_AGGREGATOR_PAD (agg->srcpad)->segment.position = self->video_running_time; + + return gst_aggregator_finish_buffer (agg, video_buf); + +need_data: + gst_clear_buffer (&video_buf); + gst_clear_buffer (&audio_buf); + + return GST_AGGREGATOR_FLOW_NEED_DATA; +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2combiner.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2combiner.h new file mode 100644 index 0000000000..7cec7d6bae --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2combiner.h @@ -0,0 +1,34 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_COMBINER (gst_decklink2_combiner_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Combiner, gst_decklink2_combiner, + GST, DECKLINK2_COMBINER, GstAggregator); + +GST_ELEMENT_REGISTER_DECLARE (decklink2combiner); + +G_END_DECLS \ No newline at end of file diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2demux.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2demux.cpp new file mode 100644 index 0000000000..34ecd7b2f8 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2demux.cpp @@ -0,0 +1,299 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2demux.h" +#include "gstdecklink2utils.h" +#include "gstdecklink2object.h" + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_demux_debug); +#define GST_CAT_DEFAULT gst_decklink2_demux_debug + +static GstStaticPadTemplate audio_template = GST_STATIC_PAD_TEMPLATE ("audio", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS ("audio/x-raw, format = (string) { S16LE, S32LE }, " + "rate = (int) 48000, channels = (int) { 2, 8, 16 }, " + "layout = (string) interleaved")); + +struct _GstDeckLink2Demux +{ + GstElement parent; + + GstPad *sink_pad; + GstPad *video_pad; + GstPad *audio_pad; + GstVideoInfo video_info; + + GstFlowCombiner *flow_combiner; + GstCaps *audio_caps; + + guint drop_count; +}; + +static void gst_decklink2_demux_finalize (GObject * object); +static GstStateChangeReturn +gst_decklink2_demux_change_state (GstElement * element, + GstStateChange transition); +static GstFlowReturn gst_decklink2_demux_chain (GstPad * sinkpad, + GstObject * parent, GstBuffer * inbuf); +static gboolean gst_decklink2_demux_sink_event (GstPad * sinkpad, + GstObject * parent, GstEvent * event); + +#define gst_decklink2_demux_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Demux, gst_decklink2_demux, GST_TYPE_ELEMENT); +GST_ELEMENT_REGISTER_DEFINE (decklink2demux, "decklink2demux", + GST_RANK_NONE, GST_TYPE_DECKLINK2_DEMUX); + +static void +gst_decklink2_demux_class_init (GstDeckLink2DemuxClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + object_class->finalize = gst_decklink2_demux_finalize; + + GstCaps *templ_caps = gst_decklink2_get_default_template_caps (); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, templ_caps)); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("video", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps)); + gst_caps_unref (templ_caps); + gst_element_class_add_static_pad_template (element_class, &audio_template); + + gst_element_class_set_static_metadata (element_class, + "Decklink2 Demux", "Video/Audio/Demuxer/Hardware", "Decklink2 Demux", + "Seungha Yang "); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_decklink2_demux_change_state); + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_demux_debug, "decklink2demux", + 0, "decklink2demux"); +} + +static void +gst_decklink2_demux_init (GstDeckLink2Demux * self) +{ + GstPadTemplate *templ; + GstElementClass *klass = GST_ELEMENT_GET_CLASS (self); + + templ = gst_element_class_get_pad_template (klass, "sink"); + self->sink_pad = gst_pad_new_from_template (templ, "sink"); + gst_pad_set_chain_function (self->sink_pad, gst_decklink2_demux_chain); + gst_pad_set_event_function (self->sink_pad, gst_decklink2_demux_sink_event); + gst_element_add_pad (GST_ELEMENT (self), self->sink_pad); + gst_object_unref (templ); + + templ = gst_element_class_get_pad_template (klass, "video"); + self->video_pad = gst_pad_new_from_template (templ, "video"); + gst_element_add_pad (GST_ELEMENT (self), self->video_pad); + gst_pad_use_fixed_caps (self->video_pad); + gst_object_unref (templ); + + self->flow_combiner = gst_flow_combiner_new (); + gst_flow_combiner_add_pad (self->flow_combiner, self->video_pad); +} + +static void +gst_decklink2_demux_finalize (GObject * object) +{ + GstDeckLink2Demux *self = GST_DECKLINK2_DEMUX (object); + + gst_flow_combiner_free (self->flow_combiner); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static GstStateChangeReturn +gst_decklink2_demux_change_state (GstElement * element, + GstStateChange transition) +{ + GstDeckLink2Demux *self = GST_DECKLINK2_DEMUX (element); + GstStateChangeReturn ret; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_clear_caps (&self->audio_caps); + self->drop_count = 0; + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + if (self->audio_pad) { + gst_flow_combiner_remove_pad (self->flow_combiner, self->audio_pad); + gst_element_remove_pad (element, self->audio_pad); + self->audio_pad = NULL; + } + gst_clear_caps (&self->audio_caps); + break; + default: + break; + } + + return ret; +} + +static GstFlowReturn +gst_decklink2_demux_chain (GstPad * sinkpad, GstObject * parent, + GstBuffer * inbuf) +{ + GstDeckLink2Demux *self = GST_DECKLINK2_DEMUX (parent); + GstDeckLink2AudioMeta *meta; + GstSample *audio_sample = NULL; + GstFlowReturn ret; + gsize buf_size; + + meta = gst_buffer_get_decklink2_audio_meta (inbuf); + if (meta) { + audio_sample = gst_sample_ref (meta->sample); + inbuf = gst_buffer_make_writable (inbuf); + gst_buffer_remove_meta (inbuf, GST_META_CAST (meta)); + } + + if (audio_sample) { + GstCaps *audio_caps = gst_sample_get_caps (audio_sample); + GstBuffer *audio_buf = gst_sample_get_buffer (audio_sample); + + if (!audio_caps) { + GST_WARNING_OBJECT (self, "Audio sample without caps"); + gst_sample_unref (audio_sample); + audio_sample = NULL; + goto out; + } + + if (!audio_buf) { + GST_WARNING_OBJECT (self, "Audio sample without buffer"); + gst_sample_unref (audio_sample); + audio_sample = NULL; + goto out; + } + + if (!self->audio_pad) { + GstEvent *event; + + self->audio_pad = gst_pad_new_from_static_template (&audio_template, + "audio"); + gst_pad_set_active (self->audio_pad, TRUE); + + event = gst_pad_get_sticky_event (self->sink_pad, + GST_EVENT_STREAM_START, 0); + + gst_pad_store_sticky_event (self->audio_pad, event); + gst_event_unref (event); + + gst_caps_replace (&self->audio_caps, audio_caps); + + event = gst_event_new_caps (self->audio_caps); + gst_pad_store_sticky_event (self->audio_pad, event); + gst_event_unref (event); + + event = gst_pad_get_sticky_event (self->sink_pad, GST_EVENT_SEGMENT, 0); + if (event) { + gst_pad_store_sticky_event (self->audio_pad, event); + gst_event_unref (event); + } + + gst_element_add_pad (GST_ELEMENT (self), self->audio_pad); + gst_flow_combiner_add_pad (self->flow_combiner, self->audio_pad); + + gst_element_no_more_pads (GST_ELEMENT (self)); + } else if (!self->audio_caps || !gst_caps_is_equal (self->audio_caps, + audio_caps)) { + GstEvent *event; + + gst_caps_replace (&self->audio_caps, audio_caps); + + event = gst_event_new_caps (self->audio_caps); + gst_pad_push_event (self->audio_pad, event); + } + } + +out: + buf_size = gst_buffer_get_size (inbuf); + if (buf_size < self->video_info.size) { + GST_WARNING_OBJECT (self, "Too small buffer size %" G_GSIZE_FORMAT + " < %" G_GSIZE_FORMAT, buf_size, self->video_info.size); + gst_buffer_unref (inbuf); + self->drop_count++; + + if (self->drop_count > 30) { + GST_ERROR_OBJECT (self, "Too many buffers were dropped"); + return GST_FLOW_ERROR; + } + + return GST_FLOW_OK; + } + + self->drop_count = 0; + + GST_LOG_OBJECT (self, "Pushing video buffer %" GST_PTR_FORMAT, inbuf); + ret = gst_pad_push (self->video_pad, inbuf); + ret = gst_flow_combiner_update_pad_flow (self->flow_combiner, + self->video_pad, ret); + + if (audio_sample) { + GstBuffer *audio_buf = gst_sample_get_buffer (audio_sample); + gst_buffer_ref (audio_buf); + gst_sample_unref (audio_sample); + + GST_LOG_OBJECT (self, "Pushing audio buffer %" GST_PTR_FORMAT, audio_buf); + ret = gst_pad_push (self->audio_pad, audio_buf); + ret = gst_flow_combiner_update_pad_flow (self->flow_combiner, + self->audio_pad, ret); + } + + return ret; +} + +static gboolean +gst_decklink2_demux_sink_event (GstPad * sinkpad, GstObject * parent, + GstEvent * event) +{ + GstDeckLink2Demux *self = GST_DECKLINK2_DEMUX (parent); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CAPS:{ + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + GST_DEBUG_OBJECT (self, "Forwarding %" GST_PTR_FORMAT, caps); + + gst_video_info_from_caps (&self->video_info, caps); + + return gst_pad_push_event (self->video_pad, event); + } + case GST_EVENT_FLUSH_STOP: + gst_flow_combiner_reset (self->flow_combiner); + break; + default: + break; + } + + return gst_pad_event_default (sinkpad, parent, event); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2demux.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2demux.h new file mode 100644 index 0000000000..8c35035416 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2demux.h @@ -0,0 +1,34 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_DEMUX (gst_decklink2_demux_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Demux, gst_decklink2_demux, + GST, DECKLINK2_DEMUX, GstElement); + +GST_ELEMENT_REGISTER_DECLARE (decklink2demux); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2deviceprovider.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2deviceprovider.cpp new file mode 100644 index 0000000000..c55bdbd647 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2deviceprovider.cpp @@ -0,0 +1,158 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2deviceprovider.h" +#include + +GST_DEBUG_CATEGORY_EXTERN (gst_decklink2_debug); +#define GST_CAT_DEFAULT gst_decklink2_debug + +struct _GstDeckLink2Device +{ + GstDevice parent; + + gboolean is_src; + guint device_number; + gint64 persistent_id; +}; + +static GstElement *gst_decklink2_device_create_element (GstDevice * device, + const gchar * name); + +G_DEFINE_TYPE (GstDeckLink2Device, gst_decklink2_device, GST_TYPE_DEVICE); + +static void +gst_decklink2_device_class_init (GstDeckLink2DeviceClass * klass) +{ + GstDeviceClass *dev_class = GST_DEVICE_CLASS (klass); + + dev_class->create_element = + GST_DEBUG_FUNCPTR (gst_decklink2_device_create_element); +} + +static void +gst_decklink2_device_init (GstDeckLink2Device * self) +{ +} + +static GstElement * +gst_decklink2_device_create_element (GstDevice * device, const gchar * name) +{ + GstDeckLink2Device *self = GST_DECKLINK2_DEVICE (device); + GstElement *elem; + + if (self->is_src) { + elem = gst_element_factory_make ("decklink2src", name); + } else { + elem = gst_element_factory_make ("decklink2sink", name); + } + + g_object_set (elem, "persistent-id", self->persistent_id, NULL); + + return elem; +} + +GstDevice * +gst_decklink2_device_new (gboolean is_src, const gchar * model_name, + const gchar * display_name, const gchar * serial_number, GstCaps * caps, + gint64 persistent_id, guint device_number, guint max_audio_channels, + const gchar * driver_ver, const gchar * api_ver) +{ + GstDevice *device; + GstDeckLink2Device *self; + const gchar *device_class; + GstStructure *props; + + if (is_src) + device_class = "Video/Audio/Source/Hardware"; + else + device_class = "Video/Audio/Sink/Hardware"; + + props = gst_structure_new ("properties", + "driver-version", G_TYPE_STRING, driver_ver, + "api-version", G_TYPE_STRING, api_ver, + "device-number", G_TYPE_UINT, device_number, + "persistent-id", G_TYPE_INT64, persistent_id, NULL); + + if (max_audio_channels > 0) { + gst_structure_set (props, + "max-channels", G_TYPE_UINT, max_audio_channels, NULL); + } + + if (serial_number && serial_number[0] != '\0') { + gst_structure_set (props, + "serial-number", G_TYPE_STRING, serial_number, NULL); + } + + device = (GstDevice *) g_object_new (GST_TYPE_DECKLINK2_DEVICE, + "display-name", display_name, "device-class", device_class, + "caps", caps, "properties", props, NULL); + + self = GST_DECKLINK2_DEVICE (device); + self->device_number = device_number; + self->persistent_id = persistent_id; + self->is_src = is_src; + + return device; +} + +struct _GstDeckLink2DeviceProvider +{ + GstDeviceProvider parent; +}; + +static GList *gst_decklink2_device_provider_probe (GstDeviceProvider * + provider); + +G_DEFINE_TYPE (GstDeckLink2DeviceProvider, gst_decklink2_device_provider, + GST_TYPE_DEVICE_PROVIDER); +GST_DEVICE_PROVIDER_REGISTER_DEFINE (decklink2deviceprovider, + "decklink2deviceprovider", GST_RANK_SECONDARY, + GST_TYPE_DECKLINK2_DEVICE_PROVIDER); + +static void +gst_decklink2_device_provider_class_init (GstDeckLink2DeviceProviderClass * + klass) +{ + GstDeviceProviderClass *provider_class = GST_DEVICE_PROVIDER_CLASS (klass); + + provider_class->probe = + GST_DEBUG_FUNCPTR (gst_decklink2_device_provider_probe); + + gst_device_provider_class_set_static_metadata (provider_class, + "Decklink Device Provider", "Hardware/Source/Sink/Audio/Video", + "Lists and provides Decklink devices", + "Seungha Yang "); +} + +static void +gst_decklink2_device_provider_init (GstDeckLink2DeviceProvider * self) +{ +} + +static GList * +gst_decklink2_device_provider_probe (GstDeviceProvider * provider) +{ + return gst_decklink2_get_devices (); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2deviceprovider.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2deviceprovider.h new file mode 100644 index 0000000000..33b268fcdc --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2deviceprovider.h @@ -0,0 +1,50 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include "gstdecklink2utils.h" +#include "gstdecklink2object.h" + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_DEVICE (gst_decklink2_device_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Device, gst_decklink2_device, + GST, DECKLINK2_DEVICE, GstDevice); + +#define GST_TYPE_DECKLINK2_DEVICE_PROVIDER (gst_decklink2_device_provider_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2DeviceProvider, gst_decklink2_device_provider, + GST, DECKLINK2_DEVICE_PROVIDER, GstDeviceProvider); + +GstDevice * gst_decklink2_device_new (gboolean is_src, + const gchar * model_name, + const gchar * display_name, + const gchar * serial_number, + GstCaps * caps, + gint64 persistent_id, + guint device_number, + guint max_audio_channels, + const gchar * driver_ver, + const gchar * api_ver); + +GST_DEVICE_PROVIDER_REGISTER_DECLARE (decklink2deviceprovider); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2input.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2input.cpp new file mode 100644 index 0000000000..2faa03682a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2input.cpp @@ -0,0 +1,2245 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2input.h" +#include "gstdecklink2object.h" +#include +#include +#include +#include +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_input_debug); +#define GST_CAT_DEFAULT gst_decklink2_input_debug + +#define INVALID_AUDIO_OFFSET ((guint64) -1) + +static HRESULT gst_decklink2_input_on_format_changed (GstDeckLink2Input * self, + BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode * mode, + BMDDetectedVideoInputFormatFlags flags); +static void gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self, + IDeckLinkVideoInputFrame * frame, IDeckLinkAudioInputPacket * packet); + +class IGstDeckLinkMemoryAllocator:public IDeckLinkMemoryAllocator +{ +public: + IGstDeckLinkMemoryAllocator ():ref_count_ (1) + { + } + + /* IUnknown */ + HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **object) + { + if (riid == IID_IDeckLinkInputCallback) { + *object = static_cast < IDeckLinkMemoryAllocator * >(this); + } else { + *object = NULL; + return E_NOINTERFACE; + } + + AddRef (); + + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef (void) + { + ULONG cnt = ref_count_.fetch_add (1); + + return cnt + 1; + } + + ULONG STDMETHODCALLTYPE Release (void) + { + ULONG cnt = ref_count_.fetch_sub (1); + if (cnt == 1) + delete this; + + return cnt - 1; + } + + /* IDeckLinkMemoryAllocator */ + HRESULT STDMETHODCALLTYPE AllocateBuffer (unsigned int size, void **alloced) + { + std::unique_lock < std::mutex > lk (lock_); + guint8 *buf = NULL; + guint8 offset = 0; + + if (size != last_alloc_size_) { + GST_DEBUG ("%p size changed %u -> %u", this, last_alloc_size_, size); + ClearPool (); + last_alloc_size_ = size; + } + + if (!buffers_.empty ()) { + buf = (guint8 *) buffers_.front (); + buffers_.pop (); + } + lk.unlock (); + + if (!buf) { + buf = (uint8_t *) g_malloc (size + 128); + + /* The Decklink SDK requires 16 byte aligned memory at least but for us + * to work nicely let's align to 64 bytes (512 bits) as this allows + * aligned AVX2 operations for example */ + if (((guintptr) buf) % 64 != 0) + offset = ((guintptr) buf) % 64; + + /* Write the allocation size at the very beginning. It's guaranteed by + * malloc() to be allocated aligned enough for doing this. */ + *((guint32 *) buf) = size; + + /* Align our buffer */ + buf += 128 - offset; + + /* And write the alignment offset right before the buffer */ + *(buf - 1) = offset; + } + + *alloced = (void *) buf; + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE ReleaseBuffer (void *buffer) + { + std::lock_guard < std::mutex > lk (lock_); + guint8 offset = *(((guint8 *) buffer) - 1); + guint8 *alloc_buffer = ((guint8 *) buffer) - 128 + offset; + guint32 size = *(guint32 *) alloc_buffer; + + if (!commited_ || size != last_alloc_size_) + g_free (alloc_buffer); + else + buffers_.push (buffer); + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE Commit (void) + { + std::lock_guard < std::mutex > lk (lock_); + GST_DEBUG ("Commit %p", this); + + ClearPool (); + commited_ = true; + last_alloc_size_ = 0; + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE Decommit (void) + { + std::lock_guard < std::mutex > lk (lock_); + + GST_DEBUG ("Decommit %p", this); + + ClearPool (); + commited_ = false; + + return S_OK; + } + +private: + virtual ~ IGstDeckLinkMemoryAllocator () { + Decommit (); + } + + void ClearPool (void) + { + while (!buffers_.empty ()) { + guint8 *buf = (guint8 *) buffers_.front (); + buffers_.pop (); + + guint8 offset = *(buf - 1); + void *alloc_buf = buf - 128 + offset; + g_free (alloc_buf); + } + } + +private: + std::atomic < ULONG > ref_count_; + std::mutex lock_; + std::queue < void *>buffers_; + unsigned int last_alloc_size_ = 0; + bool commited_ = false; +}; + + +/* IDeckLinkInputCallback interface for API version < 12.0 */ +class IGstDeckLinkInputCallback_v11_5_1:public IDeckLinkInputCallback_v11_5_1 +{ +public: + IGstDeckLinkInputCallback_v11_5_1 (GstDeckLink2Input * input) + :ref_count_ (1), input_ (input) + { + } + + /* IUnknown */ + HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **object) + { + if (riid == IID_IDeckLinkInputCallback) { + *object = static_cast < IGstDeckLinkInputCallback_v11_5_1 * >(this); + } else { + *object = NULL; + return E_NOINTERFACE; + } + + AddRef (); + + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef (void) + { + ULONG cnt = ref_count_.fetch_add (1); + + return cnt + 1; + } + + ULONG STDMETHODCALLTYPE Release (void) + { + ULONG cnt = ref_count_.fetch_sub (1); + if (cnt == 1) + delete this; + + return cnt - 1; + } + + /* IDeckLinkInputCallback_v11_5_1 */ + HRESULT STDMETHODCALLTYPE + VideoInputFormatChanged (BMDVideoInputFormatChangedEvents events, + IDeckLinkDisplayMode * mode, BMDDetectedVideoInputFormatFlags flags) + { + return gst_decklink2_input_on_format_changed (input_, events, mode, flags); + } + + HRESULT STDMETHODCALLTYPE + VideoInputFrameArrived (IDeckLinkVideoInputFrame * frame, + IDeckLinkAudioInputPacket * packet) + { + gst_decklink2_input_on_frame_arrived (input_, frame, packet); + return S_OK; + } + +private: + virtual ~ IGstDeckLinkInputCallback_v11_5_1 () { + } + +private: + std::atomic < ULONG > ref_count_; + GstDeckLink2Input *input_; +}; + +class IGstDeckLinkInputCallback:public IDeckLinkInputCallback +{ +public: + IGstDeckLinkInputCallback (GstDeckLink2Input * input) + :ref_count_ (1), input_ (input) + { + } + + /* IUnknown */ + HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **object) + { + if (riid == IID_IDeckLinkInputCallback) { + *object = static_cast < IDeckLinkInputCallback * >(this); + } else { + *object = NULL; + return E_NOINTERFACE; + } + + AddRef (); + + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef (void) + { + ULONG cnt = ref_count_.fetch_add (1); + + return cnt + 1; + } + + ULONG STDMETHODCALLTYPE Release (void) + { + ULONG cnt = ref_count_.fetch_sub (1); + if (cnt == 1) + delete this; + + return cnt - 1; + } + + /* IDeckLinkInputCallback */ + HRESULT STDMETHODCALLTYPE + VideoInputFormatChanged (BMDVideoInputFormatChangedEvents events, + IDeckLinkDisplayMode * mode, BMDDetectedVideoInputFormatFlags flags) + { + return gst_decklink2_input_on_format_changed (input_, events, mode, flags); + } + + HRESULT STDMETHODCALLTYPE + VideoInputFrameArrived (IDeckLinkVideoInputFrame * frame, + IDeckLinkAudioInputPacket * packet) + { + gst_decklink2_input_on_frame_arrived (input_, frame, packet); + return S_OK; + } + +private: + virtual ~ IGstDeckLinkInputCallback () { + } + +private: + std::atomic < ULONG > ref_count_; + GstDeckLink2Input *input_; +}; + +struct GstDecklink2InputData +{ + GstBuffer *buffer; + GstCaps *caps; +}; + +struct TimeMapping +{ + GstClockTime xbase; + GstClockTime b; + GstClockTime num; + GstClockTime den; +}; + +struct GstDeckLink2InputPrivate +{ + GstDeckLink2InputPrivate () + { + signal = false; + was_restarted = false; + stopping = false; + need_restart = false; + } + + std::mutex lock; + std::condition_variable cond; + std::atomic < bool >signal; + std::atomic < bool >was_restarted; + std::atomic stopping; + std::atomic need_restart; +}; + +struct _GstDeckLink2Input +{ + GstObject parent; + + GstDeckLink2InputPrivate *priv; + + GstDeckLink2APILevel api_level; + + IDeckLink *device; + IDeckLinkProfileAttributes *attr; + IDeckLinkAttributes_v10_11 *attr_10_11; + IDeckLinkConfiguration_v10_11 *config_10_11; + IDeckLinkConfiguration *config; + + IDeckLinkInput *input; + IDeckLinkInput_v11_5_1 *input_11_5_1; + IDeckLinkInput_v11_4 *input_11_4; + IDeckLinkInput_v10_11 *input_10_11; + + IGstDeckLinkMemoryAllocator *allocator; + IGstDeckLinkInputCallback_v11_5_1 *callback_11_5_1; + IGstDeckLinkInputCallback *callback; + + GstCaps *caps; + GArray *format_table; + GstCaps *selected_video_caps; + GstAudioInfo audio_info; + GstVideoInfo video_info; + guint max_audio_channels; + GstCaps *selected_audio_caps; + gboolean auto_detect; + + guint64 next_audio_offset; + guint64 audio_offset; + GstAdapter *audio_buf; + + GstQueueArray *queue; + + GstDeckLink2DisplayMode selected_mode; + BMDPixelFormat pixel_format; + BMDPixelFormat requested_pixel_format; + GstElement *client; + gboolean output_cc; + gboolean output_afd_bar; + gint aspect_ratio_flag; + BMDTimecodeFormat timecode_format; + guint buffer_size; + gboolean discont; + gboolean audio_discont; + gboolean flushing; + gboolean started; + GstClockTime skip_first_time; + GstClockTime start_time; + GstClockTimeDiff av_sync; + + guint window_size; + guint window_fill; + gboolean window_filled; + guint window_skip; + guint window_skip_count; + TimeMapping current_time_mapping; + TimeMapping next_time_mapping; + gboolean next_time_mapping_pending; + + GstClockTime times[256]; + + GstVideoVBIParser *vbi_parser; + GstVideoFormat anc_vformat; + + gint anc_width; + gint last_cc_vbi_line; + gint last_cc_vbi_line_field2; + gint last_afd_bar_vbi_line; + gint last_afd_bar_vbi_line_field2; +}; + +static void gst_decklink2_input_dispose (GObject * object); +static void gst_decklink2_input_finalize (GObject * object); +static HRESULT gst_decklink2_input_set_allocator (GstDeckLink2Input * input, + IDeckLinkMemoryAllocator * allocator); + +static void +gst_decklink2_input_data_clear (GstDecklink2InputData * data) +{ + gst_clear_buffer (&data->buffer); + gst_clear_caps (&data->caps); +} + +#define gst_decklink2_input_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Input, gst_decklink2_input, GST_TYPE_OBJECT); + +static void +gst_decklink2_input_class_init (GstDeckLink2InputClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gst_decklink2_input_dispose; + object_class->finalize = gst_decklink2_input_finalize; + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_input_debug, "decklink2input", + 0, "decklink2input"); +} + +static void +gst_decklink2_input_init (GstDeckLink2Input * self) +{ + self->format_table = g_array_new (FALSE, + FALSE, sizeof (GstDeckLink2DisplayMode)); + self->audio_buf = gst_adapter_new (); + self->allocator = new IGstDeckLinkMemoryAllocator (); + self->queue = gst_queue_array_new_for_struct (sizeof (GstDecklink2InputData), + 6); + gst_queue_array_set_clear_func (self->queue, + (GDestroyNotify) gst_decklink2_input_data_clear); + self->priv = new GstDeckLink2InputPrivate (); +} + +static void +gst_decklink2_input_dispose (GObject * object) +{ + GstDeckLink2Input *self = GST_DECKLINK2_INPUT (object); + + gst_clear_caps (&self->caps); + gst_clear_caps (&self->selected_video_caps); + gst_clear_caps (&self->selected_audio_caps); + g_clear_pointer (&self->vbi_parser, gst_video_vbi_parser_free); + g_clear_object (&self->audio_buf); + g_clear_pointer (&self->queue, gst_queue_array_free); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_decklink2_input_finalize (GObject * object) +{ + GstDeckLink2Input *self = GST_DECKLINK2_INPUT (object); + + GST_DECKLINK2_CLEAR_COM (self->input); + GST_DECKLINK2_CLEAR_COM (self->input_11_5_1); + GST_DECKLINK2_CLEAR_COM (self->input_11_4); + GST_DECKLINK2_CLEAR_COM (self->input_10_11); + GST_DECKLINK2_CLEAR_COM (self->allocator); + GST_DECKLINK2_CLEAR_COM (self->callback); + GST_DECKLINK2_CLEAR_COM (self->callback_11_5_1); + GST_DECKLINK2_CLEAR_COM (self->attr); + GST_DECKLINK2_CLEAR_COM (self->attr_10_11); + GST_DECKLINK2_CLEAR_COM (self->config); + GST_DECKLINK2_CLEAR_COM (self->config_10_11); + GST_DECKLINK2_CLEAR_COM (self->device); + + g_array_unref (self->format_table); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +/* Returns true if format is supported without conversion */ +static gboolean +gst_decklink2_input_does_support_video_mode (GstDeckLink2Input * self, + BMDDisplayMode mode, BMDPixelFormat format) +{ + HRESULT hr; + BMDDisplayModeSupport_v10_11 supported_v10_11 = + bmdDisplayModeNotSupported_v10_11; + dlbool_t supported = (dlbool_t) 0; + BMDDisplayMode actual_mode = mode; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->DoesSupportVideoMode (mode, format, + bmdVideoOutputFlagDefault, &supported_v10_11, NULL); + if (hr != S_OK || supported_v10_11 != bmdDisplayModeSupported_v10_11) + return FALSE; + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self-> + input_11_4->DoesSupportVideoMode (bmdVideoConnectionUnspecified, mode, + format, bmdSupportedVideoModeDefault, &supported); + if (hr != S_OK || !supported) + return FALSE; + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self-> + input_11_5_1->DoesSupportVideoMode (bmdVideoConnectionUnspecified, + mode, format, bmdNoVideoInputConversion, bmdSupportedVideoModeDefault, + &actual_mode, &supported); + if (hr != S_OK || !supported || actual_mode != mode) + return FALSE; + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->DoesSupportVideoMode (bmdVideoConnectionUnspecified, + mode, format, bmdNoVideoInputConversion, bmdSupportedVideoModeDefault, + &actual_mode, &supported); + if (hr != S_OK || !supported || actual_mode != mode) + return FALSE; + break; + default: + g_assert_not_reached (); + return FALSE; + } + + return TRUE; +} + +static IDeckLinkDisplayModeIterator * +gst_decklink2_input_get_iterator (GstDeckLink2Input * self) +{ + IDeckLinkDisplayModeIterator *iter = NULL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + self->input_10_11->GetDisplayModeIterator (&iter); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + self->input_11_4->GetDisplayModeIterator (&iter); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + self->input_11_5_1->GetDisplayModeIterator (&iter); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + self->input->GetDisplayModeIterator (&iter); + break; + default: + g_assert_not_reached (); + break; + } + + return iter; +} + +GstDeckLink2Input * +gst_decklink2_input_new (IDeckLink * device, GstDeckLink2APILevel api_level) +{ + GstDeckLink2Input *self; + IDeckLinkDisplayModeIterator *iter = NULL; + HRESULT hr; + + if (!device || api_level == GST_DECKLINK2_API_LEVEL_UNKNOWN) + return NULL; + + self = (GstDeckLink2Input *) g_object_new (GST_TYPE_DECKLINK2_INPUT, NULL); + self->api_level = api_level; + self->device = device; + device->AddRef (); + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + device->QueryInterface (IID_IDeckLinkAttributes_v10_11, + (void **) &self->attr_10_11); + } else { + device->QueryInterface (IID_IDeckLinkProfileAttributes, + (void **) &self->attr); + } + + self->max_audio_channels = 2; + gint64 max_audio_channels = 2; + if (self->attr) { + hr = self->attr->GetInt (BMDDeckLinkMaximumAudioChannels, + &max_audio_channels); + if (gst_decklink2_result (hr)) + self->max_audio_channels = (guint) max_audio_channels; + } else if (self->attr_10_11) { + hr = self->attr_10_11->GetInt (BMDDeckLinkMaximumAudioChannels, + &max_audio_channels); + if (gst_decklink2_result (hr)) + self->max_audio_channels = (guint) max_audio_channels; + } + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + device->QueryInterface (IID_IDeckLinkConfiguration_v10_11, + (void **) &self->config_10_11); + } else { + device->QueryInterface (IID_IDeckLinkConfiguration, + (void **) &self->config); + } + + if (api_level > GST_DECKLINK2_API_LEVEL_11_5_1) { + self->callback = new IGstDeckLinkInputCallback (self); + } else { + self->callback_11_5_1 = new IGstDeckLinkInputCallback_v11_5_1 (self); + } + + switch (api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = device->QueryInterface (IID_IDeckLinkInput_v10_11, + (void **) &self->input_10_11); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = device->QueryInterface (IID_IDeckLinkInput_v11_4, + (void **) &self->input_11_4); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = device->QueryInterface (IID_IDeckLinkInputCallback_v11_5_1, + (void **) &self->input_11_5_1); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = device->QueryInterface (IID_IDeckLinkInput, (void **) &self->input); + if (hr != S_OK) { + gst_object_unref (self); + return NULL; + } + break; + default: + g_assert_not_reached (); + gst_object_unref (self); + return NULL; + } + + iter = gst_decklink2_input_get_iterator (self); + if (!iter) { + gst_object_unref (self); + return NULL; + } + + hr = gst_decklink2_input_set_allocator (self, self->allocator); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + + self->caps = gst_decklink2_build_template_caps (GST_OBJECT (self), iter, + (GstDeckLink2DoesSupportVideoMode) + gst_decklink2_input_does_support_video_mode, self->format_table); + iter->Release (); + + if (!self->caps) + gst_clear_object (&self); + + return self; +} + +GstCaps * +gst_decklink2_input_get_caps (GstDeckLink2Input * input, BMDDisplayMode mode, + BMDPixelFormat format) +{ + IDeckLinkDisplayModeIterator *iter = NULL; + GstCaps *caps; + + if (mode == bmdModeUnknown && format == bmdFormatUnspecified) + return gst_caps_ref (input->caps); + + iter = gst_decklink2_input_get_iterator (input); + if (!iter) + return NULL; + + caps = gst_decklink2_build_caps (GST_OBJECT (input), iter, + mode, format, (GstDeckLink2DoesSupportVideoMode) + gst_decklink2_input_does_support_video_mode); + iter->Release (); + + return caps; +} + +gboolean +gst_decklink2_input_get_display_mode (GstDeckLink2Input * input, + const GstVideoInfo * info, GstDeckLink2DisplayMode * display_mode) +{ + for (guint i = 0; i < input->format_table->len; i++) { + const GstDeckLink2DisplayMode *m = &g_array_index (input->format_table, + GstDeckLink2DisplayMode, i); + + if (m->width == info->width && m->height == info->height && + m->fps_n == info->fps_n && m->fps_d == info->fps_d && + m->par_n == info->par_n && m->par_d == info->par_d) { + if ((m->interlaced && !GST_VIDEO_INFO_IS_INTERLACED (info)) || + (!m->interlaced && GST_VIDEO_INFO_IS_INTERLACED (info))) { + continue; + } + + *display_mode = *m; + return TRUE; + } + } + + return FALSE; +} + +static gboolean +gst_decklink2_input_get_display_mode_from_native (GstDeckLink2Input * input, + BMDDisplayMode native, GstDeckLink2DisplayMode * display_mode) +{ + for (guint i = 0; i < input->format_table->len; i++) { + const GstDeckLink2DisplayMode *m = &g_array_index (input->format_table, + GstDeckLink2DisplayMode, i); + + if (m->mode == native) { + *display_mode = *m; + return TRUE; + } + } + + return FALSE; +} + +static HRESULT +gst_decklink2_input_set_callback (GstDeckLink2Input * self, IUnknown * callback) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->SetCallback ( + (IDeckLinkInputCallback_v11_5_1 *) callback); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->SetCallback ( + (IDeckLinkInputCallback_v11_5_1 *) callback); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->SetCallback ( + (IDeckLinkInputCallback_v11_5_1 *) callback); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->SetCallback ((IDeckLinkInputCallback *) callback); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_set_allocator (GstDeckLink2Input * self, + IDeckLinkMemoryAllocator * allocator) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->SetVideoInputFrameMemoryAllocator (allocator); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->SetVideoInputFrameMemoryAllocator (allocator); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->SetVideoInputFrameMemoryAllocator (allocator); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->SetVideoInputFrameMemoryAllocator (allocator); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_enable_video (GstDeckLink2Input * self, + BMDDisplayMode mode, BMDPixelFormat format, BMDVideoInputFlags flags) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->EnableVideoInput (mode, format, flags); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->EnableVideoInput (mode, format, flags); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->EnableVideoInput (mode, format, flags); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->EnableVideoInput (mode, format, flags); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_disable_video (GstDeckLink2Input * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->DisableVideoInput (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->DisableVideoInput (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->DisableVideoInput (); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->DisableVideoInput (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_enable_audio (GstDeckLink2Input * self, + BMDAudioSampleRate rate, BMDAudioSampleType type, guint channels) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->EnableAudioInput (rate, type, channels); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->EnableAudioInput (rate, type, channels); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->EnableAudioInput (rate, type, channels); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->EnableAudioInput (rate, type, channels); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_disable_audio (GstDeckLink2Input * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->DisableAudioInput (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->DisableAudioInput (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->DisableAudioInput (); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->DisableAudioInput (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_start_streams (GstDeckLink2Input * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->StartStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->StartStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->StartStreams (); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->StartStreams (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_stop_streams (GstDeckLink2Input * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->StopStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->StopStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->StopStreams (); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->StopStreams (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_pause_streams (GstDeckLink2Input * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->PauseStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->PauseStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->PauseStreams (); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->PauseStreams (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_flush_streams (GstDeckLink2Input * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->FlushStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->FlushStreams (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->FlushStreams (); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->FlushStreams (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_input_get_reference_clock (GstDeckLink2Input * self, + BMDTimeScale scale, BMDTimeValue * hw_time, BMDTimeValue * time_in_frame, + BMDTimeValue * ticks_per_frame) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->input_10_11->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->input_11_4->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + hr = self->input_11_5_1->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->input->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static void +gst_decklink2_input_reset_time_mapping (GstDeckLink2Input * self) +{ + self->window_size = 64; + self->window_fill = 0; + self->window_filled = FALSE; + self->window_skip = 1; + self->window_skip_count = 0; + self->current_time_mapping.xbase = 0; + self->current_time_mapping.b = 0; + self->current_time_mapping.num = 1; + self->current_time_mapping.den = 1; + self->next_time_mapping.xbase = 0; + self->next_time_mapping.b = 0; + self->next_time_mapping.num = 1; + self->next_time_mapping.den = 1; +} + +static inline gboolean +is_yuv_pixel_format (BMDPixelFormat format) +{ + if (format == bmdFormat8BitYUV || format == bmdFormat10BitYUV) + return TRUE; + + return FALSE; +} + +static HRESULT +gst_decklink2_input_on_format_changed (GstDeckLink2Input * self, + BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode * mode, + BMDDetectedVideoInputFormatFlags flags) +{ + BMDPixelFormat pixel_format = bmdFormatUnspecified; + GstVideoFormat video_format; + BMDDisplayMode display_mode = mode->GetDisplayMode (); + GstDeckLink2DisplayMode new_mode; + GstCaps *caps; + GstDeckLink2InputPrivate *priv = self->priv; + + if (priv->stopping) + return S_OK; + + GST_DEBUG_OBJECT (self, "format changed, flags 0x%x", flags); + + if ((flags & bmdDetectedVideoInputRGB444) != 0) { + /* XXX: cannot detect RGB format. + * decklink SDK sample is using this value anyway */ + if ((flags & bmdDetectedVideoInput8BitDepth) != 0 || + flags == bmdDetectedVideoInputRGB444) { + pixel_format = bmdFormat8BitARGB; + } + } else if ((flags & bmdDetectedVideoInputYCbCr422) != 0) { + if ((flags & bmdDetectedVideoInput8BitDepth) != 0 || + (flags == bmdDetectedVideoInputYCbCr422)) { + pixel_format = bmdFormat8BitYUV; + } else if ((flags & bmdDetectedVideoInput10BitDepth) != 0) { + pixel_format = bmdFormat10BitYUV; + } + } + + if (pixel_format == bmdFormatUnspecified) { + GST_WARNING_OBJECT (self, "Unknown pixel format"); + return E_INVALIDARG; + } + + if (!gst_decklink2_input_get_display_mode_from_native (self, + display_mode, &new_mode)) { + GST_WARNING_OBJECT (self, "Unknown display mode"); + return E_INVALIDARG; + } + + if (self->requested_pixel_format != pixel_format && + is_yuv_pixel_format (self->requested_pixel_format) && + is_yuv_pixel_format (pixel_format)) { + GST_DEBUG_OBJECT (self, "Updating format as requested"); + pixel_format = self->requested_pixel_format; + } + + video_format = gst_decklink2_video_format_from_pixel_format (pixel_format); + + caps = gst_decklink2_get_caps_from_mode (&new_mode); + gst_caps_set_simple (caps, "format", G_TYPE_STRING, + gst_video_format_to_string (video_format), NULL); + + GST_DEBUG_OBJECT (self, "Updated caps %" GST_PTR_FORMAT, caps); + + { + std::lock_guard < std::mutex > lk (priv->lock); + if (self->selected_video_caps && + gst_caps_is_equal (self->selected_video_caps, caps) && + self->pixel_format == pixel_format) { + GST_DEBUG_OBJECT (self, "Format not changed, skipping enable video"); + gst_caps_unref (caps); + return S_OK; + } + } + + gst_decklink2_input_pause_streams (self); + gst_decklink2_input_enable_video (self, display_mode, pixel_format, + bmdVideoInputEnableFormatDetection); + gst_decklink2_input_flush_streams (self); + + std::lock_guard < std::mutex > lk (priv->lock); + self->selected_mode = new_mode; + self->pixel_format = pixel_format; + + gst_clear_caps (&self->selected_video_caps); + self->selected_video_caps = caps; + gst_video_info_from_caps (&self->video_info, self->selected_video_caps); + self->aspect_ratio_flag = -1; + self->discont = TRUE; + gst_adapter_clear (self->audio_buf); + self->audio_offset = INVALID_AUDIO_OFFSET; + self->next_audio_offset = INVALID_AUDIO_OFFSET; + self->av_sync = 0; + priv->was_restarted = true; + + gst_decklink2_input_reset_time_mapping (self); + gst_decklink2_input_start_streams (self); + + return S_OK; +} + +static void +gst_decklink2_frame_free (IDeckLinkVideoInputFrame * frame) +{ + frame->Release (); +} + +static void +extract_vbi_line (GstDeckLink2Input * self, GstBuffer * buffer, + IDeckLinkVideoFrameAncillary * vanc_frame, guint field2_offset, guint line, + gboolean * found_cc_out, gboolean * found_afd_bar_out) +{ + GstVideoAncillary gstanc; + const guint8 *vancdata; + gboolean found_cc = FALSE, found_afd_bar = FALSE; + + if (vanc_frame->GetBufferForVerticalBlankingLine (field2_offset + line, + (void **) &vancdata) != S_OK) + return; + + GST_LOG_OBJECT (self, "Checking for VBI data on field line %u (field %u)", + field2_offset + line, field2_offset ? 2 : 1); + gst_video_vbi_parser_add_line (self->vbi_parser, vancdata); + + /* Check if CC or AFD/Bar is on this line if we didn't find any on a + * previous line. Remember the line where we found them */ + + while (gst_video_vbi_parser_get_ancillary (self->vbi_parser, + &gstanc) == GST_VIDEO_VBI_PARSER_RESULT_OK) { + switch (GST_VIDEO_ANCILLARY_DID16 (&gstanc)) { + case GST_VIDEO_ANCILLARY_DID16_S334_EIA_708: + if (*found_cc_out || !self->output_cc) + continue; + + GST_LOG_OBJECT (self, + "Adding CEA-708 CDP meta to buffer for line %u", + field2_offset + line); + GST_MEMDUMP_OBJECT (self, "CDP", gstanc.data, gstanc.data_count); + gst_buffer_add_video_caption_meta (buffer, + GST_VIDEO_CAPTION_TYPE_CEA708_CDP, gstanc.data, gstanc.data_count); + + found_cc = TRUE; + if (field2_offset) + self->last_cc_vbi_line_field2 = line; + else + self->last_cc_vbi_line = line; + break; + case GST_VIDEO_ANCILLARY_DID16_S334_EIA_608: + if (*found_cc_out || !self->output_cc) + continue; + + GST_LOG_OBJECT (self, + "Adding CEA-608 meta to buffer for line %u", field2_offset + line); + GST_MEMDUMP_OBJECT (self, "CEA608", gstanc.data, gstanc.data_count); + gst_buffer_add_video_caption_meta (buffer, + GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A, gstanc.data, + gstanc.data_count); + + found_cc = TRUE; + if (field2_offset) + self->last_cc_vbi_line_field2 = line; + else + self->last_cc_vbi_line = line; + break; + case GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR:{ + GstVideoAFDValue afd; + gboolean is_letterbox; + guint16 bar1, bar2; + + if (*found_afd_bar_out || !self->output_afd_bar) + continue; + + GST_LOG_OBJECT (self, + "Adding AFD/Bar meta to buffer for line %u", field2_offset + line); + GST_MEMDUMP_OBJECT (self, "AFD/Bar", gstanc.data, gstanc.data_count); + + if (gstanc.data_count < 8) { + GST_WARNING_OBJECT (self, "AFD/Bar data too small"); + 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]); + bar2 = GST_READ_UINT16_BE (&gstanc.data[6]); + + gst_buffer_add_video_afd_meta (buffer, field2_offset ? 1 : 0, + GST_VIDEO_AFD_SPEC_SMPTE_ST2016_1, afd); + gst_buffer_add_video_bar_meta (buffer, field2_offset ? 1 : 0, + is_letterbox, bar1, bar2); + + found_afd_bar = TRUE; + if (field2_offset) + self->last_afd_bar_vbi_line_field2 = line; + else + self->last_afd_bar_vbi_line = line; + break; + } + default: + /* otherwise continue looking */ + continue; + } + } + + if (found_cc) + *found_cc_out = TRUE; + if (found_afd_bar) + *found_afd_bar_out = TRUE; +} + +static void +extract_vbi (GstDeckLink2Input * self, GstBuffer * buffer, + IDeckLinkVideoInputFrame * frame) +{ + IDeckLinkVideoFrameAncillary *vanc_frame = NULL; + gint line; + BMDPixelFormat pixel_format; + GstVideoFormat video_format; + gboolean found_cc = FALSE, found_afd_bar = FALSE; + HRESULT hr; + const GstDeckLink2DisplayMode *mode = &self->selected_mode; + + hr = frame->GetAncillaryData (&vanc_frame); + if (!gst_decklink2_result (hr) || !vanc_frame) + return; + + pixel_format = vanc_frame->GetPixelFormat (); + video_format = gst_decklink2_video_format_from_pixel_format (pixel_format); + if (video_format != GST_VIDEO_FORMAT_UYVY && + video_format != GST_VIDEO_FORMAT_v210) { + GST_DEBUG_OBJECT (self, "Unknown video format for Ancillary data"); + vanc_frame->Release (); + return; + } + + if (video_format != self->anc_vformat || mode->width != self->anc_width) + g_clear_pointer (&self->vbi_parser, gst_video_vbi_parser_free); + + if (!self->vbi_parser) { + self->vbi_parser = gst_video_vbi_parser_new (video_format, mode->width); + self->anc_vformat = video_format; + self->anc_width = mode->width; + } + + GST_LOG_OBJECT (self, "Checking for ancillary data in VBI"); + + /* First check last known lines, if any */ + if (self->last_cc_vbi_line > 0) { + extract_vbi_line (self, buffer, vanc_frame, 0, self->last_cc_vbi_line, + &found_cc, &found_afd_bar); + } + if (self->last_afd_bar_vbi_line > 0 + && self->last_cc_vbi_line != self->last_afd_bar_vbi_line) { + extract_vbi_line (self, buffer, vanc_frame, 0, self->last_afd_bar_vbi_line, + &found_cc, &found_afd_bar); + } + + if (!found_cc) + self->last_cc_vbi_line = -1; + if (!found_afd_bar) + self->last_afd_bar_vbi_line = -1; + + if ((self->output_cc && !found_cc) || (self->output_afd_bar + && !found_afd_bar)) { + /* Otherwise loop through the first 21 lines and hope to find the data */ + /* FIXME: For the different formats the number of lines that can contain + * VANC are different */ + for (line = 1; line < 22; line++) { + extract_vbi_line (self, buffer, vanc_frame, 0, line, &found_cc, + &found_afd_bar); + + /* If we found everything we wanted to extract, stop here */ + if ((!self->output_cc || found_cc) && + (!self->output_afd_bar || found_afd_bar)) + break; + } + } + + /* Do the same for field 2 in case of interlaced content */ + if (mode->interlaced) { + gboolean found_cc_field2 = FALSE, found_afd_bar_field2 = FALSE; + guint field2_offset = 0; + + /* The VANC lines for the second field are at an offset, depending on + * the format in use + */ + switch (mode->height) { + case 486: + /* NTSC: 525 / 2 + 1 */ + field2_offset = 263; + break; + case 576: + /* PAL: 625 / 2 + 1 */ + field2_offset = 313; + break; + case 1080: + /* 1080i: 1125 / 2 + 1 */ + field2_offset = 563; + break; + default: + g_assert_not_reached (); + } + + /* First try the same lines as for field 1 if we don't know yet */ + if (self->last_cc_vbi_line_field2 <= 0) + self->last_cc_vbi_line_field2 = self->last_cc_vbi_line; + if (self->last_afd_bar_vbi_line_field2 <= 0) + self->last_afd_bar_vbi_line_field2 = self->last_afd_bar_vbi_line; + + if (self->last_cc_vbi_line_field2 > 0) { + extract_vbi_line (self, buffer, vanc_frame, field2_offset, + self->last_cc_vbi_line_field2, &found_cc_field2, + &found_afd_bar_field2); + } + if (self->last_afd_bar_vbi_line_field2 > 0 + && self->last_cc_vbi_line_field2 != + self->last_afd_bar_vbi_line_field2) { + extract_vbi_line (self, buffer, vanc_frame, field2_offset, + self->last_afd_bar_vbi_line_field2, &found_cc_field2, + &found_afd_bar_field2); + } + + if (!found_cc_field2) + self->last_cc_vbi_line_field2 = -1; + if (!found_afd_bar_field2) + self->last_afd_bar_vbi_line_field2 = -1; + + if (((self->output_cc && !found_cc_field2) || (self->output_afd_bar + && !found_afd_bar_field2))) { + for (line = 1; line < 22; line++) { + extract_vbi_line (self, buffer, vanc_frame, field2_offset, line, + &found_cc_field2, &found_afd_bar_field2); + + /* If we found everything we wanted to extract, stop here */ + if ((!self->output_cc || found_cc_field2) && + (!self->output_afd_bar || found_afd_bar_field2)) + break; + } + } + } + + vanc_frame->Release (); +} + +static void +gst_decklink2_input_update_time_mapping (GstDeckLink2Input * self, + GstClockTime capture_time, GstClockTime stream_time) +{ + if (self->window_skip_count == 0) { + GstClockTime num, den, b, xbase; + gdouble r_squared; + + self->times[2 * self->window_fill] = stream_time; + self->times[2 * self->window_fill + 1] = capture_time; + + self->window_fill++; + self->window_skip_count++; + if (self->window_skip_count >= self->window_skip) + self->window_skip_count = 0; + + if (self->window_fill >= self->window_size) { + guint fps = + ((gdouble) self->selected_mode.fps_n + self->selected_mode.fps_d - + 1) / ((gdouble) self->selected_mode.fps_d); + + /* Start by updating first every frame, once full every second frame, + * etc. until we update once every 4 seconds */ + if (self->window_skip < 4 * fps) + self->window_skip *= 2; + if (self->window_skip >= 4 * fps) + self->window_skip = 4 * fps; + + self->window_fill = 0; + self->window_filled = TRUE; + } + + /* First sample ever, create some basic mapping to start */ + if (!self->window_filled && self->window_fill == 1) { + self->current_time_mapping.xbase = stream_time; + self->current_time_mapping.b = capture_time; + self->current_time_mapping.num = 1; + self->current_time_mapping.den = 1; + self->next_time_mapping_pending = FALSE; + } + + /* Only bother calculating anything here once we had enough measurements, + * i.e. let's take the window size as a start */ + if (self->window_filled && + gst_calculate_linear_regression (self->times, &self->times[128], + self->window_size, &num, &den, &b, &xbase, &r_squared)) { + + GST_LOG_OBJECT (self, + "Calculated new time mapping: pipeline time = %lf * (stream time - %" + G_GUINT64_FORMAT ") + %" G_GUINT64_FORMAT " (%lf)", + ((gdouble) num) / ((gdouble) den), xbase, b, r_squared); + + self->next_time_mapping.xbase = xbase; + self->next_time_mapping.b = b; + self->next_time_mapping.num = num; + self->next_time_mapping.den = den; + self->next_time_mapping_pending = TRUE; + } + } else { + self->window_skip_count++; + if (self->window_skip_count >= self->window_skip) + self->window_skip_count = 0; + } + + if (self->next_time_mapping_pending) { + GstClockTime expected, new_calculated, diff, max_diff; + + expected = + gst_clock_adjust_with_calibration (NULL, stream_time, + self->current_time_mapping.xbase, self->current_time_mapping.b, + self->current_time_mapping.num, self->current_time_mapping.den); + new_calculated = + gst_clock_adjust_with_calibration (NULL, stream_time, + self->next_time_mapping.xbase, self->next_time_mapping.b, + self->next_time_mapping.num, self->next_time_mapping.den); + + if (new_calculated > expected) + diff = new_calculated - expected; + else + diff = expected - new_calculated; + + /* At most 5% frame duration change per update */ + max_diff = + gst_util_uint64_scale (GST_SECOND / 20, self->selected_mode.fps_d, + self->selected_mode.fps_n); + + GST_LOG_OBJECT (self, + "New time mapping causes difference of %" GST_TIME_FORMAT, + GST_TIME_ARGS (diff)); + GST_LOG_OBJECT (self, "Maximum allowed per frame %" GST_TIME_FORMAT, + GST_TIME_ARGS (max_diff)); + + if (diff > max_diff) { + /* adjust so that we move that much closer */ + if (new_calculated > expected) { + self->current_time_mapping.b = expected + max_diff; + self->current_time_mapping.xbase = stream_time; + } else { + self->current_time_mapping.b = expected - max_diff; + self->current_time_mapping.xbase = stream_time; + } + } else { + self->current_time_mapping.xbase = self->next_time_mapping.xbase; + self->current_time_mapping.b = self->next_time_mapping.b; + self->current_time_mapping.num = self->next_time_mapping.num; + self->current_time_mapping.den = self->next_time_mapping.den; + self->next_time_mapping_pending = FALSE; + } + } +} + +/* Must be called with lock taken */ +static void +gst_decklink2_input_do_restart (GstDeckLink2Input * self) +{ + GstDeckLink2InputPrivate *priv = self->priv; + + GST_DEBUG_OBJECT (self, "Restaring input"); + + priv->was_restarted = true; + priv->need_restart = false; + priv->lock.unlock (); + gst_decklink2_input_pause_streams (self); + gst_decklink2_input_flush_streams (self); + gst_decklink2_input_start_streams (self); + priv->lock.lock (); + + gst_decklink2_input_reset_time_mapping (self); + gst_adapter_clear (self->audio_buf); + gst_queue_array_clear (self->queue); + self->audio_offset = INVALID_AUDIO_OFFSET; + self->next_audio_offset = INVALID_AUDIO_OFFSET; +} + +static void +gst_decklink2_input_on_frame_arrived (GstDeckLink2Input * self, + IDeckLinkVideoInputFrame * frame, IDeckLinkAudioInputPacket * packet) +{ + GstDeckLink2InputPrivate *priv = self->priv; + static GstStaticCaps stream_reference = + GST_STATIC_CAPS ("timestamp/x-decklink-stream"); + static GstStaticCaps hardware_reference = + GST_STATIC_CAPS ("timestamp/x-decklink-hardware"); + HRESULT hr; + GstClockTime capture_time = 0; + GstClockTime base_time = 0; + GstBuffer *buffer = NULL; + GstClock *clock = NULL; + BMDTimeValue hw_now, dummy, dummy2; + BMDTimeValue stream_time = GST_CLOCK_TIME_NONE; + BMDTimeValue stream_dur; + BMDFrameFlags flags = bmdFrameFlagDefault; + + std::unique_lock < std::mutex > lk (priv->lock); + if (frame) { + gboolean has_signal; + flags = frame->GetFlags (); + + if ((flags & bmdFrameHasNoInputSource) != 0) + has_signal = FALSE; + else + has_signal = TRUE; + + GST_TRACE_OBJECT (self, "Frame has signal: %d", has_signal); + + if (priv->was_restarted) { + /* Ignores no-signal flag of the first frame after we do restart */ + priv->was_restarted = false; + } else { + if (!has_signal) { + priv->signal = false; + } else if (!priv->signal) { + GST_LOG_OBJECT (self, "Got first frame, reset timing map"); + priv->signal = true; + gst_decklink2_input_do_restart (self); + return; + } else { + priv->signal = true; + } + } + } + + /* Restart requested, flush everything */ + if (priv->need_restart) { + GST_DEBUG_OBJECT (self, "Restring as requested"); + gst_decklink2_input_do_restart (self); + return; + } + + hr = gst_decklink2_input_get_reference_clock (self, GST_SECOND, + &hw_now, &dummy, &dummy2); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Couldn't get H/W reference clock"); + hw_now = GST_CLOCK_TIME_NONE; + } + + if (self->client) + clock = gst_element_get_clock (GST_ELEMENT (self->client)); + + if (!clock) { + GST_WARNING_OBJECT (self, + "Frame arrived but we dont have configured clock"); + return; + } + + base_time = gst_element_get_base_time (GST_ELEMENT (self->client)); + capture_time = gst_clock_get_time (clock); + gst_object_unref (clock); + if (capture_time >= base_time) + capture_time -= base_time; + + if (!GST_CLOCK_TIME_IS_VALID (self->start_time)) + self->start_time = capture_time; + + if (GST_CLOCK_TIME_IS_VALID (self->skip_first_time)) { + GstClockTime diff = capture_time - self->start_time; + if (diff < self->skip_first_time) { + GST_DEBUG_OBJECT (self, + "Skipping frame as requested: %" GST_TIME_FORMAT " < %" + GST_TIME_FORMAT, GST_TIME_ARGS (capture_time), + GST_TIME_ARGS (self->skip_first_time + self->start_time)); + return; + } + + GST_DEBUG_OBJECT (self, "All frames were skipped as requested"); + self->skip_first_time = GST_CLOCK_TIME_NONE; + } + + if (frame) { + void *frame_data; + gsize frame_size; + BMDTimeValue frame_time, frame_dur; + IDeckLinkTimecode *timecode = NULL; + GstClockTime pts, dur; + BMDPixelFormat pixel_format; + + hr = frame->GetBytes (&frame_data); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Couldn't get byte from frame"); + return; + } + + pixel_format = frame->GetPixelFormat (); + if (pixel_format != self->pixel_format) { + + GST_DEBUG_OBJECT (self, "Unexpected pixel format change %d -> %d", + self->pixel_format, pixel_format); + + gst_decklink2_input_do_restart (self); + return; + } + + auto frame_width = frame->GetWidth (); + auto frame_height = frame->GetHeight (); + if (self->video_info.width != (gint) frame_width || + self->video_info.height != (gint) frame_height) { + + GST_WARNING_OBJECT (self, "Unexpected resolution change %dx%d -> %dx%d", + self->video_info.width, self->video_info.height, + (gint) frame_width, (gint) frame_height); + + gst_decklink2_input_do_restart (self); + return; + } + + frame_size = frame_height * frame->GetRowBytes (); + buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, + frame_data, frame_size, 0, frame_size, frame, + (GDestroyNotify) gst_decklink2_frame_free); + frame->AddRef (); + + hr = frame->GetHardwareReferenceTimestamp (GST_SECOND, + &frame_time, &frame_dur); + if (gst_decklink2_result (hr)) { + GstCaps *caps = gst_static_caps_get (&hardware_reference); + gst_buffer_add_reference_timestamp_meta (buffer, caps, frame_time, + frame_dur); + if (GST_CLOCK_TIME_IS_VALID (hw_now) && hw_now > frame_time) { + GstClockTime diff = hw_now - frame_time; + if (capture_time >= diff) + capture_time -= diff; + } + } + + hr = frame->GetStreamTime (&stream_time, &stream_dur, GST_SECOND); + if (gst_decklink2_result (hr)) { + GstCaps *caps = gst_static_caps_get (&stream_reference); + gst_buffer_add_reference_timestamp_meta (buffer, caps, stream_time, + stream_dur); + + gst_decklink2_input_update_time_mapping (self, capture_time, stream_time); + pts = gst_clock_adjust_with_calibration (NULL, stream_time, + self->current_time_mapping.xbase, self->current_time_mapping.b, + self->current_time_mapping.num, self->current_time_mapping.den); + dur = gst_util_uint64_scale (stream_dur, + self->current_time_mapping.num, self->current_time_mapping.den); + } else { + pts = capture_time; + dur = GST_CLOCK_TIME_NONE; + } + + if (!priv->signal) { + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_GAP); + } else { + if (self->output_cc || self->output_afd_bar) { + extract_vbi (self, buffer, frame); + + if (self->aspect_ratio_flag == 1 && self->auto_detect) { + BMDDisplayMode mode = self->selected_mode.mode; + + switch (self->selected_mode.mode) { + case bmdModeNTSC: + mode = bmdModeNTSC_W; + break; + case bmdModeNTSC2398: + mode = bmdModeNTSC2398_W; + break; + case bmdModePAL: + mode = bmdModePAL_W; + break; + case bmdModeNTSCp: + mode = bmdModeNTSCp_W; + break; + case bmdModePALp: + mode = bmdModePALp_W; + break; + default: + break; + } + + if (mode != self->selected_mode.mode) { + GstDeckLink2DisplayMode new_mode; + GstVideoFormat video_format; + GstCaps *caps; + gst_decklink2_input_get_display_mode_from_native (self, + mode, &new_mode); + + video_format = + gst_decklink2_video_format_from_pixel_format + (self->pixel_format); + caps = gst_decklink2_get_caps_from_mode (&new_mode); + gst_caps_set_simple (caps, "format", G_TYPE_STRING, + gst_video_format_to_string (video_format), NULL); + + GST_DEBUG_OBJECT (self, "Update caps %" GST_PTR_FORMAT " to %" + GST_PTR_FORMAT, self->selected_video_caps, caps); + self->selected_mode = new_mode; + gst_caps_replace (&self->selected_video_caps, caps); + gst_caps_unref (caps); + } + } + } + } + + hr = frame->GetTimecode (self->timecode_format, &timecode); + if (hr == S_OK) { + guint8 h, m, s, f; + hr = timecode->GetComponents (&h, &m, &s, &f); + if (gst_decklink2_result (hr)) { + GstVideoTimeCodeFlags tc_flags = GST_VIDEO_TIME_CODE_FLAGS_NONE; + GstVideoTimeCode tc; + + if (self->selected_mode.interlaced) { + tc_flags = (GstVideoTimeCodeFlags) (tc_flags | + GST_VIDEO_TIME_CODE_FLAGS_INTERLACED); + } + + if (self->selected_mode.fps_d == 1001 && + (self->selected_mode.fps_n == 30000 || + self->selected_mode.fps_d == 60000)) { + tc_flags = (GstVideoTimeCodeFlags) (tc_flags | + GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME); + } + + gst_video_time_code_init (&tc, self->selected_mode.fps_n, + self->selected_mode.fps_d, NULL, tc_flags, h, m, s, f, 0); + gst_buffer_add_video_time_code_meta (buffer, &tc); + gst_video_time_code_clear (&tc); + } + + timecode->Release (); + } + + if (self->selected_mode.interlaced) { + GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED); + if (self->selected_mode.tff) + GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_TFF); + } + + if (self->discont) { + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); + self->discont = FALSE; + } + + GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE; + GST_BUFFER_PTS (buffer) = pts; + GST_BUFFER_DURATION (buffer) = dur; + } + + if (packet) { + GstBuffer *audio_buf = NULL; + void *packet_data; + BMDTimeValue packet_time; + guint64 audio_offset, audio_offset_end; + gsize audio_buf_size; + GstMapInfo map; + + if (self->audio_offset == INVALID_AUDIO_OFFSET && !frame) { + GST_DEBUG_OBJECT (self, "Drop audio without video frame"); + goto out; + } + + if (!frame) { + GST_WARNING_OBJECT (self, "Received audio packet without video frame. This indicates video processing is not fast enough."); + } + + long sample_count = packet->GetSampleFrameCount (); + if (sample_count == 0) { + GST_DEBUG_OBJECT (self, "Empty audio packet"); + goto out; + } + + hr = packet->GetPacketTime (&packet_time, self->audio_info.rate); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Unknown audio packet time"); + goto out; + } + + hr = packet->GetBytes (&packet_data); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Couldn't get audio packet data"); + goto out; + } + + audio_offset = packet_time; + audio_offset_end = audio_offset + sample_count; + audio_buf_size = self->audio_info.bpf * sample_count; + audio_buf = gst_buffer_new_and_alloc (audio_buf_size); + gst_buffer_map (audio_buf, &map, GST_MAP_WRITE); + memcpy (map.data, packet_data, map.size); + gst_buffer_unmap (audio_buf, &map); + + if (self->audio_offset == INVALID_AUDIO_OFFSET) { + GstClockTime audio_pts; + GstClockTime packet_time_in_gst; + + packet_time_in_gst = gst_util_uint64_scale (GST_SECOND, packet_time, + self->audio_info.rate); + + audio_pts = gst_clock_adjust_with_calibration (NULL, + packet_time_in_gst, + self->current_time_mapping.xbase, self->current_time_mapping.b, + self->current_time_mapping.num, self->current_time_mapping.den); + + /* Back to sample offset */ + self->audio_offset = gst_util_uint64_scale (audio_pts, + self->audio_info.rate, GST_SECOND); + + GST_DEBUG_OBJECT (self, "Initial audio offset at %" G_GUINT64_FORMAT + " for pts %" GST_TIME_FORMAT ", packet time %" GST_TIME_FORMAT, + self->audio_offset, GST_TIME_ARGS (audio_pts), + GST_TIME_ARGS (packet_time_in_gst)); + } + + if (self->next_audio_offset == INVALID_AUDIO_OFFSET) { + self->next_audio_offset = audio_offset_end; + } else if (self->next_audio_offset != audio_offset) { + GST_WARNING_OBJECT (self, "Expected offset %" G_GUINT64_FORMAT + ", received %" G_GUINT64_FORMAT, self->next_audio_offset, + audio_offset); + gst_decklink2_input_reset_time_mapping (self); + gst_decklink2_input_stop_streams (self); + gst_decklink2_input_flush_streams (self); + gst_decklink2_input_start_streams (self); + gst_adapter_clear (self->audio_buf); + self->audio_offset = INVALID_AUDIO_OFFSET; + self->next_audio_offset = INVALID_AUDIO_OFFSET; + return; + } else { + GST_LOG_OBJECT (self, "Got expected audio samples"); + self->next_audio_offset += sample_count; + } + + if (audio_buf) + gst_adapter_push (self->audio_buf, audio_buf); + } + +out: + if (buffer) { + GstSample *sample; + gsize audio_size; + while (gst_queue_array_get_length (self->queue) > self->buffer_size) { + GstDecklink2InputData *data = (GstDecklink2InputData *) + gst_queue_array_pop_head_struct (self->queue); + gst_decklink2_input_data_clear (data); + } + + audio_size = gst_adapter_available (self->audio_buf); + if (audio_size > 0) { + GstBuffer *audio_buf = gst_adapter_take_buffer (self->audio_buf, + audio_size); + guint64 sample_count = audio_size / self->audio_info.bpf; + + GST_BUFFER_DTS (audio_buf) = GST_CLOCK_TIME_NONE; + GST_BUFFER_PTS (audio_buf) = + gst_util_uint64_scale (self->audio_offset, GST_SECOND, + self->audio_info.rate); + GST_BUFFER_DURATION (audio_buf) = + gst_util_uint64_scale (sample_count, GST_SECOND, + self->audio_info.rate); + if (self->audio_discont) { + GST_BUFFER_FLAG_SET (audio_buf, GST_BUFFER_FLAG_DISCONT); + self->audio_discont = FALSE; + } + + self->audio_offset += sample_count; + + GST_LOG_OBJECT (self, "Adding audio buffer %" GST_PTR_FORMAT, audio_buf); + + sample = gst_sample_new (audio_buf, self->selected_audio_caps, NULL, + NULL); + gst_buffer_add_decklink2_audio_meta (buffer, sample); + gst_sample_unref (sample); + + if (frame && packet) { + self->av_sync = GST_CLOCK_DIFF (GST_BUFFER_PTS (buffer), + GST_BUFFER_PTS (audio_buf)); + } + + gst_buffer_unref (audio_buf); + } + + GST_LOG_OBJECT (self, "Enqueue buffer %" GST_PTR_FORMAT, buffer); + + GstDecklink2InputData new_data; + new_data.buffer = buffer; + new_data.caps = gst_caps_ref (self->selected_video_caps); + gst_queue_array_push_tail_struct (self->queue, &new_data); + priv->cond.notify_all (); + } +} + +static void +gst_decklink2_input_stop_unlocked (GstDeckLink2Input * self) +{ + GstDeckLink2InputPrivate *priv = self->priv; + + /* Temporarily unlock mutex. below API call may be blocked by callback thread + * which takes our mutex too */ + priv->stopping = true; + priv->lock.unlock (); + gst_decklink2_input_stop_streams (self); + gst_decklink2_input_disable_video (self); + gst_decklink2_input_disable_audio (self); + gst_decklink2_input_set_callback (self, NULL); + priv->lock.lock (); + priv->stopping = false; + gst_queue_array_clear (self->queue); + gst_clear_caps (&self->selected_video_caps); + gst_clear_caps (&self->selected_audio_caps); + priv->signal = false; + priv->was_restarted = false; + priv->need_restart = false; + self->skip_first_time = GST_CLOCK_TIME_NONE; + self->start_time = GST_CLOCK_TIME_NONE; + self->started = FALSE; + self->av_sync = 0; +} + +HRESULT +gst_decklink2_input_start (GstDeckLink2Input * input, GstElement * client, + BMDProfileID profile_id, guint buffer_size, GstClockTime skip_first_time, + const GstDeckLink2InputVideoConfig * video_config, + const GstDeckLink2InputAudioConfig * audio_config) +{ + GstDeckLink2InputPrivate *priv = input->priv; + std::lock_guard < std::mutex > lk (priv->lock); + HRESULT hr; + BMDVideoInputFlags input_flags = bmdVideoInputFlagDefault; + + gst_decklink2_input_stop_unlocked (input); + gst_decklink2_input_reset_time_mapping (input); + + input->started = TRUE; + + if (skip_first_time > 0 && GST_CLOCK_TIME_IS_VALID (skip_first_time)) + input->skip_first_time = skip_first_time; + + if (profile_id != bmdProfileDefault) { + GstDeckLink2Object *object; + gchar *profile_id_str = g_enum_to_string (GST_TYPE_DECKLINK2_PROFILE_ID, + profile_id); + + object = (GstDeckLink2Object *) gst_object_get_parent (GST_OBJECT (input)); + g_assert (object); + + gst_decklink2_object_set_profile_id (object, profile_id); + gst_object_unref (object); + + g_free (profile_id_str); + } + + if (video_config->connection != bmdVideoConnectionUnspecified) { + hr = E_FAIL; + if (input->config) { + hr = input->config->SetInt (bmdDeckLinkConfigVideoInputConnection, + video_config->connection); + } else if (input->config_10_11) { + hr = input->config_10_11->SetInt (bmdDeckLinkConfigVideoInputConnection, + video_config->connection); + } + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (input, "Couldn't set video connection, hr: 0x%x", + (guint) hr); + return hr; + } + + if (video_config->connection == bmdVideoConnectionComposite) { + hr = E_FAIL; + if (input->config) { + hr = input->config->SetInt (bmdDeckLinkConfigAnalogVideoInputFlags, + bmdAnalogVideoFlagCompositeSetup75); + } else if (input->config_10_11) { + hr = input-> + config_10_11->SetInt (bmdDeckLinkConfigAnalogVideoInputFlags, + bmdAnalogVideoFlagCompositeSetup75); + } + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (input, + "Couldn't set analog video input flags, hr: 0x%x", (guint) hr); + return hr; + } + } + } + + if (video_config->auto_detect) { + dlbool_t auto_detect = false; + + if (input->attr) { + hr = input->attr->GetFlag (BMDDeckLinkSupportsInputFormatDetection, + &auto_detect); + if (!gst_decklink2_result (hr) || !auto_detect) { + GST_ERROR_OBJECT (input, "Auto detect is not supported"); + return E_FAIL; + } + } else if (input->attr_10_11) { + hr = input->attr_10_11->GetFlag (BMDDeckLinkSupportsInputFormatDetection, + &auto_detect); + if (!gst_decklink2_result (hr) || !auto_detect) { + GST_ERROR_OBJECT (input, "Auto detect is not supported"); + return E_FAIL; + } + } else { + GST_ERROR_OBJECT (input, + "IDeckLinkProfileAttributes interface is not available"); + return E_FAIL; + } + + GST_DEBUG_OBJECT (input, "Enable format detection"); + + input_flags |= bmdVideoInputEnableFormatDetection; + } + + input->client = client; + input->selected_mode = video_config->display_mode; + input->pixel_format = input->requested_pixel_format = + video_config->pixel_format; + input->output_cc = video_config->output_cc; + input->output_afd_bar = video_config->output_afd_bar; + input->buffer_size = buffer_size; + input->selected_video_caps = gst_decklink2_input_get_caps (input, + input->selected_mode.mode, video_config->pixel_format); + if (!input->selected_video_caps) { + GST_ERROR_OBJECT (input, "Unable to get caps from requested mode"); + goto error; + } + + gst_video_info_from_caps (&input->video_info, input->selected_video_caps); + + input->auto_detect = video_config->auto_detect; + input->aspect_ratio_flag = -1; + input->audio_offset = INVALID_AUDIO_OFFSET; + input->next_audio_offset = INVALID_AUDIO_OFFSET; + input->audio_discont = FALSE; + + if (input->callback) + hr = gst_decklink2_input_set_callback (input, input->callback); + else + hr = gst_decklink2_input_set_callback (input, input->callback_11_5_1); + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (input, "Couldn't set callback"); + goto error; + } + + hr = gst_decklink2_input_enable_video (input, + gst_decklink2_get_real_display_mode (input->selected_mode.mode), + video_config->pixel_format, input_flags); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (input, "Couldn't enable video"); + goto error; + } + + if (audio_config->channels != GST_DECKLINK2_AUDIO_CHANNELS_DISABLED) { + guint channels = 2; + switch (audio_config->channels) { + case GST_DECKLINK2_AUDIO_CHANNELS_2: + channels = 2; + break; + case GST_DECKLINK2_AUDIO_CHANNELS_8: + channels = 8; + break; + case GST_DECKLINK2_AUDIO_CHANNELS_16: + channels = 16; + break; + case GST_DECKLINK2_AUDIO_CHANNELS_MAX: + channels = input->max_audio_channels; + break; + default: + break; + } + + hr = gst_decklink2_input_enable_audio (input, bmdAudioSampleRate48kHz, + audio_config->sample_type, channels); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (input, "Couldn't enable audio"); + goto error; + } + + gst_audio_info_set_format (&input->audio_info, + audio_config->sample_type == bmdAudioSampleType32bitInteger ? + GST_AUDIO_FORMAT_S32LE : GST_AUDIO_FORMAT_S16LE, 48000, channels, NULL); + input->selected_audio_caps = gst_audio_info_to_caps (&input->audio_info); + } + + hr = gst_decklink2_input_start_streams (input); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (input, "Couldn't start streams"); + goto error; + } + + return S_OK; + +error: + gst_decklink2_input_stop_unlocked (input); + input->client = NULL; + return E_FAIL; +} + +void +gst_decklink2_input_schedule_restart (GstDeckLink2Input * input) +{ + input->priv->need_restart = true; +} + +void +gst_decklink2_input_stop (GstDeckLink2Input * input) +{ + GstDeckLink2InputPrivate *priv = input->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + gst_decklink2_input_stop_unlocked (input); + input->client = NULL; + + priv->cond.notify_all (); +} + +void +gst_decklink2_input_set_flushing (GstDeckLink2Input * input, gboolean flush) +{ + GstDeckLink2InputPrivate *priv = input->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + input->flushing = flush; + priv->cond.notify_all (); +} + +GstFlowReturn +gst_decklink2_input_get_data (GstDeckLink2Input * input, GstBuffer ** buf, + GstCaps ** caps, GstClockTimeDiff * av_sync) +{ + GstDeckLink2InputPrivate *priv = input->priv; + std::unique_lock < std::mutex > lk (priv->lock); + GstDecklink2InputData *data; + + *buf = nullptr; + *caps = nullptr; + *av_sync = 0; + + while (gst_queue_array_is_empty (input->queue) + && !input->flushing && input->started) { + priv->cond.wait (lk); + } + + if (input->flushing) + return GST_FLOW_FLUSHING; + + if (!input->started) + return GST_DECKLINK2_INPUT_FLOW_STOPPED; + + data = (GstDecklink2InputData *) + gst_queue_array_pop_head_struct (input->queue); + *buf = data->buffer; + *caps = data->caps; + *av_sync = input->av_sync; + + return GST_FLOW_OK; +} + +gboolean +gst_decklink2_input_has_signal (GstDeckLink2Input * input) +{ + GstDeckLink2InputPrivate *priv = input->priv; + + if (priv->signal) + return TRUE; + + return FALSE; +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2input.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2input.h new file mode 100644 index 0000000000..80aa39c102 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2input.h @@ -0,0 +1,84 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include "gstdecklink2utils.h" + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_INPUT (gst_decklink2_input_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Input, gst_decklink2_input, + GST, DECKLINK2_INPUT, GstObject); + +#define GST_DECKLINK2_INPUT_FLOW_STOPPED GST_FLOW_CUSTOM_ERROR + +typedef struct _GstDeckLink2InputVideoConfig +{ + BMDVideoConnection connection; + GstDeckLink2DisplayMode display_mode; + BMDPixelFormat pixel_format; + gboolean auto_detect; + gboolean output_cc; + gboolean output_afd_bar; +} GstDeckLink2InputVideoConfig; + +typedef struct _GstDeckLink2InputAudioConfig +{ + BMDAudioConnection connection; + BMDAudioSampleType sample_type; + GstDeckLink2AudioChannels channels; +} GstDeckLink2InputAudioConfig; + +GstDeckLink2Input * gst_decklink2_input_new (IDeckLink * device, + GstDeckLink2APILevel api_level); + +GstCaps * gst_decklink2_input_get_caps (GstDeckLink2Input * input, + BMDDisplayMode mode, + BMDPixelFormat format); + +gboolean gst_decklink2_input_get_display_mode (GstDeckLink2Input * input, + const GstVideoInfo * info, + GstDeckLink2DisplayMode * display_mode); + +HRESULT gst_decklink2_input_start (GstDeckLink2Input * input, + GstElement * client, + BMDProfileID profile_id, + guint buffer_size, + GstClockTime skip_first_time, + const GstDeckLink2InputVideoConfig * video_config, + const GstDeckLink2InputAudioConfig * audio_config); + +void gst_decklink2_input_schedule_restart (GstDeckLink2Input * input); + +void gst_decklink2_input_stop (GstDeckLink2Input * input); + +void gst_decklink2_input_set_flushing (GstDeckLink2Input * input, + gboolean flush); + +GstFlowReturn gst_decklink2_input_get_data (GstDeckLink2Input * input, + GstBuffer ** buffer, + GstCaps ** caps, + GstClockTimeDiff * av_sync); + +gboolean gst_decklink2_input_has_signal (GstDeckLink2Input * input); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2object.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2object.cpp new file mode 100644 index 0000000000..9f958cc549 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2object.cpp @@ -0,0 +1,712 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2object.h" +#include "gstdecklink2deviceprovider.h" +#include +#include +#include +#include +#include +#include + +GST_DEBUG_CATEGORY_EXTERN (gst_decklink2_debug); +#define GST_CAT_DEFAULT gst_decklink2_debug + +/* *INDENT-OFF* */ +static std::vector device_list; +static std::mutex device_lock; +/* *INDENT-ON* */ + +struct _GstDeckLink2Object +{ + GstObject parent; + + GstDeckLink2APILevel api_level; + + IDeckLink *device; + IDeckLinkProfileAttributes *attr; + IDeckLinkAttributes_v10_11 *attr_10_11; + IDeckLinkConfiguration *config; + IDeckLinkConfiguration_v10_11 *config_10_11; + IDeckLinkProfileManager *profile_manager; + + GstDeckLink2Input *input; + GstDevice *input_device; + + GstDeckLink2Output *output; + GstDevice *output_device; + + guint device_number; + gint64 persistent_id; + gchar *serial_number; + gchar *model_name; + gchar *display_name; + + gboolean input_acquired; + gboolean output_acquired; +}; + +static void gst_decklink2_object_dispose (GObject * object); +static void gst_decklink2_object_finalize (GObject * object); + +#define gst_decklink2_object_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Object, gst_decklink2_object, GST_TYPE_OBJECT); + +static void +gst_decklink2_object_class_init (GstDeckLink2ObjectClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gst_decklink2_object_dispose; + object_class->finalize = gst_decklink2_object_finalize; +} + +static void +gst_decklink2_object_init (GstDeckLink2Object * self) +{ +} + +static void +gst_decklink2_object_dispose (GObject * object) +{ + GstDeckLink2Object *self = GST_DECKLINK2_OBJECT (object); + + if (self->input) { + gst_object_unparent (GST_OBJECT (self->input)); + self->input = NULL; + } + + if (self->output) { + gst_object_unparent (GST_OBJECT (self->output)); + self->output = NULL; + } + + gst_clear_object (&self->input_device); + gst_clear_object (&self->output_device); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_decklink2_object_finalize (GObject * object) +{ + GstDeckLink2Object *self = GST_DECKLINK2_OBJECT (object); + + GST_DECKLINK2_CLEAR_COM (self->attr); + GST_DECKLINK2_CLEAR_COM (self->attr_10_11); + GST_DECKLINK2_CLEAR_COM (self->config); + GST_DECKLINK2_CLEAR_COM (self->config_10_11); + GST_DECKLINK2_CLEAR_COM (self->profile_manager); + GST_DECKLINK2_CLEAR_COM (self->device); + + g_free (self->serial_number); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static GstDeckLink2Object * +gst_decklink2_object_new (IDeckLink * device, guint index, + GstDeckLink2APILevel api_level, const gchar * api_ver_str, + const gchar * driver_ver_str) +{ + HRESULT hr; + GstDeckLink2Input *input; + GstDeckLink2Output *output; + GstDeckLink2Object *self; + dlstring_t str; + gint64 max_num_audio_channels = 0; + GstCaps *caps = NULL; + + input = gst_decklink2_input_new (device, api_level); + output = gst_decklink2_output_new (device, api_level); + + if (!output && !input) + return NULL; + + self = (GstDeckLink2Object *) + g_object_new (GST_TYPE_DECKLINK2_OBJECT, NULL); + gst_object_ref_sink (self); + + self->api_level = api_level; + + if (input) + gst_object_set_parent (GST_OBJECT (input), GST_OBJECT (self)); + + if (output) + gst_object_set_parent (GST_OBJECT (output), GST_OBJECT (self)); + + self->input = input; + self->output = output; + self->device_number = index; + self->device = device; + device->AddRef (); + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + IDeckLinkConfiguration_v10_11 *config_10_11 = NULL; + hr = device->QueryInterface (IID_IDeckLinkConfiguration_v10_11, + (void **) &config_10_11); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Couldn't get config object"); + gst_object_unref (self); + return NULL; + } + + hr = config_10_11->GetString + (bmdDeckLinkConfigDeviceInformationSerialNumber, &str); + + if (gst_decklink2_result (hr)) { + std::string serial_number = DlToStdString (str); + DeleteString (str); + + self->serial_number = g_strdup (serial_number.c_str ()); + GST_DEBUG_OBJECT (self, "device %d has serial number %s", index, + GST_STR_NULL (self->serial_number)); + } + + self->config_10_11 = config_10_11; + } else { + IDeckLinkConfiguration *config = NULL; + hr = device->QueryInterface (IID_IDeckLinkConfiguration, (void **) &config); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Couldn't get config object"); + gst_object_unref (self); + return NULL; + } + + hr = config->GetString (bmdDeckLinkConfigDeviceInformationSerialNumber, + &str); + if (gst_decklink2_result (hr)) { + std::string serial_number = DlToStdString (str); + DeleteString (str); + + self->serial_number = g_strdup (serial_number.c_str ()); + GST_DEBUG_OBJECT (self, "device %d has serial number %s", index, + GST_STR_NULL (self->serial_number)); + } + + self->config = config; + device->QueryInterface (IID_IDeckLinkProfileManager, + (void **) &self->profile_manager); + } + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + hr = device->QueryInterface (IID_IDeckLinkAttributes_v10_11, + (void **) &self->attr_10_11); + } else { + hr = device->QueryInterface (IID_IDeckLinkProfileAttributes, + (void **) &self->attr); + } + + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, + "IDeckLinkProfileAttributes interface is not available"); + self->persistent_id = self->device_number; + } else { + hr = E_FAIL; + if (self->attr) { + hr = self->attr->GetInt (BMDDeckLinkPersistentID, &self->persistent_id); + if (!gst_decklink2_result (hr)) + self->persistent_id = self->device_number; + hr = self->attr->GetInt (BMDDeckLinkMaximumAudioChannels, + &max_num_audio_channels); + } else if (self->attr_10_11) { + hr = self->attr_10_11->GetInt (BMDDeckLinkPersistentID, + &self->persistent_id); + if (!gst_decklink2_result (hr)) + self->persistent_id = self->device_number; + hr = self->attr_10_11->GetInt (BMDDeckLinkMaximumAudioChannels, + &max_num_audio_channels); + } + + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (self, "Couldn't query max audio channels"); + max_num_audio_channels = 0; + } + } + + hr = device->GetModelName (&str); + if (gst_decklink2_result (hr)) { + std::string model_name = DlToStdString (str); + DeleteString (str); + + self->model_name = g_strdup (model_name.c_str ()); + } + + hr = device->GetDisplayName (&str); + if (gst_decklink2_result (hr)) { + std::string display_name = DlToStdString (str); + DeleteString (str); + + self->display_name = g_strdup (display_name.c_str ()); + } + + if (self->input) { + caps = gst_decklink2_input_get_caps (self->input, + bmdModeUnknown, bmdFormatUnspecified); + self->input_device = gst_decklink2_device_new (TRUE, self->model_name, + self->display_name, self->serial_number, caps, self->persistent_id, + self->device_number, (guint) max_num_audio_channels, driver_ver_str, + api_ver_str); + gst_clear_caps (&caps); + gst_object_ref_sink (self->input_device); + } + + if (self->output) { + caps = gst_decklink2_output_get_caps (self->output, + bmdModeUnknown, bmdFormatUnspecified); + self->output_device = gst_decklink2_device_new (FALSE, self->model_name, + self->display_name, self->serial_number, caps, self->persistent_id, + self->device_number, (guint) max_num_audio_channels, driver_ver_str, + api_ver_str); + gst_clear_caps (&caps); + gst_object_ref_sink (self->output_device); + } + + return self; +} + +#ifdef G_OS_WIN32 +static IDeckLinkIterator * +CreateDeckLinkIteratorInstance (void) +{ + IDeckLinkIterator *iter = NULL; + CoCreateInstance (CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, + IID_IDeckLinkIterator, (void **) &iter); + + return iter; +} + +static IDeckLinkIterator * +CreateDeckLinkIteratorInstance_v10_11 (void) +{ + IDeckLinkIterator *iter = NULL; + CoCreateInstance (CLSID_CDeckLinkIterator_v10_11, NULL, CLSCTX_ALL, + IID_IDeckLinkIterator, (void **) &iter); + + return iter; +} +#endif + +static void +gst_decklink2_device_init (void) +{ + GstDeckLink2APILevel api_level = gst_decklink2_get_api_level (); + IDeckLinkIterator *iter = NULL; + HRESULT hr = S_OK; + guint major, minor, sub, extra; + std::string driver_version; + std::string api_version; + + if (api_level == GST_DECKLINK2_API_LEVEL_UNKNOWN) + return; + + api_version = gst_decklink2_api_level_to_string (api_level); + + gst_decklink2_get_api_version (&major, &minor, &sub, &extra); + driver_version = std::to_string (major) + "." + std::to_string (minor) + + "." + std::to_string (sub) + "." + std::to_string (extra); + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + iter = CreateDeckLinkIteratorInstance_v10_11 (); + } else { + iter = CreateDeckLinkIteratorInstance (); + } + + if (!iter) { + GST_DEBUG ("Couldn't create device iterator"); + return; + } + + guint i = 0; + do { + IDeckLink *device = NULL; + GstDeckLink2Object *object; + hr = iter->Next (&device); + if (!gst_decklink2_result (hr)) + break; + + object = gst_decklink2_object_new (device, i, api_level, + api_version.c_str (), driver_version.c_str ()); + device->Release (); + + if (object) + device_list.push_back (object); + + i++; + } while (gst_decklink2_result (hr)); + + iter->Release (); + + std::sort (device_list.begin (), device_list.end (), + [](const GstDeckLink2Object * a, const GstDeckLink2Object * b)->bool + { + { + return a->persistent_id < b->persistent_id; + } + } + ); + + GST_DEBUG ("Found %u device", (guint) device_list.size ()); +} + +static void +gst_decklink2_device_init_once (void) +{ + GST_DECKLINK2_CALL_ONCE_BEGIN { + std::lock_guard < std::mutex > lk (device_lock); + gst_decklink2_device_init (); + } GST_DECKLINK2_CALL_ONCE_END; +} + +GstDeckLink2Input * +gst_decklink2_acquire_input (guint device_number, gint64 persistent_id) +{ + GstDeckLink2Object *target = NULL; + + gst_decklink2_device_init_once (); + + std::lock_guard < std::mutex > lk (device_lock); + + /* *INDENT-OFF* */ + if (persistent_id != -1) { + auto object = std::find_if (device_list.begin (), device_list.end (), + [&](const GstDeckLink2Object * obj) { + return obj->persistent_id == persistent_id; + }); + + if (object == device_list.end ()) { + GST_WARNING ("Couldn't find object for persistent id %" G_GINT64_FORMAT, + persistent_id); + return NULL; + } + + target = *object; + } + + if (!target) { + auto object = std::find_if (device_list.begin (), device_list.end (), + [&](const GstDeckLink2Object * obj) { + return obj->device_number == device_number; + }); + + if (object == device_list.end ()) { + GST_WARNING ("Couldn't find object for device number %u", device_number); + return NULL; + } + + target = *object; + } + /* *INDENT-ON* */ + + if (!target->input) { + GST_WARNING_OBJECT (target, "Device does not support input"); + return NULL; + } + + if (target->input_acquired) { + GST_WARNING_OBJECT (target, "Input was already acquired"); + return NULL; + } + + target->input_acquired = TRUE; + return (GstDeckLink2Input *) gst_object_ref (target->input); +} + +GstDeckLink2Output * +gst_decklink2_acquire_output (guint device_number, gint64 persistent_id) +{ + GstDeckLink2Object *target = NULL; + + gst_decklink2_device_init_once (); + + std::lock_guard < std::mutex > lk (device_lock); + + /* *INDENT-OFF* */ + if (persistent_id != -1) { + auto object = std::find_if (device_list.begin (), device_list.end (), + [&](const GstDeckLink2Object * obj) { + return obj->persistent_id == persistent_id; + }); + + if (object == device_list.end ()) { + GST_WARNING ("Couldn't find object for persistent id %" G_GINT64_FORMAT, + persistent_id); + return NULL; + } + + target = *object; + } + + if (!target) { + auto object = std::find_if (device_list.begin (), device_list.end (), + [&](const GstDeckLink2Object * obj) { + return obj->device_number == device_number; + }); + + if (object == device_list.end ()) { + GST_WARNING ("Couldn't find object for device number %u", device_number); + return NULL; + } + + target = *object; + } + /* *INDENT-ON* */ + + if (!target->output) { + GST_WARNING_OBJECT (target, "Device does not support output"); + return NULL; + } + + if (target->output_acquired) { + GST_WARNING_OBJECT (target, "Output was already acquired"); + return NULL; + } + + target->output_acquired = TRUE; + return (GstDeckLink2Output *) gst_object_ref (target->output); +} + +void +gst_decklink2_release_input (GstDeckLink2Input * input) +{ + std::unique_lock < std::mutex > lk (device_lock); + auto object = std::find_if (device_list.begin (), device_list.end (), + [&](const GstDeckLink2Object * obj) { + return obj->input == input; + } + ); + + if (object == device_list.end ()) { + GST_ERROR_OBJECT (input, "Couldn't find parent object"); + } else { + (*object)->input_acquired = FALSE; + } + lk.unlock (); + + gst_object_unref (input); +} + +void +gst_decklink2_release_output (GstDeckLink2Output * output) +{ + std::unique_lock < std::mutex > lk (device_lock); + auto object = std::find_if (device_list.begin (), device_list.end (), + [&](const GstDeckLink2Object * obj) { + return obj->output == output; + } + ); + + if (object == device_list.end ()) { + GST_ERROR_OBJECT (output, "Couldn't find parent object"); + } else { + (*object)->output_acquired = FALSE; + } + lk.unlock (); + + gst_object_unref (output); +} + +void +gst_decklink2_object_deinit (void) +{ + std::lock_guard < std::mutex > lk (device_lock); + + /* *INDENT-OFF* */ + for (auto iter : device_list) + gst_object_unref (iter); + /* *INDENT-ON* */ + + device_list.clear (); +} + +GList * +gst_decklink2_get_devices (void) +{ + GList *list = NULL; + + gst_decklink2_device_init_once (); + + std::lock_guard < std::mutex > lk (device_lock); + + /* *INDENT-OFF* */ + for (auto iter : device_list) { + if (iter->input_device) + list = g_list_append (list, gst_object_ref (iter->input_device)); + + if (iter->output_device) + list = g_list_append (list, gst_object_ref (iter->output_device)); + } + /* *INDENT-ON* */ + + return list; +} + +static HRESULT +gst_decklink2_set_duplex_mode (gint64 persistent_id, BMDDuplexMode_v10_11 mode) +{ + GstDeckLink2Object *object = NULL; + HRESULT hr = E_FAIL; + dlbool_t duplex_supported = FALSE; + + std::lock_guard < std::mutex > lk (device_lock); + + /* *INDENT-OFF* */ + for (auto iter : device_list) { + if (iter->persistent_id == persistent_id) { + object = iter; + break; + } + } + /* *INDENT-ON* */ + + if (!object) { + GST_ERROR ("Couldn't find device for persistent id %" G_GINT64_FORMAT, + persistent_id); + return E_FAIL; + } + + if (!object->attr_10_11 || !object->config_10_11) { + GST_WARNING_OBJECT (object, + "Couldn't set duplex mode, missing required interface"); + return E_FAIL; + } + + hr = object->attr_10_11->GetFlag ((BMDDeckLinkAttributeID) + BMDDeckLinkSupportsDuplexModeConfiguration_v10_11, &duplex_supported); + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (object, "Couldn't query duplex mode support"); + return hr; + } + + if (!duplex_supported) { + GST_WARNING_OBJECT (object, "Duplex mode is not supported"); + return E_FAIL; + } + + return object->config_10_11->SetInt ((BMDDeckLinkConfigurationID) + bmdDeckLinkConfigDuplexMode_v10_11, mode); +} + +HRESULT +gst_decklink2_object_set_profile_id (GstDeckLink2Object * object, + BMDProfileID profile_id) +{ + gchar *profile_id_str = NULL; + HRESULT hr = E_FAIL; + + g_return_val_if_fail (GST_IS_DECKLINK2_OBJECT (object), E_INVALIDARG); + + if (profile_id == bmdProfileDefault) + return S_OK; + + profile_id_str = g_enum_to_string (GST_TYPE_DECKLINK2_PROFILE_ID, profile_id); + + GST_DEBUG_OBJECT (object, "Setting profile id \"%s\"", profile_id_str); + + if (object->api_level == GST_DECKLINK2_API_LEVEL_10_11) { + dlbool_t duplex_supported = FALSE; + BMDDuplexMode_v10_11 duplex_mode = bmdDuplexModeHalf_v10_11; + + if (!object->attr_10_11 || !object->config_10_11) { + GST_WARNING_OBJECT (object, + "Couldn't set duplex mode, missing required interface"); + hr = E_FAIL; + goto out; + } + + switch (profile_id) { + case bmdProfileOneSubDeviceHalfDuplex: + case bmdProfileTwoSubDevicesHalfDuplex: + case bmdProfileFourSubDevicesHalfDuplex: + duplex_mode = bmdDuplexModeHalf_v10_11; + GST_DEBUG_OBJECT (object, "Mapping \"%s\" to bmdDuplexModeHalf"); + break; + default: + GST_DEBUG_OBJECT (object, "Mapping \"%s\" to bmdDuplexModeFull"); + duplex_mode = bmdDuplexModeFull_v10_11; + break; + } + + hr = object->attr_10_11->GetFlag ((BMDDeckLinkAttributeID) + BMDDeckLinkSupportsDuplexModeConfiguration_v10_11, &duplex_supported); + if (!gst_decklink2_result (hr)) + duplex_supported = FALSE; + + if (!duplex_supported) { + gint64 paired_device_id = 0; + if (duplex_mode == bmdDuplexModeFull_v10_11) { + GST_WARNING_OBJECT (object, "Device does not support Full-Duplex-Mode"); + goto out; + } + + hr = object->attr_10_11->GetInt ((BMDDeckLinkAttributeID) + BMDDeckLinkPairedDevicePersistentID_v10_11, &paired_device_id); + if (gst_decklink2_result (hr)) { + GST_DEBUG_OBJECT (object, + "Device has paired device, Setting duplex mode to paired device"); + hr = gst_decklink2_set_duplex_mode (paired_device_id, duplex_mode); + } else { + GST_WARNING_OBJECT (object, "Device does not support Half-Duplex-Mode"); + } + } else { + hr = object->config_10_11->SetInt ((BMDDeckLinkConfigurationID) + bmdDeckLinkConfigDuplexMode_v10_11, duplex_mode); + } + + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (object, + "Couldn't set profile \"%s\"", profile_id_str); + } else { + GST_DEBUG_OBJECT (object, "Profile \"%s\" is configured", profile_id_str); + } + } else { + IDeckLinkProfile *profile = NULL; + + if (!object->profile_manager) { + GST_WARNING_OBJECT (object, + "Profile \"%s\" is requested but profile manager is not available", + profile_id_str); + goto out; + } + + hr = object->profile_manager->GetProfile (profile_id, &profile); + if (gst_decklink2_result (hr)) { + hr = profile->SetActive (); + profile->Release (); + } + + if (!gst_decklink2_result (hr)) { + GST_WARNING_OBJECT (object, + "Couldn't set profile \"%s\"", profile_id_str); + } else { + GST_DEBUG_OBJECT (object, "Profile \"%s\" is configured", profile_id_str); + } + } + +out: + g_free (profile_id_str); + + return hr; +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2object.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2object.h new file mode 100644 index 0000000000..3f001e0f3c --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2object.h @@ -0,0 +1,51 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include "gstdecklink2utils.h" +#include "gstdecklink2input.h" +#include "gstdecklink2output.h" + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_OBJECT (gst_decklink2_object_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Object, gst_decklink2_object, + GST, DECKLINK2_OBJECT, GstObject); + +GstDeckLink2Input * gst_decklink2_acquire_input (guint device_number, + gint64 persistent_id); + +GstDeckLink2Output * gst_decklink2_acquire_output (guint device_number, + gint64 persistent_id); + +void gst_decklink2_release_input (GstDeckLink2Input * input); + +void gst_decklink2_release_output (GstDeckLink2Output * output); + +void gst_decklink2_object_deinit (void); + +GList * gst_decklink2_get_devices (void); + +HRESULT gst_decklink2_object_set_profile_id (GstDeckLink2Object * object, + BMDProfileID profile_id); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2output.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2output.cpp new file mode 100644 index 0000000000..b30e79dec7 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2output.cpp @@ -0,0 +1,2351 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2output.h" +#include "gstdecklink2object.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_output_debug); +#define GST_CAT_DEFAULT gst_decklink2_output_debug + +class IGstDeckLinkVideoOutputCallback; + +class IGstDeckLinkTimecode:public IDeckLinkTimecode +{ +public: + IGstDeckLinkTimecode (GstVideoTimeCode * timecode):ref_count_ (1) + { + g_assert (timecode); + + timecode_ = gst_video_time_code_copy (timecode); + } + + /* IUnknown */ + HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **object) + { + if (riid == IID_IDeckLinkTimecode) { + *object = static_cast < IDeckLinkTimecode * >(this); + } else { + *object = NULL; + return E_NOINTERFACE; + } + + AddRef (); + + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef (void) + { + ULONG cnt = ref_count_.fetch_add (1); + + return cnt + 1; + } + + ULONG STDMETHODCALLTYPE Release (void) + { + ULONG cnt = ref_count_.fetch_sub (1); + if (cnt == 1) + delete this; + + return cnt - 1; + } + + /* IDeckLinkTimecode */ + BMDTimecodeBCD STDMETHODCALLTYPE GetBCD (void) + { + BMDTimecodeBCD bcd = 0; + + bcd |= (timecode_->frames % 10) << 0; + bcd |= ((timecode_->frames / 10) & 0x0f) << 4; + bcd |= (timecode_->seconds % 10) << 8; + bcd |= ((timecode_->seconds / 10) & 0x0f) << 12; + bcd |= (timecode_->minutes % 10) << 16; + bcd |= ((timecode_->minutes / 10) & 0x0f) << 20; + bcd |= (timecode_->hours % 10) << 24; + bcd |= ((timecode_->hours / 10) & 0x0f) << 28; + + if (timecode_->config.fps_n == 24 && timecode_->config.fps_d == 1) + bcd |= 0x0 << 30; + else if (timecode_->config.fps_n == 25 && timecode_->config.fps_d == 1) + bcd |= 0x1 << 30; + else if (timecode_->config.fps_n == 30 && timecode_->config.fps_d == 1001) + bcd |= 0x2 << 30; + else if (timecode_->config.fps_n == 30 && timecode_->config.fps_d == 1) + bcd |= 0x3 << 30; + + return bcd; + } + + HRESULT STDMETHODCALLTYPE + GetComponents (unsigned char *hours, unsigned char *minutes, + unsigned char *seconds, unsigned char *frames) + { + *hours = timecode_->hours; + *minutes = timecode_->minutes; + *seconds = timecode_->seconds; + *frames = timecode_->frames; + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetString (dlstring_t * timecode) + { + gchar *s = gst_video_time_code_to_string (timecode_); + *timecode = StdToDlString (s); + g_free (s); + + return S_OK; + } + + BMDTimecodeFlags STDMETHODCALLTYPE GetFlags (void) + { + BMDTimecodeFlags flags = (BMDTimecodeFlags) 0; + + if ((timecode_->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) != 0) + flags = (BMDTimecodeFlags) (flags | bmdTimecodeIsDropFrame); + else + flags = (BMDTimecodeFlags) (flags | bmdTimecodeFlagDefault); + + if (timecode_->field_count == 2) + flags = (BMDTimecodeFlags) (flags | bmdTimecodeFieldMark); + + return flags; + } + + HRESULT STDMETHODCALLTYPE GetTimecodeUserBits (BMDTimecodeUserBits * userBits) + { + *userBits = 0; + return S_OK; + } + +private: + virtual ~ IGstDeckLinkTimecode () { + gst_video_time_code_free (timecode_); + } + +private: + GstVideoTimeCode * timecode_; + std::atomic < ULONG > ref_count_; +}; + +class IGstDeckLinkVideoFrame:public IDeckLinkVideoFrame +{ +public: + IGstDeckLinkVideoFrame (GstVideoFrame * frame):ref_count_ (1) + { + frame_ = *frame; + } + + /* IUnknown */ + HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **object) + { + if (riid == IID_IDeckLinkVideoFrame) { + *object = static_cast < IDeckLinkVideoFrame * >(this); + } else { + *object = NULL; + return E_NOINTERFACE; + } + + AddRef (); + + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef (void) + { + ULONG cnt = ref_count_.fetch_add (1); + + return cnt + 1; + } + + ULONG STDMETHODCALLTYPE Release (void) + { + ULONG cnt = ref_count_.fetch_sub (1); + if (cnt == 1) + delete this; + + return cnt - 1; + } + + /* IDeckLinkVideoFrame */ + long STDMETHODCALLTYPE GetWidth (void) + { + return GST_VIDEO_FRAME_WIDTH (&frame_); + } + + long STDMETHODCALLTYPE GetHeight (void) + { + return GST_VIDEO_FRAME_HEIGHT (&frame_); + } + + long STDMETHODCALLTYPE GetRowBytes (void) + { + return GST_VIDEO_FRAME_PLANE_STRIDE (&frame_, 0); + } + + BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat (void) + { + BMDPixelFormat format = bmdFormatUnspecified; + switch (GST_VIDEO_FRAME_FORMAT (&frame_)) { + case GST_VIDEO_FORMAT_UYVY: + format = bmdFormat8BitYUV; + break; + case GST_VIDEO_FORMAT_v210: + format = bmdFormat10BitYUV; + break; + case GST_VIDEO_FORMAT_ARGB: + format = bmdFormat8BitARGB; + break; + case GST_VIDEO_FORMAT_BGRA: + format = bmdFormat8BitBGRA; + break; + default: + g_assert_not_reached (); + break; + } + + return format; + } + + BMDFrameFlags STDMETHODCALLTYPE GetFlags (void) + { + return bmdFrameFlagDefault; + } + + HRESULT STDMETHODCALLTYPE GetBytes (void **buffer) + { + *buffer = GST_VIDEO_FRAME_PLANE_DATA (&frame_, 0); + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE + GetTimecode (BMDTimecodeFormat format, IDeckLinkTimecode ** timecode) + { + if (timecode_) { + *timecode = timecode_; + timecode_->AddRef (); + return S_OK; + } + + return S_FALSE; + } + + HRESULT STDMETHODCALLTYPE + GetAncillaryData (IDeckLinkVideoFrameAncillary ** ancillary) + { + if (ancillary_) { + *ancillary = ancillary_; + ancillary_->AddRef (); + return S_OK; + } + + return S_FALSE; + } + + /* Non-interface methods */ + HRESULT STDMETHODCALLTYPE SetTimecode (GstVideoTimeCode * timecode) + { + GST_DECKLINK2_CLEAR_COM (timecode_); + + if (timecode) + timecode_ = new IGstDeckLinkTimecode (timecode); + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE + SetAncillaryData (IDeckLinkVideoFrameAncillary * ancillary) + { + GST_DECKLINK2_CLEAR_COM (ancillary_); + + ancillary_ = ancillary; + if (ancillary_) + ancillary_->AddRef (); + + return S_OK; + } + + IGstDeckLinkVideoFrame *Clone (void) + { + IGstDeckLinkVideoFrame *cloned; + g_assert (frame_.buffer); + GstVideoFrame frame; + + if (!gst_video_frame_map (&frame, + &frame_.info, frame_.buffer, GST_MAP_READ)) { + return NULL; + } + + cloned = new IGstDeckLinkVideoFrame (&frame_); + if (ancillary_) + cloned->SetAncillaryData (ancillary_); + if (timecode_) { + timecode_->AddRef (); + cloned->timecode_ = timecode_; + } + + return cloned; + } + + void SetScheduledPts (GstClockTime pts) + { + pts_ = pts; + } + + GstClockTime GetScheduledPts (void) + { + return pts_; + } + + void SetScheduledHwTime (GstClockTime hw_time) + { + hw_time_ = hw_time; + } + + GstClockTime GetScheduledHwTime (void) + { + return hw_time_; + } + +private: + virtual ~ IGstDeckLinkVideoFrame () { + gst_video_frame_unmap (&frame_); + GST_DECKLINK2_CLEAR_COM (timecode_); + GST_DECKLINK2_CLEAR_COM (ancillary_); + } + +private: + std::atomic < ULONG > ref_count_; + GstVideoFrame frame_; + IDeckLinkTimecode *timecode_ = NULL; + IDeckLinkVideoFrameAncillary *ancillary_ = NULL; + GstClockTime pts_ = GST_CLOCK_TIME_NONE; + GstClockTime hw_time_ = GST_CLOCK_TIME_NONE; +}; + +class GstDecklink2OutputAudioBuffer +{ +public: + void Init (const gchar * debug_name, const GstAudioInfo & info, gint fps_n, + gint fps_d) + { + info_ = info; + buffer_.clear (); + video_frame_dup_drop_count_ = 0; + dup_drop_sample_offset_end_ = 0; + samples_to_drop_ = 0; + pos_ = 0; + fps_n_ = fps_n; + fps_d_ = fps_d; + init_done_ = true; + if (debug_name) + debug_name_ = debug_name; + else + debug_name_ = "GstDecklink2OutputAudioBuffer"; + } + + void Deinit () + { + buffer_.clear (); + init_done_ = false; + } + + guint64 Append (const guint8 * data, size_t size) + { + if (!data || size == 0 || !init_done_) + return 0; + + size_t cur_size = buffer_.size (); + size_t num_samples = size / info_.bpf; + + GST_LOG_ID (debug_name_.c_str (), "Appending %" G_GSIZE_FORMAT " samples", + num_samples); + + if (samples_to_drop_) { + GST_WARNING_ID (debug_name_.c_str (), "audio samples to drop %" + G_GUINT64_FORMAT ", new sample count %" G_GSIZE_FORMAT, + samples_to_drop_, num_samples); + + if (num_samples >= samples_to_drop_) { + size_t actual_append_samples = num_samples - samples_to_drop_; + size_t bytes_to_drop = samples_to_drop_ * info_.bpf; + samples_to_drop_ = 0; + if (actual_append_samples == 0) + return num_samples; + + data += bytes_to_drop; + size -= bytes_to_drop; + } else { + samples_to_drop_ -= num_samples; + return num_samples; + } + } + + buffer_.resize (cur_size + size); + memcpy (&buffer_[0] + cur_size, data, size); + + return num_samples; + } + + guint64 Drop () + { + if (!init_done_) + return 0; + + video_frame_dup_drop_count_++; + guint64 next_sample_offset = + gst_util_uint64_scale (video_frame_dup_drop_count_, + fps_d_ * info_.rate, fps_n_); + guint64 num_samples = next_sample_offset - dup_drop_sample_offset_end_; + samples_to_drop_ += num_samples; + dup_drop_sample_offset_end_ = next_sample_offset; + size_t cur_size = buffer_.size (); + guint64 samples_in_queue = cur_size / info_.bpf; + + GST_WARNING_ID (debug_name_.c_str (), "Samples to drop %" G_GUINT64_FORMAT + ", total samples to drop %" G_GUINT64_FORMAT ", samples in queue %" + G_GUINT64_FORMAT, num_samples, samples_to_drop_, samples_in_queue); + + size_t bytes_to_drop = samples_to_drop_ * info_.bpf; + if (cur_size >= bytes_to_drop) { + buffer_.resize (cur_size - bytes_to_drop); + samples_to_drop_ = 0; + } else { + guint64 samples_in_buffer = cur_size / info_.bpf; + samples_to_drop_ -= samples_in_buffer; + buffer_.clear (); + } + + return num_samples; + } + + guint64 PrependSilence () + { + if (!init_done_) + return 0; + + video_frame_dup_drop_count_++; + guint64 next_sample_offset = + gst_util_uint64_scale (video_frame_dup_drop_count_, + fps_d_ * info_.rate, fps_n_); + guint64 num_samples = next_sample_offset - dup_drop_sample_offset_end_; + dup_drop_sample_offset_end_ = next_sample_offset; + + GST_WARNING_ID (debug_name_.c_str (), "Prepending silence %" + G_GUINT64_FORMAT " samples", num_samples); + + size_t silence_length_in_bytes = num_samples * info_.bpf; + size_t cur_size = buffer_.size (); + + buffer_.resize (cur_size + silence_length_in_bytes); + if (cur_size > 0) { + memmove (&buffer_[0] + silence_length_in_bytes, &buffer_[0], cur_size); + } + + gst_audio_format_info_fill_silence (info_.finfo, &buffer_[0], + silence_length_in_bytes); + + return num_samples; + } + + guint8 *GetSamples (guint & num_samples, guint64 & sample_pos) + { + if (!init_done_) { + num_samples = 0; + return NULL; + } + + num_samples = buffer_.size () / info_.bpf; + sample_pos = pos_; + + if (num_samples == 0) + return NULL; + + return &buffer_[0]; + } + + void Flush (guint samples) + { + if (samples == 0 || buffer_.empty ()) + return; + + size_t cur_size = buffer_.size (); + size_t cur_samples = cur_size / info_.bpf; + size_t flush_size; + guint64 flush_samples; + bool clear_all = false; + + if (cur_samples <= samples) { + flush_size = cur_size; + flush_samples = cur_samples; + clear_all = true; + } else { + flush_size = samples * info_.bpf; + flush_samples = samples; + } + + pos_ += flush_samples; + if (clear_all) + buffer_.resize (0); + else + buffer_.erase (buffer_.begin (), buffer_.begin () + flush_size); + } + +private: + std::vector < guint8 > buffer_; + guint64 video_frame_dup_drop_count_ = 0; + guint64 dup_drop_sample_offset_end_ = 0; + guint64 samples_to_drop_ = 0; + guint64 pos_ = 0; + GstAudioInfo info_; + gint fps_n_; + gint fps_d_; + bool init_done_ = false; + std::string debug_name_; +}; + +struct GstDeckLink2OutputPrivate +{ + std::mutex extern_lock; + std::recursive_mutex schedule_lock; + std::condition_variable cond; + GstDecklink2OutputAudioBuffer audio_buf; +}; + +struct _GstDeckLink2Output +{ + GstObject parent; + + GstDeckLink2OutputPrivate *priv; + + GstDeckLink2APILevel api_level; + + IDeckLink *device; + IDeckLinkProfileAttributes *attr; + IDeckLinkAttributes_v10_11 *attr_10_11; + IDeckLinkConfiguration *config; + IDeckLinkConfiguration_v10_11 *config_10_11; + IDeckLinkKeyer *keyer; + + IDeckLinkOutput *output; + IDeckLinkOutput_v11_4 *output_11_4; + IDeckLinkOutput_v10_11 *output_10_11; + + IGstDeckLinkVideoOutputCallback *callback; + IGstDeckLinkVideoFrame *last_frame; + + GstCaps *caps; + GArray *format_table; + guint max_audio_channels; + + GstDeckLink2DisplayMode selected_mode; + GstAudioInfo audio_info; + + GstVideoVBIEncoder *vbi_enc; + gint vbi_width; + guint16 cdp_hdr_sequence_cntr; + guint n_prerolled; + guint64 n_frames; + guint64 n_samples; + guint n_preroll_frames; + guint min_buffered; + guint max_buffered; + guint gap_frames; + GstClockTime pts; + BMDTimeValue hw_time; + gboolean duplicating; + + gboolean configured; + gboolean prerolled; + guint64 late_count; + guint64 drop_count; + guint64 underrun_count; + guint64 overrun_count; + guint64 duplicate_count; + guint64 dropped_sample_count; + guint64 silent_sample_count; +}; + +static void gst_decklink2_output_dispose (GObject * object); +static void gst_decklink2_output_finalize (GObject * object); +static void gst_decklink2_output_on_stopped (GstDeckLink2Output * self); +static void gst_decklink2_output_on_completed (GstDeckLink2Output * self, + BMDOutputFrameCompletionResult result); +static HRESULT +gst_decklink2_output_get_completion_timestamp (GstDeckLink2Output * self, + IDeckLinkVideoFrame * frame, BMDTimeScale scale, BMDTimeValue * timestamp); + +#define gst_decklink2_output_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Output, gst_decklink2_output, GST_TYPE_OBJECT); + +class IGstDeckLinkVideoOutputCallback:public IDeckLinkVideoOutputCallback +{ +public: + IGstDeckLinkVideoOutputCallback (GstDeckLink2Output * output) + :ref_count_ (1), output_ (output) + { + } + + /* IUnknown */ + HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **object) + { + if (riid == IID_IDeckLinkVideoOutputCallback) { + *object = static_cast < IDeckLinkVideoOutputCallback * >(this); + } else { + *object = NULL; + return E_NOINTERFACE; + } + + AddRef (); + + return S_OK; + } + + ULONG STDMETHODCALLTYPE AddRef (void) + { + ULONG cnt = ref_count_.fetch_add (1); + + return cnt + 1; + } + + ULONG STDMETHODCALLTYPE Release (void) + { + ULONG cnt = ref_count_.fetch_sub (1); + if (cnt == 1) + delete this; + + return cnt - 1; + } + + /* IDeckLinkVideoOutputCallback */ + HRESULT STDMETHODCALLTYPE + ScheduledFrameCompleted (IDeckLinkVideoFrame * frame, + BMDOutputFrameCompletionResult result) + { + IGstDeckLinkVideoFrame *gst_frame = (IGstDeckLinkVideoFrame *) frame; + BMDTimeValue timestamp = GST_CLOCK_TIME_NONE; + GstClockTime pts, hw_pts; + + pts = gst_frame->GetScheduledPts (); + hw_pts = gst_frame->GetScheduledHwTime (); + gst_decklink2_output_get_completion_timestamp (output_, + frame, GST_SECOND, ×tamp); + + switch (result) { + case bmdOutputFrameCompleted: + GST_LOG_OBJECT (output_, "Frame %p completed timestamp %" + GST_TIME_FORMAT ", scheduled %" GST_TIME_FORMAT + " (gst pts %" GST_TIME_FORMAT ")", frame, + GST_TIME_ARGS (timestamp), GST_TIME_ARGS (hw_pts), + GST_TIME_ARGS (pts)); + break; + case bmdOutputFrameDisplayedLate: + GST_LOG_OBJECT (output_, "Frame %p late, completed timestamp %" + GST_TIME_FORMAT ", scheduled %" GST_TIME_FORMAT + " (gst pts %" GST_TIME_FORMAT ")", frame, + GST_TIME_ARGS (timestamp), GST_TIME_ARGS (hw_pts), + GST_TIME_ARGS (pts)); + break; + case bmdOutputFrameDropped: + GST_WARNING_OBJECT (output_, "Frame %p dropped, scheduled %" + GST_TIME_FORMAT, frame, GST_TIME_ARGS (pts)); + break; + case bmdOutputFrameFlushed: + GST_LOG_OBJECT (output_, "Flushed Frame %p", frame); + break; + default: + GST_WARNING_OBJECT (output_, "Unknown Frame %p: %d", + frame, (gint) result); + break; + } + + if (result == bmdOutputFrameCompleted || + result == bmdOutputFrameDisplayedLate || + result == bmdOutputFrameDropped) { + gst_decklink2_output_on_completed (output_, result); + } + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped (void) + { + gst_decklink2_output_on_stopped (output_); + return S_OK; + } + +private: + virtual ~ IGstDeckLinkVideoOutputCallback () { + } + +private: + std::atomic < ULONG > ref_count_; + GstDeckLink2Output *output_; +}; + +static void +gst_decklink2_output_class_init (GstDeckLink2OutputClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gst_decklink2_output_dispose; + object_class->finalize = gst_decklink2_output_finalize; + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_output_debug, "decklink2output", + 0, "decklink2output"); +} + +static void +gst_decklink2_output_init (GstDeckLink2Output * self) +{ + self->priv = new GstDeckLink2OutputPrivate (); + self->format_table = g_array_new (FALSE, + FALSE, sizeof (GstDeckLink2DisplayMode)); + self->callback = new IGstDeckLinkVideoOutputCallback (self); +} + +static void +gst_decklink2_output_dispose (GObject * object) +{ + GstDeckLink2Output *self = GST_DECKLINK2_OUTPUT (object); + + gst_clear_caps (&self->caps); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_decklink2_output_finalize (GObject * object) +{ + GstDeckLink2Output *self = GST_DECKLINK2_OUTPUT (object); + + GST_DECKLINK2_CLEAR_COM (self->output); + GST_DECKLINK2_CLEAR_COM (self->output_11_4); + GST_DECKLINK2_CLEAR_COM (self->output_10_11); + GST_DECKLINK2_CLEAR_COM (self->keyer); + GST_DECKLINK2_CLEAR_COM (self->attr); + GST_DECKLINK2_CLEAR_COM (self->attr_10_11); + GST_DECKLINK2_CLEAR_COM (self->config); + GST_DECKLINK2_CLEAR_COM (self->config_10_11); + GST_DECKLINK2_CLEAR_COM (self->device); + GST_DECKLINK2_CLEAR_COM (self->callback); + + g_array_unref (self->format_table); + g_clear_pointer (&self->vbi_enc, gst_video_vbi_encoder_free); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +/* Returns true if format is supported without conversion */ +static gboolean +gst_decklink2_output_does_support_video_mode (GstDeckLink2Output * self, + BMDDisplayMode mode, BMDPixelFormat format) +{ + HRESULT hr; + BMDDisplayModeSupport_v10_11 supported_v10_11 = + bmdDisplayModeNotSupported_v10_11; + dlbool_t supported = (dlbool_t) 0; + BMDDisplayMode actual_mode = mode; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->DoesSupportVideoMode (mode, format, + bmdVideoOutputFlagDefault, &supported_v10_11, NULL); + if (hr != S_OK || supported_v10_11 != bmdDisplayModeSupported_v10_11) + return FALSE; + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self-> + output_11_4->DoesSupportVideoMode (bmdVideoConnectionUnspecified, + mode, format, bmdSupportedVideoModeDefault, &actual_mode, &supported); + if (hr != S_OK || !supported || actual_mode != mode) + return FALSE; + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->DoesSupportVideoMode (bmdVideoConnectionUnspecified, + mode, format, bmdNoVideoOutputConversion, + bmdSupportedVideoModeDefault, &actual_mode, &supported); + if (hr != S_OK || !supported || actual_mode != mode) + return FALSE; + break; + default: + g_assert_not_reached (); + return FALSE; + } + + return TRUE; +} + +static IDeckLinkDisplayModeIterator * +gst_decklink2_output_get_iterator (GstDeckLink2Output * self) +{ + IDeckLinkDisplayModeIterator *iter = NULL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + self->output_10_11->GetDisplayModeIterator (&iter); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + self->output_11_4->GetDisplayModeIterator (&iter); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + self->output->GetDisplayModeIterator (&iter); + break; + default: + g_assert_not_reached (); + break; + } + + return iter; +} + +GstDeckLink2Output * +gst_decklink2_output_new (IDeckLink * device, GstDeckLink2APILevel api_level) +{ + GstDeckLink2Output *self; + IDeckLinkDisplayModeIterator *iter = NULL; + HRESULT hr; + + if (!device || api_level == GST_DECKLINK2_API_LEVEL_UNKNOWN) + return NULL; + + self = (GstDeckLink2Output *) g_object_new (GST_TYPE_DECKLINK2_OUTPUT, NULL); + self->api_level = api_level; + self->device = device; + device->AddRef (); + device->QueryInterface (IID_IDeckLinkKeyer, (void **) &self->keyer); + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + device->QueryInterface (IID_IDeckLinkAttributes_v10_11, + (void **) &self->attr_10_11); + } else { + device->QueryInterface (IID_IDeckLinkProfileAttributes, + (void **) &self->attr); + } + + self->max_audio_channels = 2; + gint64 max_audio_channels = 2; + if (self->attr) { + hr = self->attr->GetInt (BMDDeckLinkMaximumAudioChannels, + &max_audio_channels); + if (gst_decklink2_result (hr)) + self->max_audio_channels = (guint) max_audio_channels; + } else if (self->attr_10_11) { + hr = self->attr_10_11->GetInt (BMDDeckLinkMaximumAudioChannels, + &max_audio_channels); + if (gst_decklink2_result (hr)) + self->max_audio_channels = (guint) max_audio_channels; + } + + if (api_level == GST_DECKLINK2_API_LEVEL_10_11) { + device->QueryInterface (IID_IDeckLinkConfiguration_v10_11, + (void **) &self->config_10_11); + } else { + device->QueryInterface (IID_IDeckLinkConfiguration, + (void **) &self->config); + } + + switch (api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = device->QueryInterface (IID_IDeckLinkOutput_v10_11, + (void **) &self->output_10_11); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = device->QueryInterface (IID_IDeckLinkOutput_v11_4, + (void **) &self->output_11_4); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = device->QueryInterface (IID_IDeckLinkOutput, + (void **) &self->output); + if (!gst_decklink2_result (hr)) { + gst_object_unref (self); + return NULL; + } + break; + default: + g_assert_not_reached (); + gst_object_unref (self); + return NULL; + } + + iter = gst_decklink2_output_get_iterator (self); + if (!iter) { + gst_object_unref (self); + return NULL; + } + + self->caps = gst_decklink2_build_template_caps (GST_OBJECT (self), iter, + (GstDeckLink2DoesSupportVideoMode) + gst_decklink2_output_does_support_video_mode, self->format_table); + iter->Release (); + + if (!self->caps) + gst_clear_object (&self); + + return self; +} + +GstCaps * +gst_decklink2_output_get_caps (GstDeckLink2Output * output, BMDDisplayMode mode, + BMDPixelFormat format) +{ + IDeckLinkDisplayModeIterator *iter = NULL; + GstCaps *caps; + + if (mode == bmdModeUnknown && format == bmdFormatUnspecified) + return gst_caps_ref (output->caps); + + iter = gst_decklink2_output_get_iterator (output); + if (!iter) + return NULL; + + caps = gst_decklink2_build_caps (GST_OBJECT (output), iter, + mode, format, (GstDeckLink2DoesSupportVideoMode) + gst_decklink2_output_does_support_video_mode); + iter->Release (); + + return caps; +} + +gboolean +gst_decklink2_output_get_display_mode (GstDeckLink2Output * output, + const GstVideoInfo * info, GstDeckLink2DisplayMode * display_mode) +{ + for (guint i = 0; i < output->format_table->len; i++) { + const GstDeckLink2DisplayMode *m = &g_array_index (output->format_table, + GstDeckLink2DisplayMode, i); + + if (m->width == info->width && m->height == info->height && + m->fps_n == info->fps_n && m->fps_d == info->fps_d && + m->par_n == info->par_n && m->par_d == info->par_d) { + if ((m->interlaced && !GST_VIDEO_INFO_IS_INTERLACED (info)) || + (!m->interlaced && GST_VIDEO_INFO_IS_INTERLACED (info))) { + continue; + } + + *display_mode = *m; + return TRUE; + } + } + + return FALSE; +} + +guint +gst_decklink2_output_get_max_audio_channels (GstDeckLink2Output * output) +{ + return output->max_audio_channels; +} + +static HRESULT +gst_decklink2_output_enable_video (GstDeckLink2Output * self, + BMDDisplayMode mode, BMDVideoOutputFlags flags) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->EnableVideoOutput (mode, flags); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->EnableVideoOutput (mode, flags); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->EnableVideoOutput (mode, flags); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_enable_audio (GstDeckLink2Output * self, + BMDAudioSampleRate rate, BMDAudioSampleType sample_type, guint channels, + BMDAudioOutputStreamType stream_type) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->EnableAudioOutput (rate, + sample_type, channels, stream_type); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->EnableAudioOutput (rate, + sample_type, channels, stream_type); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->EnableAudioOutput (rate, + sample_type, channels, stream_type); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_disable_video (GstDeckLink2Output * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->DisableVideoOutput (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->DisableVideoOutput (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->DisableVideoOutput (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_disable_audio (GstDeckLink2Output * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->DisableAudioOutput (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->DisableAudioOutput (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->DisableAudioOutput (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_begin_audio_preroll (GstDeckLink2Output * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->BeginAudioPreroll (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->BeginAudioPreroll (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->BeginAudioPreroll (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_end_audio_preroll (GstDeckLink2Output * self) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->EndAudioPreroll (); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->EndAudioPreroll (); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->EndAudioPreroll (); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_schedule_audio_samples (GstDeckLink2Output * self, + void *buffer, guint count, BMDTimeValue stream_time, + BMDTimeScale scale, guint * written) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->ScheduleAudioSamples (buffer, count, stream_time, + scale, written); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->ScheduleAudioSamples (buffer, count, stream_time, + scale, written); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->ScheduleAudioSamples (buffer, count, stream_time, + scale, written); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_set_video_callback (GstDeckLink2Output * self, + IDeckLinkVideoOutputCallback * callback) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->SetScheduledFrameCompletionCallback (callback); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->SetScheduledFrameCompletionCallback (callback); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->SetScheduledFrameCompletionCallback (callback); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_create_ancillary_data (GstDeckLink2Output * self, + BMDPixelFormat format, IDeckLinkVideoFrameAncillary ** frame) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->CreateAncillaryData (format, frame); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->CreateAncillaryData (format, frame); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->CreateAncillaryData (format, frame); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_is_running (GstDeckLink2Output * self, dlbool_t * active) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->IsScheduledPlaybackRunning (active); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->IsScheduledPlaybackRunning (active); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->IsScheduledPlaybackRunning (active); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_get_num_buffered (GstDeckLink2Output * self, + guint32 * count) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->GetBufferedVideoFrameCount (count); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->GetBufferedVideoFrameCount (count); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->GetBufferedVideoFrameCount (count); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_get_num_buffered_audio (GstDeckLink2Output * self, + guint32 * count) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->GetBufferedAudioSampleFrameCount (count); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->GetBufferedAudioSampleFrameCount (count); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->GetBufferedAudioSampleFrameCount (count); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_get_reference_clock (GstDeckLink2Output * self, + BMDTimeScale scale, BMDTimeValue * hw_time, BMDTimeValue * time_in_frame, + BMDTimeValue * ticks_per_frame) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->GetHardwareReferenceClock (scale, + hw_time, time_in_frame, ticks_per_frame); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_get_completion_timestamp (GstDeckLink2Output * self, + IDeckLinkVideoFrame * frame, BMDTimeScale scale, BMDTimeValue * timestamp) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->GetFrameCompletionReferenceTimestamp (frame, + scale, timestamp); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->GetFrameCompletionReferenceTimestamp (frame, + scale, timestamp); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->GetFrameCompletionReferenceTimestamp (frame, + scale, timestamp); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_output_start (GstDeckLink2Output * self, + BMDTimeValue start_time, BMDTimeScale scale, double speed) +{ + HRESULT hr = E_FAIL; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->StartScheduledPlayback (start_time, + scale, speed); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->StartScheduledPlayback (start_time, scale, speed); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->StartScheduledPlayback (start_time, scale, speed); + break; + default: + g_assert_not_reached (); + break; + } + + return hr; +} + +static HRESULT +gst_decklink2_get_current_level (GstDeckLink2Output * self, + guint * buffered_video, GstClockTime * video_running_time, + guint * buffered_audio, GstClockTime * audio_running_time, + GstClockTimeDiff * av_diff, GstClockTime * hw_time, + GstClockTime * hw_now_gst) +{ + BMDTimeValue hw_now, dummy, dummy2; + HRESULT hr = S_OK; + + *buffered_video = 0; + *buffered_audio = 0; + *video_running_time = self->pts; + *audio_running_time = GST_CLOCK_TIME_NONE; + *av_diff = GST_CLOCK_STIME_NONE; + *hw_time = GST_CLOCK_TIME_NONE; + + hr = gst_decklink2_output_get_num_buffered (self, buffered_video); + if (!gst_decklink2_result (hr)) + return hr; + + if (self->n_samples > 0 && GST_AUDIO_INFO_IS_VALID (&self->audio_info)) { + hr = gst_decklink2_output_get_num_buffered_audio (self, buffered_audio); + if (!gst_decklink2_result (hr)) + return hr; + + *audio_running_time = gst_util_uint64_scale (self->n_samples, GST_SECOND, + self->audio_info.rate); + *av_diff = GST_CLOCK_DIFF (self->pts, *audio_running_time); + } + + if (self->prerolled) { + hr = gst_decklink2_output_get_reference_clock (self, GST_SECOND, &hw_now, + &dummy, &dummy2); + if (!gst_decklink2_result (hr)) + return hr; + + if (self->hw_time == GST_CLOCK_TIME_NONE) + self->hw_time = hw_now; + *hw_time = hw_now - self->hw_time; + } + + if (hw_now_gst) + *hw_now_gst = (GstClockTime) hw_now; + + return S_OK; +} + +static HRESULT +gst_decklink2_output_schedule_video_internal (GstDeckLink2Output * self, + IGstDeckLinkVideoFrame * frame) +{ + GstDeckLink2OutputPrivate *priv = self->priv; + GstClockTime next_pts, dur; + guint64 audio_pos; + HRESULT hr = E_FAIL; + guint num_samples; + guint num_written; + guint8 *audio_buf; + guint buffered_video = 0; + guint buffered_audio = 0; + GstClockTime video_running_time = GST_CLOCK_TIME_NONE; + GstClockTime audio_running_time = GST_CLOCK_TIME_NONE; + GstClockTime hw_time_gst = GST_CLOCK_TIME_NONE; + GstClockTime hw_now_gst = GST_CLOCK_TIME_NONE; + GstClockTimeDiff diff = GST_CLOCK_STIME_NONE; + + hr = gst_decklink2_get_current_level (self, &buffered_video, + &video_running_time, &buffered_audio, &audio_running_time, &diff, + &hw_time_gst, &hw_now_gst); + if (gst_decklink2_result (hr)) { + GST_LOG_OBJECT (self, "Before schedule, video %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ", buffered %u) audio %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ", buffered %u), av-diff: %" GST_STIME_FORMAT + ", hw-time %" GST_TIME_FORMAT, + GST_TIME_ARGS (self->pts), self->n_frames, buffered_video, + GST_TIME_ARGS (audio_running_time), self->n_samples, buffered_audio, + GST_STIME_ARGS (diff), GST_TIME_ARGS (hw_time_gst)); + } + + frame->AddRef (); + GST_DECKLINK2_CLEAR_COM (self->last_frame); + self->last_frame = frame; + + frame->SetScheduledPts (self->pts); + frame->SetScheduledHwTime (hw_now_gst); + + self->n_frames++; + next_pts = gst_util_uint64_scale (self->n_frames, + self->selected_mode.fps_d * GST_SECOND, self->selected_mode.fps_n); + dur = next_pts - self->pts; + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->ScheduleVideoFrame (frame, + self->pts, dur, GST_SECOND); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->ScheduleVideoFrame (frame, + self->pts, dur, GST_SECOND); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->ScheduleVideoFrame (frame, self->pts, dur, GST_SECOND); + break; + default: + g_assert_not_reached (); + break; + } + + self->pts = next_pts; + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Couldn't schedule video frame, hr: 0x%x", + (guint) hr); + return hr; + } + + audio_buf = priv->audio_buf.GetSamples (num_samples, audio_pos); + self->n_samples += num_samples; + + if (!self->prerolled) { + if (self->n_prerolled == 0 && GST_AUDIO_INFO_IS_VALID (&self->audio_info)) { + GST_DEBUG_OBJECT (self, "Begin audio preroll"); + + hr = gst_decklink2_output_begin_audio_preroll (self); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Couldn't start audio preroll, hr: 0x%x", + (guint) hr); + return hr; + } + } + + while (audio_buf && num_samples > 0) { + num_written = 0; + hr = gst_decklink2_output_schedule_audio_samples (self, + audio_buf, num_samples, audio_pos, self->audio_info.rate, + &num_written); + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Couldn't schedule audio sample, hr: 0x%x", + (guint) hr); + return hr; + } + + priv->audio_buf.Flush (num_written); + audio_buf = priv->audio_buf.GetSamples (num_samples, audio_pos); + }; + + self->n_prerolled++; + if (self->n_prerolled >= self->n_preroll_frames) { + if (GST_AUDIO_INFO_IS_VALID (&self->audio_info)) { + hr = gst_decklink2_output_end_audio_preroll (self); + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Audio preroll failed, hr: 0x%x", (guint) hr); + return hr; + } + } + + hr = gst_decklink2_output_start (self, 0, GST_SECOND, 1.0); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Couldn't start playback, hr: 0x%x", + (guint) hr); + return hr; + } + + GST_DEBUG_OBJECT (self, "Prerolled, start playback"); + + self->prerolled = TRUE; + } + } else { + while (audio_buf && num_samples > 0) { + num_written = 0; + hr = gst_decklink2_output_schedule_audio_samples (self, + audio_buf, num_samples, audio_pos, self->audio_info.rate, + &num_written); + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Couldn't schedule audio sample, hr: 0x%x", + (guint) hr); + return hr; + } + + priv->audio_buf.Flush (num_written); + audio_buf = priv->audio_buf.GetSamples (num_samples, audio_pos); + }; + } + + return S_OK; +} + +HRESULT +gst_decklink2_output_schedule_stream (GstDeckLink2Output * output, + IDeckLinkVideoFrame * frame, guint8 * audio_buf, gsize audio_buf_size, + GstDecklink2OutputStats * stats) +{ + GstDeckLink2OutputPrivate *priv = output->priv; + HRESULT hr; + std::unique_lock < std::mutex > lk (priv->extern_lock); + dlbool_t active; + + g_assert (output->configured); + + hr = gst_decklink2_output_is_running (output, &active); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (output, "Couldn't query active state, hr: 0x%x", + (guint) hr); + return hr; + } + + if (active) { + std::lock_guard < std::recursive_mutex > slk (priv->schedule_lock); + guint buffered_video = 0; + guint buffered_audio = 0; + GstClockTime video_running_time = GST_CLOCK_TIME_NONE; + GstClockTime audio_running_time = GST_CLOCK_TIME_NONE; + GstClockTime hw_time_gst = GST_CLOCK_TIME_NONE; + GstClockTimeDiff diff = GST_CLOCK_STIME_NONE; + + hr = gst_decklink2_get_current_level (output, &buffered_video, + &video_running_time, &buffered_audio, &audio_running_time, &diff, + &hw_time_gst, NULL); + + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (output, + "Couldn't query bufferred frame count, hr: 0x%x", (guint) hr); + return hr; + } + + stats->buffered_video = buffered_video; + stats->buffered_audio = buffered_audio; + stats->video_running_time = video_running_time; + stats->audio_running_time = audio_running_time; + stats->buffered_video_time = gst_util_uint64_scale (buffered_video, + output->selected_mode.fps_d * GST_SECOND, output->selected_mode.fps_n); + stats->buffered_audio_time = 0; + if (GST_AUDIO_INFO_IS_VALID (&output->audio_info)) { + stats->buffered_audio_time = gst_util_uint64_scale (buffered_audio, + GST_SECOND, output->audio_info.rate); + } + stats->hw_time = hw_time_gst; + stats->scheduled_video_frames = output->n_frames; + stats->scheduled_audio_samples = output->n_samples; + stats->late_count = output->late_count; + stats->drop_count = output->drop_count; + stats->overrun_count = output->overrun_count; + stats->underrun_count = output->underrun_count; + stats->duplicate_count = output->duplicate_count; + stats->silent_sample_count = output->silent_sample_count; + stats->dropped_sample_count = output->dropped_sample_count; + + if (buffered_video > output->max_buffered) { + GST_WARNING_OBJECT (output, "Skipping frame, video %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ", buffered %u) audio %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ", buffered %u), av-diff: %" GST_STIME_FORMAT + ", hw-time %" GST_TIME_FORMAT, + GST_TIME_ARGS (output->pts), output->n_frames, buffered_video, + GST_TIME_ARGS (audio_running_time), output->n_samples, buffered_audio, + GST_STIME_ARGS (diff), GST_TIME_ARGS (hw_time_gst)); + output->overrun_count++; + if (audio_buf_size > 0 && GST_AUDIO_INFO_IS_VALID (&output->audio_info)) { + gsize dropped_samples = audio_buf_size / output->audio_info.bpf; + output->dropped_sample_count += dropped_samples; + } + + return S_OK; + } + } + lk.unlock (); + + std::lock_guard < std::recursive_mutex > slk (priv->schedule_lock); + priv->audio_buf.Append (audio_buf, audio_buf_size); + + hr = gst_decklink2_output_schedule_video_internal (output, + (IGstDeckLinkVideoFrame *) frame); + + return hr; +} + +static HRESULT +gst_decklink2_output_stop_internal (GstDeckLink2Output * self) +{ + GstDeckLink2OutputPrivate *priv = self->priv; + HRESULT hr = E_FAIL; + + GST_DEBUG_OBJECT (self, "Stopping"); + + std::unique_lock < std::recursive_mutex > lk (priv->schedule_lock); + /* Steal last frame to avoid re-rendering */ + GST_DECKLINK2_CLEAR_COM (self->last_frame); + lk.unlock (); + + switch (self->api_level) { + case GST_DECKLINK2_API_LEVEL_10_11: + hr = self->output_10_11->StopScheduledPlayback (0, NULL, 0); + break; + case GST_DECKLINK2_API_LEVEL_11_4: + hr = self->output_11_4->StopScheduledPlayback (0, NULL, 0); + break; + case GST_DECKLINK2_API_LEVEL_11_5_1: + case GST_DECKLINK2_API_LEVEL_LATEST: + hr = self->output->StopScheduledPlayback (0, NULL, 0); + break; + default: + g_assert_not_reached (); + break; + } + + GST_DEBUG_OBJECT (self, "StopScheduledPlayback result 0x%x", (guint) hr); + + gst_decklink2_output_disable_audio (self); + gst_decklink2_output_disable_video (self); + gst_decklink2_output_set_video_callback (self, NULL); + self->configured = FALSE; + self->prerolled = FALSE; + self->late_count = 0; + self->drop_count = 0; + self->underrun_count = 0; + self->overrun_count = 0; + self->duplicate_count = 0; + self->dropped_sample_count = 0; + self->silent_sample_count = 0; + + return hr; +} + +HRESULT +gst_decklink2_output_stop (GstDeckLink2Output * output) +{ + GstDeckLink2OutputPrivate *priv = output->priv; + std::lock_guard < std::mutex > lk (priv->extern_lock); + + return gst_decklink2_output_stop_internal (output); +} + +/* Copied from ext/closedcaption/gstccconverter.c */ +/* Converts raw CEA708 cc_data and an optional timecode into CDP */ +static guint +convert_cea708_cc_data_cea708_cdp_internal (GstDeckLink2Output * self, + const guint8 * cc_data, guint cc_data_len, guint8 * cdp, guint cdp_len, + const GstVideoTimeCodeMeta * tc_meta) +{ + GstByteWriter bw; + guint8 flags, checksum; + guint i, len; + const GstDeckLink2DisplayMode *mode = &self->selected_mode; + + gst_byte_writer_init_with_data (&bw, cdp, cdp_len, FALSE); + gst_byte_writer_put_uint16_be_unchecked (&bw, 0x9669); + /* Write a length of 0 for now */ + gst_byte_writer_put_uint8_unchecked (&bw, 0); + if (mode->fps_n == 24000 && mode->fps_d == 1001) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x1f); + } else if (mode->fps_n == 24 && mode->fps_d == 1) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x2f); + } else if (mode->fps_n == 25 && mode->fps_d == 1) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x3f); + } else if (mode->fps_n == 30000 && mode->fps_d == 1001) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x4f); + } else if (mode->fps_n == 30 && mode->fps_d == 1) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x5f); + } else if (mode->fps_n == 50 && mode->fps_d == 1) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x6f); + } else if (mode->fps_n == 60000 && mode->fps_d == 1001) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x7f); + } else if (mode->fps_n == 60 && mode->fps_d == 1) { + gst_byte_writer_put_uint8_unchecked (&bw, 0x8f); + } else { + g_assert_not_reached (); + } + + /* ccdata_present | caption_service_active */ + flags = 0x42; + + /* time_code_present */ + if (tc_meta) + flags |= 0x80; + + /* reserved */ + flags |= 0x01; + + gst_byte_writer_put_uint8_unchecked (&bw, flags); + gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr); + + if (tc_meta) { + const GstVideoTimeCode *tc = &tc_meta->tc; + guint8 u8; + + gst_byte_writer_put_uint8_unchecked (&bw, 0x71); + /* reserved 11 - 2 bits */ + u8 = 0xc0; + /* tens of hours - 2 bits */ + u8 |= ((tc->hours / 10) & 0x3) << 4; + /* units of hours - 4 bits */ + u8 |= (tc->hours % 10) & 0xf; + gst_byte_writer_put_uint8_unchecked (&bw, u8); + + /* reserved 1 - 1 bit */ + u8 = 0x80; + /* tens of minutes - 3 bits */ + u8 |= ((tc->minutes / 10) & 0x7) << 4; + /* units of minutes - 4 bits */ + u8 |= (tc->minutes % 10) & 0xf; + gst_byte_writer_put_uint8_unchecked (&bw, u8); + + /* field flag - 1 bit */ + u8 = tc->field_count < 2 ? 0x00 : 0x80; + /* tens of seconds - 3 bits */ + u8 |= ((tc->seconds / 10) & 0x7) << 4; + /* units of seconds - 4 bits */ + u8 |= (tc->seconds % 10) & 0xf; + gst_byte_writer_put_uint8_unchecked (&bw, u8); + + /* drop frame flag - 1 bit */ + u8 = (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) ? 0x80 : + 0x00; + /* reserved0 - 1 bit */ + /* tens of frames - 2 bits */ + u8 |= ((tc->frames / 10) & 0x3) << 4; + /* units of frames 4 bits */ + u8 |= (tc->frames % 10) & 0xf; + gst_byte_writer_put_uint8_unchecked (&bw, u8); + } + + gst_byte_writer_put_uint8_unchecked (&bw, 0x72); + gst_byte_writer_put_uint8_unchecked (&bw, 0xe0 | cc_data_len / 3); + gst_byte_writer_put_data_unchecked (&bw, cc_data, cc_data_len); + + gst_byte_writer_put_uint8_unchecked (&bw, 0x74); + gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr); + self->cdp_hdr_sequence_cntr++; + /* We calculate the checksum afterwards */ + gst_byte_writer_put_uint8_unchecked (&bw, 0); + + len = gst_byte_writer_get_pos (&bw); + gst_byte_writer_set_pos (&bw, 2); + gst_byte_writer_put_uint8_unchecked (&bw, len); + + checksum = 0; + for (i = 0; i < len; i++) { + checksum += cdp[i]; + } + checksum &= 0xff; + checksum = 256 - checksum; + cdp[len - 1] = checksum; + + return len; +} + +static void +gst_decklink2_output_write_vbi (GstDeckLink2Output * self, + const GstVideoInfo * info, GstBuffer * buffer, + IGstDeckLinkVideoFrame * frame, GstVideoTimeCodeMeta * tc_meta, + gint caption_line, gint afd_bar_line) +{ + IDeckLinkVideoFrameAncillary *vanc_frame = NULL; + gpointer iter = NULL; + GstVideoCaptionMeta *cc_meta; + guint8 *vancdata; + gboolean got_captions = FALSE; + + if (caption_line == 0 && afd_bar_line == 0) + return; + + if (self->vbi_width != info->width) + g_clear_pointer (&self->vbi_enc, gst_video_vbi_encoder_free); + + if (!self->vbi_enc) { + self->vbi_enc = gst_video_vbi_encoder_new (GST_VIDEO_FORMAT_v210, + info->width); + self->vbi_width = info->width; + } + + /* Put any closed captions into the configured line */ + while ((cc_meta = + (GstVideoCaptionMeta *) gst_buffer_iterate_meta_filtered (buffer, + &iter, GST_VIDEO_CAPTION_META_API_TYPE))) { + switch (cc_meta->caption_type) { + case GST_VIDEO_CAPTION_TYPE_CEA608_RAW:{ + guint8 data[138]; + guint i, n; + + n = cc_meta->size / 2; + if (cc_meta->size > 46) { + GST_WARNING_OBJECT (self, "Too big raw CEA608 buffer"); + break; + } + + /* This is the offset from line 9 for 525-line fields and from line + * 5 for 625-line fields. + * + * The highest bit is set for field 1 but not for field 0, but we + * have no way of knowning the field here + */ + for (i = 0; i < n; i++) { + data[3 * i] = 0x80 | (info->height == + 525 ? caption_line - 9 : caption_line - 5); + data[3 * i + 1] = cc_meta->data[2 * i]; + data[3 * i + 2] = cc_meta->data[2 * i + 1]; + } + + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, FALSE, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_608 >> 8, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_608 & 0xff, data, 3)) { + GST_WARNING_OBJECT (self, "Couldn't add meta to ancillary data"); + } + + got_captions = TRUE; + + break; + } + case GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A:{ + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, FALSE, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_608 >> 8, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_608 & 0xff, cc_meta->data, + cc_meta->size)) + GST_WARNING_OBJECT (self, "Couldn't add meta to ancillary data"); + + got_captions = TRUE; + + break; + } + case GST_VIDEO_CAPTION_TYPE_CEA708_RAW:{ + guint8 data[256]; + guint n; + + n = cc_meta->size / 3; + if (cc_meta->size > 46) { + GST_WARNING_OBJECT (self, "Too big raw CEA708 buffer"); + break; + } + + n = convert_cea708_cc_data_cea708_cdp_internal (self, cc_meta->data, + cc_meta->size, data, sizeof (data), tc_meta); + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, FALSE, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 >> 8, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 & 0xff, data, n)) + GST_WARNING_OBJECT (self, "Couldn't add meta to ancillary data"); + + got_captions = TRUE; + + break; + } + case GST_VIDEO_CAPTION_TYPE_CEA708_CDP:{ + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, + FALSE, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 >> 8, + GST_VIDEO_ANCILLARY_DID16_S334_EIA_708 & 0xff, cc_meta->data, + cc_meta->size)) + GST_WARNING_OBJECT (self, "Couldn't add meta to ancillary data"); + + got_captions = TRUE; + + break; + } + default:{ + GST_FIXME_OBJECT (self, "Caption type %d not supported", + cc_meta->caption_type); + break; + } + } + } + + if ((got_captions || afd_bar_line != 0) + && gst_decklink2_output_create_ancillary_data (self, + bmdFormat10BitYUV, &vanc_frame) == S_OK) { + GstVideoAFDMeta *afd_meta = NULL, *afd_meta2 = NULL; + GstVideoBarMeta *bar_meta = NULL, *bar_meta2 = NULL; + GstMeta *meta; + gpointer meta_iter; + guint8 afd_bar_data[8] = { 0, }; + guint8 afd_bar_data2[8] = { 0, }; + guint8 afd = 0; + gboolean is_letterbox = 0; + guint16 bar1 = 0, bar2 = 0; + guint i; + + // Get any reasonable AFD/Bar metas for both fields + meta_iter = NULL; + while ((meta = + gst_buffer_iterate_meta_filtered (buffer, &meta_iter, + GST_VIDEO_AFD_META_API_TYPE))) { + GstVideoAFDMeta *tmp_meta = (GstVideoAFDMeta *) meta; + + if (tmp_meta->field == 0 || !afd_meta || (afd_meta && afd_meta->field != 0 + && tmp_meta->field == 0)) + afd_meta = tmp_meta; + if (tmp_meta->field == 1 || !afd_meta2 || (afd_meta2 + && afd_meta->field != 1 && tmp_meta->field == 1)) + afd_meta2 = tmp_meta; + } + + meta_iter = NULL; + while ((meta = + gst_buffer_iterate_meta_filtered (buffer, &meta_iter, + GST_VIDEO_BAR_META_API_TYPE))) { + GstVideoBarMeta *tmp_meta = (GstVideoBarMeta *) meta; + + if (tmp_meta->field == 0 || !bar_meta || (bar_meta && bar_meta->field != 0 + && tmp_meta->field == 0)) + bar_meta = tmp_meta; + if (tmp_meta->field == 1 || !bar_meta2 || (bar_meta2 + && bar_meta->field != 1 && tmp_meta->field == 1)) + bar_meta2 = tmp_meta; + } + + for (i = 0; i < 2; i++) { + guint8 *afd_bar_data_ptr; + + if (i == 0) { + afd_bar_data_ptr = afd_bar_data; + afd = afd_meta ? afd_meta->afd : 0; + is_letterbox = bar_meta ? bar_meta->is_letterbox : FALSE; + bar1 = bar_meta ? bar_meta->bar_data1 : 0; + bar2 = bar_meta ? bar_meta->bar_data2 : 0; + } else { + afd_bar_data_ptr = afd_bar_data2; + afd = afd_meta2 ? afd_meta2->afd : 0; + is_letterbox = bar_meta2 ? bar_meta2->is_letterbox : FALSE; + bar1 = bar_meta2 ? bar_meta2->bar_data1 : 0; + bar2 = bar_meta2 ? bar_meta2->bar_data2 : 0; + } + + /* See SMPTE 2016-3 Section 4 */ + /* AFD and AR */ + if (self->selected_mode.mode == bmdModeNTSC || + self->selected_mode.mode == bmdModeNTSC2398 || + self->selected_mode.mode == bmdModePAL || + self->selected_mode.mode == bmdModeNTSCp || + self->selected_mode.mode == bmdModePALp) { + afd_bar_data_ptr[0] = (afd << 3) | 0x0; + } else { + afd_bar_data_ptr[0] = (afd << 3) | 0x4; + } + + /* Bar flags */ + afd_bar_data_ptr[3] = is_letterbox ? 0xc0 : 0x30; + + /* Bar value 1 and 2 */ + GST_WRITE_UINT16_BE (&afd_bar_data_ptr[4], bar1); + GST_WRITE_UINT16_BE (&afd_bar_data_ptr[6], bar2); + } + + /* AFD on the same line as the captions */ + if (caption_line == afd_bar_line) { + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, + FALSE, GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR >> 8, + GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR & 0xff, afd_bar_data, + sizeof (afd_bar_data))) + GST_WARNING_OBJECT (self, + "Couldn't add AFD/Bar data to ancillary data"); + } + + /* FIXME: Add captions to the correct field? Captions for the second + * field should probably be inserted into the second field */ + + if (got_captions || caption_line == afd_bar_line) { + if (vanc_frame->GetBufferForVerticalBlankingLine (caption_line, + (void **) &vancdata) == S_OK) { + gst_video_vbi_encoder_write_line (self->vbi_enc, vancdata); + } else { + GST_WARNING_OBJECT (self, + "Failed to get buffer for line %d ancillary data", caption_line); + } + } + + /* AFD on a different line than the captions */ + if (afd_bar_line != 0 && caption_line != afd_bar_line) { + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, + FALSE, GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR >> 8, + GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR & 0xff, afd_bar_data, + sizeof (afd_bar_data))) + GST_WARNING_OBJECT (self, + "Couldn't add AFD/Bar data to ancillary data"); + + if (vanc_frame->GetBufferForVerticalBlankingLine (afd_bar_line, + (void **) &vancdata) == S_OK) { + gst_video_vbi_encoder_write_line (self->vbi_enc, vancdata); + } else { + GST_WARNING_OBJECT (self, + "Failed to get buffer for line %d ancillary data", afd_bar_line); + } + } + + /* For interlaced video we need to also add AFD to the second field */ + if (GST_VIDEO_INFO_IS_INTERLACED (info) && afd_bar_line != 0) { + guint field2_offset; + + /* The VANC lines for the second field are at an offset, depending on + * the format in use. + */ + switch (info->height) { + case 486: + /* NTSC: 525 / 2 + 1 */ + field2_offset = 263; + break; + case 576: + /* PAL: 625 / 2 + 1 */ + field2_offset = 313; + break; + case 1080: + /* 1080i: 1125 / 2 + 1 */ + field2_offset = 563; + break; + default: + g_assert_not_reached (); + } + + if (!gst_video_vbi_encoder_add_ancillary (self->vbi_enc, + FALSE, GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR >> 8, + GST_VIDEO_ANCILLARY_DID16_S2016_3_AFD_BAR & 0xff, afd_bar_data2, + sizeof (afd_bar_data))) + GST_WARNING_OBJECT (self, + "Couldn't add AFD/Bar data to ancillary data"); + + if (vanc_frame->GetBufferForVerticalBlankingLine (afd_bar_line + + field2_offset, (void **) &vancdata) == S_OK) { + gst_video_vbi_encoder_write_line (self->vbi_enc, vancdata); + } else { + GST_WARNING_OBJECT (self, + "Failed to get buffer for line %d ancillary data", afd_bar_line); + } + } + + if (frame->SetAncillaryData (vanc_frame) != S_OK) { + GST_WARNING_OBJECT (self, "Failed to set ancillary data"); + } + + vanc_frame->Release (); + } else if (got_captions || afd_bar_line != 0) { + GST_WARNING_OBJECT (self, "Failed to allocate ancillary data frame"); + } +} + +IDeckLinkVideoFrame * +gst_decklink2_output_upload (GstDeckLink2Output * output, + const GstVideoInfo * info, GstBuffer * buffer, gint caption_line, + gint afd_bar_line) +{ + GstVideoFrame vframe; + IGstDeckLinkVideoFrame *frame; + GstVideoTimeCodeMeta *tc_meta; + + if (!gst_video_frame_map (&vframe, info, buffer, GST_MAP_READ)) { + GST_ERROR_OBJECT (output, "Failed to map video frame"); + return NULL; + } + + frame = new IGstDeckLinkVideoFrame (&vframe); + + tc_meta = gst_buffer_get_video_time_code_meta (buffer); + if (tc_meta) + frame->SetTimecode (&tc_meta->tc); + + gst_decklink2_output_write_vbi (output, info, buffer, frame, tc_meta, + caption_line, afd_bar_line); + + return frame; +} + +HRESULT +gst_decklink2_output_configure (GstDeckLink2Output * output, + guint n_preroll_frames, guint min_buffered, guint max_buffered, + const GstDeckLink2DisplayMode * display_mode, + BMDVideoOutputFlags output_flags, BMDProfileID profile_id, + GstDeckLink2KeyerMode keyer_mode, guint8 keyer_level, + GstDeckLink2MappingFormat mapping_format, + BMDAudioSampleType audio_sample_type, guint audio_channels) +{ + GstDeckLink2OutputPrivate *priv = output->priv; + HRESULT hr = S_OK; + + std::lock_guard < std::mutex > lk (priv->extern_lock); + if (output->configured) + gst_decklink2_output_stop_internal (output); + + output->selected_mode = *display_mode; + + if (profile_id != bmdProfileDefault) { + GstDeckLink2Object *object; + gchar *profile_id_str = g_enum_to_string (GST_TYPE_DECKLINK2_PROFILE_ID, + profile_id); + + object = (GstDeckLink2Object *) gst_object_get_parent (GST_OBJECT (output)); + g_assert (object); + + gst_decklink2_object_set_profile_id (object, profile_id); + gst_object_unref (object); + + g_free (profile_id_str); + } + + if (mapping_format != GST_DECKLINK2_MAPPING_FORMAT_DEFAULT && + (output->attr || output->attr_10_11)) { + dlbool_t supported = false; + + if (output->attr) { + hr = output->attr->GetFlag (BMDDeckLinkSupportsSMPTELevelAOutput, + &supported); + } else { + hr = output->attr_10_11->GetFlag (BMDDeckLinkSupportsSMPTELevelAOutput, + &supported); + } + + if (gst_decklink2_result (hr) && supported) { + hr = E_FAIL; + if (mapping_format == GST_DECKLINK2_MAPPING_FORMAT_LEVEL_A) { + if (output->config_10_11) { + hr = output-> + config_10_11->SetFlag (bmdDeckLinkConfigSMPTELevelAOutput, true); + } else if (output->config) { + hr = output->config->SetFlag (bmdDeckLinkConfigSMPTELevelAOutput, + true); + } + } else if (mapping_format == GST_DECKLINK2_MAPPING_FORMAT_LEVEL_B) { + if (output->config_10_11) { + hr = output-> + config_10_11->SetFlag (bmdDeckLinkConfigSMPTELevelAOutput, false); + } else if (output->config) { + hr = output->config->SetFlag (bmdDeckLinkConfigSMPTELevelAOutput, + false); + } + } + + if (gst_decklink2_result (hr)) + GST_DEBUG_OBJECT (output, "SMPTELevelAOutput is configured"); + else + GST_WARNING_OBJECT (output, "Couldn't configure SMPTELevelAOutput"); + } else { + GST_WARNING_OBJECT (output, "SMPTELevelAOutput is not supported"); + } + } + + if (output->keyer) { + switch (keyer_mode) { + case GST_DECKLINK2_KEYER_MODE_INTERNAL: + output->keyer->Enable (false); + output->keyer->SetLevel (keyer_level); + break; + case GST_DECKLINK2_KEYER_MODE_EXTERNAL: + output->keyer->Enable (true); + output->keyer->SetLevel (keyer_level); + break; + case GST_DECKLINK2_KEYER_MODE_OFF: + default: + output->keyer->Disable (); + break; + } + } else if (keyer_mode != GST_DECKLINK2_KEYER_MODE_OFF) { + GST_WARNING_OBJECT (output, "Keyer interface is unavailable"); + } + + hr = gst_decklink2_output_enable_video (output, + gst_decklink2_get_real_display_mode (output->selected_mode.mode), + output_flags); + if (!gst_decklink2_result (hr)) + goto error; + + hr = gst_decklink2_output_set_video_callback (output, output->callback); + if (!gst_decklink2_result (hr)) + goto error; + + gst_audio_info_init (&output->audio_info); + if (audio_channels > 0) { + GST_DEBUG_OBJECT (output, "Enabling audio"); + hr = gst_decklink2_output_enable_audio (output, bmdAudioSampleRate48kHz, + audio_sample_type, audio_channels, bmdAudioOutputStreamTimestamped); + if (!gst_decklink2_result (hr)) + goto error; + + gst_audio_info_set_format (&output->audio_info, + audio_sample_type == bmdAudioSampleType16bitInteger ? + GST_AUDIO_FORMAT_S16LE : GST_AUDIO_FORMAT_S32LE, 48000, + audio_channels, NULL); + + priv->audio_buf.Init (GST_OBJECT_NAME (output), output->audio_info, + output->selected_mode.fps_n, output->selected_mode.fps_d); + } else { + priv->audio_buf.Deinit (); + } + + g_clear_pointer (&output->vbi_enc, gst_video_vbi_encoder_free); + + output->n_prerolled = 0; + output->n_preroll_frames = n_preroll_frames; + output->min_buffered = min_buffered; + output->max_buffered = max_buffered; + output->n_frames = 0; + output->n_samples = 0; + output->hw_time = GST_CLOCK_TIME_NONE; + output->cdp_hdr_sequence_cntr = 0; + output->configured = TRUE; + output->pts = 0; + output->drop_count = 0; + output->late_count = 0; + output->underrun_count = 0; + output->overrun_count = 0; + output->duplicate_count = 0; + output->dropped_sample_count = 0; + output->silent_sample_count = 0; + output->gap_frames = 1; + if (max_buffered > min_buffered) { + guint gap = (max_buffered - min_buffered) / 2; + if (gap >= 2) + output->gap_frames = 2; + } + output->duplicating = FALSE; + + return S_OK; + +error: + gst_decklink2_output_disable_audio (output); + gst_decklink2_output_disable_video (output); + gst_decklink2_output_set_video_callback (output, NULL); + return hr; +} + +static void +gst_decklink2_output_on_stopped (GstDeckLink2Output * self) +{ + GST_DEBUG_OBJECT (self, "Scheduled playback stopped"); +} + +static void +gst_decklink2_output_on_completed (GstDeckLink2Output * self, + BMDOutputFrameCompletionResult result) +{ + GstDeckLink2OutputPrivate *priv = self->priv; + dlbool_t active; + + std::lock_guard < std::recursive_mutex > lk (priv->schedule_lock); + if (result == bmdOutputFrameDisplayedLate) + self->late_count++; + else if (result == bmdOutputFrameDropped) + self->drop_count++; + + if (!self->last_frame) + return; + + HRESULT hr = gst_decklink2_output_is_running (self, &active); + if (gst_decklink2_result (hr) && active) { + guint buffered_video = 0; + guint buffered_audio = 0; + GstClockTime video_running_time = GST_CLOCK_TIME_NONE; + GstClockTime audio_running_time = GST_CLOCK_TIME_NONE; + GstClockTime hw_time_gst = GST_CLOCK_TIME_NONE; + GstClockTime dummy; + GstClockTimeDiff diff = GST_CLOCK_STIME_NONE; + + hr = gst_decklink2_get_current_level (self, &buffered_video, + &video_running_time, &buffered_audio, &audio_running_time, &diff, + &hw_time_gst, &dummy); + if (gst_decklink2_result (hr) && buffered_video <= self->min_buffered) { + GST_WARNING_OBJECT (self, "Underrun, video %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ", buffered %u) audio %" GST_TIME_FORMAT + " (%" G_GUINT64_FORMAT ", buffered %u), av-diff: %" GST_STIME_FORMAT + ", hw-time %" GST_TIME_FORMAT, + GST_TIME_ARGS (self->pts), self->n_frames, buffered_video, + GST_TIME_ARGS (audio_running_time), self->n_samples, buffered_audio, + GST_STIME_ARGS (diff), GST_TIME_ARGS (hw_time_gst)); + self->underrun_count++; + if (self->duplicating) + return; + + self->duplicating = TRUE; + for (guint i = 0; i < self->gap_frames; i++) { + IGstDeckLinkVideoFrame *copy = self->last_frame->Clone (); + if (!copy) { + GST_ERROR_OBJECT (self, "Couldn't clone last frame"); + copy = self->last_frame; + self->last_frame->AddRef (); + } + self->silent_sample_count += priv->audio_buf.PrependSilence (); + gst_decklink2_output_schedule_video_internal (self, copy); + copy->Release (); + self->duplicate_count++; + } + self->duplicating = FALSE; + } + } +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2output.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2output.h new file mode 100644 index 0000000000..f2e8eecc4e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2output.h @@ -0,0 +1,93 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include "gstdecklink2utils.h" + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_OUTPUT (gst_decklink2_output_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Output, gst_decklink2_output, + GST, DECKLINK2_OUTPUT, GstObject); + +typedef struct +{ + guint buffered_video; + guint buffered_audio; + GstClockTime video_running_time; + GstClockTime audio_running_time; + GstClockTime hw_time; + GstClockTime buffered_video_time; + GstClockTime buffered_audio_time; + guint64 scheduled_video_frames; + guint64 scheduled_audio_samples; + guint64 late_count; + guint64 drop_count; + guint64 overrun_count; + guint64 underrun_count; + guint64 duplicate_count; + guint64 dropped_sample_count; + guint64 silent_sample_count; +} GstDecklink2OutputStats; + +GstDeckLink2Output * gst_decklink2_output_new (IDeckLink * device, + GstDeckLink2APILevel api_level); + +GstCaps * gst_decklink2_output_get_caps (GstDeckLink2Output * output, + BMDDisplayMode mode, + BMDPixelFormat format); + +gboolean gst_decklink2_output_get_display_mode (GstDeckLink2Output * output, + const GstVideoInfo * info, + GstDeckLink2DisplayMode * display_mode); + +guint gst_decklink2_output_get_max_audio_channels (GstDeckLink2Output * output); + +HRESULT gst_decklink2_output_configure (GstDeckLink2Output * output, + guint n_preroll_frames, + guint min_buffered, + guint max_buffered, + const GstDeckLink2DisplayMode * display_mode, + BMDVideoOutputFlags output_flags, + BMDProfileID profile_id, + GstDeckLink2KeyerMode keyer_mode, + guint8 keyer_level, + GstDeckLink2MappingFormat mapping_format, + BMDAudioSampleType audio_sample_type, + guint audio_channels); + +IDeckLinkVideoFrame * gst_decklink2_output_upload (GstDeckLink2Output * output, + const GstVideoInfo * info, + GstBuffer * buffer, + gint caption_line, + gint afd_bar_line); + + +HRESULT gst_decklink2_output_schedule_stream (GstDeckLink2Output * output, + IDeckLinkVideoFrame * frame, + guint8 *audio_buf, + gsize audio_buf_size, + GstDecklink2OutputStats *stats); + +HRESULT gst_decklink2_output_stop (GstDeckLink2Output * output); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2sink.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2sink.cpp new file mode 100644 index 0000000000..fa21333a17 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2sink.cpp @@ -0,0 +1,1076 @@ +/* + * GStreamer + * Copyright (C) 2021 Mathieu Duponchelle + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2sink.h" +#include "gstdecklink2utils.h" +#include "gstdecklink2object.h" +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_sink_debug); +#define GST_CAT_DEFAULT gst_decklink2_sink_debug + +enum +{ + PROP_0, + PROP_MODE, + PROP_DEVICE_NUMBER, + PROP_VIDEO_FORMAT, + PROP_PROFILE_ID, + PROP_TIMECODE_FORMAT, + PROP_KEYER_MODE, + PROP_KEYER_LEVEL, + PROP_CC_LINE, + PROP_AFD_BAR_LINE, + PROP_MAPPING_FORMAT, + PROP_PERSISTENT_ID, + PROP_N_PREROLL_FRAMES, + PROP_MIN_BUFFERED_FRAMES, + PROP_MAX_BUFFERED_FRAMES, + PROP_AUTO_RESTART, + PROP_OUTPUT_STATS, + PROP_DESYNC_THRESHOLD, +}; + +#define DEFAULT_MODE bmdModeUnknown +#define DEFAULT_DEVICE_NUMBER 0 +#define DEFAULT_PERSISTENT_ID -1 +#define DEFAULT_VIDEO_FORMAT bmdFormat8BitYUV +#define DEFAULT_PROFILE_ID bmdProfileDefault +#define DEFAULT_TIMECODE_FORMAT bmdTimecodeRP188Any +#define DEFAULT_KEYER_MODE GST_DECKLINK2_KEYER_MODE_OFF +#define DEFAULT_KEYER_LEVEL 255 +#define DEFAULT_CC_LINE 0 +#define DEFAULT_AFD_BAR_LINE 0 +#define DEFAULT_MAPPING_FORMAT GST_DECKLINK2_MAPPING_FORMAT_DEFAULT +#define DEFAULT_N_PREROLL_FRAMES 7 +#define DEFAULT_MIN_BUFFERED_FRAMES 3 +#define DEFAULT_MAX_BUFFERED_FRAMES 14 +#define DEFAULT_AUTO_RESTART FALSE +#define DEFAULT_DESYNC_THRESHOLD (250 * GST_MSECOND) + +enum +{ + /* actions */ + SIGNAL_RESTART, + + SIGNAL_LAST, +}; + +static guint gst_decklink2_sink_signals[SIGNAL_LAST] = { 0, }; + +struct GstDeckLink2SinkPrivate +{ + std::mutex lock; +}; + +struct _GstDeckLink2Sink +{ + GstBaseSink parent; + + GstDeckLink2SinkPrivate *priv; + + GstDeckLink2Output *output; + + GstVideoInfo video_info; + + GstDeckLink2DisplayMode selected_mode; + BMDAudioSampleType audio_sample_type; + gint audio_channels; + gboolean configured; + + GstBufferPool *fallback_pool; + IDeckLinkVideoFrame *prepared_frame; + BMDVideoOutputFlags output_flags; + gboolean schedule_restart; + + /* properties */ + BMDDisplayMode display_mode; + gint device_number; + gint64 persistent_id; + BMDPixelFormat video_format; + BMDProfileID profile_id; + BMDTimecodeFormat timecode_format; + GstDeckLink2KeyerMode keyer_mode; + gint keyer_level; + gint caption_line; + gint afd_bar_line; + GstDeckLink2MappingFormat mapping_format; + guint n_preroll_frames; + guint min_buffered_frames; + guint max_buffered_frames; + gboolean auto_restart; + GstClockTime desync_threshold; + + GstDecklink2OutputStats stats; +}; + +static void gst_decklink2_sink_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_decklink2_sink_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_decklink2_sink_finalize (GObject * object); +static gboolean gst_decklink2_sink_query (GstBaseSink * sink, GstQuery * query); +static GstCaps *gst_decklink2_sink_get_caps (GstBaseSink * sink, + GstCaps * filter); +static gboolean gst_decklink2_sink_set_caps (GstBaseSink * sink, + GstCaps * caps); +static gboolean gst_decklink2_sink_propose_allocation (GstBaseSink * sink, + GstQuery * query); +static gboolean gst_decklink2_sink_start (GstBaseSink * sink); +static gboolean gst_decklink2_sink_stop (GstBaseSink * sink); +static gboolean gst_decklink2_sink_unlock_stop (GstBaseSink * sink); +static GstFlowReturn gst_decklink2_sink_prepare (GstBaseSink * sink, + GstBuffer * buffer); +static GstFlowReturn gst_decklink2_sink_render (GstBaseSink * sink, + GstBuffer * buffer); +static void gst_decklink2_sink_restart (GstDeckLink2Sink * self); + +#define gst_decklink2_sink_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Sink, gst_decklink2_sink, GST_TYPE_BASE_SINK); +GST_ELEMENT_REGISTER_DEFINE (decklink2sink, "decklink2sink", + GST_RANK_NONE, GST_TYPE_DECKLINK2_SINK); + +static void +gst_decklink2_sink_class_init (GstDeckLink2SinkClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS (klass); + GParamFlags param_flags = (GParamFlags) (G_PARAM_READWRITE | + GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS); + + object_class->finalize = gst_decklink2_sink_finalize; + object_class->set_property = gst_decklink2_sink_set_property; + object_class->get_property = gst_decklink2_sink_get_property; + + g_object_class_install_property (object_class, PROP_MODE, + g_param_spec_enum ("mode", "Playback Mode", + "Video Mode to use for playback", + GST_TYPE_DECKLINK2_MODE, DEFAULT_MODE, param_flags)); + + g_object_class_install_property (object_class, PROP_DEVICE_NUMBER, + g_param_spec_int ("device-number", "Device number", + "Output device instance to use", 0, G_MAXINT, DEFAULT_DEVICE_NUMBER, + param_flags)); + + g_object_class_install_property (object_class, PROP_PERSISTENT_ID, + g_param_spec_int64 ("persistent-id", "Persistent id", + "Output device instance to use. Higher priority than \"device-number\".", + DEFAULT_PERSISTENT_ID, G_MAXINT64, DEFAULT_PERSISTENT_ID, + param_flags)); + + g_object_class_install_property (object_class, PROP_VIDEO_FORMAT, + g_param_spec_enum ("video-format", "Video format", + "Video format type to use for playback", + GST_TYPE_DECKLINK2_VIDEO_FORMAT, DEFAULT_VIDEO_FORMAT, param_flags)); + + g_object_class_install_property (object_class, PROP_PROFILE_ID, + g_param_spec_enum ("profile", "Profile", + "Certain DeckLink devices such as the DeckLink 8K Pro, the DeckLink " + "Quad 2 and the DeckLink Duo 2 support multiple profiles to " + "configure the capture and playback behavior of its sub-devices." + "For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared " + "between any 2 sub-devices that utilize the same connectors. For the " + "DeckLink 8K Pro, a profile is shared between all 4 sub-devices. Any " + "sub-devices that share a profile are considered to be part of the " + "same profile group." + "DeckLink Duo 2 support configuration of the duplex mode of " + "individual sub-devices.", + GST_TYPE_DECKLINK2_PROFILE_ID, DEFAULT_PROFILE_ID, param_flags)); + + g_object_class_install_property (object_class, PROP_TIMECODE_FORMAT, + g_param_spec_enum ("timecode-format", "Timecode format", + "Timecode format type to use for playback", + GST_TYPE_DECKLINK2_TIMECODE_FORMAT, DEFAULT_TIMECODE_FORMAT, + param_flags)); + + g_object_class_install_property (object_class, PROP_KEYER_MODE, + g_param_spec_enum ("keyer-mode", "Keyer mode", + "Keyer mode to be enabled", + GST_TYPE_DECKLINK2_KEYER_MODE, DEFAULT_KEYER_MODE, param_flags)); + + g_object_class_install_property (object_class, PROP_KEYER_LEVEL, + g_param_spec_int ("keyer-level", "Keyer level", + "Keyer level", 0, 255, DEFAULT_KEYER_LEVEL, param_flags)); + + g_object_class_install_property (object_class, PROP_CC_LINE, + g_param_spec_int ("cc-line", "CC Line", + "Line number to use for inserting closed captions (0 = disabled)", + 0, 22, DEFAULT_CC_LINE, param_flags)); + + g_object_class_install_property (object_class, PROP_AFD_BAR_LINE, + g_param_spec_int ("afd-bar-line", "AFD/Bar Line", + "Line number to use for inserting AFD/Bar data (0 = disabled)", + 0, 10000, DEFAULT_AFD_BAR_LINE, param_flags)); + + g_object_class_install_property (object_class, PROP_MAPPING_FORMAT, + g_param_spec_enum ("mapping-format", "3G-SDI Mapping Format", + "3G-SDI Mapping Format (Level A/B)", + GST_TYPE_DECKLINK2_MAPPING_FORMAT, DEFAULT_MAPPING_FORMAT, + param_flags)); + + g_object_class_install_property (object_class, PROP_N_PREROLL_FRAMES, + g_param_spec_int ("n-preroll-frames", "Number of preroll frames", + "How many frames to preroll before starting scheduled playback", + 0, 16, DEFAULT_N_PREROLL_FRAMES, param_flags)); + + g_object_class_install_property (object_class, PROP_MIN_BUFFERED_FRAMES, + g_param_spec_int ("min-buffered-frames", "Min number of buffered frames", + "Min number of frames to buffer before duplicating", + 0, 16, DEFAULT_MIN_BUFFERED_FRAMES, param_flags)); + + g_object_class_install_property (object_class, PROP_MAX_BUFFERED_FRAMES, + g_param_spec_int ("max-buffered-frames", "Max number of buffered frames", + "Max number of frames to buffer before dropping", + 0, 16, DEFAULT_MAX_BUFFERED_FRAMES, param_flags)); + + g_object_class_install_property (object_class, PROP_AUTO_RESTART, + g_param_spec_boolean ("auto-restart", "Auto Restart", + "Restart streaming when frame is being dropped by hardware", + DEFAULT_AUTO_RESTART, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_OUTPUT_STATS, + g_param_spec_boxed ("output-stats", "Output Statistics", + "Output Statistics", GST_TYPE_STRUCTURE, + (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_DESYNC_THRESHOLD, + g_param_spec_uint64 ("desync-threshold", "Desync Threshold", + "Maximum allowed a/v desync threshold. " + "If larger desync is detected, streaming will be restarted " + "(0 = disable auto-restart)", 0, + G_MAXUINT64, DEFAULT_DESYNC_THRESHOLD, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + gst_decklink2_sink_signals[SIGNAL_RESTART] = + g_signal_new_class_handler ("restart", G_TYPE_FROM_CLASS (klass), + (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + G_CALLBACK (gst_decklink2_sink_restart), + NULL, NULL, NULL, G_TYPE_NONE, 0); + + GstCaps *templ_caps = gst_decklink2_get_default_template_caps (); + templ_caps = gst_caps_make_writable (templ_caps); + + GValue ch_list = G_VALUE_INIT; + gint ch[] = { 0, 2, 8, 16 }; + g_value_init (&ch_list, GST_TYPE_LIST); + for (guint i = 0; i < G_N_ELEMENTS (ch); i++) { + GValue ch_val = G_VALUE_INIT; + g_value_init (&ch_val, G_TYPE_INT); + g_value_set_int (&ch_val, ch[i]); + gst_value_list_append_and_take_value (&ch_list, &ch_val); + } + + gst_caps_set_value (templ_caps, "audio-channels", &ch_list); + g_value_unset (&ch_list); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, templ_caps)); + gst_caps_unref (templ_caps); + + gst_element_class_set_static_metadata (element_class, + "Decklink2 Sink", "Video/Audio/Sink/Hardware", "Decklink2 Sink", + "Seungha Yang "); + + basesink_class->query = GST_DEBUG_FUNCPTR (gst_decklink2_sink_query); + basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_decklink2_sink_get_caps); + basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_decklink2_sink_set_caps); + basesink_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_decklink2_sink_propose_allocation); + basesink_class->start = GST_DEBUG_FUNCPTR (gst_decklink2_sink_start); + basesink_class->stop = GST_DEBUG_FUNCPTR (gst_decklink2_sink_stop); + basesink_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_decklink2_sink_unlock_stop); + basesink_class->prepare = GST_DEBUG_FUNCPTR (gst_decklink2_sink_prepare); + basesink_class->render = GST_DEBUG_FUNCPTR (gst_decklink2_sink_render); + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_sink_debug, "decklink2sink", + 0, "decklink2sink"); + + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_MODE, (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_VIDEO_FORMAT, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_PROFILE_ID, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_TIMECODE_FORMAT, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_KEYER_MODE, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_MAPPING_FORMAT, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_MAPPING_FORMAT, + (GstPluginAPIFlags) 0); +} + +static void +gst_decklink2_sink_init (GstDeckLink2Sink * self) +{ + self->display_mode = DEFAULT_MODE; + self->device_number = DEFAULT_DEVICE_NUMBER; + self->persistent_id = DEFAULT_PERSISTENT_ID; + self->video_format = DEFAULT_VIDEO_FORMAT; + self->profile_id = DEFAULT_PROFILE_ID; + self->timecode_format = DEFAULT_TIMECODE_FORMAT; + self->keyer_mode = DEFAULT_KEYER_MODE; + self->keyer_level = DEFAULT_KEYER_LEVEL; + self->caption_line = DEFAULT_CC_LINE; + self->afd_bar_line = DEFAULT_AFD_BAR_LINE; + self->mapping_format = DEFAULT_MAPPING_FORMAT; + self->n_preroll_frames = DEFAULT_N_PREROLL_FRAMES; + self->min_buffered_frames = DEFAULT_MIN_BUFFERED_FRAMES; + self->max_buffered_frames = DEFAULT_MAX_BUFFERED_FRAMES; + self->auto_restart = DEFAULT_AUTO_RESTART; + self->desync_threshold = DEFAULT_DESYNC_THRESHOLD; + + self->priv = new GstDeckLink2SinkPrivate (); +} + +static void +gst_decklink2_sink_finalize (GObject * object) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (object); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_decklink2_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (object); + GstDeckLink2SinkPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + switch (prop_id) { + case PROP_MODE: + self->display_mode = (BMDDisplayMode) g_value_get_enum (value); + break; + case PROP_DEVICE_NUMBER: + self->device_number = g_value_get_int (value); + break; + case PROP_PERSISTENT_ID: + self->persistent_id = g_value_get_int64 (value); + break; + case PROP_VIDEO_FORMAT: + self->video_format = (BMDPixelFormat) g_value_get_enum (value); + break; + case PROP_PROFILE_ID: + self->profile_id = (BMDProfileID) g_value_get_enum (value); + break; + case PROP_TIMECODE_FORMAT: + self->timecode_format = (BMDTimecodeFormat) g_value_get_enum (value); + break; + case PROP_KEYER_MODE: + self->keyer_mode = (GstDeckLink2KeyerMode) g_value_get_enum (value); + break; + case PROP_KEYER_LEVEL: + self->keyer_level = g_value_get_int (value); + break; + case PROP_CC_LINE: + self->caption_line = g_value_get_int (value); + break; + case PROP_AFD_BAR_LINE: + self->afd_bar_line = g_value_get_int (value); + break; + case PROP_MAPPING_FORMAT: + self->mapping_format = + (GstDeckLink2MappingFormat) g_value_get_enum (value); + break; + case PROP_N_PREROLL_FRAMES: + self->n_preroll_frames = g_value_get_int (value); + break; + case PROP_MIN_BUFFERED_FRAMES: + self->min_buffered_frames = g_value_get_int (value); + break; + case PROP_MAX_BUFFERED_FRAMES: + self->max_buffered_frames = g_value_get_int (value); + break; + case PROP_AUTO_RESTART: + self->auto_restart = g_value_get_boolean (value); + break; + case PROP_DESYNC_THRESHOLD: + self->desync_threshold = g_value_get_uint64 (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_decklink2_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (object); + GstDeckLink2SinkPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + switch (prop_id) { + case PROP_MODE: + g_value_set_enum (value, self->display_mode); + break; + case PROP_DEVICE_NUMBER: + g_value_set_int (value, self->device_number); + break; + case PROP_PERSISTENT_ID: + g_value_set_int64 (value, self->persistent_id); + break; + case PROP_VIDEO_FORMAT: + g_value_set_enum (value, self->video_format); + break; + case PROP_PROFILE_ID: + g_value_set_enum (value, self->profile_id); + break; + case PROP_TIMECODE_FORMAT: + g_value_set_enum (value, self->timecode_format); + break; + case PROP_KEYER_MODE: + g_value_set_enum (value, self->keyer_mode); + break; + case PROP_KEYER_LEVEL: + g_value_set_int (value, self->keyer_level); + break; + case PROP_CC_LINE: + g_value_set_int (value, self->caption_line); + break; + case PROP_AFD_BAR_LINE: + g_value_set_int (value, self->afd_bar_line); + break; + case PROP_MAPPING_FORMAT: + g_value_set_enum (value, self->mapping_format); + break; + case PROP_N_PREROLL_FRAMES: + g_value_set_int (value, self->n_preroll_frames); + break; + case PROP_MIN_BUFFERED_FRAMES: + g_value_set_int (value, self->min_buffered_frames); + break; + case PROP_MAX_BUFFERED_FRAMES: + g_value_set_int (value, self->max_buffered_frames); + break; + case PROP_AUTO_RESTART: + g_value_set_boolean (value, self->auto_restart); + break; + case PROP_OUTPUT_STATS: + { + GstStructure *s; + GstDecklink2OutputStats *stats = &self->stats; + + s = gst_structure_new ("output-stats", + "buffered-video", G_TYPE_UINT, stats->buffered_video, + "buffered-audio", G_TYPE_UINT, stats->buffered_audio, + "buffered-video-time", G_TYPE_UINT64, stats->buffered_video_time, + "buffered-audio-time", G_TYPE_UINT64, stats->buffered_audio_time, + "video-running-time", G_TYPE_UINT64, stats->video_running_time, + "audio-running-time", G_TYPE_UINT64, stats->audio_running_time, + "hardware-time", G_TYPE_UINT64, stats->hw_time, + "scheduled-video-frames", G_TYPE_UINT64, + stats->scheduled_video_frames, "scheduled-audio-samples", + G_TYPE_UINT64, stats->scheduled_audio_samples, "dropped-frames", + G_TYPE_UINT64, stats->drop_count, "dropped-samples", G_TYPE_UINT64, + stats->dropped_sample_count, "late-count", G_TYPE_UINT64, + stats->late_count, "overrun-count", G_TYPE_UINT64, + stats->overrun_count, "underrun-count", G_TYPE_UINT64, + stats->underrun_count, "duplicated-frames", G_TYPE_UINT64, + stats->duplicate_count, "silent-samples", G_TYPE_UINT64, + stats->silent_sample_count, NULL); + g_value_take_boxed (value, s); + + break; + } + case PROP_DESYNC_THRESHOLD: + g_value_set_uint64 (value, self->desync_threshold); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gst_decklink2_sink_query (GstBaseSink * sink, GstQuery * query) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ACCEPT_CAPS: + { + GstCaps *caps, *allowed; + gboolean can_intercept; + + gst_query_parse_accept_caps (query, &caps); + allowed = gst_decklink2_sink_get_caps (sink, NULL); + can_intercept = gst_caps_can_intersect (caps, allowed); + GST_DEBUG_OBJECT (self, "Checking if requested caps %" GST_PTR_FORMAT + " are intersectable of pad caps %" GST_PTR_FORMAT " result %d", caps, + allowed, can_intercept); + gst_caps_unref (allowed); + gst_query_set_accept_caps_result (query, can_intercept); + return TRUE; + } + default: + break; + } + + return GST_BASE_SINK_CLASS (parent_class)->query (sink, query); +} + +static GstCaps * +gst_decklink2_sink_get_caps (GstBaseSink * sink, GstCaps * filter) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + GstDeckLink2SinkPrivate *priv = self->priv; + GstCaps *caps; + GstCaps *ret; + std::lock_guard < std::mutex > lk (priv->lock); + + if (!self->output) { + GST_DEBUG_OBJECT (self, "Output is not configured yet"); + caps = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (self)); + } else { + caps = gst_decklink2_output_get_caps (self->output, self->display_mode, + self->video_format); + } + + if (!caps) { + GST_WARNING_OBJECT (self, "Couldn't get caps"); + caps = gst_caps_new_empty (); + } else if (self->output) { + guint max_ch; + GValue ch_list = G_VALUE_INIT; + GValue ch_val = G_VALUE_INIT; + + max_ch = gst_decklink2_output_get_max_audio_channels (self->output); + + caps = gst_caps_make_writable (caps); + + g_value_init (&ch_list, GST_TYPE_LIST); + + g_value_init (&ch_val, G_TYPE_INT); + g_value_set_int (&ch_val, 0); + gst_value_list_append_and_take_value (&ch_list, &ch_val); + + g_value_init (&ch_val, G_TYPE_INT); + g_value_set_int (&ch_val, 2); + gst_value_list_append_and_take_value (&ch_list, &ch_val); + + if (max_ch >= 8) { + g_value_init (&ch_val, G_TYPE_INT); + g_value_set_int (&ch_val, 8); + gst_value_list_append_and_take_value (&ch_list, &ch_val); + } + + if (max_ch >= 16) { + g_value_init (&ch_val, G_TYPE_INT); + g_value_set_int (&ch_val, 16); + gst_value_list_append_and_take_value (&ch_list, &ch_val); + } + + gst_caps_set_value (caps, "audio-channels", &ch_list); + g_value_unset (&ch_list); + } + + if (filter) { + ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + } else { + ret = caps; + } + + GST_LOG_OBJECT (self, "Returning caps %" GST_PTR_FORMAT, ret); + + return ret; +} + +static gboolean +gst_decklink2_sink_set_caps (GstBaseSink * sink, GstCaps * caps) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + HRESULT hr; + GstVideoInfo info; + GstDeckLink2DisplayMode mode; + GstStructure *config; + GstAllocationParams params = { (GstMemoryFlags) 0, 15, 0, 0 }; + GstStructure *s; + GstAudioFormat audio_format = GST_AUDIO_FORMAT_UNKNOWN; + const gchar *audio_format_str; + gint audio_channels = 0; + BMDAudioSampleType audio_sample_type = bmdAudioSampleType16bitInteger; + + GST_DEBUG_OBJECT (self, "Set caps %" GST_PTR_FORMAT, caps); + + if (!self->output) { + GST_ERROR_OBJECT (self, "output has not been configured yet"); + return FALSE; + } + + if (!gst_video_info_from_caps (&info, caps)) { + GST_ERROR_OBJECT (self, "Invalid caps"); + return FALSE; + } + + if (!gst_decklink2_output_get_display_mode (self->output, &info, &mode)) { + GST_ERROR_OBJECT (self, "Couldn't get display mode"); + return FALSE; + } + + self->video_info = info; + + s = gst_caps_get_structure (caps, 0); + audio_format_str = gst_structure_get_string (s, "audio-format"); + if (audio_format_str) + audio_format = gst_audio_format_from_string (audio_format_str); + gst_structure_get_int (s, "audio-channels", &audio_channels); + + if (audio_format == GST_AUDIO_FORMAT_S16LE) { + audio_sample_type = bmdAudioSampleType16bitInteger; + } else if (audio_format == GST_AUDIO_FORMAT_S32LE) { + audio_sample_type = bmdAudioSampleType32bitInteger; + } else { + audio_channels = 0; + } + + if (self->configured) { + if (self->selected_mode.mode == mode.mode && + self->audio_sample_type == audio_sample_type && + self->audio_channels == audio_channels) { + return TRUE; + } + + GST_DEBUG_OBJECT (self, "Configuration changed"); + gst_decklink2_output_stop (self->output); + self->configured = FALSE; + } + + self->selected_mode = mode; + self->audio_sample_type = audio_sample_type; + self->audio_channels = audio_channels; + + /* The timecode_format itself is used when we embed the actual timecode data + * into the frame. Now we only need to know which of the two standards the + * timecode format will adhere to: VITC or RP188, and send the appropriate + * flag to EnableVideoOutput. The exact format is specified later. + * + * Note that this flag will have no effect in practice if the video stream + * does not contain timecode metadata. + */ + if (self->timecode_format == bmdTimecodeVITC || + self->timecode_format == bmdTimecodeVITCField2) { + self->output_flags = bmdVideoOutputVITC; + } else { + self->output_flags = bmdVideoOutputRP188; + } + + if (self->caption_line > 0 || self->afd_bar_line > 0) { + self->output_flags = (BMDVideoOutputFlags) + (self->output_flags | bmdVideoOutputVANC); + } + + GST_DEBUG_OBJECT (self, "Configuring output, mode %" GST_FOURCC_FORMAT + ", audio-sample-type %d, audio-channles %d", + GST_DECKLINK2_FOURCC_ARGS (self->selected_mode.mode), + self->audio_sample_type, self->audio_channels); + + hr = gst_decklink2_output_configure (self->output, self->n_preroll_frames, + self->min_buffered_frames, self->max_buffered_frames, + &self->selected_mode, self->output_flags, self->profile_id, + self->keyer_mode, (guint8) self->keyer_level, self->mapping_format, + self->audio_sample_type, self->audio_channels); + if (hr != S_OK) { + GST_ERROR_OBJECT (self, "Couldn't configure output"); + return FALSE; + } + + if (self->fallback_pool) { + gst_buffer_pool_set_active (self->fallback_pool, FALSE); + gst_object_unref (self->fallback_pool); + } + + self->fallback_pool = gst_video_buffer_pool_new (); + config = gst_buffer_pool_get_config (self->fallback_pool); + gst_buffer_pool_config_set_params (config, caps, info.size, 0, 0); + gst_buffer_pool_config_set_allocator (config, NULL, ¶ms); + + if (!gst_buffer_pool_set_config (self->fallback_pool, config)) { + GST_ERROR_OBJECT (self, "Couldn't set pool config"); + goto error; + } + + if (!gst_buffer_pool_set_active (self->fallback_pool, TRUE)) { + GST_ERROR_OBJECT (self, "Couldn't set active state to pool"); + goto error; + } + + self->configured = TRUE; + { + std::lock_guard < std::mutex > lk (self->priv->lock); + self->schedule_restart = FALSE; + } + + return TRUE; + +error: + gst_clear_object (&self->fallback_pool); + + return FALSE; +} + +static gboolean +gst_decklink2_sink_propose_allocation (GstBaseSink * sink, GstQuery * query) +{ + GstCaps *caps; + GstVideoInfo info; + GstBufferPool *pool; + guint size; + + gst_query_parse_allocation (query, &caps, NULL); + + if (!caps) + return FALSE; + + if (!gst_video_info_from_caps (&info, caps)) + return FALSE; + + size = GST_VIDEO_INFO_SIZE (&info); + if (gst_query_get_n_allocation_pools (query) == 0) { + GstStructure *structure; + GstAllocator *allocator = NULL; + GstAllocationParams params = { (GstMemoryFlags) 0, 15, 0, 0 }; + + if (gst_query_get_n_allocation_params (query) > 0) + gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms); + else + gst_query_add_allocation_param (query, allocator, ¶ms); + + pool = gst_video_buffer_pool_new (); + + structure = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (structure, caps, size, 0, 0); + gst_buffer_pool_config_set_allocator (structure, allocator, ¶ms); + + if (allocator) + gst_object_unref (allocator); + + if (!gst_buffer_pool_set_config (pool, structure)) { + GST_ERROR_OBJECT (sink, "Couldn't set pool config"); + gst_object_unref (pool); + return FALSE; + } + + gst_query_add_allocation_pool (query, pool, size, 0, 0); + gst_object_unref (pool); + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + } + + return TRUE; +} + +static gboolean +gst_decklink2_sink_start (GstBaseSink * sink) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + GstDeckLink2SinkPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + GST_DEBUG_OBJECT (self, "Start"); + + memset (&self->stats, 0, sizeof (GstDecklink2OutputStats)); + + self->output = gst_decklink2_acquire_output (self->device_number, + self->persistent_id); + + if (!self->output) { + GST_ERROR_OBJECT (self, "Couldn't acquire output object"); + return FALSE; + } + + if (self->n_preroll_frames < self->min_buffered_frames || + self->n_preroll_frames > self->max_buffered_frames || + self->max_buffered_frames < self->min_buffered_frames) { + GST_WARNING_OBJECT (self, "Invalid buffering configuration"); + self->n_preroll_frames = DEFAULT_N_PREROLL_FRAMES; + self->min_buffered_frames = DEFAULT_MIN_BUFFERED_FRAMES; + self->max_buffered_frames = DEFAULT_MAX_BUFFERED_FRAMES; + } + + memset (&self->selected_mode, 0, sizeof (GstDeckLink2DisplayMode)); + self->audio_sample_type = bmdAudioSampleType16bitInteger; + self->audio_channels = 0; + self->configured = FALSE; + + return TRUE; +} + +static gboolean +gst_decklink2_sink_stop (GstBaseSink * sink) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + GstDeckLink2SinkPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + GST_DECKLINK2_CLEAR_COM (self->prepared_frame); + + if (self->output) { + gst_decklink2_output_stop (self->output); + gst_decklink2_release_output (self->output); + self->output = NULL; + } + + if (self->fallback_pool) { + gst_buffer_pool_set_active (self->fallback_pool, FALSE); + gst_clear_object (&self->fallback_pool); + } + + self->schedule_restart = FALSE; + + return TRUE; +} + +static gboolean +gst_decklink2_sink_unlock_stop (GstBaseSink * sink) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + + GST_DECKLINK2_CLEAR_COM (self->prepared_frame); + + return TRUE; +} + +static gboolean +buffer_is_pbo_memory (GstBuffer * buffer) +{ + GstMemory *mem; + + mem = gst_buffer_peek_memory (buffer, 0); + if (mem->allocator + && g_strcmp0 (mem->allocator->mem_type, "GLMemoryPBO") == 0) + return TRUE; + return FALSE; +} + +static IDeckLinkVideoFrame * +gst_decklink2_sink_upload_frame (GstDeckLink2Sink * self, GstBuffer * buffer) +{ + GstBuffer *uploaded_buffer = buffer; + + if (buffer_is_pbo_memory (buffer)) { + GstVideoFrame other_frame; + GstVideoFrame vframe; + GstBuffer *fallback; + + if (!gst_video_frame_map (&vframe, &self->video_info, buffer, GST_MAP_READ)) { + GST_ERROR_OBJECT (self, "Failed to map video frame"); + return NULL; + } + + GstFlowReturn ret = gst_buffer_pool_acquire_buffer (self->fallback_pool, + &fallback, NULL); + if (ret != GST_FLOW_OK) { + GST_ERROR_OBJECT (self, "Couldn't acquire fallback buffer"); + gst_video_frame_unmap (&vframe); + return NULL; + } + + if (!gst_video_frame_map (&other_frame, + &self->video_info, fallback, GST_MAP_WRITE)) { + GST_ERROR_OBJECT (self, "Couldn't map fallback buffer"); + gst_video_frame_unmap (&vframe); + gst_buffer_unref (fallback); + return NULL; + } + + if (!gst_video_frame_copy (&other_frame, &vframe)) { + GST_ERROR_OBJECT (self, "Couldn't copy to fallback buffer"); + gst_video_frame_unmap (&vframe); + gst_video_frame_unmap (&other_frame); + gst_buffer_unref (fallback); + return NULL; + } + + gst_video_frame_unmap (&vframe); + gst_video_frame_unmap (&other_frame); + + gst_buffer_copy_into (fallback, buffer, GST_BUFFER_COPY_META, 0, -1); + uploaded_buffer = fallback; + } + + IDeckLinkVideoFrame *frame = + gst_decklink2_output_upload (self->output, &self->video_info, + uploaded_buffer, self->caption_line, self->afd_bar_line); + /* frame will hold buffer */ + if (uploaded_buffer != buffer) + gst_buffer_unref (uploaded_buffer); + + return frame; +} + +static GstFlowReturn +gst_decklink2_sink_prepare (GstBaseSink * sink, GstBuffer * buffer) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + + GST_DECKLINK2_CLEAR_COM (self->prepared_frame); + + self->prepared_frame = gst_decklink2_sink_upload_frame (self, buffer); + if (!self->prepared_frame) { + GST_ERROR_OBJECT (self, "Couldn't upload frame"); + return GST_FLOW_ERROR; + } + + return GST_FLOW_OK; +} + +static GstFlowReturn +gst_decklink2_sink_render (GstBaseSink * sink, GstBuffer * buffer) +{ + GstDeckLink2Sink *self = GST_DECKLINK2_SINK (sink); + GstDeckLink2SinkPrivate *priv = self->priv; + HRESULT hr; + GstBuffer *audio_buf = NULL; + GstMapInfo info; + guint8 *audio_data = NULL; + gsize audio_data_size = 0; + GstDecklink2OutputStats stats = { 0, }; + gboolean do_restart = FALSE; + + if (!self->prepared_frame) { + GST_ERROR_OBJECT (self, "No prepared frame"); + return GST_FLOW_ERROR; + } + + if (self->audio_channels > 0) { + GstDeckLink2AudioMeta *meta = gst_buffer_get_decklink2_audio_meta (buffer); + if (meta) + audio_buf = gst_sample_get_buffer (meta->sample); + + if (audio_buf) { + if (!gst_buffer_map (audio_buf, &info, GST_MAP_READ)) { + GST_ERROR_OBJECT (self, "Couldn't map audio buffer"); + return GST_FLOW_ERROR; + } + + audio_data = info.data; + audio_data_size = info.size; + } else { + GST_DEBUG_OBJECT (self, "Received buffer without audio meta"); + } + } + + { + std::lock_guard < std::mutex > lk (priv->lock); + + if (self->schedule_restart) { + GST_DEBUG_OBJECT (self, "Restarting sink as scheduled"); + self->schedule_restart = FALSE; + + hr = gst_decklink2_output_configure (self->output, self->n_preroll_frames, + self->min_buffered_frames, self->max_buffered_frames, + &self->selected_mode, self->output_flags, self->profile_id, + self->keyer_mode, (guint8) self->keyer_level, self->mapping_format, + self->audio_sample_type, self->audio_channels); + + if (hr != S_OK) { + GST_ERROR_OBJECT (self, "Couldn't configure output"); + return GST_FLOW_OK; + } + } + } + + GST_LOG_OBJECT (self, "schedule frame %p with audio buffer size %" + G_GSIZE_FORMAT, self->prepared_frame, audio_data_size); + + hr = gst_decklink2_output_schedule_stream (self->output, + self->prepared_frame, audio_data, audio_data_size, &stats); + + if (audio_buf) + gst_buffer_unmap (audio_buf, &info); + + if (hr != S_OK) { + GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), + ("Failed to schedule frame: 0x%x", (guint) hr)); + return GST_FLOW_ERROR; + } + + if (self->audio_channels > 0 && self->desync_threshold != 0 && + GST_CLOCK_TIME_IS_VALID (self->desync_threshold)) { + GstClockTime diff; + + if (stats.buffered_audio_time > stats.buffered_video_time) + diff = stats.buffered_audio_time - stats.buffered_video_time; + else + diff = stats.buffered_video_time - stats.buffered_audio_time; + + if (diff >= self->desync_threshold) { + GST_WARNING_OBJECT (self, "Restart output, buffered video: %" + GST_TIME_FORMAT ", buffered audio: %" GST_TIME_FORMAT + ", threshold %" GST_TIME_FORMAT, + GST_TIME_ARGS (stats.buffered_video_time), + GST_TIME_ARGS (stats.buffered_audio_time), + GST_TIME_ARGS (self->desync_threshold)); + do_restart = TRUE; + } + } + + if (self->auto_restart && (stats.drop_count + stats.late_count > + (guint) self->n_preroll_frames)) { + GST_WARNING_OBJECT (self, "Restart output, drop count: %" G_GUINT64_FORMAT + ", late cout: %" G_GUINT64_FORMAT ", underrun count: %" + G_GUINT64_FORMAT, stats.drop_count, stats.late_count, + stats.underrun_count); + do_restart = TRUE; + } + + if (do_restart) { + hr = gst_decklink2_output_configure (self->output, self->n_preroll_frames, + self->min_buffered_frames, self->max_buffered_frames, + &self->selected_mode, self->output_flags, self->profile_id, + self->keyer_mode, (guint8) self->keyer_level, self->mapping_format, + self->audio_sample_type, self->audio_channels); + + if (hr != S_OK) { + GST_ERROR_OBJECT (self, "Couldn't configure output"); + return GST_FLOW_OK; + } + } + + std::lock_guard < std::mutex > lk (priv->lock); + self->stats = stats; + + return GST_FLOW_OK; +} + +static void +gst_decklink2_sink_restart (GstDeckLink2Sink * self) +{ + GstDeckLink2SinkPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + GST_DEBUG_OBJECT (self, "Schedule restart"); + self->schedule_restart = TRUE; +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2sink.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2sink.h new file mode 100644 index 0000000000..3b0f9e3347 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2sink.h @@ -0,0 +1,34 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_SINK (gst_decklink2_sink_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Sink, gst_decklink2_sink, + GST, DECKLINK2_SINK, GstBaseSink); + +GST_ELEMENT_REGISTER_DECLARE (decklink2sink); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2src.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2src.cpp new file mode 100644 index 0000000000..10705adf9f --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2src.cpp @@ -0,0 +1,802 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2src.h" +#include "gstdecklink2utils.h" +#include "gstdecklink2object.h" + +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_src_debug); +#define GST_CAT_DEFAULT gst_decklink2_src_debug + +enum +{ + PROP_0, + PROP_MODE, + PROP_DEVICE_NUMBER, + PROP_PERSISTENT_ID, + PROP_VIDEO_CONNECTION, + PROP_AUDIO_CONNECTION, + PROP_VIDEO_FORMAT, + PROP_AUDIO_CHANNELS, + PROP_PROFILE_ID, + PROP_TIMECODE_FORMAT, + PROP_OUTPUT_CC, + PROP_OUTPUT_AFD_BAR, + PROP_BUFFER_SIZE, + PROP_SIGNAL, + PROP_SKIP_FIRST_TIME, + PROP_DESYNC_THRESHOLD, +}; + +#define DEFAULT_MODE bmdModeUnknown +#define DEFAULT_DEVICE_NUMBER 0 +#define DEFAULT_PERSISTENT_ID -1 +#define DEFAULT_VIDEO_CONNECTION bmdVideoConnectionUnspecified +#define DEFAULT_AUDIO_CONNECTION bmdAudioConnectionUnspecified +#define DEFAULT_VIDEO_FORMAT bmdFormat8BitYUV +#define DEFAULT_PROFILE_ID bmdProfileDefault +#define DEFAULT_TIMECODE_FORMAT bmdTimecodeRP188Any +#define DEFAULT_OUTPUT_CC FALSE +#define DEFAULT_OUTPUT_AFD_BAR FALSE +#define DEFAULT_BUFFER_SIZE 5 +#define DEFAULT_AUDIO_CHANNELS GST_DECKLINK2_AUDIO_CHANNELS_2 +#define DEFAULT_SKIP_FIRST_TIME 0 +#define DEFAULT_DESYNC_THRESHOLD (250 * GST_MSECOND) + +enum +{ + /* actions */ + SIGNAL_RESTART, + + SIGNAL_LAST, +}; + +static guint gst_decklink2_src_signals[SIGNAL_LAST] = { 0, }; + +struct GstDeckLink2SrcPrivate +{ + std::mutex lock; +}; + +struct _GstDeckLink2Src +{ + GstPushSrc parent; + + GstDeckLink2SrcPrivate *priv; + + GstVideoInfo video_info; + + GstDeckLink2Input *input; + GstDeckLink2DisplayMode selected_mode; + GstCaps *selected_caps; + gboolean is_gap_buf; + + gboolean running; + + /* properties */ + BMDDisplayMode display_mode; + gint device_number; + gint64 persistent_id; + BMDVideoConnection video_conn; + BMDAudioConnection audio_conn; + BMDPixelFormat video_format; + GstDeckLink2AudioChannels audio_channels; + BMDProfileID profile_id; + BMDTimecodeFormat timecode_format; + gboolean output_cc; + gboolean output_afd_bar; + guint buffer_size; + GstClockTime skip_first_time; + GstClockTime desync_threshold; +}; + +static void gst_decklink2_src_finalize (GObject * object); +static void gst_decklink2_src_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_decklink2_src_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static GstCaps *gst_decklink2_src_get_caps (GstBaseSrc * src, GstCaps * filter); +static gboolean gst_decklink2_src_set_caps (GstBaseSrc * src, GstCaps * caps); +static gboolean gst_decklink2_src_query (GstBaseSrc * src, GstQuery * query); +static gboolean gst_decklink2_src_start (GstBaseSrc * src); +static gboolean gst_decklink2_src_stop (GstBaseSrc * src); +static gboolean gst_decklink2_src_unlock (GstBaseSrc * src); +static gboolean gst_decklink2_src_unlock_stop (GstBaseSrc * src); + +static GstFlowReturn gst_decklink2_src_create (GstPushSrc * src, + GstBuffer ** buffer); + +#define gst_decklink2_src_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2Src, gst_decklink2_src, GST_TYPE_PUSH_SRC); +GST_ELEMENT_REGISTER_DEFINE (decklink2src, "decklink2src", + GST_RANK_NONE, GST_TYPE_DECKLINK2_SRC); + +static void +gst_decklink2_src_class_init (GstDeckLink2SrcClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass); + GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass); + GstCaps *templ_caps; + + object_class->finalize = gst_decklink2_src_finalize; + object_class->set_property = gst_decklink2_src_set_property; + object_class->get_property = gst_decklink2_src_get_property; + + gst_decklink2_src_install_properties (object_class); + + gst_decklink2_src_signals[SIGNAL_RESTART] = + g_signal_new_class_handler ("restart", G_TYPE_FROM_CLASS (klass), + (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + G_CALLBACK (gst_decklink2_src_restart), NULL, NULL, NULL, G_TYPE_NONE, 0); + + templ_caps = gst_decklink2_get_default_template_caps (); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps)); + gst_caps_unref (templ_caps); + + gst_element_class_set_static_metadata (element_class, + "Decklink2 Source", "Video/Audio/Source/Hardware", "Decklink2 Source", + "Seungha Yang "); + + basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_decklink2_src_get_caps); + basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_decklink2_src_set_caps); + basesrc_class->query = GST_DEBUG_FUNCPTR (gst_decklink2_src_query); + basesrc_class->start = GST_DEBUG_FUNCPTR (gst_decklink2_src_start); + basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_decklink2_src_stop); + basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_decklink2_src_unlock); + basesrc_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_decklink2_src_unlock_stop); + + pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_decklink2_src_create); + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_src_debug, "decklink2src", + 0, "decklink2src"); + + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_MODE, (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_VIDEO_CONNECTION, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_AUDIO_CONNECTION, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_VIDEO_FORMAT, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_AUDIO_CHANNELS, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_PROFILE_ID, + (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_DECKLINK2_TIMECODE_FORMAT, + (GstPluginAPIFlags) 0); +} + +static void +gst_decklink2_src_init (GstDeckLink2Src * self) +{ + self->display_mode = DEFAULT_MODE; + self->device_number = DEFAULT_DEVICE_NUMBER; + self->persistent_id = DEFAULT_PERSISTENT_ID; + self->video_conn = DEFAULT_VIDEO_CONNECTION; + self->audio_conn = DEFAULT_AUDIO_CONNECTION; + self->video_format = DEFAULT_VIDEO_FORMAT; + self->profile_id = DEFAULT_PROFILE_ID; + self->audio_channels = DEFAULT_AUDIO_CHANNELS; + self->timecode_format = DEFAULT_TIMECODE_FORMAT; + self->output_cc = DEFAULT_OUTPUT_CC; + self->output_afd_bar = DEFAULT_OUTPUT_AFD_BAR; + self->buffer_size = DEFAULT_BUFFER_SIZE; + self->is_gap_buf = FALSE; + self->desync_threshold = DEFAULT_DESYNC_THRESHOLD; + + self->priv = new GstDeckLink2SrcPrivate (); + + gst_base_src_set_live (GST_BASE_SRC (self), TRUE); + gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME); +} + +static void +gst_decklink2_src_finalize (GObject * object) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (object); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_decklink2_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (object); + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + switch (prop_id) { + case PROP_MODE: + self->display_mode = (BMDDisplayMode) g_value_get_enum (value); + break; + case PROP_DEVICE_NUMBER: + self->device_number = g_value_get_int (value); + break; + case PROP_PERSISTENT_ID: + self->persistent_id = g_value_get_int64 (value); + break; + case PROP_VIDEO_CONNECTION: + self->video_conn = (BMDVideoConnection) g_value_get_enum (value); + break; + case PROP_AUDIO_CONNECTION: + self->audio_conn = (BMDAudioConnection) g_value_get_enum (value); + break; + case PROP_VIDEO_FORMAT: + self->video_format = (BMDPixelFormat) g_value_get_enum (value); + break; + case PROP_AUDIO_CHANNELS: + self->audio_channels = + (GstDeckLink2AudioChannels) g_value_get_enum (value); + break; + case PROP_PROFILE_ID: + self->profile_id = (BMDProfileID) g_value_get_enum (value); + break; + case PROP_TIMECODE_FORMAT: + self->timecode_format = (BMDTimecodeFormat) g_value_get_enum (value); + break; + case PROP_OUTPUT_CC: + self->output_cc = g_value_get_boolean (value); + break; + case PROP_OUTPUT_AFD_BAR: + self->output_afd_bar = g_value_get_boolean (value); + break; + case PROP_BUFFER_SIZE: + self->buffer_size = g_value_get_uint (value); + break; + case PROP_SKIP_FIRST_TIME: + self->skip_first_time = g_value_get_uint64 (value); + break; + case PROP_DESYNC_THRESHOLD: + self->desync_threshold = g_value_get_uint64 (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_decklink2_src_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (object); + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + switch (prop_id) { + case PROP_MODE: + g_value_set_enum (value, self->display_mode); + break; + case PROP_DEVICE_NUMBER: + g_value_set_int (value, self->device_number); + break; + case PROP_PERSISTENT_ID: + g_value_set_int64 (value, self->persistent_id); + break; + case PROP_VIDEO_CONNECTION: + g_value_set_enum (value, self->video_conn); + break; + case PROP_AUDIO_CONNECTION: + g_value_set_enum (value, self->audio_conn); + break; + case PROP_VIDEO_FORMAT: + g_value_set_enum (value, self->video_format); + break; + case PROP_AUDIO_CHANNELS: + g_value_set_enum (value, self->audio_channels); + break; + case PROP_PROFILE_ID: + g_value_set_enum (value, self->profile_id); + break; + case PROP_TIMECODE_FORMAT: + g_value_set_enum (value, self->timecode_format); + break; + case PROP_OUTPUT_CC: + g_value_set_boolean (value, self->output_cc); + break; + case PROP_OUTPUT_AFD_BAR: + g_value_set_boolean (value, self->output_afd_bar); + break; + case PROP_BUFFER_SIZE: + g_value_set_uint (value, self->buffer_size); + break; + case PROP_SIGNAL: + { + gboolean has_signal = FALSE; + if (self->input) + has_signal = gst_decklink2_input_has_signal (self->input); + + g_value_set_boolean (value, has_signal); + break; + } + case PROP_SKIP_FIRST_TIME: + g_value_set_uint64 (value, self->skip_first_time); + break; + case PROP_DESYNC_THRESHOLD: + g_value_set_uint64 (value, self->desync_threshold); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstCaps * +gst_decklink2_src_get_caps (GstBaseSrc * src, GstCaps * filter) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + GstCaps *caps; + GstCaps *ret; + std::unique_lock < std::mutex > lk (priv->lock); + + if (!self->input) { + lk.unlock (); + return GST_BASE_SRC_CLASS (parent_class)->get_caps (src, filter); + } + + if (self->selected_caps) { + caps = gst_caps_ref (self->selected_caps); + } else { + caps = gst_decklink2_input_get_caps (self->input, self->display_mode, + self->video_format); + } + + if (!caps) { + GST_WARNING_OBJECT (self, "Couldn't get caps"); + caps = gst_caps_new_empty (); + } + + if (filter) { + ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + } else { + ret = caps; + } + + GST_DEBUG_OBJECT (self, "Returning caps %" GST_PTR_FORMAT, ret); + + return ret; +} + +static gboolean +gst_decklink2_src_set_caps (GstBaseSrc * src, GstCaps * caps) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + BMDPixelFormat pixel_format; + std::lock_guard < std::mutex > lk (priv->lock); + + GST_DEBUG_OBJECT (self, "Set caps %" GST_PTR_FORMAT, caps); + + if (!self->input) { + GST_WARNING_OBJECT (self, + "Couldn't accept caps without configured input object"); + return FALSE; + } + + if (self->running) + return TRUE; + + if (!gst_video_info_from_caps (&self->video_info, caps)) { + GST_WARNING_OBJECT (self, "Invalid caps %" GST_PTR_FORMAT, caps); + return FALSE; + } + + if (!gst_decklink2_input_get_display_mode (self->input, &self->video_info, + &self->selected_mode)) { + GST_ERROR_OBJECT (self, "Not a supported caps"); + return FALSE; + } + + gst_clear_caps (&self->selected_caps); + pixel_format = + gst_decklink2_pixel_format_from_video_format (GST_VIDEO_INFO_FORMAT + (&self->video_info)); + self->selected_caps = + gst_decklink2_input_get_caps (self->input, self->selected_mode.mode, + pixel_format); + + if (!self->selected_caps) { + GST_ERROR_OBJECT (self, "Couldn't get caps from selected mode"); + return FALSE; + } + + return TRUE; +} + +static gboolean +gst_decklink2_src_query (GstBaseSrc * src, GstQuery * query) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_LATENCY: + { + std::lock_guard < std::mutex > lk (priv->lock); + gint fps_n, fps_d; + GstClockTime min, max; + if (self->selected_mode.fps_n > 0 && self->selected_mode.fps_d > 0) { + fps_n = self->selected_mode.fps_n; + fps_d = self->selected_mode.fps_d; + } else { + fps_n = 30; + fps_d = 1; + } + + min = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n); + max = self->buffer_size * min; + gst_query_set_latency (query, TRUE, min, max); + return TRUE; + } + default: + break; + } + + return GST_BASE_SRC_CLASS (parent_class)->query (src, query); +} + +static gboolean +gst_decklink2_src_start (GstBaseSrc * src) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + self->running = FALSE; + memset (&self->selected_mode, 0, sizeof (GstDeckLink2DisplayMode)); + + gst_clear_caps (&self->selected_caps); + self->input = gst_decklink2_acquire_input (self->device_number, + self->persistent_id); + + if (!self->input) { + GST_ERROR_OBJECT (self, "Couldn't acquire input object"); + return FALSE; + } + + return TRUE; +} + +static gboolean +gst_decklink2_src_stop (GstBaseSrc * src) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + if (self->input) { + gst_decklink2_input_stop (self->input); + gst_decklink2_release_input (self->input); + self->input = NULL; + } + + gst_clear_caps (&self->selected_caps); + memset (&self->selected_mode, 0, sizeof (GstDeckLink2DisplayMode)); + + self->running = FALSE; + + return TRUE; +} + +static gboolean +gst_decklink2_src_unlock (GstBaseSrc * src) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + if (self->input) + gst_decklink2_input_set_flushing (self->input, TRUE); + + return TRUE; +} + +static gboolean +gst_decklink2_src_unlock_stop (GstBaseSrc * src) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + if (self->input) + gst_decklink2_input_set_flushing (self->input, FALSE); + + return TRUE; +} + +static gboolean +gst_decklink2_src_run_unlocked (GstDeckLink2Src * self, gboolean auto_restart) +{ + HRESULT hr; + GstDeckLink2InputVideoConfig video_config; + GstDeckLink2InputAudioConfig audio_config; + + video_config.connection = self->video_conn; + video_config.display_mode = self->selected_mode; + video_config.pixel_format = self->video_format; + video_config.auto_detect = self->display_mode == bmdModeUnknown; + video_config.output_cc = self->output_cc; + video_config.output_afd_bar = self->output_afd_bar; + + audio_config.connection = self->audio_conn; + audio_config.sample_type = bmdAudioSampleType32bitInteger; + audio_config.channels = self->audio_channels; + + hr = gst_decklink2_input_start (self->input, GST_ELEMENT (self), + self->profile_id, self->buffer_size, + auto_restart ? 0 : self->skip_first_time, &video_config, &audio_config); + if (!gst_decklink2_result (hr)) { + GST_ERROR_OBJECT (self, "Couldn't start stream, hr: 0x%x", (guint) hr); + return FALSE; + } + + self->running = TRUE; + return TRUE; +} + +static gboolean +gst_decklink2_src_run (GstDeckLink2Src * self) +{ + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + if (self->running) + return TRUE; + + if (!self->input) { + GST_ERROR_OBJECT (self, "Input object was not configured"); + return FALSE; + } + + return gst_decklink2_src_run_unlocked (self, FALSE); +} + +static GstFlowReturn +gst_decklink2_src_create (GstPushSrc * src, GstBuffer ** buffer) +{ + GstDeckLink2Src *self = GST_DECKLINK2_SRC (src); + GstBuffer *buf = nullptr; + GstCaps *caps = nullptr; + GstFlowReturn ret; + GstDeckLink2SrcPrivate *priv = self->priv; + gboolean is_gap_buf = FALSE; + GstClockTimeDiff av_sync; + guint retry_count = 0; + gsize buf_size; + +again: + if (retry_count > 30) { + GST_ERROR_OBJECT (self, "Too many buffers were dropped"); + return GST_FLOW_ERROR; + } + + if (!gst_decklink2_src_run (self)) { + GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), + ("Failed to start stream")); + return GST_FLOW_ERROR; + } + + ret = gst_decklink2_input_get_data (self->input, &buf, &caps, &av_sync); + if (ret != GST_FLOW_OK) { + if (ret == GST_DECKLINK2_INPUT_FLOW_STOPPED) { + GST_DEBUG_OBJECT (self, "Input was stopped for restarting"); + retry_count++; + goto again; + } + + return ret; + } + + if (!caps) { + GST_WARNING_OBJECT (self, "Buffer without caps"); + gst_clear_buffer (&buf); + retry_count++; + goto again; + } + + priv->lock.lock (); + if (!gst_caps_is_equal (caps, self->selected_caps)) { + GST_DEBUG_OBJECT (self, "Set updated caps %" GST_PTR_FORMAT, caps); + gst_caps_replace (&self->selected_caps, caps); + gst_video_info_from_caps (&self->video_info, caps); + priv->lock.unlock (); + if (!gst_pad_set_caps (GST_BASE_SRC_PAD (self), caps)) { + GST_ERROR_OBJECT (self, "Couldn't set caps"); + gst_clear_buffer (&buf); + gst_clear_caps (&caps); + + return GST_FLOW_NOT_NEGOTIATED; + } + } else { + priv->lock.unlock (); + } + gst_clear_caps (&caps); + + if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)) + is_gap_buf = TRUE; + + if (is_gap_buf != self->is_gap_buf) { + self->is_gap_buf = is_gap_buf; + g_object_notify (G_OBJECT (self), "signal"); + } + + buf_size = gst_buffer_get_size (buf); + if (buf_size < self->video_info.size) { + GST_WARNING_OBJECT (self, "Too small buffer size %" G_GSIZE_FORMAT + " < %" G_GSIZE_FORMAT, buf_size, self->video_info.size); + gst_clear_buffer (&buf); + retry_count++; + goto again; + } + + std::unique_lock < std::mutex > lk (priv->lock); + *buffer = buf; + + if (self->desync_threshold != 0 && + GST_CLOCK_TIME_IS_VALID (self->desync_threshold)) { + GstClockTime diff; + if (av_sync >= 0) + diff = av_sync; + else + diff = -av_sync; + + GST_LOG_OBJECT (self, "Current AV sync %" GST_STIME_FORMAT, + GST_STIME_ARGS (av_sync)); + + if (diff >= self->desync_threshold) { + GST_WARNING_OBJECT (self, "Large AV desync is detected, desync %" + GST_STIME_FORMAT ", threshold %" GST_TIME_FORMAT, + GST_STIME_ARGS (av_sync), GST_TIME_ARGS (self->desync_threshold)); + + gst_decklink2_input_schedule_restart (self->input); + } + } + + return GST_FLOW_OK; +} + +void +gst_decklink2_src_install_properties (GObjectClass * object_class) +{ + GParamFlags param_flags = (GParamFlags) (G_PARAM_READWRITE | + GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_property (object_class, PROP_MODE, + g_param_spec_enum ("mode", "Playback Mode", + "Video Mode to use for playback", + GST_TYPE_DECKLINK2_MODE, DEFAULT_MODE, param_flags)); + + g_object_class_install_property (object_class, PROP_DEVICE_NUMBER, + g_param_spec_int ("device-number", "Device number", + "Output device instance to use", 0, G_MAXINT, DEFAULT_DEVICE_NUMBER, + param_flags)); + + g_object_class_install_property (object_class, PROP_PERSISTENT_ID, + g_param_spec_int64 ("persistent-id", "Persistent id", + "Output device instance to use. Higher priority than \"device-number\".", + DEFAULT_PERSISTENT_ID, G_MAXINT64, DEFAULT_PERSISTENT_ID, + param_flags)); + + g_object_class_install_property (object_class, PROP_VIDEO_CONNECTION, + g_param_spec_enum ("video-connection", "Video Connection", + "Video input connection to use", + GST_TYPE_DECKLINK2_VIDEO_CONNECTION, DEFAULT_VIDEO_CONNECTION, + param_flags)); + + g_object_class_install_property (object_class, PROP_AUDIO_CONNECTION, + g_param_spec_enum ("audio-connection", "Audio Connection", + "Audio input connection to use", + GST_TYPE_DECKLINK2_AUDIO_CONNECTION, DEFAULT_AUDIO_CONNECTION, + param_flags)); + + g_object_class_install_property (object_class, PROP_VIDEO_FORMAT, + g_param_spec_enum ("video-format", "Video format", + "Video format type to use for playback", + GST_TYPE_DECKLINK2_VIDEO_FORMAT, DEFAULT_VIDEO_FORMAT, param_flags)); + + g_object_class_install_property (object_class, PROP_AUDIO_CHANNELS, + g_param_spec_enum ("audio-channels", "Audio Channels", + "Audio Channels", + GST_TYPE_DECKLINK2_AUDIO_CHANNELS, DEFAULT_AUDIO_CHANNELS, + param_flags)); + + g_object_class_install_property (object_class, PROP_PROFILE_ID, + g_param_spec_enum ("profile", "Profile", + "Certain DeckLink devices such as the DeckLink 8K Pro, the DeckLink " + "Quad 2 and the DeckLink Duo 2 support multiple profiles to " + "configure the capture and playback behavior of its sub-devices." + "For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared " + "between any 2 sub-devices that utilize the same connectors. For the " + "DeckLink 8K Pro, a profile is shared between all 4 sub-devices. Any " + "sub-devices that share a profile are considered to be part of the " + "same profile group." + "DeckLink Duo 2 support configuration of the duplex mode of " + "individual sub-devices.", + GST_TYPE_DECKLINK2_PROFILE_ID, DEFAULT_PROFILE_ID, param_flags)); + + g_object_class_install_property (object_class, PROP_TIMECODE_FORMAT, + g_param_spec_enum ("timecode-format", "Timecode format", + "Timecode format type to use for playback", + GST_TYPE_DECKLINK2_TIMECODE_FORMAT, DEFAULT_TIMECODE_FORMAT, + param_flags)); + + g_object_class_install_property (object_class, PROP_OUTPUT_CC, + g_param_spec_boolean ("output-cc", "Output Closed Caption", + "Extract and output CC as GstMeta (if present)", + DEFAULT_OUTPUT_CC, param_flags)); + + g_object_class_install_property (object_class, PROP_OUTPUT_AFD_BAR, + g_param_spec_boolean ("output-afd-bar", "Output AFD/Bar data", + "Extract and output AFD/Bar as GstMeta (if present)", + DEFAULT_OUTPUT_AFD_BAR, param_flags)); + + g_object_class_install_property (object_class, PROP_BUFFER_SIZE, + g_param_spec_uint ("buffer-size", "Buffer Size", + "Size of internal buffer in number of video frames", 1, + 16, DEFAULT_BUFFER_SIZE, param_flags)); + + g_object_class_install_property (object_class, PROP_SIGNAL, + g_param_spec_boolean ("signal", "Signal", + "True if there is a valid input signal available", + FALSE, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_SKIP_FIRST_TIME, + g_param_spec_uint64 ("skip-first-time", "Skip First Time", + "Skip that much time of initial frames after starting", 0, + G_MAXUINT64, DEFAULT_SKIP_FIRST_TIME, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_DESYNC_THRESHOLD, + g_param_spec_uint64 ("desync-threshold", "Desync Threshold", + "Maximum allowed a/v desync threshold. " + "If larger desync is detected, streaming will be restarted " + "(0 = disable auto-restart)", 0, + G_MAXUINT64, DEFAULT_DESYNC_THRESHOLD, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); +} + +void +gst_decklink2_src_restart (GstDeckLink2Src * self) +{ + g_return_if_fail (GST_IS_DECKLINK2_SRC (self)); + + GstDeckLink2SrcPrivate *priv = self->priv; + std::lock_guard < std::mutex > lk (priv->lock); + + if (self->input && self->running) { + GST_INFO_OBJECT (self, "Scheduling restart"); + gst_decklink2_input_schedule_restart (self->input); + } +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2src.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2src.h new file mode 100644 index 0000000000..8816945db3 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2src.h @@ -0,0 +1,38 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_SRC (gst_decklink2_src_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2Src, gst_decklink2_src, + GST, DECKLINK2_SRC, GstPushSrc); + +GST_ELEMENT_REGISTER_DECLARE (decklink2src); + +void gst_decklink2_src_install_properties (GObjectClass * object_class); + +void gst_decklink2_src_restart (GstDeckLink2Src * self); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2srcbin.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2srcbin.cpp new file mode 100644 index 0000000000..8150ecb7ca --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2srcbin.cpp @@ -0,0 +1,233 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2srcbin.h" +#include "gstdecklink2src.h" +#include "gstdecklink2utils.h" + +GST_DEBUG_CATEGORY_STATIC (gst_decklink2_src_bin_debug); +#define GST_CAT_DEFAULT gst_decklink2_src_bin_debug + +static GstStaticPadTemplate audio_template = GST_STATIC_PAD_TEMPLATE ("audio", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS ("audio/x-raw, format = (string) { S16LE, S32LE }, " + "rate = (int) 48000, channels = (int) { 2, 8, 16 }, " + "layout = (string) interleaved")); + +enum +{ + /* actions */ + SIGNAL_RESTART, + + SIGNAL_LAST, +}; + +static guint gst_decklink2_src_bin_signals[SIGNAL_LAST] = { 0, }; + +struct _GstDeckLink2SrcBin +{ + GstBin parent; + + GstElement *src; + GstElement *demux; +}; + +static void gst_decklink2_src_bin_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_decklink2_src_bin_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +static void on_signal (GObject * object, GParamSpec * pspec, GstElement * self); +static void on_pad_added (GstElement * demux, GstPad * pad, + GstDeckLink2SrcBin * self); +static void on_pad_removed (GstElement * demux, GstPad * pad, + GstDeckLink2SrcBin * self); +static void on_no_more_pads (GstElement * demux, GstDeckLink2SrcBin * self); +static void on_restart (GstDeckLink2SrcBin * self); + +#define gst_decklink2_src_bin_parent_class parent_class +G_DEFINE_TYPE (GstDeckLink2SrcBin, gst_decklink2_src_bin, GST_TYPE_BIN); +GST_ELEMENT_REGISTER_DEFINE (decklink2srcbin, "decklink2srcbin", + GST_RANK_NONE, GST_TYPE_DECKLINK2_SRC_BIN); + +static void +gst_decklink2_src_bin_class_init (GstDeckLink2SrcBinClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstCaps *templ_caps; + + object_class->set_property = gst_decklink2_src_bin_set_property; + object_class->get_property = gst_decklink2_src_bin_get_property; + + gst_decklink2_src_install_properties (object_class); + + gst_decklink2_src_bin_signals[SIGNAL_RESTART] = + g_signal_new_class_handler ("restart", G_TYPE_FROM_CLASS (klass), + (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + G_CALLBACK (on_restart), NULL, NULL, NULL, G_TYPE_NONE, 0); + + templ_caps = gst_decklink2_get_default_template_caps (); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("video", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps)); + gst_caps_unref (templ_caps); + + gst_element_class_add_static_pad_template (element_class, &audio_template); + + gst_element_class_set_static_metadata (element_class, + "Decklink2 Source Bin", "Video/Audio/Source/Hardware", + "Decklink2 Source Bin", "Seungha Yang "); + + GST_DEBUG_CATEGORY_INIT (gst_decklink2_src_bin_debug, "decklink2srcbin", + 0, "decklink2srcbin"); +} + +static void +gst_decklink2_src_bin_init (GstDeckLink2SrcBin * self) +{ + GstPad *pad; + GstPad *gpad; + GstElement *queue; + + self->src = gst_element_factory_make ("decklink2src", NULL); + self->demux = gst_element_factory_make ("decklink2demux", NULL); + + queue = gst_element_factory_make ("queue", NULL); + + g_object_set (queue, "max-size-buffers", 3, "max-size-bytes", 0, + "max-size-time", (guint64) 0, NULL); + + gst_bin_add_many (GST_BIN (self), self->src, queue, self->demux, NULL); + gst_element_link_many (self->src, queue, self->demux, NULL); + + pad = gst_element_get_static_pad (self->demux, "video"); + gpad = gst_ghost_pad_new ("video", pad); + gst_object_unref (pad); + gst_element_add_pad (GST_ELEMENT (self), gpad); + + g_signal_connect (self->src, "notify::signal", G_CALLBACK (on_signal), self); + + g_signal_connect (self->demux, "pad-added", G_CALLBACK (on_pad_added), self); + g_signal_connect (self->demux, + "pad-removed", G_CALLBACK (on_pad_removed), self); + g_signal_connect (self->demux, "no-more-pads", + G_CALLBACK (on_no_more_pads), self); + + gst_bin_set_suppressed_flags (GST_BIN (self), + (GstElementFlags) (GST_ELEMENT_FLAG_SOURCE | GST_ELEMENT_FLAG_SINK)); + GST_OBJECT_FLAG_SET (self, GST_ELEMENT_FLAG_SOURCE); +} + +static void +gst_decklink2_src_bin_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDeckLink2SrcBin *self = GST_DECKLINK2_SRC_BIN (object); + + g_object_set_property (G_OBJECT (self->src), pspec->name, value); +} + +static void +gst_decklink2_src_bin_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDeckLink2SrcBin *self = GST_DECKLINK2_SRC_BIN (object); + + g_object_get_property (G_OBJECT (self->src), pspec->name, value); +} + +static gboolean +copy_sticky_events (GstPad * pad, GstEvent ** event, GstPad * gpad) +{ + gst_pad_store_sticky_event (gpad, *event); + + return TRUE; +} + +static void +on_signal (GObject * object, GParamSpec * pspec, GstElement * self) +{ + g_object_notify (G_OBJECT (self), "signal"); +} + +static void +on_pad_added (GstElement * demux, GstPad * pad, GstDeckLink2SrcBin * self) +{ + GstPad *gpad; + gchar *pad_name; + + GST_DEBUG_OBJECT (self, "Pad added %" GST_PTR_FORMAT, pad); + + if (!GST_PAD_IS_SRC (pad)) + return; + + pad_name = gst_pad_get_name (pad); + if (g_strcmp0 (pad_name, "audio") != 0) { + g_free (pad_name); + return; + } + + g_free (pad_name); + + gpad = gst_ghost_pad_new ("audio", pad); + g_object_set_data (G_OBJECT (pad), "decklink2srcbin.ghostpad", gpad); + + gst_pad_set_active (gpad, TRUE); + gst_pad_sticky_events_foreach (pad, + (GstPadStickyEventsForeachFunction) copy_sticky_events, gpad); + gst_element_add_pad (GST_ELEMENT (self), gpad); +} + +static void +on_pad_removed (GstElement * demux, GstPad * pad, GstDeckLink2SrcBin * self) +{ + GstPad *gpad; + + GST_DEBUG_OBJECT (self, "Pad removed %" GST_PTR_FORMAT, pad); + + if (!GST_PAD_IS_SRC (pad)) + return; + + gpad = (GstPad *) g_object_get_data (G_OBJECT (pad), + "decklink2srcbin.ghostpad"); + if (!gpad) { + GST_DEBUG_OBJECT (self, "No ghost pad found"); + return; + } + + gst_element_remove_pad (GST_ELEMENT (self), gpad); +} + +static void +on_no_more_pads (GstElement * demux, GstDeckLink2SrcBin * self) +{ + gst_element_no_more_pads (GST_ELEMENT (self)); +} + +static void +on_restart (GstDeckLink2SrcBin * self) +{ + gst_decklink2_src_restart (GST_DECKLINK2_SRC (self->src)); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2srcbin.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2srcbin.h new file mode 100644 index 0000000000..1503332787 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2srcbin.h @@ -0,0 +1,34 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_DECKLINK2_SRC_BIN (gst_decklink2_src_bin_get_type()) +G_DECLARE_FINAL_TYPE (GstDeckLink2SrcBin, gst_decklink2_src_bin, + GST, DECKLINK2_SRC_BIN, GstBin); + +GST_ELEMENT_REGISTER_DECLARE (decklink2srcbin); + +G_END_DECLS diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2utils.cpp b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2utils.cpp new file mode 100644 index 0000000000..276795499e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2utils.cpp @@ -0,0 +1,1254 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstdecklink2utils.h" +#include "gstdecklink2object.h" +#include +#include +#include +#include + +GST_DEBUG_CATEGORY_EXTERN (gst_decklink2_debug); +#define GST_CAT_DEFAULT gst_decklink2_debug + +static guint api_version_major = 0; +static guint api_version_minor = 0; +static guint api_version_sub = 0; +static guint api_version_extra = 0; + +#ifdef G_OS_WIN32 +static GThread *win32_com_thread = NULL; +/* *INDENT-OFF* */ +static std::mutex com_init_lock; +static std::mutex com_deinit_lock; +static std::condition_variable com_init_cond; +static std::condition_variable com_deinit_cond; +/* *INDENT-ON* */ +static bool com_thread_running = false; +static bool exit_com_thread = false; + +static gpointer +gst_decklink2_win32_com_thread (gpointer user_data) +{ + std::unique_lock < std::mutex > init_lk (com_init_lock); + + CoInitializeEx (0, COINIT_MULTITHREADED); + com_thread_running = true; + com_init_cond.notify_all (); + init_lk.unlock (); + + std::unique_lock < std::mutex > deinit_lk (com_deinit_lock); + while (!exit_com_thread) { + com_deinit_cond.wait (deinit_lk); + } + CoUninitialize (); + + return NULL; +} + +static IDeckLinkAPIInformation * +CreateDeckLinkAPIInformationInstance (void) +{ + IDeckLinkAPIInformation *info = NULL; + + CoCreateInstance (CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL, + IID_IDeckLinkAPIInformation, (void **) &info); + + return info; +} +#endif + +gboolean +gst_decklink2_init_once (void) +{ + static gboolean ret = FALSE; + GST_DECKLINK2_CALL_ONCE_BEGIN { + IDeckLinkAPIInformation *info = NULL; + gint64 version = 0; + HRESULT hr; + +#ifdef G_OS_WIN32 + std::unique_lock < std::mutex > lk (com_init_lock); + win32_com_thread = g_thread_new ("GstDeckLink2Win32", + gst_decklink2_win32_com_thread, NULL); + while (!com_thread_running) + com_init_cond.wait (lk); +#endif + + info = CreateDeckLinkAPIInformationInstance (); + if (!info) + return; + + hr = info->GetInt (BMDDeckLinkAPIVersion, &version); + if (gst_decklink2_result (hr)) { + api_version_major = (version & 0xff000000) >> 24; + api_version_minor = (version & 0xff0000) >> 16; + api_version_sub = (version & 0xff00) >> 8; + api_version_extra = version & 0xff; + ret = TRUE; + } + + info->Release (); + } + GST_DECKLINK2_CALL_ONCE_END; + + return ret; +} + +void +gst_decklink2_deinit (void) +{ + gst_decklink2_object_deinit (); +#ifdef G_OS_WIN32 + std::unique_lock < std::mutex > deinit_lk (com_deinit_lock); + if (win32_com_thread) { + exit_com_thread = true; + com_deinit_cond.notify_all (); + deinit_lk.unlock (); + g_thread_join (win32_com_thread); + win32_com_thread = NULL; + } +#endif +} + +gboolean +gst_decklink2_get_api_version (guint * major, guint * minor, guint * sub, + guint * extra) +{ + if (!gst_decklink2_init_once ()) + return FALSE; + + if (major) + *major = api_version_major; + if (minor) + *minor = api_version_minor; + if (sub) + *sub = api_version_sub; + if (extra) + *extra = api_version_extra; + + return TRUE; +} + +GstDeckLink2APILevel +gst_decklink2_get_api_level (void) +{ + static GstDeckLink2APILevel level = GST_DECKLINK2_API_LEVEL_UNKNOWN; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + guint major, minor, sub; + if (!gst_decklink2_get_api_version (&major, &minor, &sub, NULL)) + return; + + if (major >= 12) { + level = GST_DECKLINK2_API_LEVEL_LATEST; + return; + } else if (major == 11) { + if (minor > 5 || (minor == 5 && sub >= 1)) { + level = GST_DECKLINK2_API_LEVEL_11_5_1; + } else if (minor == 4) { + level = GST_DECKLINK2_API_LEVEL_11_4; + } else { + level = GST_DECKLINK2_API_LEVEL_10_11; + } + } else if (major == 10 && minor >= 11) { + level = GST_DECKLINK2_API_LEVEL_10_11; + } + } + GST_DECKLINK2_CALL_ONCE_END; + + return level; +} + +const gchar * +gst_decklink2_api_level_to_string (GstDeckLink2APILevel level) +{ + switch (level) { + case GST_DECKLINK2_API_LEVEL_10_11: + return "10.11"; + case GST_DECKLINK2_API_LEVEL_11_4: + return "11.4"; + case GST_DECKLINK2_API_LEVEL_11_5_1: + return "11.5.1"; + case GST_DECKLINK2_API_LEVEL_LATEST: + return "latest"; + default: + break; + } + + return "unknown"; +} + +GType +gst_decklink2_mode_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue modes[] = { + {bmdModeUnknown, "Automatic detection", "auto"}, + + {bmdModeNTSC, "NTSC SD 60i", "ntsc"}, + {bmdModeNTSC2398, "NTSC SD 60i (24 fps)", "ntsc2398"}, + {bmdModePAL, "PAL SD 50i", "pal"}, + {bmdModeNTSCp, "NTSC SD 60p", "ntsc-p"}, + {bmdModePALp, "PAL SD 50p", "pal-p"}, + + {bmdModeNTSC_W, "NTSC SD 60i Widescreen", "ntsc-widescreen"}, + {bmdModeNTSC2398_W, "NTSC SD 60i Widescreen (24 fps)", + "ntsc2398-widescreen"}, + {bmdModePAL_W, "PAL SD 50i Widescreen", "pal-widescreen"}, + {bmdModeNTSCp_W, "NTSC SD 60p Widescreen", "ntsc-p-widescreen"}, + {bmdModePALp_W, "PAL SD 50p Widescreen", "pal-p-widescreen"}, + + {bmdModeHD1080p2398, "HD1080 23.98p", "1080p2398"}, + {bmdModeHD1080p24, "HD1080 24p", "1080p24"}, + {bmdModeHD1080p25, "HD1080 25p", "1080p25"}, + {bmdModeHD1080p2997, "HD1080 29.97p", "1080p2997"}, + {bmdModeHD1080p30, "HD1080 30p", "1080p30"}, + {bmdModeHD1080p50, "HD1080 50p", "1080p50"}, + {bmdModeHD1080p5994, "HD1080 59.94p", "1080p5994"}, + {bmdModeHD1080p6000, "HD1080 60p", "1080p60"}, + {bmdModeHD1080i50, "HD1080 50i", "1080i50"}, + {bmdModeHD1080i5994, "HD1080 59.94i", "1080i5994"}, + {bmdModeHD1080i6000, "HD1080 60i", "1080i60"}, + + {bmdModeHD720p50, "HD720 50p", "720p50"}, + {bmdModeHD720p5994, "HD720 59.94p", "720p5994"}, + {bmdModeHD720p60, "HD720 60p", "720p60"}, + + {bmdMode2k2398, "2k 23.98p", "1556p2398"}, + {bmdMode2k24, "2k 24p", "1556p24"}, + {bmdMode2k25, "2k 25p", "1556p25"}, + + {bmdMode2kDCI2398, "2k dci 23.98p", "2kdcip2398"}, + {bmdMode2kDCI24, "2k dci 24p", "2kdcip24"}, + {bmdMode2kDCI25, "2k dci 25p", "2kdcip25"}, + {bmdMode2kDCI2997, "2k dci 29.97p", "2kdcip2997"}, + {bmdMode2kDCI30, "2k dci 30p", "2kdcip30"}, + {bmdMode2kDCI50, "2k dci 50p", "2kdcip50"}, + {bmdMode2kDCI5994, "2k dci 59.94p", "2kdcip5994"}, + {bmdMode2kDCI60, "2k dci 60p", "2kdcip60"}, + + {bmdMode4K2160p2398, "4k 23.98p", "2160p2398"}, + {bmdMode4K2160p24, "4k 24p", "2160p24"}, + {bmdMode4K2160p25, "4k 25p", "2160p25"}, + {bmdMode4K2160p2997, "4k 29.97p", "2160p2997"}, + {bmdMode4K2160p30, "4k 30p", "2160p30"}, + {bmdMode4K2160p50, "4k 50p", "2160p50"}, + {bmdMode4K2160p5994, "4k 59.94p", "2160p5994"}, + {bmdMode4K2160p60, "4k 60p", "2160p60"}, + + {bmdMode4kDCI2398, "4k dci 23.98p", "4kdcip2398"}, + {bmdMode4kDCI24, "4k dci 24p", "4kdcip24"}, + {bmdMode4kDCI25, "4k dci 25p", "4kdcip25"}, + {bmdMode4kDCI2997, "4k dci 29.97p", "4kdcip2997"}, + {bmdMode4kDCI30, "4k dci 30p", "4kdcip30"}, + {bmdMode4kDCI50, "4k dci 50p", "4kdcip50"}, + {bmdMode4kDCI5994, "4k dci 59.94p", "4kdcip5994"}, + {bmdMode4kDCI60, "4k dci 60p", "4kdcip60"}, + + {bmdMode8K4320p2398, "8k 23.98p", "8kp2398"}, + {bmdMode8K4320p24, "8k 24p", "8kp24"}, + {bmdMode8K4320p25, "8k 25p", "8kp25"}, + {bmdMode8K4320p2997, "8k 29.97p", "8kp2997"}, + {bmdMode8K4320p30, "8k 30p", "8kp30"}, + {bmdMode8K4320p50, "8k 50p", "8kp50"}, + {bmdMode8K4320p5994, "8k 59.94p", "8kp5994"}, + {bmdMode8K4320p60, "8k 60p", "8kp60"}, + + {bmdMode8kDCI2398, "8k dci 23.98p", "8kdcip2398"}, + {bmdMode8kDCI24, "8k dci 24p", "8kdcip24"}, + {bmdMode8kDCI25, "8k dci 25p", "8kdcip25"}, + {bmdMode8kDCI2997, "8k dci 29.97p", "8kdcip2997"}, + {bmdMode8kDCI30, "8k dci 30p", "8kdcip30"}, + {bmdMode8kDCI50, "8k dci 50p", "8kdcip50"}, + {bmdMode8kDCI5994, "8k dci 59.94p", "8kdcip5994"}, + {bmdMode8kDCI60, "8k dci 60p", "8kdcip60"}, + + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2Mode", modes); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_video_format_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue formats[] = { + {bmdFormatUnspecified, "Auto", "auto"}, + {bmdFormat8BitYUV, "bmdFormat8BitYUV", "8bit-yuv"}, + {bmdFormat10BitYUV, "bmdFormat10BitYUV", "10bit-yuv"}, + {bmdFormat8BitARGB, "bmdFormat8BitARGB", "8bit-argb"}, + {bmdFormat8BitBGRA, "bmdFormat8BitBGRA", "8bit-bgra"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2VideoFormat", formats); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_profile_id_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue profiles[] = { + {bmdProfileDefault, "Default, don't change profile", + "default"}, + {bmdProfileOneSubDeviceFullDuplex, + "One sub-device, Full-Duplex", "one-sub-device-full"}, + {bmdProfileOneSubDeviceHalfDuplex, + "One sub-device, Half-Duplex", "one-sub-device-half"}, + {bmdProfileTwoSubDevicesFullDuplex, + "Two sub-devices, Full-Duplex", "two-sub-devices-full"}, + {bmdProfileTwoSubDevicesHalfDuplex, + "Two sub-devices, Half-Duplex", "two-sub-devices-half"}, + {bmdProfileFourSubDevicesHalfDuplex, + "Four sub-devices, Half-Duplex", "four-sub-devices-half"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2ProfileId", profiles); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_keyer_mode_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue modes[] = { + {GST_DECKLINK2_KEYER_MODE_OFF, "Off", "off"}, + {GST_DECKLINK2_KEYER_MODE_INTERNAL, "Internal", "internal"}, + {GST_DECKLINK2_KEYER_MODE_EXTERNAL, "External", "external"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2KeyerMode", modes); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_mapping_format_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue formats[] = { + {GST_DECKLINK2_MAPPING_FORMAT_DEFAULT, + "Default, don't change mapping format", + "default"}, + {GST_DECKLINK2_MAPPING_FORMAT_LEVEL_A, "Level A", "level-a"}, + {GST_DECKLINK2_MAPPING_FORMAT_LEVEL_B, "Level B", "level-b"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2MappingFormat", formats); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_timecode_format_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue formats[] = { + {bmdTimecodeRP188VITC1, "bmdTimecodeRP188VITC1", "rp188vitc1"}, + {bmdTimecodeRP188VITC2, "bmdTimecodeRP188VITC2", "rp188vitc2"}, + {bmdTimecodeRP188LTC, "bmdTimecodeRP188LTC", "rp188ltc"}, + {bmdTimecodeRP188Any, "bmdTimecodeRP188Any", "rp188any"}, + {bmdTimecodeVITC, "bmdTimecodeVITC", "vitc"}, + {bmdTimecodeVITCField2, "bmdTimecodeVITCField2", "vitcfield2"}, + {bmdTimecodeSerial, "bmdTimecodeSerial", "serial"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2TimecodeFormat", formats); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_video_connection_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue connections[] = { + {bmdVideoConnectionUnspecified, "Auto", "auto"}, + {bmdVideoConnectionSDI, "SDI", "sdi"}, + {bmdVideoConnectionHDMI, "HDMI", "hdmi"}, + {bmdVideoConnectionOpticalSDI, "Optical SDI", "optical-sdi"}, + {bmdVideoConnectionComponent, "Component", "component"}, + {bmdVideoConnectionComposite, "Composite", "composite"}, + {bmdVideoConnectionSVideo, "S-Video", "svideo"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2VideoConnection", connections); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_audio_connection_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue connections[] = { + {bmdAudioConnectionUnspecified, "Auto", "auto"}, + {bmdAudioConnectionEmbedded, "SDI/HDMI embedded audio", "embedded"}, + {bmdAudioConnectionAESEBU, "AES/EBU", "aes"}, + {bmdAudioConnectionAnalog, "Analog", "analog"}, + {bmdAudioConnectionAnalogXLR, "Analog (XLR)", "analog-xlr"}, + {bmdAudioConnectionAnalogRCA, "Analog (RCA)", "analog-rca"}, +#if 0 + {bmdAudioConnectionMicrophone, "Microphone", "microphone"}, + {bmdAudioConnectionHeadphones, "Headpones", "headphones"}, +#endif + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2AudioConnection", connections); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +GType +gst_decklink2_audio_channels_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const GEnumValue channles[] = { + {GST_DECKLINK2_AUDIO_CHANNELS_DISABLED, "Disabled", "disabled"}, + {GST_DECKLINK2_AUDIO_CHANNELS_2, "2 Channels", "2"}, + {GST_DECKLINK2_AUDIO_CHANNELS_8, "8 Channels", "8"}, + {GST_DECKLINK2_AUDIO_CHANNELS_16, "16 Channels", "16"}, + {GST_DECKLINK2_AUDIO_CHANNELS_MAX, "Maximum channels supported", "max"}, + {0, NULL, NULL} + }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = g_enum_register_static ("GstDeckLink2AudioChannels", channles); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +#define NTSC 10, 11, FALSE +#define PAL 12, 11, TRUE +#define NTSC_WS 40, 33, FALSE +#define PAL_WS 16, 11, TRUE +#define HD 1, 1, TRUE +#define UHD 1, 1, TRUE + +static const GstDeckLink2DisplayMode all_modes[] = { + {bmdModeUnknown, 0, 0, 0, 0, FALSE, 0, 0, 0}, + /* SD Modes */ + {bmdModeNTSC, 720, 486, 30000, 1001, TRUE, NTSC}, + {bmdModeNTSC2398, 720, 486, 24000, 1001, TRUE, NTSC}, + {bmdModePAL, 720, 576, 25, 1, TRUE, PAL}, + {bmdModeNTSCp, 720, 486, 30000, 1001, FALSE, NTSC}, + {bmdModePALp, 720, 576, 25, 1, FALSE, PAL}, + + /* Custom wide modes */ + {bmdModeNTSC_W, 720, 486, 30000, 1001, TRUE, NTSC_WS}, + {bmdModeNTSC2398_W, 720, 486, 24000, 1001, TRUE, NTSC_WS}, + {bmdModePAL_W, 720, 576, 25, 1, TRUE, PAL_WS}, + {bmdModeNTSCp_W, 720, 486, 30000, 1001, FALSE, NTSC_WS}, + {bmdModePALp_W, 720, 576, 25, 1, FALSE, PAL_WS}, + + /* HD 1080 Modes */ + {bmdModeHD1080p2398, 1920, 1080, 24000, 1001, FALSE, HD}, + {bmdModeHD1080p24, 1920, 1080, 24, 1, FALSE, HD}, + {bmdModeHD1080p25, 1920, 1080, 25, 1, FALSE, HD}, + {bmdModeHD1080p2997, 1920, 1080, 30000, 1001, FALSE, HD}, + {bmdModeHD1080p30, 1920, 1080, 30, 1, FALSE, HD}, + /* FIXME: + * bmdModeHD1080p4795 + * bmdModeHD1080p48 + */ + {bmdModeHD1080p50, 1920, 1080, 50, 1, FALSE, HD}, + {bmdModeHD1080p5994, 1920, 1080, 60000, 1001, FALSE, HD}, + {bmdModeHD1080p6000, 1920, 1080, 60, 1, FALSE, HD}, + /* FIXME: + * bmdModeHD1080p9590 + * bmdModeHD1080p96 + * bmdModeHD1080p100 + * bmdModeHD1080p11988 + * bmdModeHD1080p120 + */ + {bmdModeHD1080i50, 1920, 1080, 25, 1, TRUE, HD}, + {bmdModeHD1080i5994, 1920, 1080, 30000, 1001, TRUE, HD}, + {bmdModeHD1080i6000, 1920, 1080, 30, 1, TRUE, HD}, + + /* HD 720 Modes */ + {bmdModeHD720p50, 1280, 720, 50, 1, FALSE, HD}, + {bmdModeHD720p5994, 1280, 720, 60000, 1001, FALSE, HD}, + {bmdModeHD720p60, 1280, 720, 60, 1, FALSE, HD}, + + /* 2K Modes */ + {bmdMode2k2398, 2048, 1556, 24000, 1001, FALSE, HD}, + {bmdMode2k24, 2048, 1556, 24, 1, FALSE, HD}, + {bmdMode2k25, 2048, 1556, 25, 1, FALSE, HD}, + + /* 2K DCI Modes */ + {bmdMode2kDCI2398, 2048, 1080, 24000, 1001, FALSE, HD}, + {bmdMode2kDCI24, 2048, 1080, 24, 1, FALSE, HD}, + {bmdMode2kDCI25, 2048, 1080, 25, 1, FALSE, HD}, + {bmdMode2kDCI2997, 2048, 1080, 30000, 1001, FALSE, HD}, + {bmdMode2kDCI30, 2048, 1080, 30, 1, FALSE, HD}, + /* FIXME: + * bmdMode2kDCI4795 + * bmdMode2kDCI48 + */ + {bmdMode2kDCI50, 2048, 1080, 50, 1, FALSE, HD}, + {bmdMode2kDCI5994, 2048, 1080, 60000, 1001, FALSE, HD}, + {bmdMode2kDCI60, 2048, 1080, 60, 1, FALSE, HD}, + /* FIXME: + * bmdMode2kDCI9590 + * bmdMode2kDCI96 + * bmdMode2kDCI100 + * bmdMode2kDCI11988 + * bmdMode2kDCI120 + */ + + /* 4K UHD Modes */ + {bmdMode4K2160p2398, 3840, 2160, 24000, 1001, FALSE, UHD}, + {bmdMode4K2160p24, 3840, 2160, 24, 1, FALSE, UHD}, + {bmdMode4K2160p25, 3840, 2160, 25, 1, FALSE, UHD}, + {bmdMode4K2160p2997, 3840, 2160, 30000, 1001, FALSE, UHD}, + {bmdMode4K2160p30, 3840, 2160, 30, 1, FALSE, UHD}, + /* FIXME: + * bmdMode4K2160p4795 + * bmdMode4K2160p48 + */ + {bmdMode4K2160p50, 3840, 2160, 50, 1, FALSE, UHD}, + {bmdMode4K2160p5994, 3840, 2160, 60000, 1001, FALSE, UHD}, + {bmdMode4K2160p60, 3840, 2160, 60, 1, FALSE, UHD}, + /* FIXME: + * bmdMode4K2160p9590 + * bmdMode4K2160p96 + * bmdMode4K2160p100 + * bmdMode4K2160p11988 + * bmdMode4K2160p120 + */ + + /* 4K DCI Modes */ + {bmdMode4kDCI2398, 4096, 2160, 24000, 1001, FALSE, UHD}, + {bmdMode4kDCI24, 4096, 2160, 24, 1, FALSE, UHD}, + {bmdMode4kDCI25, 4096, 2160, 25, 1, FALSE, UHD}, + {bmdMode4kDCI2997, 4096, 2160, 30000, 1001, FALSE, UHD}, + {bmdMode4kDCI30, 4096, 2160, 30, 1, FALSE, UHD}, + /* FIXME: + * bmdMode4kDCI4795 + * bmdMode4kDCI48 + */ + {bmdMode4kDCI50, 4096, 2160, 50, 1, FALSE, UHD}, + {bmdMode4kDCI5994, 4096, 2160, 60000, 1001, FALSE, UHD}, + {bmdMode4kDCI60, 4096, 2160, 60, 1, FALSE, UHD}, + /* FIXME: + * bmdMode4kDCI9590 + * bmdMode4kDCI96 + * bmdMode4kDCI100 + * bmdMode4kDCI11988 + * bmdMode4kDCI120 + */ + + /* 8K UHD Modes */ + {bmdMode8K4320p2398, 7680, 4320, 24000, 1001, FALSE, UHD}, + {bmdMode8K4320p24, 7680, 4320, 24, 1, FALSE, UHD}, + {bmdMode8K4320p25, 7680, 4320, 25, 1, FALSE, UHD}, + {bmdMode8K4320p2997, 7680, 4320, 30000, 1001, FALSE, UHD}, + {bmdMode8K4320p30, 7680, 4320, 30, 1, FALSE, UHD}, + /* FIXME: + * bmdMode8K4320p4795 + * bmdMode8K4320p48 + */ + {bmdMode8K4320p50, 7680, 4320, 50, 1, FALSE, UHD}, + {bmdMode8K4320p5994, 7680, 4320, 60000, 1001, FALSE, UHD}, + {bmdMode8K4320p60, 7680, 4320, 60, 1, FALSE, UHD}, + + /* 8K DCI Modes */ + {bmdMode8kDCI2398, 8192, 4320, 24000, 1001, FALSE, UHD}, + {bmdMode8kDCI24, 8192, 4320, 24, 1, FALSE, UHD}, + {bmdMode8kDCI25, 8192, 4320, 25, 1, FALSE, UHD}, + {bmdMode8kDCI2997, 8192, 4320, 30000, 1001, FALSE, UHD}, + {bmdMode8kDCI30, 8192, 4320, 30, 1, FALSE, UHD}, + /* FIXME: + * bmdMode8kDCI4795 + * bmdMode8kDCI48 + */ + {bmdMode8kDCI50, 8192, 4320, 50, 1, FALSE, UHD}, + {bmdMode8kDCI5994, 8192, 4320, 60000, 1001, FALSE, UHD}, + {bmdMode8kDCI60, 8192, 4320, 60, 1, FALSE, UHD}, + + /* FIXME: Add PC modes */ +}; + +static const struct +{ + BMDPixelFormat format; + gint bpp; + GstVideoFormat vformat; +} formats[] = { + {bmdFormatUnspecified, 0, GST_VIDEO_FORMAT_UNKNOWN}, + {bmdFormat8BitYUV, 2, GST_VIDEO_FORMAT_UYVY}, + {bmdFormat10BitYUV, 4, GST_VIDEO_FORMAT_v210}, + {bmdFormat8BitARGB, 4, GST_VIDEO_FORMAT_ARGB}, + {bmdFormat8BitBGRA, 4, GST_VIDEO_FORMAT_BGRA}, +}; + +GstVideoFormat +gst_decklink2_video_format_from_pixel_format (BMDPixelFormat format) +{ + switch (format) { + case bmdFormat8BitYUV: + return GST_VIDEO_FORMAT_UYVY; + case bmdFormat10BitYUV: + return GST_VIDEO_FORMAT_v210; + case bmdFormat8BitARGB: + return GST_VIDEO_FORMAT_ARGB; + case bmdFormat8BitBGRA: + return GST_VIDEO_FORMAT_BGRA; + default: + break; + } + + return GST_VIDEO_FORMAT_UNKNOWN; +} + +BMDPixelFormat +gst_decklink2_pixel_format_from_video_format (GstVideoFormat format) +{ + switch (format) { + case GST_VIDEO_FORMAT_UYVY: + return bmdFormat8BitYUV; + case GST_VIDEO_FORMAT_v210: + return bmdFormat10BitYUV; + case GST_VIDEO_FORMAT_ARGB: + return bmdFormat8BitARGB; + case GST_VIDEO_FORMAT_BGRA: + return bmdFormat8BitBGRA; + default: + break; + } + + return bmdFormatUnspecified; +} + + +static const gchar * +gst_decklink2_pixel_format_to_string (BMDPixelFormat format) +{ + switch (format) { + case bmdFormat8BitYUV: + return "UYVY"; + case bmdFormat10BitYUV: + return "v210"; + case bmdFormat8BitARGB: + return "ARGB"; + case bmdFormat8BitBGRA: + return "BGRA"; + default: + g_assert_not_reached (); + break; + } + + return ""; +} + +static GstStructure * +gst_decklink2_mode_get_structure (const GstDeckLink2DisplayMode * mode, + BMDPixelFormat f) +{ + GstStructure *s = gst_structure_new ("video/x-raw", + "width", G_TYPE_INT, mode->width, + "height", G_TYPE_INT, mode->height, + "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 bmdFormatUnspecified: + { + GValue format_values = G_VALUE_INIT; + + g_value_init (&format_values, GST_TYPE_LIST); + for (guint i = 1; i < G_N_ELEMENTS (formats); i++) { + GValue f = G_VALUE_INIT; + + g_value_init (&f, G_TYPE_STRING); + g_value_set_static_string (&f, + gst_decklink2_pixel_format_to_string (formats[i].format)); + gst_value_list_append_and_take_value (&format_values, &f); + } + + gst_structure_set_value (s, "format", &format_values); + g_value_unset (&format_values); + break; + } + case bmdFormat8BitYUV: + gst_structure_set (s, "format", G_TYPE_STRING, "UYVY", NULL); + break; + case bmdFormat10BitYUV: + gst_structure_set (s, "format", G_TYPE_STRING, "v210", NULL); + break; + case bmdFormat8BitARGB: + gst_structure_set (s, "format", G_TYPE_STRING, "ARGB", NULL); + break; + case bmdFormat8BitBGRA: + gst_structure_set (s, "format", G_TYPE_STRING, "BGRA", NULL); + break; + default: + GST_WARNING ("format not supported %d", f); + gst_structure_free (s); + s = NULL; + break; + } + + return s; +} + +static GstCaps * +gst_decklink2_mode_get_all_format_caps (const GstDeckLink2DisplayMode * mode) +{ + GstCaps *caps; + GstStructure *s; + + if (!mode) + return NULL; + + caps = gst_caps_new_empty (); + s = gst_decklink2_mode_get_structure (mode, bmdFormatUnspecified); + return gst_caps_merge_structure (caps, s); +} + +static gboolean +gst_decklink2_get_display_mode (BMDDisplayMode mode, + GstDeckLink2DisplayMode * display_mode) +{ + for (guint i = 0; i < G_N_ELEMENTS (all_modes); i++) { + if (mode == all_modes[i].mode) { + *display_mode = all_modes[i]; + return TRUE; + } + } + + return FALSE; +} + +BMDDisplayMode +gst_decklink2_get_real_display_mode (BMDDisplayMode mode) +{ + switch (mode) { + case bmdModeNTSC_W: + return bmdModeNTSC; + case bmdModeNTSC2398_W: + return bmdModeNTSC2398; + case bmdModePAL_W: + return bmdModePAL; + case bmdModeNTSCp_W: + return bmdModeNTSCp; + case bmdModePALp_W: + return bmdModePALp; + default: + break; + } + + return mode; +} + +GstCaps * +gst_decklink2_build_caps (GstObject * io_object, + IDeckLinkDisplayModeIterator * iter, BMDDisplayMode requested_mode, + BMDPixelFormat format, GstDeckLink2DoesSupportVideoMode func) +{ + HRESULT hr = S_OK; + GstCaps *caps = NULL; + BMDDisplayMode real_mode = + gst_decklink2_get_real_display_mode (requested_mode); + + GST_LOG_OBJECT (io_object, "Building caps, mode: %" GST_FOURCC_FORMAT + ", format: %" GST_FOURCC_FORMAT, + GST_DECKLINK2_FOURCC_ARGS (requested_mode), + GST_DECKLINK2_FOURCC_ARGS (format)); + + do { + IDeckLinkDisplayMode *mode = NULL; + BMDDisplayMode bdm_mode; + GstDeckLink2DisplayMode gst_mode; + std::vector < std::string > formats; + GstStructure *s; + GstStructure *s_wide = NULL; + const gchar *format_str; + + hr = iter->Next (&mode); + if (hr != S_OK) + break; + + bdm_mode = mode->GetDisplayMode (); + if (requested_mode != bmdModeUnknown) { + if (real_mode != bdm_mode) + goto next; + + if (!gst_decklink2_get_display_mode (requested_mode, &gst_mode)) { + GST_WARNING_OBJECT (io_object, "Couldn't get mode"); + goto next; + } + } else if (!gst_decklink2_get_display_mode (bdm_mode, &gst_mode)) { + goto next; + } + + if (format == bmdFormatUnspecified) { + if (func (io_object, bdm_mode, bmdFormat8BitYUV)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat8BitYUV); + formats.push_back (format_str); + } + + if (func (io_object, bdm_mode, bmdFormat10BitYUV)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat10BitYUV); + formats.push_back (format_str); + } + + if (func (io_object, bdm_mode, bmdFormat8BitARGB)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat8BitARGB); + formats.push_back (format_str); + } + + if (func (io_object, bdm_mode, bmdFormat8BitBGRA)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat8BitBGRA); + formats.push_back (format_str); + } + } else if (func (io_object, bdm_mode, format)) { + format_str = gst_decklink2_pixel_format_to_string (format); + formats.push_back (format_str); + } + + if (formats.empty ()) + goto next; + + if (!caps) + caps = gst_caps_new_empty (); + + gst_mode.width = (gint) mode->GetWidth (); + gst_mode.height = (gint) mode->GetHeight (); + + s = gst_structure_new ("video/x-raw", + "width", G_TYPE_INT, gst_mode.width, + "height", G_TYPE_INT, gst_mode.height, + "pixel-aspect-ratio", GST_TYPE_FRACTION, gst_mode.par_n, gst_mode.par_d, + "interlace-mode", G_TYPE_STRING, + gst_mode.interlaced ? "interleaved" : "progressive", + "framerate", GST_TYPE_FRACTION, gst_mode.fps_n, gst_mode.fps_d, NULL); + + if (gst_mode.interlaced) { + BMDFieldDominance field; + + field = mode->GetFieldDominance (); + if (field == bmdLowerFieldFirst) + gst_mode.tff = FALSE; + else if (field == bmdUpperFieldFirst) + gst_mode.tff = TRUE; + + if (gst_mode.tff) { + gst_structure_set (s, + "field-order", G_TYPE_STRING, "top-field-first", NULL); + } else { + gst_structure_set (s, + "field-order", G_TYPE_STRING, "bottom-field-first", NULL); + } + } + + if (formats.size () == 1) { + gst_structure_set (s, "format", G_TYPE_STRING, formats[0].c_str (), NULL); + } else { + GValue format_values = G_VALUE_INIT; + + g_value_init (&format_values, GST_TYPE_LIST); + + /* *INDENT-OFF* */ + for (const auto & iter: formats) { + GValue f = G_VALUE_INIT; + + g_value_init (&f, G_TYPE_STRING); + g_value_set_string (&f, iter.c_str ()); + gst_value_list_append_and_take_value (&format_values, &f); + } + /* *INDENT-ON* */ + + gst_structure_set_value (s, "format", &format_values); + g_value_unset (&format_values); + } + + /* Add custom wide mode */ + if (requested_mode == bmdModeUnknown) { + switch (bdm_mode) { + case bmdModeNTSC: + case bmdModeNTSC2398: + case bmdModeNTSCp: + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 40, 33, NULL); + break; + case bmdModePAL: + case bmdModePALp: + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 16, 11, NULL); + break; + default: + break; + } + } + + gst_caps_append_structure (caps, s); + if (s_wide) + gst_caps_append_structure (caps, s_wide); + + next: + mode->Release (); + } while (gst_decklink2_result (hr)); + + return caps; +} + +GstCaps * +gst_decklink2_build_template_caps (GstObject * io_object, + IDeckLinkDisplayModeIterator * iter, GstDeckLink2DoesSupportVideoMode func, + GArray * format_table) +{ + HRESULT hr = S_OK; + GstCaps *caps = NULL; + + do { + IDeckLinkDisplayMode *mode = NULL; + BMDDisplayMode bdm_mode; + GstDeckLink2DisplayMode gst_mode; + GstDeckLink2DisplayMode gst_mode_wide; + std::vector < std::string > formats; + GstStructure *s; + GstStructure *s_wide = NULL; + const gchar *format_str; + + hr = iter->Next (&mode); + if (hr != S_OK) + break; + + bdm_mode = mode->GetDisplayMode (); + if (!gst_decklink2_get_display_mode (bdm_mode, &gst_mode)) + goto next; + + if (func (io_object, bdm_mode, bmdFormat8BitYUV)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat8BitYUV); + formats.push_back (format_str); + } + + if (func (io_object, bdm_mode, bmdFormat10BitYUV)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat10BitYUV); + formats.push_back (format_str); + } + + if (func (io_object, bdm_mode, bmdFormat8BitARGB)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat8BitARGB); + formats.push_back (format_str); + } + + if (func (io_object, bdm_mode, bmdFormat8BitBGRA)) { + format_str = gst_decklink2_pixel_format_to_string (bmdFormat8BitBGRA); + formats.push_back (format_str); + } + + if (formats.empty ()) + goto next; + + if (!caps) + caps = gst_caps_new_empty (); + + gst_mode.width = (gint) mode->GetWidth (); + gst_mode.height = (gint) mode->GetHeight (); + if (gst_mode.interlaced) { + BMDFieldDominance field; + + field = mode->GetFieldDominance (); + if (field == bmdLowerFieldFirst) + gst_mode.tff = FALSE; + else if (field == bmdUpperFieldFirst) + gst_mode.tff = TRUE; + } + + s = gst_structure_new ("video/x-raw", + "width", G_TYPE_INT, gst_mode.width, + "height", G_TYPE_INT, gst_mode.height, + "pixel-aspect-ratio", GST_TYPE_FRACTION, gst_mode.par_n, gst_mode.par_d, + "interlace-mode", G_TYPE_STRING, + gst_mode.interlaced ? "interleaved" : "progressive", + "framerate", GST_TYPE_FRACTION, gst_mode.fps_n, gst_mode.fps_d, NULL); + + if (gst_mode.interlaced) { + if (gst_mode.tff) { + gst_structure_set (s, + "field-order", G_TYPE_STRING, "top-field-first", NULL); + } else { + gst_structure_set (s, + "field-order", G_TYPE_STRING, "bottom-field-first", NULL); + } + } + + if (formats.size () == 1) { + gst_structure_set (s, "format", G_TYPE_STRING, formats[0].c_str (), NULL); + } else { + GValue format_values = G_VALUE_INIT; + + g_value_init (&format_values, GST_TYPE_LIST); + + /* *INDENT-OFF* */ + for (const auto & iter: formats) { + GValue f = G_VALUE_INIT; + + g_value_init (&f, G_TYPE_STRING); + g_value_set_string (&f, iter.c_str ()); + gst_value_list_append_and_take_value (&format_values, &f); + } + /* *INDENT-ON* */ + + gst_structure_set_value (s, "format", &format_values); + g_value_unset (&format_values); + } + + /* Add custom wide mode */ + switch (bdm_mode) { + case bmdModeNTSC: + gst_mode_wide = gst_mode; + gst_mode_wide.mode = bmdModeNTSC_W; + gst_mode_wide.par_n = 40; + gst_mode_wide.par_d = 33; + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 40, 33, NULL); + break; + case bmdModeNTSC2398: + gst_mode_wide = gst_mode; + gst_mode_wide.mode = bmdModeNTSC2398_W; + gst_mode_wide.par_n = 40; + gst_mode_wide.par_d = 33; + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 40, 33, NULL); + break; + case bmdModeNTSCp: + gst_mode_wide = gst_mode; + gst_mode_wide.mode = bmdModeNTSCp_W; + gst_mode_wide.par_n = 40; + gst_mode_wide.par_d = 33; + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 40, 33, NULL); + break; + case bmdModePAL: + gst_mode_wide = gst_mode; + gst_mode_wide.mode = bmdModePAL_W; + gst_mode_wide.par_n = 16; + gst_mode_wide.par_d = 11; + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 16, 11, NULL); + break; + case bmdModePALp: + gst_mode_wide = gst_mode; + gst_mode_wide.mode = bmdModePALp_W; + gst_mode_wide.par_n = 16; + gst_mode_wide.par_d = 11; + s_wide = gst_structure_copy (s); + gst_structure_set (s_wide, + "pixel-aspect-ratio", GST_TYPE_FRACTION, 16, 11, NULL); + break; + default: + break; + } + + gst_caps_append_structure (caps, s); + g_array_append_val (format_table, gst_mode); + + if (s_wide) { + gst_caps_append_structure (caps, s_wide); + g_array_append_val (format_table, gst_mode_wide); + } + + next: + mode->Release (); + } while (gst_decklink2_result (hr)); + + return caps; +} + +GstCaps * +gst_decklink2_get_default_template_caps (void) +{ + static GstCaps *template_caps = NULL; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + template_caps = gst_caps_new_empty (); + + for (guint i = 1; i < G_N_ELEMENTS (all_modes); i++) { + GstCaps *other; + + other = gst_decklink2_mode_get_all_format_caps (&all_modes[i]); + template_caps = gst_caps_merge (template_caps, other); + } + + GST_MINI_OBJECT_FLAG_SET (template_caps, + GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED); + } + GST_DECKLINK2_CALL_ONCE_END; + + return gst_caps_ref (template_caps); +} + +GstCaps * +gst_decklink2_get_caps_from_mode (const GstDeckLink2DisplayMode * mode) +{ + GstCaps *caps = gst_caps_new_simple ("video/x-raw", + "width", G_TYPE_INT, mode->width, + "height", G_TYPE_INT, mode->height, + "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); + + if (mode->interlaced) { + if (mode->tff) { + gst_caps_set_simple (caps, + "field-order", G_TYPE_STRING, "top-field-first", NULL); + } else { + gst_caps_set_simple (caps, + "field-order", G_TYPE_STRING, "bottom-field-first", NULL); + } + } + + return caps; +} + +GType +gst_decklink2_audio_meta_api_get_type (void) +{ + static GType type = G_TYPE_INVALID; + static const gchar *tags[] = { NULL }; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + type = gst_meta_api_type_register ("GstDeckLink2AudioMetaAPI", tags); + } GST_DECKLINK2_CALL_ONCE_END; + + return type; +} + +static gboolean +gst_decklink2_audio_meta_transform (GstBuffer * dest, GstMeta * meta, + GstBuffer * buffer, GQuark type, gpointer data) +{ + GstDeckLink2AudioMeta *dmeta, *smeta; + + if (GST_META_TRANSFORM_IS_COPY (type)) { + smeta = (GstDeckLink2AudioMeta *) meta; + + dmeta = gst_buffer_add_decklink2_audio_meta (dest, smeta->sample); + if (!dmeta) + return FALSE; + } else { + /* return FALSE, if transform type is not supported */ + return FALSE; + } + return TRUE; +} + +static gboolean +gst_decklink2_audio_meta_init (GstMeta * meta, gpointer params, + GstBuffer * buffer) +{ + GstDeckLink2AudioMeta *dmeta = (GstDeckLink2AudioMeta *) meta; + + dmeta->sample = NULL; + + return TRUE; +} + +static void +gst_decklink2_audio_meta_free (GstMeta * meta, GstBuffer * buffer) +{ + GstDeckLink2AudioMeta *dmeta = (GstDeckLink2AudioMeta *) meta; + + if (dmeta->sample) + gst_sample_unref (dmeta->sample); +} + +const GstMetaInfo * +gst_decklink2_audio_meta_get_info (void) +{ + static GstMetaInfo *meta_info = NULL; + + GST_DECKLINK2_CALL_ONCE_BEGIN { + const GstMetaInfo *m = gst_meta_register (GST_DECKLINK2_AUDIO_META_API_TYPE, + "GstDeckLink2AudioMeta", + sizeof (GstDeckLink2AudioMeta), + gst_decklink2_audio_meta_init, + gst_decklink2_audio_meta_free, + gst_decklink2_audio_meta_transform); + meta_info = (GstMetaInfo *) m; + } + GST_DECKLINK2_CALL_ONCE_END; + + return meta_info; +} + +GstDeckLink2AudioMeta * +gst_buffer_add_decklink2_audio_meta (GstBuffer * buffer, + GstSample * audio_sample) +{ + GstDeckLink2AudioMeta *meta; + + g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (audio_sample != NULL, NULL); + + meta = (GstDeckLink2AudioMeta *) gst_buffer_add_meta (buffer, + GST_DECKLINK2_AUDIO_META_INFO, NULL); + + meta->sample = gst_sample_ref (audio_sample); + + return meta; +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2utils.h b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2utils.h new file mode 100644 index 0000000000..abd176d7db --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/gstdecklink2utils.h @@ -0,0 +1,336 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#pragma once + +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#ifndef INITGUID +#include +#endif /* INITGUID */ +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* G_OS_WIN32 */ + +#include + +#if defined(G_OS_WIN32) +#define dlbool_t BOOL +#define dlstring_t BSTR +#elif defined(__APPLE__) +#define dlbool_t bool +#define dlstring_t CFStringRef +#else +#define dlbool_t bool +#define dlstring_t const char* +#endif + +G_BEGIN_DECLS + +typedef struct _GstDeckLink2AudioMeta GstDeckLink2AudioMeta; +typedef struct _GstDeckLink2DisplayMode GstDeckLink2DisplayMode; + +typedef enum +{ + GST_DECKLINK2_API_LEVEL_UNKNOWN, + GST_DECKLINK2_API_LEVEL_10_11, + GST_DECKLINK2_API_LEVEL_11_4, + GST_DECKLINK2_API_LEVEL_11_5_1, + GST_DECKLINK2_API_LEVEL_LATEST, +} GstDeckLink2APILevel; + +/* defines custom display mode for wide screen */ +#define bmdModeNTSC_W ((BMDDisplayMode) 0x4E545343) /* 'NTSC' */ +#define bmdModeNTSC2398_W ((BMDDisplayMode) 0x4E543233) /* 'NT23' */ +#define bmdModePAL_W ((BMDDisplayMode) 0x50414C20) /* 'PAL ' */ +#define bmdModeNTSCp_W ((BMDDisplayMode) 0x4E545350) /* 'NTSP' */ +#define bmdModePALp_W ((BMDDisplayMode) 0x50414C50) /* 'PALP' */ + +#define GST_TYPE_DECKLINK2_MODE (gst_decklink2_mode_get_type ()) +GType gst_decklink2_mode_get_type (void); + +#define GST_TYPE_DECKLINK2_VIDEO_FORMAT (gst_decklink2_video_format_get_type ()) +GType gst_decklink2_video_format_get_type (void); + +#define bmdProfileDefault ((BMDProfileID) 0) +#define GST_TYPE_DECKLINK2_PROFILE_ID (gst_decklink2_profile_id_get_type ()) +GType gst_decklink2_profile_id_get_type (void); + +typedef enum +{ + GST_DECKLINK2_KEYER_MODE_OFF, + GST_DECKLINK2_KEYER_MODE_INTERNAL, + GST_DECKLINK2_KEYER_MODE_EXTERNAL +} GstDeckLink2KeyerMode; +#define GST_TYPE_DECKLINK2_KEYER_MODE (gst_decklink2_keyer_mode_get_type ()) +GType gst_decklink2_keyer_mode_get_type (void); + +typedef enum +{ + GST_DECKLINK2_MAPPING_FORMAT_DEFAULT, + GST_DECKLINK2_MAPPING_FORMAT_LEVEL_A, /* bmdDeckLinkConfigSMPTELevelAOutput = true */ + GST_DECKLINK2_MAPPING_FORMAT_LEVEL_B, /* bmdDeckLinkConfigSMPTELevelAOutput = false */ +} GstDeckLink2MappingFormat; +#define GST_TYPE_DECKLINK2_MAPPING_FORMAT (gst_decklink2_mapping_format_get_type ()) +GType gst_decklink2_mapping_format_get_type (void); + +#define GST_TYPE_DECKLINK2_TIMECODE_FORMAT (gst_decklink2_timecode_format_get_type ()) +GType gst_decklink2_timecode_format_get_type (void); + +#define GST_TYPE_DECKLINK2_VIDEO_CONNECTION (gst_decklink2_video_connection_get_type ()) +GType gst_decklink2_video_connection_get_type (void); + +#define bmdAudioConnectionUnspecified ((BMDAudioConnection) 0) +#define GST_TYPE_DECKLINK2_AUDIO_CONNECTION (gst_decklink2_audio_connection_get_type ()) +GType gst_decklink2_audio_connection_get_type (void); + +typedef enum +{ + GST_DECKLINK2_AUDIO_CHANNELS_DISABLED = -1, + GST_DECKLINK2_AUDIO_CHANNELS_MAX = 0, + GST_DECKLINK2_AUDIO_CHANNELS_2 = 2, + GST_DECKLINK2_AUDIO_CHANNELS_8 = 8, + GST_DECKLINK2_AUDIO_CHANNELS_16 = 16, +} GstDeckLink2AudioChannels; +#define GST_TYPE_DECKLINK2_AUDIO_CHANNELS (gst_decklink2_audio_channels_get_type ()) +GType gst_decklink2_audio_channels_get_type (void); + +struct _GstDeckLink2DisplayMode +{ + BMDDisplayMode mode; + gint width; + gint height; + gint fps_n; + gint fps_d; + gboolean interlaced; + gint par_n; + gint par_d; + gboolean tff; +}; + +gboolean gst_decklink2_init_once (void); + +void gst_decklink2_deinit (void); + +gboolean gst_decklink2_get_api_version (guint * major, + guint * minor, + guint * sub, + guint * extra); + +GstDeckLink2APILevel gst_decklink2_get_api_level (void); + +const gchar * gst_decklink2_api_level_to_string (GstDeckLink2APILevel level); + +GstCaps * gst_decklink2_get_default_template_caps (void); + +BMDDisplayMode gst_decklink2_get_real_display_mode (BMDDisplayMode mode); + +typedef gboolean (*GstDeckLink2DoesSupportVideoMode) (GstObject * object, + BMDDisplayMode mode, + BMDPixelFormat format); + +GstCaps * gst_decklink2_build_caps (GstObject * io_object, + IDeckLinkDisplayModeIterator * iter, + BMDDisplayMode requested_mode, + BMDPixelFormat format, + GstDeckLink2DoesSupportVideoMode func); + +GstCaps * gst_decklink2_build_template_caps (GstObject * io_object, + IDeckLinkDisplayModeIterator * iter, + GstDeckLink2DoesSupportVideoMode func, + GArray * format_table); + +GstCaps * gst_decklink2_get_caps_from_mode (const GstDeckLink2DisplayMode * mode); + + +GstVideoFormat gst_decklink2_video_format_from_pixel_format (BMDPixelFormat format); + +BMDPixelFormat gst_decklink2_pixel_format_from_video_format (GstVideoFormat format); + + +struct _GstDeckLink2AudioMeta +{ + GstMeta meta; + + GstSample *sample; +}; + +GType gst_decklink2_audio_meta_api_get_type (void); +#define GST_DECKLINK2_AUDIO_META_API_TYPE (gst_decklink2_audio_meta_api_get_type()) + +const GstMetaInfo *gst_decklink2_audio_meta_get_info (void); +#define GST_DECKLINK2_AUDIO_META_INFO (gst_decklink2_audio_meta_get_info()) + +#define gst_buffer_get_decklink2_audio_meta(b) \ + ((GstDeckLink2AudioMeta*)gst_buffer_get_meta((b),GST_DECKLINK2_AUDIO_META_API_TYPE)) + +GstDeckLink2AudioMeta * gst_buffer_add_decklink2_audio_meta (GstBuffer * buffer, + GstSample * audio_sample); + +#ifndef GST_DISABLE_GST_DEBUG +static inline gboolean +_gst_decklink2_result (HRESULT hr, GstDebugCategory * cat, const gchar * file, + const gchar * function, gint line) +{ + if (hr == S_OK) + return TRUE; + +#ifdef G_OS_WIN32 + { + gchar *error_text = g_win32_error_message ((guint) hr); + gst_debug_log (cat, GST_LEVEL_WARNING, file, function, line, NULL, + "DeckLink call failed: 0x%x (%s)", (guint) hr, + GST_STR_NULL (error_text)); + g_free (error_text); + } +#else + gst_debug_log (cat, GST_LEVEL_WARNING, file, function, line, NULL, + "DeckLink call failed: 0x%x", (guint) hr); +#endif /* G_OS_WIN32 */ + + return FALSE; +} + +#define gst_decklink2_result(hr) \ + _gst_decklink2_result (hr, GST_CAT_DEFAULT, __FILE__, GST_FUNCTION, __LINE__) +#else /* GST_DISABLE_GST_DEBUG */ +static inline gboolean +gst_decklink2_result (HRESULT hr) +{ + if (hr == S_OK) + return TRUE; + + return FALSE; +} +#endif /* GST_DISABLE_GST_DEBUG */ + +#define GST_DECKLINK2_PRINT_CHAR(c) \ + g_ascii_isprint(c) ? (c) : '.' + +#define GST_DECKLINK2_FOURCC_ARGS(fourcc) \ + GST_DECKLINK2_PRINT_CHAR(((fourcc) >> 24) & 0xff), \ + GST_DECKLINK2_PRINT_CHAR(((fourcc) >> 16) & 0xff), \ + GST_DECKLINK2_PRINT_CHAR(((fourcc) >> 8) & 0xff), \ + GST_DECKLINK2_PRINT_CHAR((fourcc) & 0xff) + +G_END_DECLS + +#ifdef __cplusplus +#include +#include +#include +#include + +#define GST_DECKLINK2_CALL_ONCE_BEGIN \ + static std::once_flag __once_flag; \ + std::call_once (__once_flag, [&]() + +#define GST_DECKLINK2_CALL_ONCE_END ) + +#define GST_DECKLINK2_CLEAR_COM(obj) G_STMT_START { \ + if (obj) { \ + (obj)->Release (); \ + (obj) = NULL; \ + } \ + } G_STMT_END + +#ifndef G_OS_WIN32 +#include +inline bool operator==(REFIID a, REFIID b) +{ + if (memcmp (&a, &b, sizeof (REFIID)) != 0) + return false; + + return true; +} +#endif + +#if defined(G_OS_WIN32) +const std::function DeleteString = SysFreeString; + +const std::function DlToStdString = [](dlstring_t dl_str) -> std::string +{ + int wlen = ::SysStringLen(dl_str); + int mblen = ::WideCharToMultiByte(CP_ACP, 0, (wchar_t*)dl_str, wlen, NULL, 0, NULL, NULL); + + std::string ret_str(mblen, '\0'); + mblen = ::WideCharToMultiByte(CP_ACP, 0, (wchar_t*)dl_str, wlen, &ret_str[0], mblen, NULL, NULL); + + return ret_str; +}; + +const std::function StdToDlString = [](std::string std_str) -> dlstring_t +{ + int wlen = ::MultiByteToWideChar(CP_ACP, 0, std_str.data(), (int)std_str.length(), NULL, 0); + + dlstring_t ret_str = ::SysAllocStringLen(NULL, wlen); + ::MultiByteToWideChar(CP_ACP, 0, std_str.data(), (int)std_str.length(), ret_str, wlen); + + return ret_str; +}; +#elif defined(__APPLE__) +const auto DeleteString = CFRelease; + +const auto DlToStdString = [](dlstring_t dl_str) -> std::string +{ + CFIndex len; + CFStringGetBytes(dl_str, CFRangeMake(0, CFStringGetLength(dl_str)), + kCFStringEncodingUTF8, 0, FALSE, NULL, 0, &len); + std::string ret_str (len, '\0'); + CFStringGetCString (dl_str, &ret_str[0], len, kCFStringEncodingUTF8); + + return ret_str; +}; + +const auto StdToDlString = [](std::string std_str) -> dlstring_t +{ + return CFStringCreateWithCString(kCFAllocatorMalloc, std_str.c_str(), kCFStringEncodingUTF8); +}; +#else +#include + +const std::function DeleteString = [](dlstring_t dl_str) +{ + free((void*)dl_str); +}; + +const std::function DlToStdString = [](dlstring_t dl_str) -> std::string +{ + return dl_str; +}; + +const std::function StdToDlString = [](std::string std_str) -> dlstring_t +{ + return strcpy((char*)malloc(std_str.length()+1), std_str.c_str()); +}; +#endif +#endif /* __cplusplus */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI.h new file mode 100644 index 0000000000..84f201c7ad --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI.h @@ -0,0 +1,1299 @@ +/* -LICENSE-START- + ** Copyright (c) 2022 Blackmagic Design + ** + ** Permission is hereby granted, free of charge, to any person or organization + ** obtaining a copy of the software and accompanying documentation (the + ** "Software") to use, reproduce, display, distribute, sub-license, execute, + ** and transmit the Software, and to prepare derivative works of the Software, + ** and to permit third-parties to whom the Software is furnished to do so, in + ** accordance with: + ** + ** (1) if the Software is obtained from Blackmagic Design, the End User License + ** Agreement for the Software Development Kit ("EULA") available at + ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + ** + ** (2) if the Software is obtained from any third party, such licensing terms + ** as notified by that third party, + ** + ** and all subject to the following: + ** + ** (3) the copyright notices in the Software and this entire statement, + ** including the above license grant, this restriction and the following + ** disclaimer, must be included in all copies of the Software, in whole or in + ** part, and all derivative works of the Software, unless such copies or + ** derivative works are solely in the form of machine-executable object code + ** generated by a source language processor. + ** + ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + ** DEALINGS IN THE SOFTWARE. + ** + ** A copy of the Software is available free of charge at + ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + ** + ** -LICENSE-END- + */ + + +#ifndef BMD_DECKLINKAPI_H +#define BMD_DECKLINKAPI_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +/* DeckLink API */ + +#include +#include "LinuxCOM.h" + +#include "DeckLinkAPITypes.h" +#include "DeckLinkAPIModes.h" +#include "DeckLinkAPIDiscovery.h" +#include "DeckLinkAPIConfiguration.h" +#include "DeckLinkAPIDeckControl.h" + +#define BLACKMAGIC_DECKLINK_API_MAGIC 1 + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkVideoOutputCallback = /* 20AA5225-1958-47CB-820B-80A8D521A6EE */ { 0x20,0xAA,0x52,0x25,0x19,0x58,0x47,0xCB,0x82,0x0B,0x80,0xA8,0xD5,0x21,0xA6,0xEE }; +BMD_CONST REFIID IID_IDeckLinkInputCallback = /* C6FCE4C9-C4E4-4047-82FB-5D238232A902 */ { 0xC6,0xFC,0xE4,0xC9,0xC4,0xE4,0x40,0x47,0x82,0xFB,0x5D,0x23,0x82,0x32,0xA9,0x02 }; +BMD_CONST REFIID IID_IDeckLinkEncoderInputCallback = /* ACF13E61-F4A0-4974-A6A7-59AFF6268B31 */ { 0xAC,0xF1,0x3E,0x61,0xF4,0xA0,0x49,0x74,0xA6,0xA7,0x59,0xAF,0xF6,0x26,0x8B,0x31 }; +BMD_CONST REFIID IID_IDeckLinkMemoryAllocator = /* B36EB6E7-9D29-4AA8-92EF-843B87A289E8 */ { 0xB3,0x6E,0xB6,0xE7,0x9D,0x29,0x4A,0xA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8 }; +BMD_CONST REFIID IID_IDeckLinkAudioOutputCallback = /* 403C681B-7F46-4A12-B993-2BB127084EE6 */ { 0x40,0x3C,0x68,0x1B,0x7F,0x46,0x4A,0x12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6 }; +BMD_CONST REFIID IID_IDeckLinkIterator = /* 50FB36CD-3063-4B73-BDBB-958087F2D8BA */ { 0x50,0xFB,0x36,0xCD,0x30,0x63,0x4B,0x73,0xBD,0xBB,0x95,0x80,0x87,0xF2,0xD8,0xBA }; +BMD_CONST REFIID IID_IDeckLinkAPIInformation = /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ { 0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4 }; +BMD_CONST REFIID IID_IDeckLinkOutput = /* BE2D9020-461E-442F-84B7-E949CB953B9D */ { 0xBE,0x2D,0x90,0x20,0x46,0x1E,0x44,0x2F,0x84,0xB7,0xE9,0x49,0xCB,0x95,0x3B,0x9D }; +BMD_CONST REFIID IID_IDeckLinkInput = /* C21CDB6E-F414-46E4-A636-80A566E0ED37 */ { 0xC2,0x1C,0xDB,0x6E,0xF4,0x14,0x46,0xE4,0xA6,0x36,0x80,0xA5,0x66,0xE0,0xED,0x37 }; +BMD_CONST REFIID IID_IDeckLinkHDMIInputEDID = /* ABBBACBC-45BC-4665-9D92-ACE6E5A97902 */ { 0xAB,0xBB,0xAC,0xBC,0x45,0xBC,0x46,0x65,0x9D,0x92,0xAC,0xE6,0xE5,0xA9,0x79,0x02 }; +BMD_CONST REFIID IID_IDeckLinkEncoderInput = /* F222551D-13DF-4FD8-B587-9D4F19EC12C9 */ { 0xF2,0x22,0x55,0x1D,0x13,0xDF,0x4F,0xD8,0xB5,0x87,0x9D,0x4F,0x19,0xEC,0x12,0xC9 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrame = /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ { 0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17 }; +BMD_CONST REFIID IID_IDeckLinkMutableVideoFrame = /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ { 0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrame3DExtensions = /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ { 0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions = /* E232A5B7-4DB4-44C9-9152-F47C12E5F051 */ { 0xE2,0x32,0xA5,0xB7,0x4D,0xB4,0x44,0xC9,0x91,0x52,0xF4,0x7C,0x12,0xE5,0xF0,0x51 }; +BMD_CONST REFIID IID_IDeckLinkVideoInputFrame = /* 05CFE374-537C-4094-9A57-680525118F44 */ { 0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44 }; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacket = /* CC5BBF7E-029C-4D3B-9158-6000EF5E3670 */ { 0xCC,0x5B,0xBF,0x7E,0x02,0x9C,0x4D,0x3B,0x91,0x58,0x60,0x00,0xEF,0x5E,0x36,0x70 }; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacketIterator = /* 3FC8994B-88FB-4C17-968F-9AAB69D964A7 */ { 0x3F,0xC8,0x99,0x4B,0x88,0xFB,0x4C,0x17,0x96,0x8F,0x9A,0xAB,0x69,0xD9,0x64,0xA7 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillaryPackets = /* 6C186C0F-459E-41D8-AEE2-4812D81AEE68 */ { 0x6C,0x18,0x6C,0x0F,0x45,0x9E,0x41,0xD8,0xAE,0xE2,0x48,0x12,0xD8,0x1A,0xEE,0x68 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillary = /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ { 0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04 }; +BMD_CONST REFIID IID_IDeckLinkEncoderPacket = /* B693F36C-316E-4AF1-B6C2-F389A4BCA620 */ { 0xB6,0x93,0xF3,0x6C,0x31,0x6E,0x4A,0xF1,0xB6,0xC2,0xF3,0x89,0xA4,0xBC,0xA6,0x20 }; +BMD_CONST REFIID IID_IDeckLinkEncoderVideoPacket = /* 4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0 */ { 0x4E,0x7F,0xD9,0x44,0xE8,0xC7,0x4E,0xAC,0xB8,0xC0,0x7B,0x77,0xF8,0x0F,0x5A,0xE0 }; +BMD_CONST REFIID IID_IDeckLinkEncoderAudioPacket = /* 49E8EDC8-693B-4E14-8EF6-12C658F5A07A */ { 0x49,0xE8,0xED,0xC8,0x69,0x3B,0x4E,0x14,0x8E,0xF6,0x12,0xC6,0x58,0xF5,0xA0,0x7A }; +BMD_CONST REFIID IID_IDeckLinkH265NALPacket = /* 639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7 */ { 0x63,0x9C,0x8E,0x0B,0x68,0xD5,0x4B,0xDE,0xA6,0xD4,0x95,0xF3,0xAE,0xAF,0xF2,0xE7 }; +BMD_CONST REFIID IID_IDeckLinkAudioInputPacket = /* E43D5870-2894-11DE-8C30-0800200C9A66 */ { 0xE4,0x3D,0x58,0x70,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66 }; +BMD_CONST REFIID IID_IDeckLinkScreenPreviewCallback = /* B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438 */ { 0xB1,0xD3,0xF4,0x9A,0x85,0xFE,0x4C,0x5D,0x95,0xC8,0x0B,0x5D,0x5D,0xCC,0xD4,0x38 }; +BMD_CONST REFIID IID_IDeckLinkGLScreenPreviewHelper = /* 504E2209-CAC7-4C1A-9FB4-C5BB6274D22F */ { 0x50,0x4E,0x22,0x09,0xCA,0xC7,0x4C,0x1A,0x9F,0xB4,0xC5,0xBB,0x62,0x74,0xD2,0x2F }; +BMD_CONST REFIID IID_IDeckLinkNotificationCallback = /* B002A1EC-070D-4288-8289-BD5D36E5FF0D */ { 0xB0,0x02,0xA1,0xEC,0x07,0x0D,0x42,0x88,0x82,0x89,0xBD,0x5D,0x36,0xE5,0xFF,0x0D }; +BMD_CONST REFIID IID_IDeckLinkNotification = /* B85DF4C8-BDF5-47C1-8064-28162EBDD4EB */ { 0xB8,0x5D,0xF4,0xC8,0xBD,0xF5,0x47,0xC1,0x80,0x64,0x28,0x16,0x2E,0xBD,0xD4,0xEB }; +BMD_CONST REFIID IID_IDeckLinkProfileAttributes = /* 17D4BF8E-4911-473A-80A0-731CF6FF345B */ { 0x17,0xD4,0xBF,0x8E,0x49,0x11,0x47,0x3A,0x80,0xA0,0x73,0x1C,0xF6,0xFF,0x34,0x5B }; +BMD_CONST REFIID IID_IDeckLinkProfileIterator = /* 29E5A8C0-8BE4-46EB-93AC-31DAAB5B7BF2 */ { 0x29,0xE5,0xA8,0xC0,0x8B,0xE4,0x46,0xEB,0x93,0xAC,0x31,0xDA,0xAB,0x5B,0x7B,0xF2 }; +BMD_CONST REFIID IID_IDeckLinkProfile = /* 16093466-674A-432B-9DA0-1AC2C5A8241C */ { 0x16,0x09,0x34,0x66,0x67,0x4A,0x43,0x2B,0x9D,0xA0,0x1A,0xC2,0xC5,0xA8,0x24,0x1C }; +BMD_CONST REFIID IID_IDeckLinkProfileCallback = /* A4F9341E-97AA-4E04-8935-15F809898CEA */ { 0xA4,0xF9,0x34,0x1E,0x97,0xAA,0x4E,0x04,0x89,0x35,0x15,0xF8,0x09,0x89,0x8C,0xEA }; +BMD_CONST REFIID IID_IDeckLinkProfileManager = /* 30D41429-3998-4B6D-84F8-78C94A797C6E */ { 0x30,0xD4,0x14,0x29,0x39,0x98,0x4B,0x6D,0x84,0xF8,0x78,0xC9,0x4A,0x79,0x7C,0x6E }; +BMD_CONST REFIID IID_IDeckLinkStatus = /* 5F558200-4028-49BC-BEAC-DB3FA4A96E46 */ { 0x5F,0x55,0x82,0x00,0x40,0x28,0x49,0xBC,0xBE,0xAC,0xDB,0x3F,0xA4,0xA9,0x6E,0x46 }; +BMD_CONST REFIID IID_IDeckLinkKeyer = /* 89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3 */ { 0x89,0xAF,0xCA,0xF5,0x65,0xF8,0x42,0x1E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3 }; +BMD_CONST REFIID IID_IDeckLinkVideoConversion = /* 3BBCB8A2-DA2C-42D9-B5D8-88083644E99A */ { 0x3B,0xBC,0xB8,0xA2,0xDA,0x2C,0x42,0xD9,0xB5,0xD8,0x88,0x08,0x36,0x44,0xE9,0x9A }; +BMD_CONST REFIID IID_IDeckLinkDeviceNotificationCallback = /* 4997053B-0ADF-4CC8-AC70-7A50C4BE728F */ { 0x49,0x97,0x05,0x3B,0x0A,0xDF,0x4C,0xC8,0xAC,0x70,0x7A,0x50,0xC4,0xBE,0x72,0x8F }; +BMD_CONST REFIID IID_IDeckLinkDiscovery = /* CDBF631C-BC76-45FA-B44D-C55059BC6101 */ { 0xCD,0xBF,0x63,0x1C,0xBC,0x76,0x45,0xFA,0xB4,0x4D,0xC5,0x50,0x59,0xBC,0x61,0x01 }; + +/* Enum BMDVideoOutputFlags - Flags to control the output of ancillary data along with video. */ + +typedef uint32_t BMDVideoOutputFlags; +enum _BMDVideoOutputFlags { + bmdVideoOutputFlagDefault = 0, + bmdVideoOutputVANC = 1 << 0, + bmdVideoOutputVITC = 1 << 1, + bmdVideoOutputRP188 = 1 << 2, + bmdVideoOutputDualStream3D = 1 << 4, + bmdVideoOutputSynchronizeToPlaybackGroup = 1 << 6 +}; + +/* Enum BMDSupportedVideoModeFlags - Flags to describe supported video modes */ + +typedef uint32_t BMDSupportedVideoModeFlags; +enum _BMDSupportedVideoModeFlags { + bmdSupportedVideoModeDefault = 0, + bmdSupportedVideoModeKeying = 1 << 0, + bmdSupportedVideoModeDualStream3D = 1 << 1, + bmdSupportedVideoModeSDISingleLink = 1 << 2, + bmdSupportedVideoModeSDIDualLink = 1 << 3, + bmdSupportedVideoModeSDIQuadLink = 1 << 4, + bmdSupportedVideoModeInAnyProfile = 1 << 5 +}; + +/* Enum BMDPacketType - Type of packet */ + +typedef uint32_t BMDPacketType; +enum _BMDPacketType { + bmdPacketTypeStreamInterruptedMarker = /* 'sint' */ 0x73696E74, // A packet of this type marks the time when a video stream was interrupted, for example by a disconnected cable + bmdPacketTypeStreamData = /* 'sdat' */ 0x73646174 // Regular stream data +}; + +/* Enum BMDFrameFlags - Frame flags */ + +typedef uint32_t BMDFrameFlags; +enum _BMDFrameFlags { + bmdFrameFlagDefault = 0, + bmdFrameFlagFlipVertical = 1 << 0, + bmdFrameContainsHDRMetadata = 1 << 1, + + /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */ + + bmdFrameCapturedAsPsF = 1 << 30, + bmdFrameHasNoInputSource = 1 << 31 +}; + +/* Enum BMDVideoInputFlags - Flags applicable to video input */ + +typedef uint32_t BMDVideoInputFlags; +enum _BMDVideoInputFlags { + bmdVideoInputFlagDefault = 0, + bmdVideoInputEnableFormatDetection = 1 << 0, + bmdVideoInputDualStream3D = 1 << 1, + bmdVideoInputSynchronizeToCaptureGroup = 1 << 2 +}; + +/* Enum BMDVideoInputFormatChangedEvents - Bitmask passed to the VideoInputFormatChanged notification to identify the properties of the input signal that have changed */ + +typedef uint32_t BMDVideoInputFormatChangedEvents; +enum _BMDVideoInputFormatChangedEvents { + bmdVideoInputDisplayModeChanged = 1 << 0, + bmdVideoInputFieldDominanceChanged = 1 << 1, + bmdVideoInputColorspaceChanged = 1 << 2 +}; + +/* Enum BMDDetectedVideoInputFormatFlags - Flags passed to the VideoInputFormatChanged notification to describe the detected video input signal */ + +typedef uint32_t BMDDetectedVideoInputFormatFlags; +enum _BMDDetectedVideoInputFormatFlags { + bmdDetectedVideoInputYCbCr422 = 1 << 0, + bmdDetectedVideoInputRGB444 = 1 << 1, + bmdDetectedVideoInputDualStream3D = 1 << 2, + bmdDetectedVideoInput12BitDepth = 1 << 3, + bmdDetectedVideoInput10BitDepth = 1 << 4, + bmdDetectedVideoInput8BitDepth = 1 << 5 +}; + +/* Enum BMDDeckLinkCapturePassthroughMode - Enumerates whether the video output is electrically connected to the video input or if the clean switching mode is enabled */ + +typedef uint32_t BMDDeckLinkCapturePassthroughMode; +enum _BMDDeckLinkCapturePassthroughMode { + bmdDeckLinkCapturePassthroughModeDisabled = /* 'pdis' */ 0x70646973, + bmdDeckLinkCapturePassthroughModeDirect = /* 'pdir' */ 0x70646972, + bmdDeckLinkCapturePassthroughModeCleanSwitch = /* 'pcln' */ 0x70636C6E +}; + +/* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */ + +typedef uint32_t BMDOutputFrameCompletionResult; +enum _BMDOutputFrameCompletionResult { + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed +}; + +/* Enum BMDReferenceStatus - GenLock input status */ + +typedef uint32_t BMDReferenceStatus; +enum _BMDReferenceStatus { + bmdReferenceUnlocked = 0, + bmdReferenceNotSupportedByHardware = 1 << 0, + bmdReferenceLocked = 1 << 1 +}; + +/* Enum BMDAudioFormat - Audio Format */ + +typedef uint32_t BMDAudioFormat; +enum _BMDAudioFormat { + bmdAudioFormatPCM = /* 'lpcm' */ 0x6C70636D // Linear signed PCM samples +}; + +/* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */ + +typedef uint32_t BMDAudioSampleRate; +enum _BMDAudioSampleRate { + bmdAudioSampleRate48kHz = 48000 +}; + +/* Enum BMDAudioSampleType - Audio sample sizes supported for output/input */ + +typedef uint32_t BMDAudioSampleType; +enum _BMDAudioSampleType { + bmdAudioSampleType16bitInteger = 16, + bmdAudioSampleType32bitInteger = 32 +}; + +/* Enum BMDAudioOutputStreamType - Audio output stream type */ + +typedef uint32_t BMDAudioOutputStreamType; +enum _BMDAudioOutputStreamType { + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped +}; + +/* Enum BMDAncillaryPacketFormat - Ancillary packet format */ + +typedef uint32_t BMDAncillaryPacketFormat; +enum _BMDAncillaryPacketFormat { + bmdAncillaryPacketFormatUInt8 = /* 'ui08' */ 0x75693038, + bmdAncillaryPacketFormatUInt16 = /* 'ui16' */ 0x75693136, + bmdAncillaryPacketFormatYCbCr10 = /* 'v210' */ 0x76323130 +}; + +/* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ + +typedef uint32_t BMDTimecodeFormat; +enum _BMDTimecodeFormat { + bmdTimecodeRP188VITC1 = /* 'rpv1' */ 0x72707631, // RP188 timecode where DBB1 equals VITC1 (line 9) + bmdTimecodeRP188VITC2 = /* 'rp12' */ 0x72703132, // RP188 timecode where DBB1 equals VITC2 (line 9 for progressive or line 571 for interlaced/PsF) + bmdTimecodeRP188LTC = /* 'rplt' */ 0x72706C74, // RP188 timecode where DBB1 equals LTC (line 10) + bmdTimecodeRP188HighFrameRate = /* 'rphr' */ 0x72706872, // RP188 timecode where DBB1 is an HFRTC (SMPTE ST 12-3), the only timecode allowing the frame value to go above 30 + bmdTimecodeRP188Any = /* 'rp18' */ 0x72703138, // Convenience for capture, returning the first valid timecode in {HFRTC (if supported), VITC1, VITC2, LTC } + bmdTimecodeVITC = /* 'vitc' */ 0x76697463, + bmdTimecodeVITCField2 = /* 'vit2' */ 0x76697432, + bmdTimecodeSerial = /* 'seri' */ 0x73657269 +}; + +/* Enum BMDAnalogVideoFlags - Analog video display flags */ + +typedef uint32_t BMDAnalogVideoFlags; +enum _BMDAnalogVideoFlags { + bmdAnalogVideoFlagCompositeSetup75 = 1 << 0, + bmdAnalogVideoFlagComponentBetacamLevels = 1 << 1 +}; + +/* Enum BMDAudioOutputAnalogAESSwitch - Audio output Analog/AESEBU switch */ + +typedef uint32_t BMDAudioOutputAnalogAESSwitch; +enum _BMDAudioOutputAnalogAESSwitch { + bmdAudioOutputSwitchAESEBU = /* 'aes ' */ 0x61657320, + bmdAudioOutputSwitchAnalog = /* 'anlg' */ 0x616E6C67 +}; + +/* Enum BMDVideoOutputConversionMode - Video/audio conversion mode */ + +typedef uint32_t BMDVideoOutputConversionMode; +enum _BMDVideoOutputConversionMode { + bmdNoVideoOutputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoOutputLetterboxDownconversion = /* 'ltbx' */ 0x6C746278, + bmdVideoOutputAnamorphicDownconversion = /* 'amph' */ 0x616D7068, + bmdVideoOutputHD720toHD1080Conversion = /* '720c' */ 0x37323063, + bmdVideoOutputHardwareLetterboxDownconversion = /* 'HWlb' */ 0x48576C62, + bmdVideoOutputHardwareAnamorphicDownconversion = /* 'HWam' */ 0x4857616D, + bmdVideoOutputHardwareCenterCutDownconversion = /* 'HWcc' */ 0x48576363, + bmdVideoOutputHardware720p1080pCrossconversion = /* 'xcap' */ 0x78636170, + bmdVideoOutputHardwareAnamorphic720pUpconversion = /* 'ua7p' */ 0x75613770, + bmdVideoOutputHardwareAnamorphic1080iUpconversion = /* 'ua1i' */ 0x75613169, + bmdVideoOutputHardwareAnamorphic149To720pUpconversion = /* 'u47p' */ 0x75343770, + bmdVideoOutputHardwareAnamorphic149To1080iUpconversion = /* 'u41i' */ 0x75343169, + bmdVideoOutputHardwarePillarbox720pUpconversion = /* 'up7p' */ 0x75703770, + bmdVideoOutputHardwarePillarbox1080iUpconversion = /* 'up1i' */ 0x75703169 +}; + +/* Enum BMDVideoInputConversionMode - Video input conversion mode */ + +typedef uint32_t BMDVideoInputConversionMode; +enum _BMDVideoInputConversionMode { + bmdNoVideoInputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoInputLetterboxDownconversionFromHD1080 = /* '10lb' */ 0x31306C62, + bmdVideoInputAnamorphicDownconversionFromHD1080 = /* '10am' */ 0x3130616D, + bmdVideoInputLetterboxDownconversionFromHD720 = /* '72lb' */ 0x37326C62, + bmdVideoInputAnamorphicDownconversionFromHD720 = /* '72am' */ 0x3732616D, + bmdVideoInputLetterboxUpconversion = /* 'lbup' */ 0x6C627570, + bmdVideoInputAnamorphicUpconversion = /* 'amup' */ 0x616D7570 +}; + +/* Enum BMDVideo3DPackingFormat - Video 3D packing format */ + +typedef uint32_t BMDVideo3DPackingFormat; +enum _BMDVideo3DPackingFormat { + bmdVideo3DPackingSidebySideHalf = /* 'sbsh' */ 0x73627368, + bmdVideo3DPackingLinebyLine = /* 'lbyl' */ 0x6C62796C, + bmdVideo3DPackingTopAndBottom = /* 'tabo' */ 0x7461626F, + bmdVideo3DPackingFramePacking = /* 'frpk' */ 0x6672706B, + bmdVideo3DPackingLeftOnly = /* 'left' */ 0x6C656674, + bmdVideo3DPackingRightOnly = /* 'righ' */ 0x72696768 +}; + +/* Enum BMDIdleVideoOutputOperation - Video output operation when not playing video */ + +typedef uint32_t BMDIdleVideoOutputOperation; +enum _BMDIdleVideoOutputOperation { + bmdIdleVideoOutputBlack = /* 'blac' */ 0x626C6163, + bmdIdleVideoOutputLastFrame = /* 'lafa' */ 0x6C616661 +}; + +/* Enum BMDVideoEncoderFrameCodingMode - Video frame coding mode */ + +typedef uint32_t BMDVideoEncoderFrameCodingMode; +enum _BMDVideoEncoderFrameCodingMode { + bmdVideoEncoderFrameCodingModeInter = /* 'inte' */ 0x696E7465, + bmdVideoEncoderFrameCodingModeIntra = /* 'intr' */ 0x696E7472 +}; + +/* Enum BMDDNxHRLevel - DNxHR Levels */ + +typedef uint32_t BMDDNxHRLevel; +enum _BMDDNxHRLevel { + bmdDNxHRLevelSQ = /* 'dnsq' */ 0x646E7371, + bmdDNxHRLevelLB = /* 'dnlb' */ 0x646E6C62, + bmdDNxHRLevelHQ = /* 'dnhq' */ 0x646E6871, + bmdDNxHRLevelHQX = /* 'dhqx' */ 0x64687178, + bmdDNxHRLevel444 = /* 'd444' */ 0x64343434 +}; + +/* Enum BMDLinkConfiguration - Video link configuration */ + +typedef uint32_t BMDLinkConfiguration; +enum _BMDLinkConfiguration { + bmdLinkConfigurationSingleLink = /* 'lcsl' */ 0x6C63736C, + bmdLinkConfigurationDualLink = /* 'lcdl' */ 0x6C63646C, + bmdLinkConfigurationQuadLink = /* 'lcql' */ 0x6C63716C +}; + +/* Enum BMDDeviceInterface - Device interface type */ + +typedef uint32_t BMDDeviceInterface; +enum _BMDDeviceInterface { + bmdDeviceInterfacePCI = /* 'pci ' */ 0x70636920, + bmdDeviceInterfaceUSB = /* 'usb ' */ 0x75736220, + bmdDeviceInterfaceThunderbolt = /* 'thun' */ 0x7468756E +}; + +/* Enum BMDColorspace - Colorspace */ + +typedef uint32_t BMDColorspace; +enum _BMDColorspace { + bmdColorspaceRec601 = /* 'r601' */ 0x72363031, + bmdColorspaceRec709 = /* 'r709' */ 0x72373039, + bmdColorspaceRec2020 = /* '2020' */ 0x32303230 +}; + +/* Enum BMDDynamicRange - SDR or HDR */ + +typedef uint32_t BMDDynamicRange; +enum _BMDDynamicRange { + bmdDynamicRangeSDR = 0, // Standard Dynamic Range in accordance with SMPTE ST 2036-1 + bmdDynamicRangeHDRStaticPQ = 1 << 29, // High Dynamic Range PQ in accordance with SMPTE ST 2084 + bmdDynamicRangeHDRStaticHLG = 1 << 30 // High Dynamic Range HLG in accordance with ITU-R BT.2100-0 +}; + +/* Enum BMDDeckLinkHDMIInputEDIDID - DeckLink HDMI Input EDID ID */ + +typedef uint32_t BMDDeckLinkHDMIInputEDIDID; +enum _BMDDeckLinkHDMIInputEDIDID { + + /* Integers */ + + bmdDeckLinkHDMIInputEDIDDynamicRange = /* 'HIDy' */ 0x48494479 // Parameter is of type BMDDynamicRange. Default is (bmdDynamicRangeSDR|bmdDynamicRangeHDRStaticPQ) +}; + +/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ + +typedef uint32_t BMDDeckLinkFrameMetadataID; +enum _BMDDeckLinkFrameMetadataID { + + /* Colorspace Metadata - Integers */ + + bmdDeckLinkFrameMetadataColorspace = /* 'cspc' */ 0x63737063, // Colorspace of video frame (see BMDColorspace) + + /* HDR Metadata - Integers */ + + bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc = /* 'eotf' */ 0x656F7466, // EOTF in range 0-7 as per CEA 861.3 + + /* HDR Metadata - Floats */ + + bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX = /* 'hdrx' */ 0x68647278, // Red display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY = /* 'hdry' */ 0x68647279, // Red display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX = /* 'hdgx' */ 0x68646778, // Green display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenY = /* 'hdgy' */ 0x68646779, // Green display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueX = /* 'hdbx' */ 0x68646278, // Blue display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueY = /* 'hdby' */ 0x68646279, // Blue display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRWhitePointX = /* 'hdwx' */ 0x68647778, // White point in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRWhitePointY = /* 'hdwy' */ 0x68647779, // White point in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance = /* 'hdml' */ 0x68646D6C, // Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance = /* 'hmil' */ 0x686D696C, // Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel = /* 'mcll' */ 0x6D636C6C, // Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 +}; + +/* Enum BMDProfileID - Identifies a profile */ + +typedef uint32_t BMDProfileID; +enum _BMDProfileID { + bmdProfileOneSubDeviceFullDuplex = /* '1dfd' */ 0x31646664, + bmdProfileOneSubDeviceHalfDuplex = /* '1dhd' */ 0x31646864, + bmdProfileTwoSubDevicesFullDuplex = /* '2dfd' */ 0x32646664, + bmdProfileTwoSubDevicesHalfDuplex = /* '2dhd' */ 0x32646864, + bmdProfileFourSubDevicesHalfDuplex = /* '4dhd' */ 0x34646864 +}; + +/* Enum BMDHDMITimecodePacking - Packing form of timecode on HDMI */ + +typedef uint32_t BMDHDMITimecodePacking; +enum _BMDHDMITimecodePacking { + bmdHDMITimecodePackingIEEEOUI000085 = 0x00008500, + bmdHDMITimecodePackingIEEEOUI080046 = 0x08004601, + bmdHDMITimecodePackingIEEEOUI5CF9F0 = 0x5CF9F003 +}; + +/* Enum BMDInternalKeyingAncillaryDataSource - Source for VANC and timecode data when performing internal keying */ + +typedef uint32_t BMDInternalKeyingAncillaryDataSource; +enum _BMDInternalKeyingAncillaryDataSource { + bmdInternalKeyingUsesAncillaryDataFromInputSignal = /* 'ikai' */ 0x696B6169, + bmdInternalKeyingUsesAncillaryDataFromKeyFrame = /* 'ikak' */ 0x696B616B +}; + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkAttributeID; +enum _BMDDeckLinkAttributeID { + + /* Flags */ + + BMDDeckLinkSupportsInternalKeying = /* 'keyi' */ 0x6B657969, + BMDDeckLinkSupportsExternalKeying = /* 'keye' */ 0x6B657965, + BMDDeckLinkSupportsInputFormatDetection = /* 'infd' */ 0x696E6664, + BMDDeckLinkHasReferenceInput = /* 'hrin' */ 0x6872696E, + BMDDeckLinkHasSerialPort = /* 'hspt' */ 0x68737074, + BMDDeckLinkHasAnalogVideoOutputGain = /* 'avog' */ 0x61766F67, + BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain = /* 'ovog' */ 0x6F766F67, + BMDDeckLinkHasVideoInputAntiAliasingFilter = /* 'aafl' */ 0x6161666C, + BMDDeckLinkHasBypass = /* 'byps' */ 0x62797073, + BMDDeckLinkSupportsClockTimingAdjustment = /* 'ctad' */ 0x63746164, + BMDDeckLinkSupportsFullFrameReferenceInputTimingOffset = /* 'frin' */ 0x6672696E, + BMDDeckLinkSupportsSMPTELevelAOutput = /* 'lvla' */ 0x6C766C61, + BMDDeckLinkSupportsAutoSwitchingPPsFOnInput = /* 'apsf' */ 0x61707366, + BMDDeckLinkSupportsDualLinkSDI = /* 'sdls' */ 0x73646C73, + BMDDeckLinkSupportsQuadLinkSDI = /* 'sqls' */ 0x73716C73, + BMDDeckLinkSupportsIdleOutput = /* 'idou' */ 0x69646F75, + BMDDeckLinkVANCRequires10BitYUVVideoFrames = /* 'vioY' */ 0x76696F59, // Legacy product requires v210 active picture for IDeckLinkVideoFrameAncillaryPackets or 10-bit VANC + BMDDeckLinkHasLTCTimecodeInput = /* 'hltc' */ 0x686C7463, + BMDDeckLinkSupportsHDRMetadata = /* 'hdrm' */ 0x6864726D, + BMDDeckLinkSupportsColorspaceMetadata = /* 'cmet' */ 0x636D6574, + BMDDeckLinkSupportsHDMITimecode = /* 'htim' */ 0x6874696D, + BMDDeckLinkSupportsHighFrameRateTimecode = /* 'HFRT' */ 0x48465254, + BMDDeckLinkSupportsSynchronizeToCaptureGroup = /* 'stcg' */ 0x73746367, + BMDDeckLinkSupportsSynchronizeToPlaybackGroup = /* 'stpg' */ 0x73747067, + + /* Integers */ + + BMDDeckLinkMaximumAudioChannels = /* 'mach' */ 0x6D616368, + BMDDeckLinkMaximumAnalogAudioInputChannels = /* 'iach' */ 0x69616368, + BMDDeckLinkMaximumAnalogAudioOutputChannels = /* 'aach' */ 0x61616368, + BMDDeckLinkNumberOfSubDevices = /* 'nsbd' */ 0x6E736264, + BMDDeckLinkSubDeviceIndex = /* 'subi' */ 0x73756269, + BMDDeckLinkPersistentID = /* 'peid' */ 0x70656964, + BMDDeckLinkDeviceGroupID = /* 'dgid' */ 0x64676964, + BMDDeckLinkTopologicalID = /* 'toid' */ 0x746F6964, + BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkVideoIOSupport = /* 'vios' */ 0x76696F73, // Returns a BMDVideoIOSupport bit field + BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, // Returns a BMDDeckControlConnection bit field + BMDDeckLinkDeviceInterface = /* 'dbus' */ 0x64627573, // Returns a BMDDeviceInterface + BMDDeckLinkAudioInputRCAChannelCount = /* 'airc' */ 0x61697263, + BMDDeckLinkAudioInputXLRChannelCount = /* 'aixc' */ 0x61697863, + BMDDeckLinkAudioOutputRCAChannelCount = /* 'aorc' */ 0x616F7263, + BMDDeckLinkAudioOutputXLRChannelCount = /* 'aoxc' */ 0x616F7863, + BMDDeckLinkProfileID = /* 'prid' */ 0x70726964, // Returns a BMDProfileID + BMDDeckLinkDuplex = /* 'dupx' */ 0x64757078, + BMDDeckLinkMinimumPrerollFrames = /* 'mprf' */ 0x6D707266, + BMDDeckLinkSupportedDynamicRange = /* 'sudr' */ 0x73756472, + + /* Floats */ + + BMDDeckLinkVideoInputGainMinimum = /* 'vigm' */ 0x7669676D, + BMDDeckLinkVideoInputGainMaximum = /* 'vigx' */ 0x76696778, + BMDDeckLinkVideoOutputGainMinimum = /* 'vogm' */ 0x766F676D, + BMDDeckLinkVideoOutputGainMaximum = /* 'vogx' */ 0x766F6778, + BMDDeckLinkMicrophoneInputGainMinimum = /* 'migm' */ 0x6D69676D, + BMDDeckLinkMicrophoneInputGainMaximum = /* 'migx' */ 0x6D696778, + + /* Strings */ + + BMDDeckLinkSerialPortDeviceName = /* 'slpn' */ 0x736C706E, + BMDDeckLinkVendorName = /* 'vndr' */ 0x766E6472, + BMDDeckLinkDisplayName = /* 'dspn' */ 0x6473706E, + BMDDeckLinkModelName = /* 'mdln' */ 0x6D646C6E, + BMDDeckLinkDeviceHandle = /* 'devh' */ 0x64657668 +}; + +/* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */ + +typedef uint32_t BMDDeckLinkAPIInformationID; +enum _BMDDeckLinkAPIInformationID { + + /* Integer or String */ + + BMDDeckLinkAPIVersion = /* 'vers' */ 0x76657273 +}; + +/* Enum BMDDeckLinkStatusID - DeckLink Status ID */ + +typedef uint32_t BMDDeckLinkStatusID; +enum _BMDDeckLinkStatusID { + + /* Integers */ + + bmdDeckLinkStatusDetectedVideoInputMode = /* 'dvim' */ 0x6476696D, + bmdDeckLinkStatusDetectedVideoInputFormatFlags = /* 'dvff' */ 0x64766666, + bmdDeckLinkStatusDetectedVideoInputFieldDominance = /* 'dvfd' */ 0x64766664, + bmdDeckLinkStatusDetectedVideoInputColorspace = /* 'dscl' */ 0x6473636C, + bmdDeckLinkStatusDetectedVideoInputDynamicRange = /* 'dsdr' */ 0x64736472, + bmdDeckLinkStatusDetectedSDILinkConfiguration = /* 'dslc' */ 0x64736C63, + bmdDeckLinkStatusCurrentVideoInputMode = /* 'cvim' */ 0x6376696D, + bmdDeckLinkStatusCurrentVideoInputPixelFormat = /* 'cvip' */ 0x63766970, + bmdDeckLinkStatusCurrentVideoInputFlags = /* 'cvif' */ 0x63766966, + bmdDeckLinkStatusCurrentVideoOutputMode = /* 'cvom' */ 0x63766F6D, + bmdDeckLinkStatusCurrentVideoOutputFlags = /* 'cvof' */ 0x63766F66, + bmdDeckLinkStatusPCIExpressLinkWidth = /* 'pwid' */ 0x70776964, + bmdDeckLinkStatusPCIExpressLinkSpeed = /* 'plnk' */ 0x706C6E6B, + bmdDeckLinkStatusLastVideoOutputPixelFormat = /* 'opix' */ 0x6F706978, + bmdDeckLinkStatusReferenceSignalMode = /* 'refm' */ 0x7265666D, + bmdDeckLinkStatusReferenceSignalFlags = /* 'reff' */ 0x72656666, + bmdDeckLinkStatusBusy = /* 'busy' */ 0x62757379, + bmdDeckLinkStatusInterchangeablePanelType = /* 'icpt' */ 0x69637074, + bmdDeckLinkStatusDeviceTemperature = /* 'dtmp' */ 0x64746D70, + + /* Flags */ + + bmdDeckLinkStatusVideoInputSignalLocked = /* 'visl' */ 0x7669736C, + bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C, + + /* Bytes */ + + bmdDeckLinkStatusReceivedEDID = /* 'edid' */ 0x65646964 +}; + +/* Enum BMDDeckLinkVideoStatusFlags - */ + +typedef uint32_t BMDDeckLinkVideoStatusFlags; +enum _BMDDeckLinkVideoStatusFlags { + bmdDeckLinkVideoStatusPsF = 1 << 0, + bmdDeckLinkVideoStatusDualStream3D = 1 << 1 +}; + +/* Enum BMDDuplexMode - Duplex of the device */ + +typedef uint32_t BMDDuplexMode; +enum _BMDDuplexMode { + bmdDuplexFull = /* 'dxfu' */ 0x64786675, + bmdDuplexHalf = /* 'dxha' */ 0x64786861, + bmdDuplexSimplex = /* 'dxsp' */ 0x64787370, + bmdDuplexInactive = /* 'dxin' */ 0x6478696E +}; + +/* Enum BMDPanelType - The type of interchangeable panel */ + +typedef uint32_t BMDPanelType; +enum _BMDPanelType { + bmdPanelNotDetected = /* 'npnl' */ 0x6E706E6C, + bmdPanelTeranexMiniSmartPanel = /* 'tmsm' */ 0x746D736D +}; + +/* Enum BMDDeviceBusyState - Current device busy state */ + +typedef uint32_t BMDDeviceBusyState; +enum _BMDDeviceBusyState { + bmdDeviceCaptureBusy = 1 << 0, + bmdDevicePlaybackBusy = 1 << 1, + bmdDeviceSerialPortBusy = 1 << 2 +}; + +/* Enum BMDVideoIOSupport - Device video input/output support */ + +typedef uint32_t BMDVideoIOSupport; +enum _BMDVideoIOSupport { + bmdDeviceSupportsCapture = 1 << 0, + bmdDeviceSupportsPlayback = 1 << 1 +}; + +/* Enum BMD3DPreviewFormat - Linked Frame preview format */ + +typedef uint32_t BMD3DPreviewFormat; +enum _BMD3DPreviewFormat { + bmd3DPreviewFormatDefault = /* 'defa' */ 0x64656661, + bmd3DPreviewFormatLeftOnly = /* 'left' */ 0x6C656674, + bmd3DPreviewFormatRightOnly = /* 'righ' */ 0x72696768, + bmd3DPreviewFormatSideBySide = /* 'side' */ 0x73696465, + bmd3DPreviewFormatTopBottom = /* 'topb' */ 0x746F7062 +}; + +/* Enum BMDNotifications - Events that can be subscribed through IDeckLinkNotification */ + +typedef uint32_t BMDNotifications; +enum _BMDNotifications { + bmdPreferencesChanged = /* 'pref' */ 0x70726566, + bmdStatusChanged = /* 'stat' */ 0x73746174 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkVideoOutputCallback; +class IDeckLinkInputCallback; +class IDeckLinkEncoderInputCallback; +class IDeckLinkMemoryAllocator; +class IDeckLinkAudioOutputCallback; +class IDeckLinkIterator; +class IDeckLinkAPIInformation; +class IDeckLinkOutput; +class IDeckLinkInput; +class IDeckLinkHDMIInputEDID; +class IDeckLinkEncoderInput; +class IDeckLinkVideoFrame; +class IDeckLinkMutableVideoFrame; +class IDeckLinkVideoFrame3DExtensions; +class IDeckLinkVideoFrameMetadataExtensions; +class IDeckLinkVideoInputFrame; +class IDeckLinkAncillaryPacket; +class IDeckLinkAncillaryPacketIterator; +class IDeckLinkVideoFrameAncillaryPackets; +class IDeckLinkVideoFrameAncillary; +class IDeckLinkEncoderPacket; +class IDeckLinkEncoderVideoPacket; +class IDeckLinkEncoderAudioPacket; +class IDeckLinkH265NALPacket; +class IDeckLinkAudioInputPacket; +class IDeckLinkScreenPreviewCallback; +class IDeckLinkGLScreenPreviewHelper; +class IDeckLinkNotificationCallback; +class IDeckLinkNotification; +class IDeckLinkProfileAttributes; +class IDeckLinkProfileIterator; +class IDeckLinkProfile; +class IDeckLinkProfileCallback; +class IDeckLinkProfileManager; +class IDeckLinkStatus; +class IDeckLinkKeyer; +class IDeckLinkVideoConversion; +class IDeckLinkDeviceNotificationCallback; +class IDeckLinkDiscovery; + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +class BMD_PUBLIC IDeckLinkVideoOutputCallback : public IUnknown +{ +public: + virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame* completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; + virtual HRESULT ScheduledPlaybackHasStopped (void) = 0; + +protected: + virtual ~IDeckLinkVideoOutputCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkInputCallback : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode* newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkEncoderInputCallback : public IUnknown +{ +public: + virtual HRESULT VideoInputSignalChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode* newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoPacketArrived (/* in */ IDeckLinkEncoderVideoPacket* videoPacket) = 0; + virtual HRESULT AudioPacketArrived (/* in */ IDeckLinkEncoderAudioPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkEncoderInputCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */ + +class BMD_PUBLIC IDeckLinkMemoryAllocator : public IUnknown +{ +public: + virtual HRESULT AllocateBuffer (/* in */ uint32_t bufferSize, /* out */ void** allocatedBuffer) = 0; + virtual HRESULT ReleaseBuffer (/* in */ void* buffer) = 0; + virtual HRESULT Commit (void) = 0; + virtual HRESULT Decommit (void) = 0; +}; + +/* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */ + +class BMD_PUBLIC IDeckLinkAudioOutputCallback : public IUnknown +{ +public: + virtual HRESULT RenderAudioSamples (/* in */ bool preroll) = 0; +}; + +/* Interface IDeckLinkIterator - Enumerates installed DeckLink hardware */ + +class BMD_PUBLIC IDeckLinkIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLink** deckLinkInstance) = 0; +}; + +/* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */ + +class BMD_PUBLIC IDeckLinkAPIInformation : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ const char** value) = 0; + +protected: + virtual ~IDeckLinkAPIInformation () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDVideoOutputConversionMode conversionMode, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame** outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary** outBuffer) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback* theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t* bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + virtual HRESULT WriteAudioSamplesSync (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t* bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback* theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue* actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool* active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* streamTime, /* out */ double* playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus* referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + virtual HRESULT GetFrameCompletionReferenceTimestamp (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* frameCompletionTimestamp) = 0; + +protected: + virtual ~IDeckLinkOutput () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDVideoInputConversionMode conversionMode, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t* availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkHDMIInputEDID - Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default */ + +class BMD_PUBLIC IDeckLinkHDMIInputEDID : public IUnknown +{ +public: + virtual HRESULT SetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT WriteToEDID (void) = 0; + +protected: + virtual ~IDeckLinkHDMIInputEDID () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkEncoderInput : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedCodec, /* in */ uint32_t requestedCodecProfile, /* in */ BMDSupportedVideoModeFlags flags, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailablePacketsCount (/* out */ uint32_t* availablePacketsCount) = 0; + virtual HRESULT SetMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioFormat audioFormat, /* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkEncoderInputCallback* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkEncoderInput () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +class BMD_PUBLIC IDeckLinkVideoFrame : public IUnknown +{ +public: + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual long GetRowBytes (void) = 0; + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual BMDFrameFlags GetFlags (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode** timecode) = 0; + virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary** ancillary) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + +protected: + virtual ~IDeckLinkVideoFrame () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +class BMD_PUBLIC IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame +{ +public: + virtual HRESULT SetFlags (/* in */ BMDFrameFlags newFlags) = 0; + virtual HRESULT SetTimecode (/* in */ BMDTimecodeFormat format, /* in */ IDeckLinkTimecode* timecode) = 0; + virtual HRESULT SetTimecodeFromComponents (/* in */ BMDTimecodeFormat format, /* in */ uint8_t hours, /* in */ uint8_t minutes, /* in */ uint8_t seconds, /* in */ uint8_t frames, /* in */ BMDTimecodeFlags flags) = 0; + virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary* ancillary) = 0; + virtual HRESULT SetTimecodeUserBits (/* in */ BMDTimecodeFormat format, /* in */ BMDTimecodeUserBits userBits) = 0; + +protected: + virtual ~IDeckLinkMutableVideoFrame () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrame3DExtensions - Optional interface implemented on IDeckLinkVideoFrame to support 3D frames */ + +class BMD_PUBLIC IDeckLinkVideoFrame3DExtensions : public IUnknown +{ +public: + virtual BMDVideo3DPackingFormat Get3DPackingFormat (void) = 0; + virtual HRESULT GetFrameForRightEye (/* out */ IDeckLinkVideoFrame** rightEyeFrame) = 0; + +protected: + virtual ~IDeckLinkVideoFrame3DExtensions () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDR information */ + +class BMD_PUBLIC IDeckLinkVideoFrameMetadataExtensions : public IUnknown +{ +public: + virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ double* value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ bool* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ const char** value) = 0; + virtual HRESULT GetBytes (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ void* buffer /* optional */, /* in, out */ uint32_t* bufferSize) = 0; + +protected: + virtual ~IDeckLinkVideoFrameMetadataExtensions () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame +{ +public: + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue* frameTime, /* out */ BMDTimeValue* frameDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue* frameTime, /* out */ BMDTimeValue* frameDuration) = 0; + +protected: + virtual ~IDeckLinkVideoInputFrame () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAncillaryPacket - On output, user needs to implement this interface */ + +class BMD_PUBLIC IDeckLinkAncillaryPacket : public IUnknown +{ +public: + virtual HRESULT GetBytes (/* in */ BMDAncillaryPacketFormat format /* For output, only one format need be offered */, /* out */ const void** data /* Optional */, /* out */ uint32_t* size /* Optional */) = 0; + virtual uint8_t GetDID (void) = 0; + virtual uint8_t GetSDID (void) = 0; + virtual uint32_t GetLineNumber (void) = 0; // On output, zero is auto + virtual uint8_t GetDataStreamIndex (void) = 0; // Usually zero. Can only be 1 if non-SD and the first data stream is completely full + +protected: + virtual ~IDeckLinkAncillaryPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAncillaryPacketIterator - Enumerates ancillary packets */ + +class BMD_PUBLIC IDeckLinkAncillaryPacketIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkAncillaryPacket** packet) = 0; + +protected: + virtual ~IDeckLinkAncillaryPacketIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillaryPackets - Obtained through QueryInterface on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets : public IUnknown +{ +public: + virtual HRESULT GetPacketIterator (/* out */ IDeckLinkAncillaryPacketIterator** iterator) = 0; + virtual HRESULT GetFirstPacketByID (/* in */ uint8_t DID, /* in */ uint8_t SDID, /* out */ IDeckLinkAncillaryPacket** packet) = 0; + virtual HRESULT AttachPacket (/* in */ IDeckLinkAncillaryPacket* packet) = 0; // Implement IDeckLinkAncillaryPacket to output your own + virtual HRESULT DetachPacket (/* in */ IDeckLinkAncillaryPacket* packet) = 0; + virtual HRESULT DetachAllPackets (void) = 0; + +protected: + virtual ~IDeckLinkVideoFrameAncillaryPackets () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillary - Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillary : public IUnknown +{ +public: + virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void** buffer) = 0; // Pixels/rowbytes is same as display mode, except for above HD where it's 1920 pixels for UHD modes and 2048 pixels for DCI modes + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual BMDDisplayMode GetDisplayMode (void) = 0; + +protected: + virtual ~IDeckLinkVideoFrameAncillary () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */ + +class BMD_PUBLIC IDeckLinkEncoderPacket : public IUnknown +{ +public: + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual long GetSize (void) = 0; + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue* frameTime, /* in */ BMDTimeScale timeScale) = 0; + virtual BMDPacketType GetPacketType (void) = 0; + +protected: + virtual ~IDeckLinkEncoderPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */ + +class BMD_PUBLIC IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket +{ +public: + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue* frameTime, /* out */ BMDTimeValue* frameDuration) = 0; + virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode** timecode) = 0; + +protected: + virtual ~IDeckLinkEncoderVideoPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */ + +class BMD_PUBLIC IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket +{ +public: + virtual BMDAudioFormat GetAudioFormat (void) = 0; + +protected: + virtual ~IDeckLinkEncoderAudioPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface on an IDeckLinkEncoderVideoPacket object */ + +class BMD_PUBLIC IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket +{ +public: + virtual HRESULT GetUnitType (/* out */ uint8_t* unitType) = 0; + virtual HRESULT GetBytesNoPrefix (/* out */ void** buffer) = 0; + virtual long GetSizeNoPrefix (void) = 0; + +protected: + virtual ~IDeckLinkH265NALPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */ + +class BMD_PUBLIC IDeckLinkAudioInputPacket : public IUnknown +{ +public: + virtual long GetSampleFrameCount (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual HRESULT GetPacketTime (/* out */ BMDTimeValue* packetTime, /* in */ BMDTimeScale timeScale) = 0; + +protected: + virtual ~IDeckLinkAudioInputPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +class BMD_PUBLIC IDeckLinkScreenPreviewCallback : public IUnknown +{ +public: + virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + +protected: + virtual ~IDeckLinkScreenPreviewCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance on platforms with native COM support or from CreateOpenGLScreenPreviewHelper/CreateOpenGL3ScreenPreviewHelper on other platforms. */ + +class BMD_PUBLIC IDeckLinkGLScreenPreviewHelper : public IUnknown +{ +public: + + /* Methods must be called with OpenGL context set */ + + virtual HRESULT InitializeGL (void) = 0; + virtual HRESULT PaintGL (void) = 0; + virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT Set3DPreviewFormat (/* in */ BMD3DPreviewFormat previewFormat) = 0; + +protected: + virtual ~IDeckLinkGLScreenPreviewHelper () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkNotificationCallback - DeckLink Notification Callback Interface */ + +class BMD_PUBLIC IDeckLinkNotificationCallback : public IUnknown +{ +public: + virtual HRESULT Notify (/* in */ BMDNotifications topic, /* in */ uint64_t param1, /* in */ uint64_t param2) = 0; +}; + +/* Interface IDeckLinkNotification - DeckLink Notification interface */ + +class BMD_PUBLIC IDeckLinkNotification : public IUnknown +{ +public: + virtual HRESULT Subscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback* theCallback) = 0; + virtual HRESULT Unsubscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback* theCallback) = 0; + +protected: + virtual ~IDeckLinkNotification () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileAttributes - Created by QueryInterface from an IDeckLinkProfile, or from IDeckLink. When queried from IDeckLink, interrogates the active profile */ + +class BMD_PUBLIC IDeckLinkProfileAttributes : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ const char** value) = 0; + +protected: + virtual ~IDeckLinkProfileAttributes () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileIterator - Enumerates IDeckLinkProfile interfaces */ + +class BMD_PUBLIC IDeckLinkProfileIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkProfile** profile) = 0; + +protected: + virtual ~IDeckLinkProfileIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfile - Represents the active profile when queried from IDeckLink */ + +class BMD_PUBLIC IDeckLinkProfile : public IUnknown +{ +public: + virtual HRESULT GetDevice (/* out */ IDeckLink** device) = 0; // Device affected when this profile becomes active + virtual HRESULT IsActive (/* out */ bool* isActive) = 0; + virtual HRESULT SetActive (void) = 0; // Activating a profile will also change the profile on all devices enumerated by GetPeers. Activation is not complete until IDeckLinkProfileCallback::ProfileActivated is called + virtual HRESULT GetPeers (/* out */ IDeckLinkProfileIterator** profileIterator) = 0; // Profiles of other devices activated with this profile + +protected: + virtual ~IDeckLinkProfile () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileCallback - Receive notifications about profiles related to this device */ + +class BMD_PUBLIC IDeckLinkProfileCallback : public IUnknown +{ +public: + virtual HRESULT ProfileChanging (/* in */ IDeckLinkProfile* profileToBeActivated, /* in */ bool streamsWillBeForcedToStop) = 0; // Called before this device changes profile. User has an opportunity for teardown if streamsWillBeForcedToStop + virtual HRESULT ProfileActivated (/* in */ IDeckLinkProfile* activatedProfile) = 0; // Called after this device has been activated with a new profile + +protected: + virtual ~IDeckLinkProfileCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileManager - Created by QueryInterface from IDeckLink when a device has multiple optional profiles */ + +class BMD_PUBLIC IDeckLinkProfileManager : public IUnknown +{ +public: + virtual HRESULT GetProfiles (/* out */ IDeckLinkProfileIterator** profileIterator) = 0; // All available profiles for this device + virtual HRESULT GetProfile (/* in */ BMDProfileID profileID, /* out */ IDeckLinkProfile** profile) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkProfileCallback* callback) = 0; + +protected: + virtual ~IDeckLinkProfileManager () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkStatus - DeckLink Status interface */ + +class BMD_PUBLIC IDeckLinkStatus : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkStatusID statusID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkStatusID statusID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkStatusID statusID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkStatusID statusID, /* out */ const char** value) = 0; + virtual HRESULT GetBytes (/* in */ BMDDeckLinkStatusID statusID, /* out */ void* buffer, /* in, out */ uint32_t* bufferSize) = 0; + +protected: + virtual ~IDeckLinkStatus () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkKeyer - DeckLink Keyer interface */ + +class BMD_PUBLIC IDeckLinkKeyer : public IUnknown +{ +public: + virtual HRESULT Enable (/* in */ bool isExternal) = 0; + virtual HRESULT SetLevel (/* in */ uint8_t level) = 0; + virtual HRESULT RampUp (/* in */ uint32_t numberOfFrames) = 0; + virtual HRESULT RampDown (/* in */ uint32_t numberOfFrames) = 0; + virtual HRESULT Disable (void) = 0; + +protected: + virtual ~IDeckLinkKeyer () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance. */ + +class BMD_PUBLIC IDeckLinkVideoConversion : public IUnknown +{ +public: + virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame* srcFrame, /* in */ IDeckLinkVideoFrame* dstFrame) = 0; + +protected: + virtual ~IDeckLinkVideoConversion () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDeviceNotificationCallback - DeckLink device arrival/removal notification callbacks */ + +class BMD_PUBLIC IDeckLinkDeviceNotificationCallback : public IUnknown +{ +public: + virtual HRESULT DeckLinkDeviceArrived (/* in */ IDeckLink* deckLinkDevice) = 0; + virtual HRESULT DeckLinkDeviceRemoved (/* in */ IDeckLink* deckLinkDevice) = 0; + +protected: + virtual ~IDeckLinkDeviceNotificationCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDiscovery - DeckLink device discovery */ + +class BMD_PUBLIC IDeckLinkDiscovery : public IUnknown +{ +public: + virtual HRESULT InstallDeviceNotifications (/* in */ IDeckLinkDeviceNotificationCallback* deviceNotificationCallback) = 0; + virtual HRESULT UninstallDeviceNotifications (void) = 0; + +protected: + virtual ~IDeckLinkDiscovery () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + BMD_PUBLIC IDeckLinkIterator* CreateDeckLinkIteratorInstance(void); + BMD_PUBLIC IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance(void); + BMD_PUBLIC IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance(void); + BMD_PUBLIC IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper(void); + BMD_PUBLIC IDeckLinkGLScreenPreviewHelper* CreateOpenGL3ScreenPreviewHelper(void); // Requires OpenGL 3.2 support and provides improved performance and color handling + BMD_PUBLIC IDeckLinkVideoConversion* CreateVideoConversionInstance(void); + BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance(void); // For use when creating a custom IDeckLinkVideoFrame without wrapping IDeckLinkOutput::CreateVideoFrame + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPI_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration.h new file mode 100644 index 0000000000..42e2441357 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration.h @@ -0,0 +1,269 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_H +#define BMD_DECKLINKAPICONFIGURATION_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration = /* 912F634B-2D4E-40A4-8AAB-8D80B73F1289 */ { 0x91,0x2F,0x63,0x4B,0x2D,0x4E,0x40,0xA4,0x8A,0xAB,0x8D,0x80,0xB7,0x3F,0x12,0x89 }; +BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration = /* 138050E5-C60A-4552-BF3F-0F358049327E */ { 0x13,0x80,0x50,0xE5,0xC6,0x0A,0x45,0x52,0xBF,0x3F,0x0F,0x35,0x80,0x49,0x32,0x7E }; + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID; +enum _BMDDeckLinkConfigurationID { + + /* Serial port Flags */ + + bmdDeckLinkConfigSwapSerialRxTx = /* 'ssrt' */ 0x73737274, + + /* Video Input/Output Integers */ + + bmdDeckLinkConfigHDMI3DPackingFormat = /* '3dpf' */ 0x33647066, + bmdDeckLinkConfigBypass = /* 'byps' */ 0x62797073, + bmdDeckLinkConfigClockTimingAdjustment = /* 'ctad' */ 0x63746164, + + /* Audio Input/Output Flags */ + + bmdDeckLinkConfigAnalogAudioConsumerLevels = /* 'aacl' */ 0x6161636C, + bmdDeckLinkConfigSwapHDMICh3AndCh4OnInput = /* 'hi34' */ 0x68693334, + bmdDeckLinkConfigSwapHDMICh3AndCh4OnOutput = /* 'ho34' */ 0x686F3334, + + /* Video Output Flags */ + + bmdDeckLinkConfigFieldFlickerRemoval = /* 'fdfr' */ 0x66646672, + bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion = /* 'to59' */ 0x746F3539, + bmdDeckLinkConfig444SDIVideoOutput = /* '444o' */ 0x3434346F, + bmdDeckLinkConfigBlackVideoOutputDuringCapture = /* 'bvoc' */ 0x62766F63, + bmdDeckLinkConfigLowLatencyVideoOutput = /* 'llvo' */ 0x6C6C766F, + bmdDeckLinkConfigDownConversionOnAllAnalogOutput = /* 'caao' */ 0x6361616F, + bmdDeckLinkConfigSMPTELevelAOutput = /* 'smta' */ 0x736D7461, + bmdDeckLinkConfigRec2020Output = /* 'rec2' */ 0x72656332, // Ensure output is Rec.2020 colorspace + bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit = /* 'SDQS' */ 0x53445153, + bmdDeckLinkConfigOutput1080pAsPsF = /* 'pfpr' */ 0x70667072, + + /* Video Output Integers */ + + bmdDeckLinkConfigVideoOutputConnection = /* 'vocn' */ 0x766F636E, + bmdDeckLinkConfigVideoOutputConversionMode = /* 'vocm' */ 0x766F636D, + bmdDeckLinkConfigAnalogVideoOutputFlags = /* 'avof' */ 0x61766F66, + bmdDeckLinkConfigReferenceInputTimingOffset = /* 'glot' */ 0x676C6F74, + bmdDeckLinkConfigVideoOutputIdleOperation = /* 'voio' */ 0x766F696F, + bmdDeckLinkConfigDefaultVideoOutputMode = /* 'dvom' */ 0x64766F6D, + bmdDeckLinkConfigDefaultVideoOutputModeFlags = /* 'dvof' */ 0x64766F66, + bmdDeckLinkConfigSDIOutputLinkConfiguration = /* 'solc' */ 0x736F6C63, + bmdDeckLinkConfigHDMITimecodePacking = /* 'htpk' */ 0x6874706B, + bmdDeckLinkConfigPlaybackGroup = /* 'plgr' */ 0x706C6772, + + /* Video Output Floats */ + + bmdDeckLinkConfigVideoOutputComponentLumaGain = /* 'oclg' */ 0x6F636C67, + bmdDeckLinkConfigVideoOutputComponentChromaBlueGain = /* 'occb' */ 0x6F636362, + bmdDeckLinkConfigVideoOutputComponentChromaRedGain = /* 'occr' */ 0x6F636372, + bmdDeckLinkConfigVideoOutputCompositeLumaGain = /* 'oilg' */ 0x6F696C67, + bmdDeckLinkConfigVideoOutputCompositeChromaGain = /* 'oicg' */ 0x6F696367, + bmdDeckLinkConfigVideoOutputSVideoLumaGain = /* 'oslg' */ 0x6F736C67, + bmdDeckLinkConfigVideoOutputSVideoChromaGain = /* 'oscg' */ 0x6F736367, + + /* Video Input Flags */ + + bmdDeckLinkConfigVideoInputScanning = /* 'visc' */ 0x76697363, // Applicable to H264 Pro Recorder only + bmdDeckLinkConfigUseDedicatedLTCInput = /* 'dltc' */ 0x646C7463, // Use timecode from LTC input instead of SDI stream + bmdDeckLinkConfigSDIInput3DPayloadOverride = /* '3dds' */ 0x33646473, + bmdDeckLinkConfigCapture1080pAsPsF = /* 'cfpr' */ 0x63667072, + + /* Video Input Integers */ + + bmdDeckLinkConfigVideoInputConnection = /* 'vicn' */ 0x7669636E, + bmdDeckLinkConfigAnalogVideoInputFlags = /* 'avif' */ 0x61766966, + bmdDeckLinkConfigVideoInputConversionMode = /* 'vicm' */ 0x7669636D, + bmdDeckLinkConfig32PulldownSequenceInitialTimecodeFrame = /* 'pdif' */ 0x70646966, + bmdDeckLinkConfigVANCSourceLine1Mapping = /* 'vsl1' */ 0x76736C31, + bmdDeckLinkConfigVANCSourceLine2Mapping = /* 'vsl2' */ 0x76736C32, + bmdDeckLinkConfigVANCSourceLine3Mapping = /* 'vsl3' */ 0x76736C33, + bmdDeckLinkConfigCapturePassThroughMode = /* 'cptm' */ 0x6370746D, + bmdDeckLinkConfigCaptureGroup = /* 'cpgr' */ 0x63706772, + + /* Video Input Floats */ + + bmdDeckLinkConfigVideoInputComponentLumaGain = /* 'iclg' */ 0x69636C67, + bmdDeckLinkConfigVideoInputComponentChromaBlueGain = /* 'iccb' */ 0x69636362, + bmdDeckLinkConfigVideoInputComponentChromaRedGain = /* 'iccr' */ 0x69636372, + bmdDeckLinkConfigVideoInputCompositeLumaGain = /* 'iilg' */ 0x69696C67, + bmdDeckLinkConfigVideoInputCompositeChromaGain = /* 'iicg' */ 0x69696367, + bmdDeckLinkConfigVideoInputSVideoLumaGain = /* 'islg' */ 0x69736C67, + bmdDeckLinkConfigVideoInputSVideoChromaGain = /* 'iscg' */ 0x69736367, + + /* Keying Integers */ + + bmdDeckLinkConfigInternalKeyingAncillaryDataSource = /* 'ikas' */ 0x696B6173, + + /* Audio Input Flags */ + + bmdDeckLinkConfigMicrophonePhantomPower = /* 'mphp' */ 0x6D706870, + + /* Audio Input Integers */ + + bmdDeckLinkConfigAudioInputConnection = /* 'aicn' */ 0x6169636E, + + /* Audio Input Floats */ + + bmdDeckLinkConfigAnalogAudioInputScaleChannel1 = /* 'ais1' */ 0x61697331, + bmdDeckLinkConfigAnalogAudioInputScaleChannel2 = /* 'ais2' */ 0x61697332, + bmdDeckLinkConfigAnalogAudioInputScaleChannel3 = /* 'ais3' */ 0x61697333, + bmdDeckLinkConfigAnalogAudioInputScaleChannel4 = /* 'ais4' */ 0x61697334, + bmdDeckLinkConfigDigitalAudioInputScale = /* 'dais' */ 0x64616973, + bmdDeckLinkConfigMicrophoneInputGain = /* 'micg' */ 0x6D696367, + + /* Audio Output Integers */ + + bmdDeckLinkConfigAudioOutputAESAnalogSwitch = /* 'aoaa' */ 0x616F6161, + + /* Audio Output Floats */ + + bmdDeckLinkConfigAnalogAudioOutputScaleChannel1 = /* 'aos1' */ 0x616F7331, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel2 = /* 'aos2' */ 0x616F7332, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel3 = /* 'aos3' */ 0x616F7333, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel4 = /* 'aos4' */ 0x616F7334, + bmdDeckLinkConfigDigitalAudioOutputScale = /* 'daos' */ 0x64616F73, + bmdDeckLinkConfigHeadphoneVolume = /* 'hvol' */ 0x68766F6C, + + /* Device Information Strings */ + + bmdDeckLinkConfigDeviceInformationLabel = /* 'dila' */ 0x64696C61, + bmdDeckLinkConfigDeviceInformationSerialNumber = /* 'disn' */ 0x6469736E, + bmdDeckLinkConfigDeviceInformationCompany = /* 'dico' */ 0x6469636F, + bmdDeckLinkConfigDeviceInformationPhone = /* 'diph' */ 0x64697068, + bmdDeckLinkConfigDeviceInformationEmail = /* 'diem' */ 0x6469656D, + bmdDeckLinkConfigDeviceInformationDate = /* 'dida' */ 0x64696461, + + /* Deck Control Integers */ + + bmdDeckLinkConfigDeckControlConnection = /* 'dcco' */ 0x6463636F +}; + +/* Enum BMDDeckLinkEncoderConfigurationID - DeckLink Encoder Configuration ID */ + +typedef uint32_t BMDDeckLinkEncoderConfigurationID; +enum _BMDDeckLinkEncoderConfigurationID { + + /* Video Encoder Integers */ + + bmdDeckLinkEncoderConfigPreferredBitDepth = /* 'epbr' */ 0x65706272, + bmdDeckLinkEncoderConfigFrameCodingMode = /* 'efcm' */ 0x6566636D, + + /* HEVC/H.265 Encoder Integers */ + + bmdDeckLinkEncoderConfigH265TargetBitrate = /* 'htbr' */ 0x68746272, + + /* DNxHR/DNxHD Compression ID */ + + bmdDeckLinkEncoderConfigDNxHRCompressionID = /* 'dcid' */ 0x64636964, + + /* DNxHR/DNxHD Level */ + + bmdDeckLinkEncoderConfigDNxHRLevel = /* 'dlev' */ 0x646C6576, + + /* Encoded Sample Decriptions */ + + bmdDeckLinkEncoderConfigMPEG4SampleDescription = /* 'stsE' */ 0x73747345, // Full MPEG4 sample description (aka SampleEntry of an 'stsd' atom-box). Useful for MediaFoundation, QuickTime, MKV and more + bmdDeckLinkEncoderConfigMPEG4CodecSpecificDesc = /* 'esds' */ 0x65736473 // Sample description extensions only (atom stream, each with size and fourCC header). Useful for AVFoundation, VideoToolbox, MKV and more +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkConfiguration; +class IDeckLinkEncoderConfiguration; + +/* Interface IDeckLinkConfiguration - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool* value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double* value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char** value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ + +class BMD_PUBLIC IDeckLinkEncoderConfiguration : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool* value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double* value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ const char* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ const char** value) = 0; + virtual HRESULT GetBytes (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ void* buffer /* optional */, /* in, out */ uint32_t* bufferSize) = 0; + +protected: + virtual ~IDeckLinkEncoderConfiguration () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_11.h new file mode 100644 index 0000000000..9fe70ffca4 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_11.h @@ -0,0 +1,84 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_11_H +#define BMD_DECKLINKAPICONFIGURATION_v10_11_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_11 = /* EF90380B-4AE5-4346-9077-E288E149F129 */ {0xEF,0x90,0x38,0x0B,0x4A,0xE5,0x43,0x46,0x90,0x77,0xE2,0x88,0xE1,0x49,0xF1,0x29}; + +/* Enum BMDDeckLinkConfigurationID_v10_11 - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_11; +enum _BMDDeckLinkConfigurationID_v10_11 { + + /* Video Input/Output Integers */ + + bmdDeckLinkConfigDuplexMode_v10_11 = /* 'dupx' */ 0x64757078, +}; + +// Forward Declarations + +class IDeckLinkConfiguration_v10_11; + +/* Interface IDeckLinkConfiguration_v10_11 - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration_v10_11 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_11 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_2.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_2.h new file mode 100644 index 0000000000..a75821923b --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_2.h @@ -0,0 +1,73 @@ +/* -LICENSE-START- +** Copyright (c) 2014 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_2_H +#define BMD_DECKLINKAPICONFIGURATION_v10_2_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_2 = /* C679A35B-610C-4D09-B748-1D0478100FC0 */ {0xC6,0x79,0xA3,0x5B,0x61,0x0C,0x4D,0x09,0xB7,0x48,0x1D,0x04,0x78,0x10,0x0F,0xC0}; + +// Forward Declarations + +class IDeckLinkConfiguration_v10_2; + +/* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration_v10_2 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_2 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_2_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_4.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_4.h new file mode 100644 index 0000000000..eabb917cc0 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_4.h @@ -0,0 +1,76 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_4_H +#define BMD_DECKLINKAPICONFIGURATION_v10_4_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_4 = /* 1E69FCF6-4203-4936-8076-2A9F4CFD50CB */ {0x1E,0x69,0xFC,0xF6,0x42,0x03,0x49,0x36,0x80,0x76,0x2A,0x9F,0x4C,0xFD,0x50,0xCB}; + + +// +// Forward Declarations + +class IDeckLinkConfiguration_v10_4; + +/* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration_v10_4 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_4 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_5.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_5.h new file mode 100644 index 0000000000..fd8ef772e1 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_5.h @@ -0,0 +1,73 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_5_H +#define BMD_DECKLINKAPICONFIGURATION_v10_5_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration_v10_5 = /* 67455668-0848-45DF-8D8E-350A77C9A028 */ {0x67,0x45,0x56,0x68,0x08,0x48,0x45,0xDF,0x8D,0x8E,0x35,0x0A,0x77,0xC9,0xA0,0x28}; + +// Forward Declarations + +class IDeckLinkEncoderConfiguration_v10_5; + +/* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ + +class BMD_PUBLIC IDeckLinkEncoderConfiguration_v10_5 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ const char *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ const char **value) = 0; + virtual HRESULT GetDecoderConfigurationInfo (/* out */ void *buffer, /* in */ long bufferSize, /* out */ long *returnedSize) = 0; + +protected: + virtual ~IDeckLinkEncoderConfiguration_v10_5 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_5_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_9.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_9.h new file mode 100644 index 0000000000..84ad1d681b --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIConfiguration_v10_9.h @@ -0,0 +1,75 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_9_H +#define BMD_DECKLINKAPICONFIGURATION_v10_9_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_9 = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2}; + +// +// Forward Declarations + +class IDeckLinkConfiguration_v10_9; + +/* Interface IDeckLinkConfiguration_v10_9 - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration_v10_9 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_9 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_9_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDeckControl.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDeckControl.h new file mode 100644 index 0000000000..7ae9bd9798 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDeckControl.h @@ -0,0 +1,223 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIDECKCONTROL_H +#define BMD_DECKLINKAPIDECKCONTROL_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkDeckControlStatusCallback = /* 53436FFB-B434-4906-BADC-AE3060FFE8EF */ { 0x53,0x43,0x6F,0xFB,0xB4,0x34,0x49,0x06,0xBA,0xDC,0xAE,0x30,0x60,0xFF,0xE8,0xEF }; +BMD_CONST REFIID IID_IDeckLinkDeckControl = /* 8E1C3ACE-19C7-4E00-8B92-D80431D958BE */ { 0x8E,0x1C,0x3A,0xCE,0x19,0xC7,0x4E,0x00,0x8B,0x92,0xD8,0x04,0x31,0xD9,0x58,0xBE }; + +/* Enum BMDDeckControlMode - DeckControl mode */ + +typedef uint32_t BMDDeckControlMode; +enum _BMDDeckControlMode { + bmdDeckControlNotOpened = /* 'ntop' */ 0x6E746F70, + bmdDeckControlVTRControlMode = /* 'vtrc' */ 0x76747263, + bmdDeckControlExportMode = /* 'expm' */ 0x6578706D, + bmdDeckControlCaptureMode = /* 'capm' */ 0x6361706D +}; + +/* Enum BMDDeckControlEvent - DeckControl event */ + +typedef uint32_t BMDDeckControlEvent; +enum _BMDDeckControlEvent { + bmdDeckControlAbortedEvent = /* 'abte' */ 0x61627465, // This event is triggered when a capture or edit-to-tape operation is aborted. + + /* Export-To-Tape events */ + + bmdDeckControlPrepareForExportEvent = /* 'pfee' */ 0x70666565, // This event is triggered a few frames before reaching the in-point. IDeckLinkInput::StartScheduledPlayback should be called at this point. + bmdDeckControlExportCompleteEvent = /* 'exce' */ 0x65786365, // This event is triggered a few frames after reaching the out-point. At this point, it is safe to stop playback. Upon reception of this event the deck's control mode is set back to bmdDeckControlVTRControlMode. + + /* Capture events */ + + bmdDeckControlPrepareForCaptureEvent = /* 'pfce' */ 0x70666365, // This event is triggered a few frames before reaching the in-point. The serial timecode attached to IDeckLinkVideoInputFrames is now valid. + bmdDeckControlCaptureCompleteEvent = /* 'ccev' */ 0x63636576 // This event is triggered a few frames after reaching the out-point. Upon reception of this event the deck's control mode is set back to bmdDeckControlVTRControlMode. +}; + +/* Enum BMDDeckControlVTRControlState - VTR Control state */ + +typedef uint32_t BMDDeckControlVTRControlState; +enum _BMDDeckControlVTRControlState { + bmdDeckControlNotInVTRControlMode = /* 'nvcm' */ 0x6E76636D, + bmdDeckControlVTRControlPlaying = /* 'vtrp' */ 0x76747270, + bmdDeckControlVTRControlRecording = /* 'vtrr' */ 0x76747272, + bmdDeckControlVTRControlStill = /* 'vtra' */ 0x76747261, + bmdDeckControlVTRControlShuttleForward = /* 'vtsf' */ 0x76747366, + bmdDeckControlVTRControlShuttleReverse = /* 'vtsr' */ 0x76747372, + bmdDeckControlVTRControlJogForward = /* 'vtjf' */ 0x76746A66, + bmdDeckControlVTRControlJogReverse = /* 'vtjr' */ 0x76746A72, + bmdDeckControlVTRControlStopped = /* 'vtro' */ 0x7674726F +}; + +/* Enum BMDDeckControlStatusFlags - Deck Control status flags */ + +typedef uint32_t BMDDeckControlStatusFlags; +enum _BMDDeckControlStatusFlags { + bmdDeckControlStatusDeckConnected = 1 << 0, + bmdDeckControlStatusRemoteMode = 1 << 1, + bmdDeckControlStatusRecordInhibited = 1 << 2, + bmdDeckControlStatusCassetteOut = 1 << 3 +}; + +/* Enum BMDDeckControlExportModeOpsFlags - Export mode flags */ + +typedef uint32_t BMDDeckControlExportModeOpsFlags; +enum _BMDDeckControlExportModeOpsFlags { + bmdDeckControlExportModeInsertVideo = 1 << 0, + bmdDeckControlExportModeInsertAudio1 = 1 << 1, + bmdDeckControlExportModeInsertAudio2 = 1 << 2, + bmdDeckControlExportModeInsertAudio3 = 1 << 3, + bmdDeckControlExportModeInsertAudio4 = 1 << 4, + bmdDeckControlExportModeInsertAudio5 = 1 << 5, + bmdDeckControlExportModeInsertAudio6 = 1 << 6, + bmdDeckControlExportModeInsertAudio7 = 1 << 7, + bmdDeckControlExportModeInsertAudio8 = 1 << 8, + bmdDeckControlExportModeInsertAudio9 = 1 << 9, + bmdDeckControlExportModeInsertAudio10 = 1 << 10, + bmdDeckControlExportModeInsertAudio11 = 1 << 11, + bmdDeckControlExportModeInsertAudio12 = 1 << 12, + bmdDeckControlExportModeInsertTimeCode = 1 << 13, + bmdDeckControlExportModeInsertAssemble = 1 << 14, + bmdDeckControlExportModeInsertPreview = 1 << 15, + bmdDeckControlUseManualExport = 1 << 16 +}; + +/* Enum BMDDeckControlError - Deck Control error */ + +typedef uint32_t BMDDeckControlError; +enum _BMDDeckControlError { + bmdDeckControlNoError = /* 'noer' */ 0x6E6F6572, + bmdDeckControlModeError = /* 'moer' */ 0x6D6F6572, + bmdDeckControlMissedInPointError = /* 'mier' */ 0x6D696572, + bmdDeckControlDeckTimeoutError = /* 'dter' */ 0x64746572, + bmdDeckControlCommandFailedError = /* 'cfer' */ 0x63666572, + bmdDeckControlDeviceAlreadyOpenedError = /* 'dalo' */ 0x64616C6F, + bmdDeckControlFailedToOpenDeviceError = /* 'fder' */ 0x66646572, + bmdDeckControlInLocalModeError = /* 'lmer' */ 0x6C6D6572, + bmdDeckControlEndOfTapeError = /* 'eter' */ 0x65746572, + bmdDeckControlUserAbortError = /* 'uaer' */ 0x75616572, + bmdDeckControlNoTapeInDeckError = /* 'nter' */ 0x6E746572, + bmdDeckControlNoVideoFromCardError = /* 'nvfc' */ 0x6E766663, + bmdDeckControlNoCommunicationError = /* 'ncom' */ 0x6E636F6D, + bmdDeckControlBufferTooSmallError = /* 'btsm' */ 0x6274736D, + bmdDeckControlBadChecksumError = /* 'chks' */ 0x63686B73, + bmdDeckControlUnknownError = /* 'uner' */ 0x756E6572 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkDeckControlStatusCallback; +class IDeckLinkDeckControl; + +/* Interface IDeckLinkDeckControlStatusCallback - Deck control state change callback. */ + +class BMD_PUBLIC IDeckLinkDeckControlStatusCallback : public IUnknown +{ +public: + virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; + virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState newState, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0; + +protected: + virtual ~IDeckLinkDeckControlStatusCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDeckControl - Deck Control main interface */ + +class BMD_PUBLIC IDeckLinkDeckControl : public IUnknown +{ +public: + virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Close (/* in */ bool standbyOn) = 0; + virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode* mode, /* out */ BMDDeckControlVTRControlState* vtrControlState, /* out */ BMDDeckControlStatusFlags* flags) = 0; + virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0; + virtual HRESULT SendCommand (/* in */ uint8_t* inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t* outBuffer, /* out */ uint32_t* outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Play (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Stop (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Eject (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT StepForward (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT StepBack (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetTimecodeString (/* out */ const char** currentTimeCode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode** currentTimecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD* currentTimecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0; + virtual HRESULT GetPreroll (/* out */ uint32_t* prerollSeconds) = 0; + virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0; + virtual HRESULT GetExportOffset (/* out */ int32_t* exportOffsetFields) = 0; + virtual HRESULT GetManualExportOffset (/* out */ int32_t* deckManualExportOffsetFields) = 0; + virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0; + virtual HRESULT GetCaptureOffset (/* out */ int32_t* captureOffsetFields) = 0; + virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetDeviceID (/* out */ uint16_t* deviceId, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Abort (void) = 0; + virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback* callback) = 0; + +protected: + virtual ~IDeckLinkDeckControl () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPIDECKCONTROL_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDiscovery.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDiscovery.h new file mode 100644 index 0000000000..02bbca4ea4 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDiscovery.h @@ -0,0 +1,79 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIDISCOVERY_H +#define BMD_DECKLINKAPIDISCOVERY_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLink = /* C418FBDD-0587-48ED-8FE5-640F0A14AF91 */ { 0xC4,0x18,0xFB,0xDD,0x05,0x87,0x48,0xED,0x8F,0xE5,0x64,0x0F,0x0A,0x14,0xAF,0x91 }; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLink; + +/* Interface IDeckLink - Represents a DeckLink device */ + +class BMD_PUBLIC IDeckLink : public IUnknown +{ +public: + virtual HRESULT GetModelName (/* out */ const char** modelName) = 0; + virtual HRESULT GetDisplayName (/* out */ const char** displayName) = 0; + +protected: + virtual ~IDeckLink () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPIDISCOVERY_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch.cpp b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch.cpp new file mode 100644 index 0000000000..fd57c2eeb2 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch.cpp @@ -0,0 +1,188 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +**/ + +#include +#include +#include + +#include "DeckLinkAPI.h" + +#define kDeckLinkAPI_Name "libDeckLinkAPI.so" +#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGL3ScreenPreviewHelperFunc)(void); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); +typedef IDeckLinkVideoFrameAncillaryPackets* (*CreateVideoFrameAncillaryPacketsInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; + +static bool gLoadedDeckLinkAPI = false; + +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateOpenGL3ScreenPreviewHelperFunc gCreateOpenGL3PreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; +static CreateVideoFrameAncillaryPacketsInstanceFunc gCreateVideoFrameAncillaryPacketsFunc = NULL; + +static void InitDeckLinkAPI (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + + gLoadedDeckLinkAPI = true; + + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0004"); + if (!gCreateIteratorFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001"); + if (!gCreateAPIInformationFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); + if (!gCreateVideoConversionFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)dlsym(libraryHandle, "CreateDeckLinkDiscoveryInstance_0003"); + if (!gCreateDeckLinkDiscoveryFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoFrameAncillaryPacketsFunc = (CreateVideoFrameAncillaryPacketsInstanceFunc)dlsym(libraryHandle, "CreateVideoFrameAncillaryPacketsInstance_0001"); + if (!gCreateVideoFrameAncillaryPacketsFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +static void InitDeckLinkPreviewAPI (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001"); + if (!gCreateOpenGLPreviewFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateOpenGL3PreviewFunc = (CreateOpenGL3ScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGL3ScreenPreviewHelper_0001"); + if (!gCreateOpenGL3PreviewFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +bool IsDeckLinkAPIPresent (void) +{ + // If the DeckLink API dynamic library was successfully loaded, return this knowledge to the caller + return gLoadedDeckLinkAPI; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGL3ScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); + + if (gCreateOpenGL3PreviewFunc == NULL) + return NULL; + return gCreateOpenGL3PreviewFunc(); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + return gCreateDeckLinkDiscoveryFunc(); +} + +IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoFrameAncillaryPacketsFunc == NULL) + return NULL; + return gCreateVideoFrameAncillaryPacketsFunc(); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v10_11.cpp b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v10_11.cpp new file mode 100644 index 0000000000..e0cac2be94 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v10_11.cpp @@ -0,0 +1,175 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +**/ + +#include +#include +#include + +#include "DeckLinkAPI_v10_11.h" + +#define kDeckLinkAPI_Name "libDeckLinkAPI.so" +#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); +typedef IDeckLinkVideoFrameAncillaryPackets* (*CreateVideoFrameAncillaryPacketsInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; + +static bool gLoadedDeckLinkAPI = false; + +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; +static CreateVideoFrameAncillaryPacketsInstanceFunc gCreateVideoFrameAncillaryPacketsFunc = NULL; + +#define fprintf(a,b,c) do{}while(0) + +static void InitDeckLinkAPI (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + + gLoadedDeckLinkAPI = true; + + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0003"); + if (!gCreateIteratorFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001"); + if (!gCreateAPIInformationFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); + if (!gCreateVideoConversionFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)dlsym(libraryHandle, "CreateDeckLinkDiscoveryInstance_0002"); + if (!gCreateDeckLinkDiscoveryFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoFrameAncillaryPacketsFunc = (CreateVideoFrameAncillaryPacketsInstanceFunc)dlsym(libraryHandle, "CreateVideoFrameAncillaryPacketsInstance_0001"); + if (!gCreateVideoFrameAncillaryPacketsFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +static void InitDeckLinkPreviewAPI (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001"); + if (!gCreateOpenGLPreviewFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +bool IsDeckLinkAPIPresent_v10_11 (void) +{ + // If the DeckLink API dynamic library was successfully loaded, return this knowledge to the caller + return gLoadedDeckLinkAPI; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + return gCreateDeckLinkDiscoveryFunc(); +} + +IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoFrameAncillaryPacketsFunc == NULL) + return NULL; + return gCreateVideoFrameAncillaryPacketsFunc(); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v10_8.cpp b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v10_8.cpp new file mode 100644 index 0000000000..3260c52d27 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v10_8.cpp @@ -0,0 +1,161 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +**/ + +#include +#include +#include + +#include "DeckLinkAPI.h" + +#define kDeckLinkAPI_Name "libDeckLinkAPI.so" +#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; + +static bool gLoadedDeckLinkAPI = false; + +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; + +#define fprintf(a,b,c) do{}while(0) + +static void InitDeckLinkAPI(void) +{ + void *libraryHandle; + + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW | RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + + gLoadedDeckLinkAPI = true; + + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0002"); + if (!gCreateIteratorFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001"); + if (!gCreateAPIInformationFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); + if (!gCreateVideoConversionFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)dlsym(libraryHandle, "CreateDeckLinkDiscoveryInstance_0001"); + if (!gCreateDeckLinkDiscoveryFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +static void InitDeckLinkPreviewAPI(void) +{ + void *libraryHandle; + + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW | RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001"); + if (!gCreateOpenGLPreviewFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +bool IsDeckLinkAPIPresent(void) +{ + // If the DeckLink API dynamic library was successfully loaded, return this knowledge to the caller + return gLoadedDeckLinkAPI; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + return gCreateDeckLinkDiscoveryFunc(); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v7_6.cpp b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v7_6.cpp new file mode 100644 index 0000000000..f65e815c26 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v7_6.cpp @@ -0,0 +1,124 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +**/ + +#include +#include +#include + +#include "DeckLinkAPI_v7_6.h" + +#define kDeckLinkAPI_Name "libDeckLinkAPI.so" +#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" + +typedef IDeckLinkIterator* (*CreateIteratorFunc_v7_6)(void); +typedef IDeckLinkGLScreenPreviewHelper_v7_6* (*CreateOpenGLScreenPreviewHelperFunc_v7_6)(void); +typedef IDeckLinkVideoConversion_v7_6* (*CreateVideoConversionInstanceFunc_v7_6)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; + +static CreateIteratorFunc_v7_6 gCreateIteratorFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc_v7_6 gCreateOpenGLPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc_v7_6 gCreateVideoConversionFunc = NULL; + +#define fprintf(a,b,c) do{}while(0) + +static void InitDeckLinkAPI_v7_6 (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + + gCreateIteratorFunc = (CreateIteratorFunc_v7_6)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance"); + if (!gCreateIteratorFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc_v7_6)dlsym(libraryHandle, "CreateVideoConversionInstance"); + if (!gCreateVideoConversionFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +static void InitDeckLinkPreviewAPI_v7_6 (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc_v7_6)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper"); + if (!gCreateOpenGLPreviewFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + + if (gCreateIteratorFunc == NULL) + return NULL; + return gCreateIteratorFunc(); +} + +IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI_v7_6); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + return gCreateVideoConversionFunc(); +} + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v8_0.cpp b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v8_0.cpp new file mode 100644 index 0000000000..0d4be9fd56 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIDispatch_v8_0.cpp @@ -0,0 +1,148 @@ +/* -LICENSE-START- +** Copyright (c) 2011 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +**/ + +#include +#include +#include + +#include "DeckLinkAPI_v8_0.h" + +#define kDeckLinkAPI_Name "libDeckLinkAPI.so" +#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" + +typedef IDeckLinkIterator_v8_0* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; + +static bool gLoadedDeckLinkAPI = false; + +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; + +#define fprintf(a,b,c) do{}while(0) + +static void InitDeckLinkAPI (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + + gLoadedDeckLinkAPI = true; + + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0001"); + if (!gCreateIteratorFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001"); + if (!gCreateAPIInformationFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); + if (!gCreateVideoConversionFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +static void InitDeckLinkPreviewAPI (void) +{ + void *libraryHandle; + + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001"); + if (!gCreateOpenGLPreviewFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +bool IsDeckLinkAPIPresent (void) +{ + // If the DeckLink API dynamic library was successfully loaded, return this knowledge to the caller + return gLoadedDeckLinkAPI; +} + +IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + return gCreateVideoConversionFunc(); +} + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIModes.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIModes.h new file mode 100644 index 0000000000..0a54dca4cc --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIModes.h @@ -0,0 +1,289 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIMODES_H +#define BMD_DECKLINKAPIMODES_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkDisplayModeIterator = /* 9C88499F-F601-4021-B80B-032E4EB41C35 */ { 0x9C,0x88,0x49,0x9F,0xF6,0x01,0x40,0x21,0xB8,0x0B,0x03,0x2E,0x4E,0xB4,0x1C,0x35 }; +BMD_CONST REFIID IID_IDeckLinkDisplayMode = /* 3EB2C1AB-0A3D-4523-A3AD-F40D7FB14E78 */ { 0x3E,0xB2,0xC1,0xAB,0x0A,0x3D,0x45,0x23,0xA3,0xAD,0xF4,0x0D,0x7F,0xB1,0x4E,0x78 }; + +/* Enum BMDDisplayMode - BMDDisplayMode enumerates the video modes supported. */ + +typedef uint32_t BMDDisplayMode; +enum _BMDDisplayMode { + + /* SD Modes */ + + bmdModeNTSC = /* 'ntsc' */ 0x6E747363, + bmdModeNTSC2398 = /* 'nt23' */ 0x6E743233, // 3:2 pulldown + bmdModePAL = /* 'pal ' */ 0x70616C20, + bmdModeNTSCp = /* 'ntsp' */ 0x6E747370, + bmdModePALp = /* 'palp' */ 0x70616C70, + + /* HD 1080 Modes */ + + bmdModeHD1080p2398 = /* '23ps' */ 0x32337073, + bmdModeHD1080p24 = /* '24ps' */ 0x32347073, + bmdModeHD1080p25 = /* 'Hp25' */ 0x48703235, + bmdModeHD1080p2997 = /* 'Hp29' */ 0x48703239, + bmdModeHD1080p30 = /* 'Hp30' */ 0x48703330, + bmdModeHD1080p4795 = /* 'Hp47' */ 0x48703437, + bmdModeHD1080p48 = /* 'Hp48' */ 0x48703438, + bmdModeHD1080p50 = /* 'Hp50' */ 0x48703530, + bmdModeHD1080p5994 = /* 'Hp59' */ 0x48703539, + bmdModeHD1080p6000 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080p9590 = /* 'Hp95' */ 0x48703935, + bmdModeHD1080p96 = /* 'Hp96' */ 0x48703936, + bmdModeHD1080p100 = /* 'Hp10' */ 0x48703130, + bmdModeHD1080p11988 = /* 'Hp11' */ 0x48703131, + bmdModeHD1080p120 = /* 'Hp12' */ 0x48703132, + bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, + bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, + bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. + + /* HD 720 Modes */ + + bmdModeHD720p50 = /* 'hp50' */ 0x68703530, + bmdModeHD720p5994 = /* 'hp59' */ 0x68703539, + bmdModeHD720p60 = /* 'hp60' */ 0x68703630, + + /* 2K Modes */ + + bmdMode2k2398 = /* '2k23' */ 0x326B3233, + bmdMode2k24 = /* '2k24' */ 0x326B3234, + bmdMode2k25 = /* '2k25' */ 0x326B3235, + + /* 2K DCI Modes */ + + bmdMode2kDCI2398 = /* '2d23' */ 0x32643233, + bmdMode2kDCI24 = /* '2d24' */ 0x32643234, + bmdMode2kDCI25 = /* '2d25' */ 0x32643235, + bmdMode2kDCI2997 = /* '2d29' */ 0x32643239, + bmdMode2kDCI30 = /* '2d30' */ 0x32643330, + bmdMode2kDCI4795 = /* '2d47' */ 0x32643437, + bmdMode2kDCI48 = /* '2d48' */ 0x32643438, + bmdMode2kDCI50 = /* '2d50' */ 0x32643530, + bmdMode2kDCI5994 = /* '2d59' */ 0x32643539, + bmdMode2kDCI60 = /* '2d60' */ 0x32643630, + bmdMode2kDCI9590 = /* '2d95' */ 0x32643935, + bmdMode2kDCI96 = /* '2d96' */ 0x32643936, + bmdMode2kDCI100 = /* '2d10' */ 0x32643130, + bmdMode2kDCI11988 = /* '2d11' */ 0x32643131, + bmdMode2kDCI120 = /* '2d12' */ 0x32643132, + + /* 4K UHD Modes */ + + bmdMode4K2160p2398 = /* '4k23' */ 0x346B3233, + bmdMode4K2160p24 = /* '4k24' */ 0x346B3234, + bmdMode4K2160p25 = /* '4k25' */ 0x346B3235, + bmdMode4K2160p2997 = /* '4k29' */ 0x346B3239, + bmdMode4K2160p30 = /* '4k30' */ 0x346B3330, + bmdMode4K2160p4795 = /* '4k47' */ 0x346B3437, + bmdMode4K2160p48 = /* '4k48' */ 0x346B3438, + bmdMode4K2160p50 = /* '4k50' */ 0x346B3530, + bmdMode4K2160p5994 = /* '4k59' */ 0x346B3539, + bmdMode4K2160p60 = /* '4k60' */ 0x346B3630, + bmdMode4K2160p9590 = /* '4k95' */ 0x346B3935, + bmdMode4K2160p96 = /* '4k96' */ 0x346B3936, + bmdMode4K2160p100 = /* '4k10' */ 0x346B3130, + bmdMode4K2160p11988 = /* '4k11' */ 0x346B3131, + bmdMode4K2160p120 = /* '4k12' */ 0x346B3132, + + /* 4K DCI Modes */ + + bmdMode4kDCI2398 = /* '4d23' */ 0x34643233, + bmdMode4kDCI24 = /* '4d24' */ 0x34643234, + bmdMode4kDCI25 = /* '4d25' */ 0x34643235, + bmdMode4kDCI2997 = /* '4d29' */ 0x34643239, + bmdMode4kDCI30 = /* '4d30' */ 0x34643330, + bmdMode4kDCI4795 = /* '4d47' */ 0x34643437, + bmdMode4kDCI48 = /* '4d48' */ 0x34643438, + bmdMode4kDCI50 = /* '4d50' */ 0x34643530, + bmdMode4kDCI5994 = /* '4d59' */ 0x34643539, + bmdMode4kDCI60 = /* '4d60' */ 0x34643630, + bmdMode4kDCI9590 = /* '4d95' */ 0x34643935, + bmdMode4kDCI96 = /* '4d96' */ 0x34643936, + bmdMode4kDCI100 = /* '4d10' */ 0x34643130, + bmdMode4kDCI11988 = /* '4d11' */ 0x34643131, + bmdMode4kDCI120 = /* '4d12' */ 0x34643132, + + /* 8K UHD Modes */ + + bmdMode8K4320p2398 = /* '8k23' */ 0x386B3233, + bmdMode8K4320p24 = /* '8k24' */ 0x386B3234, + bmdMode8K4320p25 = /* '8k25' */ 0x386B3235, + bmdMode8K4320p2997 = /* '8k29' */ 0x386B3239, + bmdMode8K4320p30 = /* '8k30' */ 0x386B3330, + bmdMode8K4320p4795 = /* '8k47' */ 0x386B3437, + bmdMode8K4320p48 = /* '8k48' */ 0x386B3438, + bmdMode8K4320p50 = /* '8k50' */ 0x386B3530, + bmdMode8K4320p5994 = /* '8k59' */ 0x386B3539, + bmdMode8K4320p60 = /* '8k60' */ 0x386B3630, + + /* 8K DCI Modes */ + + bmdMode8kDCI2398 = /* '8d23' */ 0x38643233, + bmdMode8kDCI24 = /* '8d24' */ 0x38643234, + bmdMode8kDCI25 = /* '8d25' */ 0x38643235, + bmdMode8kDCI2997 = /* '8d29' */ 0x38643239, + bmdMode8kDCI30 = /* '8d30' */ 0x38643330, + bmdMode8kDCI4795 = /* '8d47' */ 0x38643437, + bmdMode8kDCI48 = /* '8d48' */ 0x38643438, + bmdMode8kDCI50 = /* '8d50' */ 0x38643530, + bmdMode8kDCI5994 = /* '8d59' */ 0x38643539, + bmdMode8kDCI60 = /* '8d60' */ 0x38643630, + + /* PC Modes */ + + bmdMode640x480p60 = /* 'vga6' */ 0x76676136, + bmdMode800x600p60 = /* 'svg6' */ 0x73766736, + bmdMode1440x900p50 = /* 'wxg5' */ 0x77786735, + bmdMode1440x900p60 = /* 'wxg6' */ 0x77786736, + bmdMode1440x1080p50 = /* 'sxg5' */ 0x73786735, + bmdMode1440x1080p60 = /* 'sxg6' */ 0x73786736, + bmdMode1600x1200p50 = /* 'uxg5' */ 0x75786735, + bmdMode1600x1200p60 = /* 'uxg6' */ 0x75786736, + bmdMode1920x1200p50 = /* 'wux5' */ 0x77757835, + bmdMode1920x1200p60 = /* 'wux6' */ 0x77757836, + bmdMode1920x1440p50 = /* '1945' */ 0x31393435, + bmdMode1920x1440p60 = /* '1946' */ 0x31393436, + bmdMode2560x1440p50 = /* 'wqh5' */ 0x77716835, + bmdMode2560x1440p60 = /* 'wqh6' */ 0x77716836, + bmdMode2560x1600p50 = /* 'wqx5' */ 0x77717835, + bmdMode2560x1600p60 = /* 'wqx6' */ 0x77717836, + + /* Special Modes */ + + bmdModeUnknown = /* 'iunk' */ 0x69756E6B +}; + +/* Enum BMDFieldDominance - BMDFieldDominance enumerates settings applicable to video fields. */ + +typedef uint32_t BMDFieldDominance; +enum _BMDFieldDominance { + bmdUnknownFieldDominance = 0, + bmdLowerFieldFirst = /* 'lowr' */ 0x6C6F7772, + bmdUpperFieldFirst = /* 'uppr' */ 0x75707072, + bmdProgressiveFrame = /* 'prog' */ 0x70726F67, + bmdProgressiveSegmentedFrame = /* 'psf ' */ 0x70736620 +}; + +/* Enum BMDPixelFormat - Video pixel formats supported for output/input */ + +typedef uint32_t BMDPixelFormat; +enum _BMDPixelFormat { + bmdFormatUnspecified = 0, + bmdFormat8BitYUV = /* '2vuy' */ 0x32767579, + bmdFormat10BitYUV = /* 'v210' */ 0x76323130, + bmdFormat8BitARGB = 32, + bmdFormat8BitBGRA = /* 'BGRA' */ 0x42475241, + bmdFormat10BitRGB = /* 'r210' */ 0x72323130, // Big-endian RGB 10-bit per component with SMPTE video levels (64-960). Packed as 2:10:10:10 + bmdFormat12BitRGB = /* 'R12B' */ 0x52313242, // Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component + bmdFormat12BitRGBLE = /* 'R12L' */ 0x5231324C, // Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component + bmdFormat10BitRGBXLE = /* 'R10l' */ 0x5231306C, // Little-endian 10-bit RGB with SMPTE video levels (64-940) + bmdFormat10BitRGBX = /* 'R10b' */ 0x52313062, // Big-endian 10-bit RGB with SMPTE video levels (64-940) + bmdFormatH265 = /* 'hev1' */ 0x68657631, // High Efficiency Video Coding (HEVC/h.265) + + /* AVID DNxHR */ + + bmdFormatDNxHR = /* 'AVdh' */ 0x41566468 +}; + +/* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */ + +typedef uint32_t BMDDisplayModeFlags; +enum _BMDDisplayModeFlags { + bmdDisplayModeSupports3D = 1 << 0, + bmdDisplayModeColorspaceRec601 = 1 << 1, + bmdDisplayModeColorspaceRec709 = 1 << 2, + bmdDisplayModeColorspaceRec2020 = 1 << 3 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkDisplayModeIterator; +class IDeckLinkDisplayMode; + +/* Interface IDeckLinkDisplayModeIterator - Enumerates over supported input/output display modes. */ + +class BMD_PUBLIC IDeckLinkDisplayModeIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkDisplayMode** deckLinkDisplayMode) = 0; + +protected: + virtual ~IDeckLinkDisplayModeIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDisplayMode - Represents a display mode */ + +class BMD_PUBLIC IDeckLinkDisplayMode : public IUnknown +{ +public: + virtual HRESULT GetName (/* out */ const char** name) = 0; + virtual BMDDisplayMode GetDisplayMode (void) = 0; + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual HRESULT GetFrameRate (/* out */ BMDTimeValue* frameDuration, /* out */ BMDTimeScale* timeScale) = 0; + virtual BMDFieldDominance GetFieldDominance (void) = 0; + virtual BMDDisplayModeFlags GetFlags (void) = 0; + +protected: + virtual ~IDeckLinkDisplayMode () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPIMODES_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPITypes.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPITypes.h new file mode 100644 index 0000000000..893c3c92e4 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPITypes.h @@ -0,0 +1,132 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPITYPES_H +#define BMD_DECKLINKAPITYPES_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + +typedef int64_t BMDTimeValue; +typedef int64_t BMDTimeScale; +typedef uint32_t BMDTimecodeBCD; +typedef uint32_t BMDTimecodeUserBits; + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkTimecode = /* BC6CFBD3-8317-4325-AC1C-1216391E9340 */ { 0xBC,0x6C,0xFB,0xD3,0x83,0x17,0x43,0x25,0xAC,0x1C,0x12,0x16,0x39,0x1E,0x93,0x40 }; + +/* Enum BMDTimecodeFlags - Timecode flags */ + +typedef uint32_t BMDTimecodeFlags; +enum _BMDTimecodeFlags { + bmdTimecodeFlagDefault = 0, + bmdTimecodeIsDropFrame = 1 << 0, + bmdTimecodeFieldMark = 1 << 1, + bmdTimecodeColorFrame = 1 << 2, + bmdTimecodeEmbedRecordingTrigger = 1 << 3, // On SDI recording trigger utilises a user-bit. + bmdTimecodeRecordingTriggered = 1 << 4 +}; + +/* Enum BMDVideoConnection - Video connection types */ + +typedef uint32_t BMDVideoConnection; +enum _BMDVideoConnection { + bmdVideoConnectionUnspecified = 0, + bmdVideoConnectionSDI = 1 << 0, + bmdVideoConnectionHDMI = 1 << 1, + bmdVideoConnectionOpticalSDI = 1 << 2, + bmdVideoConnectionComponent = 1 << 3, + bmdVideoConnectionComposite = 1 << 4, + bmdVideoConnectionSVideo = 1 << 5 +}; + +/* Enum BMDAudioConnection - Audio connection types */ + +typedef uint32_t BMDAudioConnection; +enum _BMDAudioConnection { + bmdAudioConnectionEmbedded = 1 << 0, + bmdAudioConnectionAESEBU = 1 << 1, + bmdAudioConnectionAnalog = 1 << 2, + bmdAudioConnectionAnalogXLR = 1 << 3, + bmdAudioConnectionAnalogRCA = 1 << 4, + bmdAudioConnectionMicrophone = 1 << 5, + bmdAudioConnectionHeadphones = 1 << 6 +}; + +/* Enum BMDDeckControlConnection - Deck control connections */ + +typedef uint32_t BMDDeckControlConnection; +enum _BMDDeckControlConnection { + bmdDeckControlConnectionRS422Remote1 = 1 << 0, + bmdDeckControlConnectionRS422Remote2 = 1 << 1 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkTimecode; + +/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ + +class BMD_PUBLIC IDeckLinkTimecode : public IUnknown +{ +public: + virtual BMDTimecodeBCD GetBCD (void) = 0; + virtual HRESULT GetComponents (/* out */ uint8_t* hours, /* out */ uint8_t* minutes, /* out */ uint8_t* seconds, /* out */ uint8_t* frames) = 0; + virtual HRESULT GetString (/* out */ const char** timecode) = 0; + virtual BMDTimecodeFlags GetFlags (void) = 0; + virtual HRESULT GetTimecodeUserBits (/* out */ BMDTimecodeUserBits* userBits) = 0; + +protected: + virtual ~IDeckLinkTimecode () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPITYPES_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVersion.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVersion.h new file mode 100644 index 0000000000..679ef92584 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVersion.h @@ -0,0 +1,50 @@ +/* -LICENSE-START- + * ** Copyright (c) 2014 Blackmagic Design + * ** + * ** Permission is hereby granted, free of charge, to any person or organization + * ** obtaining a copy of the software and accompanying documentation (the + * ** "Software") to use, reproduce, display, distribute, sub-license, execute, + * ** and transmit the Software, and to prepare derivative works of the Software, + * ** and to permit third-parties to whom the Software is furnished to do so, in + * ** accordance with: + * ** + * ** (1) if the Software is obtained from Blackmagic Design, the End User License + * ** Agreement for the Software Development Kit (“EULA”) available at + * ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + * ** + * ** (2) if the Software is obtained from any third party, such licensing terms + * ** as notified by that third party, + * ** + * ** and all subject to the following: + * ** + * ** (3) the copyright notices in the Software and this entire statement, + * ** including the above license grant, this restriction and the following + * ** disclaimer, must be included in all copies of the Software, in whole or in + * ** part, and all derivative works of the Software, unless such copies or + * ** derivative works are solely in the form of machine-executable object code + * ** generated by a source language processor. + * ** + * ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * ** DEALINGS IN THE SOFTWARE. + * ** + * ** A copy of the Software is available free of charge at + * ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + * ** + * ** -LICENSE-END- + * */ + +/* DeckLinkAPIVersion.h */ + +#ifndef __DeckLink_API_Version_h__ +#define __DeckLink_API_Version_h__ + +#define BLACKMAGIC_DECKLINK_API_VERSION 0x0c040200 +#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "12.4.2" + +#endif // __DeckLink_API_Version_h__ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoEncoderInput_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoEncoderInput_v10_11.h new file mode 100644 index 0000000000..590a485588 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoEncoderInput_v10_11.h @@ -0,0 +1,87 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOENCODERINPUT_v10_11_H +#define BMD_DECKLINKAPIVIDEOENCODERINPUT_v10_11_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Type Declarations +BMD_CONST REFIID IID_IDeckLinkEncoderInput_v10_11 = /* 270587DA-6B7D-42E7-A1F0-6D853F581185 */ {0x27,0x05,0x87,0xDA,0x6B,0x7D,0x42,0xE7,0xA1,0xF0,0x6D,0x85,0x3F,0x58,0x11,0x85}; + +/* Interface IDeckLinkEncoderInput_v10_11 - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkEncoderInput_v10_11 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailablePacketsCount (/* out */ uint32_t *availablePacketsCount) = 0; + virtual HRESULT SetMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioFormat audioFormat, /* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkEncoderInputCallback *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkEncoderInput_v10_11 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOENCODERINPUT_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v10_11.h new file mode 100644 index 0000000000..c4c3d70ef8 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v10_11.h @@ -0,0 +1,90 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOINPUT_v10_11_H +#define BMD_DECKLINKAPIVIDEOINPUT_v10_11_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" +#include "DeckLinkAPIVideoInput_v11_5_1.h" + +// Type Declarations +BMD_CONST REFIID IID_IDeckLinkInput_v10_11 = /* AF22762B-DFAC-4846-AA79-FA8883560995 */ {0xAF,0x22,0x76,0x2B,0xDF,0xAC,0x48,0x46,0xAA,0x79,0xFA,0x88,0x83,0x56,0x09,0x95}; + +/* Interface IDeckLinkInput_v10_11 - DeckLink input interface. */ + +class IDeckLinkInput_v10_11 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1 *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v10_11 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOINPUT_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v11_4.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v11_4.h new file mode 100644 index 0000000000..ade2250676 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v11_4.h @@ -0,0 +1,89 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOINPUT_v11_4_H +#define BMD_DECKLINKAPIVIDEOINPUT_v11_4_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPIVideoInput_v11_5_1.h" + +// Type Declarations +BMD_CONST REFIID IID_IDeckLinkInput_v11_4 = /* 2A88CF76-F494-4216-A7EF-DC74EEB83882 */ { 0x2A,0x88,0xCF,0x76,0xF4,0x94,0x42,0x16,0xA7,0xEF,0xDC,0x74,0xEE,0xB8,0x38,0x82 }; + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v11_4 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of 0 is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDSupportedVideoModeFlags flags, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t* availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v11_4 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOINPUT_v11_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v11_5_1.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v11_5_1.h new file mode 100644 index 0000000000..51fb5172ac --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoInput_v11_5_1.h @@ -0,0 +1,102 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOINPUT_v11_5_1_H +#define BMD_DECKLINKAPIVIDEOINPUT_v11_5_1_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkInputCallback_v11_5_1 = /* DD04E5EC-7415-42AB-AE4A-E80C4DFC044A */ { 0xDD, 0x04, 0xE5, 0xEC, 0x74, 0x15, 0x42, 0xAB, 0xAE, 0x4A, 0xE8, 0x0C, 0x4D, 0xFC, 0x04, 0x4A }; +BMD_CONST REFIID IID_IDeckLinkInput_v11_5_1 = /* 9434C6E4-B15D-4B1C-979E-661E3DDCB4B9 */ { 0x94, 0x34, 0xC6, 0xE4, 0xB1, 0x5D, 0x4B, 0x1C, 0x97, 0x9E, 0x66, 0x1E, 0x3D, 0xDC, 0xB4, 0xB9 }; + +/* Interface IDeckLinkInputCallback_v11_5_1 - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkInputCallback_v11_5_1 : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode* newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback_v11_5_1 () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkInput_v11_5_1 - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v11_5_1 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDVideoInputConversionMode conversionMode, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t* availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v11_5_1 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOINPUT_v11_5_1_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoOutput_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoOutput_v10_11.h new file mode 100644 index 0000000000..21d3d150d3 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoOutput_v10_11.h @@ -0,0 +1,107 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOOUTPUT_v10_11_H +#define BMD_DECKLINKAPIVIDEOOUTPUT_v10_11_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Type Declarations +BMD_CONST REFIID IID_IDeckLinkOutput_v10_11 = /* CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564 */ {0xCC,0x5C,0x8A,0x6E,0x3F,0x2F,0x4B,0x3A,0x87,0xEA,0xFD,0x78,0xAF,0x30,0x05,0x64}; + +/* Interface IDeckLinkOutput_v10_11 - DeckLink output interface. */ + +class IDeckLinkOutput_v10_11 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + virtual HRESULT GetFrameCompletionReferenceTimestamp (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *frameCompletionTimestamp) = 0; + +protected: + virtual ~IDeckLinkOutput_v10_11 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOOUTPUT_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoOutput_v11_4.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoOutput_v11_4.h new file mode 100644 index 0000000000..ba4b01f9ac --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPIVideoOutput_v11_4.h @@ -0,0 +1,100 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOOUTPUT_v11_4_H +#define BMD_DECKLINKAPIVIDEOOUTPUT_v11_4_H + +#include "DeckLinkAPI.h" + +// Type Declarations +BMD_CONST REFIID IID_IDeckLinkOutput_v11_4 = /* 065A0F6C-C508-4D0D-B919-F5EB0EBFC96B */ { 0x06,0x5A,0x0F,0x6C,0xC5,0x08,0x4D,0x0D,0xB9,0x19,0xF5,0xEB,0x0E,0xBF,0xC9,0x6B }; + +/* Interface IDeckLinkOutput_v11_4 - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput_v11_4 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of 0 is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame** outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary** outBuffer) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback* theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t* bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + virtual HRESULT WriteAudioSamplesSync (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t* bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback* theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue* actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool* active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* streamTime, /* out */ double* playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus* referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + virtual HRESULT GetFrameCompletionReferenceTimestamp (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* frameCompletionTimestamp) = 0; + +protected: + virtual ~IDeckLinkOutput_v11_4 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOOUTPUT_v11_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_11.h new file mode 100644 index 0000000000..26d5117187 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_11.h @@ -0,0 +1,134 @@ +/* -LICENSE-START- +** Copyright (c) 2018 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_11_H +#define BMD_DECKLINKAPI_v10_11_H + +#include "DeckLinkAPI.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkAttributes_v10_11 = /* ABC11843-D966-44CB-96E2-A1CB5D3135C4 */ {0xAB,0xC1,0x18,0x43,0xD9,0x66,0x44,0xCB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4}; +BMD_CONST REFIID IID_IDeckLinkNotification_v10_11 = /* 0A1FB207-E215-441B-9B19-6FA1575946C5 */ {0x0A,0x1F,0xB2,0x07,0xE2,0x15,0x44,0x1B,0x9B,0x19,0x6F,0xA1,0x57,0x59,0x46,0xC5}; + +/* Enum BMDDisplayModeSupport_v10_11 - Output mode supported flags */ + +typedef uint32_t BMDDisplayModeSupport_v10_11; +enum _BMDDisplayModeSupport_v10_11 { + bmdDisplayModeNotSupported_v10_11 = 0, + bmdDisplayModeSupported_v10_11, + bmdDisplayModeSupportedWithConversion_v10_11 +}; + +/* Enum BMDDuplexMode_v10_11 - Duplex for configurable ports */ + +typedef uint32_t BMDDuplexMode_v10_11; +enum _BMDDuplexMode_v10_11 { + bmdDuplexModeFull_v10_11 = /* 'fdup' */ 0x66647570, + bmdDuplexModeHalf_v10_11 = /* 'hdup' */ 0x68647570 +}; + +/* Enum BMDDeckLinkAttributeID_v10_11 - DeckLink Attribute ID */ + +enum _BMDDeckLinkAttributeID_v10_11 { + + /* Flags */ + + BMDDeckLinkSupportsDuplexModeConfiguration_v10_11 = 'dupx', + BMDDeckLinkSupportsHDKeying_v10_11 = 'keyh', + + /* Integers */ + + BMDDeckLinkPairedDevicePersistentID_v10_11 = 'ppid', + BMDDeckLinkSupportsFullDuplex_v10_11 = 'fdup', +}; + +enum _BMDDeckLinkStatusID_v10_11 { + bmdDeckLinkStatusDuplexMode_v10_11 = 'dupx', +}; + +typedef uint32_t BMDDuplexStatus_v10_11; +enum _BMDDuplexStatus_v10_11 { + bmdDuplexFullDuplex_v10_11 = 'fdup', + bmdDuplexHalfDuplex_v10_11 = 'hdup', + bmdDuplexSimplex_v10_11 = 'splx', + bmdDuplexInactive_v10_11 = 'inac', +}; + +#if defined(__cplusplus) + +/* Interface IDeckLinkAttributes_v10_11 - DeckLink Attribute interface */ + +class BMD_PUBLIC IDeckLinkAttributes_v10_11 : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool *value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ double *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ const char **value) = 0; + +protected: + virtual ~IDeckLinkAttributes_v10_11 () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkNotification_v10_11 - DeckLink Notification interface */ + +class BMD_PUBLIC IDeckLinkNotification_v10_11 : public IUnknown +{ +public: + virtual HRESULT Subscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback *theCallback) = 0; + virtual HRESULT Unsubscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback *theCallback) = 0; +}; + +/* Functions */ + +extern "C" { + + BMD_PUBLIC IDeckLinkIterator* CreateDeckLinkIteratorInstance_v10_11 (void); + BMD_PUBLIC IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance_v10_11 (void); + BMD_PUBLIC IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance_v10_11 (void); + BMD_PUBLIC IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper_v10_11 (void); + BMD_PUBLIC IDeckLinkVideoConversion* CreateVideoConversionInstance_v10_11 (void); + BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance_v10_11 (void); // For use when creating a custom IDeckLinkVideoFrame without wrapping IDeckLinkOutput::CreateVideoFrame + +} + +#endif // defined(__cplusplus) +#endif /* defined(BMD_DECKLINKAPI_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_2.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_2.h new file mode 100644 index 0000000000..d1633a01e8 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_2.h @@ -0,0 +1,68 @@ +/* -LICENSE-START- +** Copyright (c) 2014 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_2_H +#define BMD_DECKLINKAPI_v10_2_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_2; +enum _BMDDeckLinkConfigurationID_v10_2 { + /* Video output flags */ + + bmdDeckLinkConfig3GBpsVideoOutput_v10_2 = '3gbs', +}; + +/* Enum BMDAudioConnection_v10_2 - Audio connection types */ + +typedef uint32_t BMDAudioConnection_v10_2; +enum _BMDAudioConnection_v10_2 { + bmdAudioConnectionEmbedded_v10_2 = /* 'embd' */ 0x656D6264, + bmdAudioConnectionAESEBU_v10_2 = /* 'aes ' */ 0x61657320, + bmdAudioConnectionAnalog_v10_2 = /* 'anlg' */ 0x616E6C67, + bmdAudioConnectionAnalogXLR_v10_2 = /* 'axlr' */ 0x61786C72, + bmdAudioConnectionAnalogRCA_v10_2 = /* 'arca' */ 0x61726361 +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_2_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_4.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_4.h new file mode 100644 index 0000000000..fa5892dd0a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_4.h @@ -0,0 +1,58 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_4_H +#define BMD_DECKLINKAPI_v10_4_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_4; +enum _BMDDeckLinkConfigurationID_v10_4 { + + /* Video output flags */ + + bmdDeckLinkConfigSingleLinkVideoOutput_v10_4 = /* 'sglo' */ 0x73676C6F, +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_5.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_5.h new file mode 100644 index 0000000000..40ce330f09 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_5.h @@ -0,0 +1,59 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_5_H +#define BMD_DECKLINKAPI_v10_5_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkAttributeID_v10_5; +enum _BMDDeckLinkAttributeID_v10_5 { + + /* Integers */ + + BMDDeckLinkDeviceBusyState_v10_5 = /* 'dbst' */ 0x64627374, +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_5_H) */ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_6.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_6.h new file mode 100644 index 0000000000..2bc306c6b7 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_6.h @@ -0,0 +1,63 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_6_H +#define BMD_DECKLINKAPI_v10_6_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkAttributeID_c10_6; +enum _BMDDeckLinkAttributeID_v10_6 { + + /* Flags */ + + BMDDeckLinkSupportsDesktopDisplay_v10_6 = /* 'extd' */ 0x65787464, +}; + +typedef uint32_t BMDIdleVideoOutputOperation_v10_6; +enum _BMDIdleVideoOutputOperation_v10_6 { + bmdIdleVideoOutputDesktop_v10_6 = /* 'desk' */ 0x6465736B +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_6_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_9.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_9.h new file mode 100644 index 0000000000..8b6b4b208f --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v10_9.h @@ -0,0 +1,58 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_9_H +#define BMD_DECKLINKAPI_v10_9_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_9; +enum _BMDDeckLinkConfigurationID_v10_9 { + + /* Flags */ + + bmdDeckLinkConfig1080pNotPsF_v10_9 = 'fpro', +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_9_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v11_5.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v11_5.h new file mode 100644 index 0000000000..30578e5df1 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v11_5.h @@ -0,0 +1,113 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v11_5_H +#define BMD_DECKLINKAPI_v11_5_H + +#include "DeckLinkAPI.h" + +BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions_v11_5 = /* D5973DC9-6432-46D0-8F0B-2496F8A1238F */ {0xD5,0x97,0x3D,0xC9,0x64,0x32,0x46,0xD0,0x8F,0x0B,0x24,0x96,0xF8,0xA1,0x23,0x8F}; + +/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ + +typedef uint32_t BMDDeckLinkFrameMetadataID_v11_5; +enum _BMDDeckLinkFrameMetadataID_v11_5 { + bmdDeckLinkFrameMetadataCintelFilmType_v11_5 = /* 'cfty' */ 0x63667479, // Current film type + bmdDeckLinkFrameMetadataCintelFilmGauge_v11_5 = /* 'cfga' */ 0x63666761, // Current film gauge + bmdDeckLinkFrameMetadataCintelKeykodeLow_v11_5 = /* 'ckkl' */ 0x636B6B6C, // Raw keykode value - low 64 bits + bmdDeckLinkFrameMetadataCintelKeykodeHigh_v11_5 = /* 'ckkh' */ 0x636B6B68, // Raw keykode value - high 64 bits + bmdDeckLinkFrameMetadataCintelTile1Size_v11_5 = /* 'ct1s' */ 0x63743173, // Size in bytes of compressed raw tile 1 + bmdDeckLinkFrameMetadataCintelTile2Size_v11_5 = /* 'ct2s' */ 0x63743273, // Size in bytes of compressed raw tile 2 + bmdDeckLinkFrameMetadataCintelTile3Size_v11_5 = /* 'ct3s' */ 0x63743373, // Size in bytes of compressed raw tile 3 + bmdDeckLinkFrameMetadataCintelTile4Size_v11_5 = /* 'ct4s' */ 0x63743473, // Size in bytes of compressed raw tile 4 + bmdDeckLinkFrameMetadataCintelImageWidth_v11_5 = /* 'IWPx' */ 0x49575078, // Width in pixels of image + bmdDeckLinkFrameMetadataCintelImageHeight_v11_5 = /* 'IHPx' */ 0x49485078, // Height in pixels of image + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInRed_v11_5 = /* 'mrir' */ 0x6D726972, // Red in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInRed_v11_5 = /* 'mgir' */ 0x6D676972, // Green in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInRed_v11_5 = /* 'mbir' */ 0x6D626972, // Blue in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInGreen_v11_5 = /* 'mrig' */ 0x6D726967, // Red in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInGreen_v11_5 = /* 'mgig' */ 0x6D676967, // Green in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInGreen_v11_5 = /* 'mbig' */ 0x6D626967, // Blue in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInBlue_v11_5 = /* 'mrib' */ 0x6D726962, // Red in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInBlue_v11_5 = /* 'mgib' */ 0x6D676962, // Green in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInBlue_v11_5 = /* 'mbib' */ 0x6D626962, // Blue in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInRed_v11_5 = /* 'mlrr' */ 0x6D6C7272, // Red in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInRed_v11_5 = /* 'mlgr' */ 0x6D6C6772, // Green in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInRed_v11_5 = /* 'mlbr' */ 0x6D6C6272, // Blue in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInGreen_v11_5 = /* 'mlrg' */ 0x6D6C7267, // Red in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInGreen_v11_5 = /* 'mlgg' */ 0x6D6C6767, // Green in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInGreen_v11_5 = /* 'mlbg' */ 0x6D6C6267, // Blue in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInBlue_v11_5 = /* 'mlrb' */ 0x6D6C7262, // Red in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInBlue_v11_5 = /* 'mlgb' */ 0x6D6C6762, // Green in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInBlue_v11_5 = /* 'mlbb' */ 0x6D6C6262, // Blue in blue log masking parameter + bmdDeckLinkFrameMetadataCintelFilmFrameRate_v11_5 = /* 'cffr' */ 0x63666672, // Film frame rate + bmdDeckLinkFrameMetadataCintelOffsetToApplyHorizontal_v11_5 = /* 'otah' */ 0x6F746168, // Horizontal offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelOffsetToApplyVertical_v11_5 = /* 'otav' */ 0x6F746176, // Vertical offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelGainRed_v11_5 = /* 'LfRd' */ 0x4C665264, // Red gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainGreen_v11_5 = /* 'LfGr' */ 0x4C664772, // Green gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainBlue_v11_5 = /* 'LfBl' */ 0x4C66426C, // Blue gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelLiftRed_v11_5 = /* 'GnRd' */ 0x476E5264, // Red lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftGreen_v11_5 = /* 'GnGr' */ 0x476E4772, // Green lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftBlue_v11_5 = /* 'GnBl' */ 0x476E426C, // Blue lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelHDRGainRed_v11_5 = /* 'HGRd' */ 0x48475264, // Red gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintelHDRGainGreen_v11_5 = /* 'HGGr' */ 0x48474772, // Green gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintelHDRGainBlue_v11_5 = /* 'HGBl' */ 0x4847426C, // Blue gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintel16mmCropRequired_v11_5 = /* 'c16c' */ 0x63313663, // The image should be cropped to 16mm size + bmdDeckLinkFrameMetadataCintelInversionRequired_v11_5 = /* 'cinv' */ 0x63696E76, // The image should be colour inverted + bmdDeckLinkFrameMetadataCintelFlipRequired_v11_5 = /* 'cflr' */ 0x63666C72, // The image should be flipped horizontally + bmdDeckLinkFrameMetadataCintelFocusAssistEnabled_v11_5 = /* 'cfae' */ 0x63666165, // Focus Assist is currently enabled + bmdDeckLinkFrameMetadataCintelKeykodeIsInterpolated_v11_5 = /* 'kkii' */ 0x6B6B6969 // The keykode for this frame is interpolated from nearby keykodes +}; + +/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */ + +class BMD_PUBLIC IDeckLinkVideoFrameMetadataExtensions_v11_5 : public IUnknown +{ +public: + virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ int64_t *value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ double *value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ bool* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ const char **value) = 0; + +protected: + virtual ~IDeckLinkVideoFrameMetadataExtensions_v11_5 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPI_v11_5_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v11_5_1.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v11_5_1.h new file mode 100644 index 0000000000..42bc74fcc2 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v11_5_1.h @@ -0,0 +1,57 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v11_5_1_H +#define BMD_DECKLINKAPI_v11_5_1_H + +#include "DeckLinkAPI.h" + +/* Enum BMDDeckLinkStatusID - DeckLink Status ID */ + +typedef uint32_t BMDDeckLinkStatusID_v11_5_1; +enum _BMDDeckLinkStatusID_v11_5_1 { + + /* Video output flags */ + + bmdDeckLinkStatusDetectedVideoInputFlags_v11_5_1 = /* 'dvif' */ 0x64766966, + +}; + +#endif /* defined(BMD_DECKLINKAPI_v11_5_1_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_1.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_1.h new file mode 100644 index 0000000000..3c59736c2a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_1.h @@ -0,0 +1,212 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v7_1.h */ + +#ifndef __DeckLink_API_v7_1_h__ +#define __DeckLink_API_v7_1_h__ + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// "B28131B6-59AC-4857-B5AC-CD75D5883E2F" +#define IID_IDeckLinkDisplayModeIterator_v7_1 (REFIID){0xB2,0x81,0x31,0xB6,0x59,0xAC,0x48,0x57,0xB5,0xAC,0xCD,0x75,0xD5,0x88,0x3E,0x2F} + +// "AF0CD6D5-8376-435E-8433-54F9DD530AC3" +#define IID_IDeckLinkDisplayMode_v7_1 (REFIID){0xAF,0x0C,0xD6,0xD5,0x83,0x76,0x43,0x5E,0x84,0x33,0x54,0xF9,0xDD,0x53,0x0A,0xC3} + +// "EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9" +#define IID_IDeckLinkVideoOutputCallback_v7_1 (REFIID){0xEB,0xD0,0x1A,0xFA,0xE4,0xB0,0x49,0xC6,0xA0,0x1D,0xED,0xB9,0xD1,0xB5,0x5F,0xD9} + +// "7F94F328-5ED4-4E9F-9729-76A86BDC99CC" +#define IID_IDeckLinkInputCallback_v7_1 (REFIID){0x7F,0x94,0xF3,0x28,0x5E,0xD4,0x4E,0x9F,0x97,0x29,0x76,0xA8,0x6B,0xDC,0x99,0xCC} + +// "AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5" +#define IID_IDeckLinkOutput_v7_1 (REFIID){0xAE,0x5B,0x3E,0x9B,0x4E,0x1E,0x45,0x35,0xB6,0xE8,0x48,0x0F,0xF5,0x2F,0x6C,0xE5} + +// "2B54EDEF-5B32-429F-BA11-BB990596EACD" +#define IID_IDeckLinkInput_v7_1 (REFIID){0x2B,0x54,0xED,0xEF,0x5B,0x32,0x42,0x9F,0xBA,0x11,0xBB,0x99,0x05,0x96,0xEA,0xCD} + +// "333F3A10-8C2D-43CF-B79D-46560FEEA1CE" +#define IID_IDeckLinkVideoFrame_v7_1 (REFIID){0x33,0x3F,0x3A,0x10,0x8C,0x2D,0x43,0xCF,0xB7,0x9D,0x46,0x56,0x0F,0xEE,0xA1,0xCE} + +// "C8B41D95-8848-40EE-9B37-6E3417FB114B" +#define IID_IDeckLinkVideoInputFrame_v7_1 (REFIID){0xC8,0xB4,0x1D,0x95,0x88,0x48,0x40,0xEE,0x9B,0x37,0x6E,0x34,0x17,0xFB,0x11,0x4B} + +// "C86DE4F6-A29F-42E3-AB3A-1363E29F0788" +#define IID_IDeckLinkAudioInputPacket_v7_1 (REFIID){0xC8,0x6D,0xE4,0xF6,0xA2,0x9F,0x42,0xE3,0xAB,0x3A,0x13,0x63,0xE2,0x9F,0x07,0x88} + +#if defined(__cplusplus) + +class IDeckLinkDisplayModeIterator_v7_1; +class IDeckLinkDisplayMode_v7_1; +class IDeckLinkVideoFrame_v7_1; +class IDeckLinkVideoInputFrame_v7_1; +class IDeckLinkAudioInputPacket_v7_1; + +class BMD_PUBLIC IDeckLinkDisplayModeIterator_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE Next (IDeckLinkDisplayMode_v7_1* *deckLinkDisplayMode) = 0; +}; + + +class BMD_PUBLIC IDeckLinkDisplayMode_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetName (const char **name) = 0; + virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode () = 0; + virtual long STDMETHODCALLTYPE GetWidth () = 0; + virtual long STDMETHODCALLTYPE GetHeight () = 0; + virtual HRESULT STDMETHODCALLTYPE GetFrameRate (BMDTimeValue *frameDuration, BMDTimeScale *timeScale) = 0; +}; + +class BMD_PUBLIC IDeckLinkVideoOutputCallback_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted (IDeckLinkVideoFrame_v7_1* completedFrame, BMDOutputFrameCompletionResult result) = 0; +}; + +class BMD_PUBLIC IDeckLinkInputCallback_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived (IDeckLinkVideoInputFrame_v7_1* videoFrame, IDeckLinkAudioInputPacket_v7_1* audioPacket) = 0; +}; + +// IDeckLinkOutput_v7_1. Created by QueryInterface from IDeckLink. +class BMD_PUBLIC IDeckLinkOutput_v7_1 : public IUnknown +{ +public: + // Display mode predicates + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1* *iterator) = 0; + + + // Video output + virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput (BMDDisplayMode displayMode) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput () = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator (IDeckLinkMemoryAllocator* theAllocator) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrameFromBuffer (void* buffer, int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame) = 0; + virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0; + virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback (IDeckLinkVideoOutputCallback_v7_1* theCallback) = 0; + + + // Audio output + virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput () = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll () = 0; + virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll () = 0; + virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples (void* buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; + virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples () = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback (IDeckLinkAudioOutputCallback* theCallback) = 0; + + + // Output control + virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0; + virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0; + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0; +}; + +// IDeckLinkInput_v7_1. Created by QueryInterface from IDeckLink. +class BMD_PUBLIC IDeckLinkInput_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0; + + // Video input + virtual HRESULT STDMETHODCALLTYPE EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableVideoInput () = 0; + + // Audio input + virtual HRESULT STDMETHODCALLTYPE EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableAudioInput () = 0; + virtual HRESULT STDMETHODCALLTYPE ReadAudioSamples (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesRead, BMDTimeValue *audioPacketTime, BMDTimeScale timeScale) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; + + + virtual HRESULT STDMETHODCALLTYPE StartStreams () = 0; + virtual HRESULT STDMETHODCALLTYPE StopStreams () = 0; + virtual HRESULT STDMETHODCALLTYPE PauseStreams () = 0; + virtual HRESULT STDMETHODCALLTYPE SetCallback (IDeckLinkInputCallback_v7_1* theCallback) = 0; +}; + +// IDeckLinkVideoFrame_v7_1. Created by IDeckLinkOutput::CreateVideoFrame. +class BMD_PUBLIC IDeckLinkVideoFrame_v7_1 : public IUnknown +{ +public: + virtual long STDMETHODCALLTYPE GetWidth () = 0; + virtual long STDMETHODCALLTYPE GetHeight () = 0; + virtual long STDMETHODCALLTYPE GetRowBytes () = 0; + virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat () = 0; + virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags () = 0; + virtual HRESULT STDMETHODCALLTYPE GetBytes (void* *buffer) = 0; +}; + +// IDeckLinkVideoInputFrame_v7_1. Provided by the IDeckLinkInput_v7_1 frame arrival callback. +class BMD_PUBLIC IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1 +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; +}; + +// IDeckLinkAudioInputPacket_v7_1. Provided by the IDeckLinkInput_v7_1 callback. +class BMD_PUBLIC IDeckLinkAudioInputPacket_v7_1 : public IUnknown +{ +public: + virtual long STDMETHODCALLTYPE GetSampleCount () = 0; + virtual HRESULT STDMETHODCALLTYPE GetBytes (void* *buffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale) = 0; +}; + +#endif // defined(__cplusplus) + +#endif // __DeckLink_API_v7_1_h__ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_3.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_3.h new file mode 100644 index 0000000000..37e0464db5 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_3.h @@ -0,0 +1,187 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v7_3.h */ + +#ifndef __DeckLink_API_v7_3_h__ +#define __DeckLink_API_v7_3_h__ + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v7_6.h" +#include "DeckLinkAPI_v10_11.h" + +/* Interface ID Declarations */ + +#define IID_IDeckLinkInputCallback_v7_3 /* FD6F311D-4D00-444B-9ED4-1F25B5730AD0 */ (REFIID){0xFD,0x6F,0x31,0x1D,0x4D,0x00,0x44,0x4B,0x9E,0xD4,0x1F,0x25,0xB5,0x73,0x0A,0xD0} +#define IID_IDeckLinkOutput_v7_3 /* 271C65E3-C323-4344-A30F-D908BCB20AA3 */ (REFIID){0x27,0x1C,0x65,0xE3,0xC3,0x23,0x43,0x44,0xA3,0x0F,0xD9,0x08,0xBC,0xB2,0x0A,0xA3} +#define IID_IDeckLinkInput_v7_3 /* 4973F012-9925-458C-871C-18774CDBBECB */ (REFIID){0x49,0x73,0xF0,0x12,0x99,0x25,0x45,0x8C,0x87,0x1C,0x18,0x77,0x4C,0xDB,0xBE,0xCB} +#define IID_IDeckLinkVideoInputFrame_v7_3 /* CF317790-2894-11DE-8C30-0800200C9A66 */ (REFIID){0xCF,0x31,0x77,0x90,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66} + +/* End Interface ID Declarations */ + +#if defined(__cplusplus) + +/* Forward Declarations */ + +class IDeckLinkVideoInputFrame_v7_3; + +/* End Forward Declarations */ + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput_v7_3 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (BMDDisplayMode displayMode, BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0; + virtual HRESULT CreateAncillaryData (BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount, BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0; + +protected: + virtual ~IDeckLinkOutput_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkOutput */ + + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkInputCallback_v7_3 : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_3 *videoFrame, /* in */ IDeckLinkAudioInputPacket *audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkInputCallback */ + + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v7_3 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_3 *theCallback) = 0; + +protected: + virtual ~IDeckLinkInput_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkInput */ + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame_v7_6 +{ +public: + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; + +protected: + virtual ~IDeckLinkVideoInputFrame_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkVideoInputFrame */ + +#endif // defined(__cplusplus) +#endif // __DeckLink_API_v7_3_h__ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_6.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_6.h new file mode 100644 index 0000000000..2920e45e20 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_6.h @@ -0,0 +1,418 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v7_6.h */ + +#ifndef __DeckLink_API_v7_6_h__ +#define __DeckLink_API_v7_6_h__ + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Interface ID Declarations + +#define IID_IDeckLinkVideoOutputCallback_v7_6 /* E763A626-4A3C-49D1-BF13-E7AD3692AE52 */ (REFIID){0xE7,0x63,0xA6,0x26,0x4A,0x3C,0x49,0xD1,0xBF,0x13,0xE7,0xAD,0x36,0x92,0xAE,0x52} +#define IID_IDeckLinkInputCallback_v7_6 /* 31D28EE7-88B6-4CB1-897A-CDBF79A26414 */ (REFIID){0x31,0xD2,0x8E,0xE7,0x88,0xB6,0x4C,0xB1,0x89,0x7A,0xCD,0xBF,0x79,0xA2,0x64,0x14} +#define IID_IDeckLinkDisplayModeIterator_v7_6 /* 455D741F-1779-4800-86F5-0B5D13D79751 */ (REFIID){0x45,0x5D,0x74,0x1F,0x17,0x79,0x48,0x00,0x86,0xF5,0x0B,0x5D,0x13,0xD7,0x97,0x51} +#define IID_IDeckLinkDisplayMode_v7_6 /* 87451E84-2B7E-439E-A629-4393EA4A8550 */ (REFIID){0x87,0x45,0x1E,0x84,0x2B,0x7E,0x43,0x9E,0xA6,0x29,0x43,0x93,0xEA,0x4A,0x85,0x50} +#define IID_IDeckLinkOutput_v7_6 /* 29228142-EB8C-4141-A621-F74026450955 */ (REFIID){0x29,0x22,0x81,0x42,0xEB,0x8C,0x41,0x41,0xA6,0x21,0xF7,0x40,0x26,0x45,0x09,0x55} +#define IID_IDeckLinkInput_v7_6 /* 300C135A-9F43-48E2-9906-6D7911D93CF1 */ (REFIID){0x30,0x0C,0x13,0x5A,0x9F,0x43,0x48,0xE2,0x99,0x06,0x6D,0x79,0x11,0xD9,0x3C,0xF1} +#define IID_IDeckLinkTimecode_v7_6 /* EFB9BCA6-A521-44F7-BD69-2332F24D9EE6 */ (REFIID){0xEF,0xB9,0xBC,0xA6,0xA5,0x21,0x44,0xF7,0xBD,0x69,0x23,0x32,0xF2,0x4D,0x9E,0xE6} +#define IID_IDeckLinkVideoFrame_v7_6 /* A8D8238E-6B18-4196-99E1-5AF717B83D32 */ (REFIID){0xA8,0xD8,0x23,0x8E,0x6B,0x18,0x41,0x96,0x99,0xE1,0x5A,0xF7,0x17,0xB8,0x3D,0x32} +#define IID_IDeckLinkMutableVideoFrame_v7_6 /* 46FCEE00-B4E6-43D0-91C0-023A7FCEB34F */ (REFIID){0x46,0xFC,0xEE,0x00,0xB4,0xE6,0x43,0xD0,0x91,0xC0,0x02,0x3A,0x7F,0xCE,0xB3,0x4F} +#define IID_IDeckLinkVideoInputFrame_v7_6 /* 9A74FA41-AE9F-47AC-8CF4-01F42DD59965 */ (REFIID){0x9A,0x74,0xFA,0x41,0xAE,0x9F,0x47,0xAC,0x8C,0xF4,0x01,0xF4,0x2D,0xD5,0x99,0x65} +#define IID_IDeckLinkScreenPreviewCallback_v7_6 /* 373F499D-4B4D-4518-AD22-6354E5A5825E */ (REFIID){0x37,0x3F,0x49,0x9D,0x4B,0x4D,0x45,0x18,0xAD,0x22,0x63,0x54,0xE5,0xA5,0x82,0x5E} +#define IID_IDeckLinkGLScreenPreviewHelper_v7_6 /* BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA */ (REFIID){0xBA,0x57,0x5C,0xD9,0xA1,0x5E,0x49,0x7B,0xB2,0xC2,0xF9,0xAF,0xE7,0xBE,0x4E,0xBA} +#define IID_IDeckLinkVideoConversion_v7_6 /* 3EB504C9-F97D-40FE-A158-D407D48CB53B */ (REFIID){0x3E,0xB5,0x04,0xC9,0xF9,0x7D,0x40,0xFE,0xA1,0x58,0xD4,0x07,0xD4,0x8C,0xB5,0x3B} +#define IID_IDeckLinkConfiguration_v7_6 /* B8EAD569-B764-47F0-A73F-AE40DF6CBF10 */ (REFIID){0xB8,0xEA,0xD5,0x69,0xB7,0x64,0x47,0xF0,0xA7,0x3F,0xAE,0x40,0xDF,0x6C,0xBF,0x10} + + +#if defined(__cplusplus) + +/* Enum BMDVideoConnection - Video connection types */ + +typedef uint32_t BMDVideoConnection_v7_6; +enum _BMDVideoConnection_v7_6 { + bmdVideoConnectionSDI_v7_6 = 'sdi ', + bmdVideoConnectionHDMI_v7_6 = 'hdmi', + bmdVideoConnectionOpticalSDI_v7_6 = 'opti', + bmdVideoConnectionComponent_v7_6 = 'cpnt', + bmdVideoConnectionComposite_v7_6 = 'cmst', + bmdVideoConnectionSVideo_v7_6 = 'svid' +}; + +// Forward Declarations + +class IDeckLinkVideoOutputCallback_v7_6; +class IDeckLinkInputCallback_v7_6; +class IDeckLinkDisplayModeIterator_v7_6; +class IDeckLinkDisplayMode_v7_6; +class IDeckLinkOutput_v7_6; +class IDeckLinkInput_v7_6; +class IDeckLinkTimecode_v7_6; +class IDeckLinkVideoFrame_v7_6; +class IDeckLinkMutableVideoFrame_v7_6; +class IDeckLinkVideoInputFrame_v7_6; +class IDeckLinkScreenPreviewCallback_v7_6; +class IDeckLinkGLScreenPreviewHelper_v7_6; +class IDeckLinkVideoConversion_v7_6; + + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +class BMD_PUBLIC IDeckLinkVideoOutputCallback_v7_6 : public IUnknown +{ +public: + virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame_v7_6 *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; + virtual HRESULT ScheduledPlaybackHasStopped (void) = 0; + +protected: + virtual ~IDeckLinkVideoOutputCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkInputCallback_v7_6 : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_6* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ + +class BMD_PUBLIC IDeckLinkDisplayModeIterator_v7_6 : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode) = 0; + +protected: + virtual ~IDeckLinkDisplayModeIterator_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkDisplayMode - represents a display mode */ + +class BMD_PUBLIC IDeckLinkDisplayMode_v7_6 : public IUnknown +{ +public: + virtual HRESULT GetName (/* out */ const char **name) = 0; + virtual BMDDisplayMode GetDisplayMode (void) = 0; + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual HRESULT GetFrameRate (/* out */ BMDTimeValue *frameDuration, /* out */ BMDTimeScale *timeScale) = 0; + virtual BMDFieldDominance GetFieldDominance (void) = 0; + +protected: + virtual ~IDeckLinkDisplayMode_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput_v7_6 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback_v7_6 *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkOutput_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkInput_v7_6 - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v7_6 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_6 *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ + +class BMD_PUBLIC IDeckLinkTimecode_v7_6 : public IUnknown +{ +public: + virtual BMDTimecodeBCD GetBCD (void) = 0; + virtual HRESULT GetComponents (/* out */ uint8_t *hours, /* out */ uint8_t *minutes, /* out */ uint8_t *seconds, /* out */ uint8_t *frames) = 0; + virtual HRESULT GetString (/* out */ const char **timecode) = 0; + virtual BMDTimecodeFlags GetFlags (void) = 0; + +protected: + virtual ~IDeckLinkTimecode_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +class BMD_PUBLIC IDeckLinkVideoFrame_v7_6 : public IUnknown +{ +public: + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual long GetRowBytes (void) = 0; + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual BMDFrameFlags GetFlags (void) = 0; + virtual HRESULT GetBytes (/* out */ void **buffer) = 0; + + virtual HRESULT GetTimecode (BMDTimecodeFormat format, /* out */ IDeckLinkTimecode_v7_6 **timecode) = 0; + virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0; + +protected: + virtual ~IDeckLinkVideoFrame_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +class BMD_PUBLIC IDeckLinkMutableVideoFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 +{ +public: + virtual HRESULT SetFlags (BMDFrameFlags newFlags) = 0; + + virtual HRESULT SetTimecode (BMDTimecodeFormat format, /* in */ IDeckLinkTimecode_v7_6 *timecode) = 0; + virtual HRESULT SetTimecodeFromComponents (BMDTimecodeFormat format, uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t frames, BMDTimecodeFlags flags) = 0; + virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary *ancillary) = 0; + +protected: + virtual ~IDeckLinkMutableVideoFrame_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkVideoInputFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 +{ +public: + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; + virtual HRESULT GetHardwareReferenceTimestamp (BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0; + +protected: + virtual ~IDeckLinkVideoInputFrame_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +class BMD_PUBLIC IDeckLinkScreenPreviewCallback_v7_6 : public IUnknown +{ +public: + virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + +protected: + virtual ~IDeckLinkScreenPreviewCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ + +class BMD_PUBLIC IDeckLinkGLScreenPreviewHelper_v7_6 : public IUnknown +{ +public: + + /* Methods must be called with OpenGL context set */ + + virtual HRESULT InitializeGL (void) = 0; + virtual HRESULT PaintGL (void) = 0; + virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + +protected: + virtual ~IDeckLinkGLScreenPreviewHelper_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */ + +class BMD_PUBLIC IDeckLinkVideoConversion_v7_6 : public IUnknown +{ +public: + virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame_v7_6* srcFrame, /* in */ IDeckLinkVideoFrame_v7_6* dstFrame) = 0; + +protected: + virtual ~IDeckLinkVideoConversion_v7_6 () {}; // call Release method to drop reference count +}; + +/* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkConfiguration_v7_6 : public IUnknown +{ +public: + virtual HRESULT GetConfigurationValidator (/* out */ IDeckLinkConfiguration_v7_6 **configObject) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + + /* Video Output Configuration */ + + virtual HRESULT SetVideoOutputFormat (/* in */ BMDVideoConnection_v7_6 videoOutputConnection) = 0; + virtual HRESULT IsVideoOutputActive (/* in */ BMDVideoConnection_v7_6 videoOutputConnection, /* out */ bool *active) = 0; + + virtual HRESULT SetAnalogVideoOutputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; + virtual HRESULT GetAnalogVideoOutputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; + + virtual HRESULT EnableFieldFlickerRemovalWhenPaused (/* in */ bool enable) = 0; + virtual HRESULT IsEnabledFieldFlickerRemovalWhenPaused (/* out */ bool *enabled) = 0; + + virtual HRESULT Set444And3GBpsVideoOutput (/* in */ bool enable444VideoOutput, /* in */ bool enable3GbsOutput) = 0; + virtual HRESULT Get444And3GBpsVideoOutput (/* out */ bool *is444VideoOutputEnabled, /* out */ bool *threeGbsOutputEnabled) = 0; + + virtual HRESULT SetVideoOutputConversionMode (/* in */ BMDVideoOutputConversionMode conversionMode) = 0; + virtual HRESULT GetVideoOutputConversionMode (/* out */ BMDVideoOutputConversionMode *conversionMode) = 0; + + virtual HRESULT Set_HD1080p24_to_HD1080i5994_Conversion (/* in */ bool enable) = 0; + virtual HRESULT Get_HD1080p24_to_HD1080i5994_Conversion (/* out */ bool *enabled) = 0; + + /* Video Input Configuration */ + + virtual HRESULT SetVideoInputFormat (/* in */ BMDVideoConnection_v7_6 videoInputFormat) = 0; + virtual HRESULT GetVideoInputFormat (/* out */ BMDVideoConnection_v7_6 *videoInputFormat) = 0; + + virtual HRESULT SetAnalogVideoInputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; + virtual HRESULT GetAnalogVideoInputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; + + virtual HRESULT SetVideoInputConversionMode (/* in */ BMDVideoInputConversionMode conversionMode) = 0; + virtual HRESULT GetVideoInputConversionMode (/* out */ BMDVideoInputConversionMode *conversionMode) = 0; + + virtual HRESULT SetBlackVideoOutputDuringCapture (/* in */ bool blackOutInCapture) = 0; + virtual HRESULT GetBlackVideoOutputDuringCapture (/* out */ bool *blackOutInCapture) = 0; + + virtual HRESULT Set32PulldownSequenceInitialTimecodeFrame (/* in */ uint32_t aFrameTimecode) = 0; + virtual HRESULT Get32PulldownSequenceInitialTimecodeFrame (/* out */ uint32_t *aFrameTimecode) = 0; + + virtual HRESULT SetVancSourceLineMapping (/* in */ uint32_t activeLine1VANCsource, /* in */ uint32_t activeLine2VANCsource, /* in */ uint32_t activeLine3VANCsource) = 0; + virtual HRESULT GetVancSourceLineMapping (/* out */ uint32_t *activeLine1VANCsource, /* out */ uint32_t *activeLine2VANCsource, /* out */ uint32_t *activeLine3VANCsource) = 0; + + /* Audio Input Configuration */ + + virtual HRESULT SetAudioInputFormat (/* in */ BMDAudioConnection audioInputFormat) = 0; + virtual HRESULT GetAudioInputFormat (/* out */ BMDAudioConnection *audioInputFormat) = 0; +}; + +/* Functions */ + +extern "C" { + + BMD_PUBLIC IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void); + BMD_PUBLIC IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void); + BMD_PUBLIC IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void); + +}; + + +#endif // defined(__cplusplus) +#endif // __DeckLink_API_v7_6_h__ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_9.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_9.h new file mode 100644 index 0000000000..54c92f1745 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v7_9.h @@ -0,0 +1,101 @@ +/* -LICENSE-START- +** Copyright (c) 2010 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v7_9.h */ + +#ifndef __DeckLink_API_v7_9_h__ +#define __DeckLink_API_v7_9_h__ + +#include "DeckLinkAPI.h" + +// Interface ID Declarations +#define IID_IDeckLinkDeckControl_v7_9 /* A4D81043-0619-42B7-8ED6-602D29041DF7 */ (REFIID){0xA4,0xD8,0x10,0x43,0x06,0x19,0x42,0xB7,0x8E,0xD6,0x60,0x2D,0x29,0x04,0x1D,0xF7} + +#if defined(__cplusplus) + + +// Forward Declarations +class IDeckLinkDeckControl_v7_9; + +/* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */ +class BMD_PUBLIC IDeckLinkDeckControl_v7_9 : public IUnknown +{ +public: + virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Close (/* in */ bool standbyOn) = 0; + virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0; + virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0; + virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeString (/* out */ const char **currentTimeCode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0; + virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0; + virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0; + virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0; + virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0; + virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0; + virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0; + virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Abort (void) = 0; + virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback *callback) = 0; + +protected: + virtual ~IDeckLinkDeckControl_v7_9 () {}; // call Release method to drop reference count +}; + + + +#endif // defined(__cplusplus) +#endif // __DeckLink_API_v7_9_h__ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v8_0.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v8_0.h new file mode 100644 index 0000000000..32e7b93670 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v8_0.h @@ -0,0 +1,76 @@ +/* -LICENSE-START- +** Copyright (c) 2011 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v8_0_H +#define BMD_DECKLINKAPI_v8_0_H + +#include "DeckLinkAPI.h" + +// Interface ID Declarations + +#define IID_IDeckLink_v8_0 /* 62BFF75D-6569-4E55-8D4D-66AA03829ABC */ (REFIID){0x62,0xBF,0xF7,0x5D,0x65,0x69,0x4E,0x55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC} +#define IID_IDeckLinkIterator_v8_0 /* 74E936FC-CC28-4A67-81A0-1E94E52D4E69 */ (REFIID){0x74,0xE9,0x36,0xFC,0xCC,0x28,0x4A,0x67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69} + +#if defined (__cplusplus) + +/* Interface IDeckLink_v8_0 - represents a DeckLink device */ + +class BMD_PUBLIC IDeckLink_v8_0 : public IUnknown +{ +public: + virtual HRESULT GetModelName (/* out */ const char **modelName) = 0; +}; + +/* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */ + +class BMD_PUBLIC IDeckLinkIterator_v8_0 : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLink_v8_0 **deckLinkInstance) = 0; +}; + +extern "C" { + BMD_PUBLIC IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance_v8_0 (void); +}; + +#endif // defined __cplusplus + +#endif /* defined(BMD_DECKLINKAPI_v8_0_H) */ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v8_1.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v8_1.h new file mode 100644 index 0000000000..5bc67de2ab --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v8_1.h @@ -0,0 +1,124 @@ +/* -LICENSE-START- + ** Copyright (c) 2011 Blackmagic Design + ** + ** Permission is hereby granted, free of charge, to any person or organization + ** obtaining a copy of the software and accompanying documentation (the + ** "Software") to use, reproduce, display, distribute, sub-license, execute, + ** and transmit the Software, and to prepare derivative works of the Software, + ** and to permit third-parties to whom the Software is furnished to do so, in + ** accordance with: + ** + ** (1) if the Software is obtained from Blackmagic Design, the End User License + ** Agreement for the Software Development Kit (“EULA”) available at + ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + ** + ** (2) if the Software is obtained from any third party, such licensing terms + ** as notified by that third party, + ** + ** and all subject to the following: + ** + ** (3) the copyright notices in the Software and this entire statement, + ** including the above license grant, this restriction and the following + ** disclaimer, must be included in all copies of the Software, in whole or in + ** part, and all derivative works of the Software, unless such copies or + ** derivative works are solely in the form of machine-executable object code + ** generated by a source language processor. + ** + ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + ** DEALINGS IN THE SOFTWARE. + ** + ** A copy of the Software is available free of charge at + ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + ** + ** -LICENSE-END- + */ + +#ifndef BMD_DECKLINKAPI_v8_1_H +#define BMD_DECKLINKAPI_v8_1_H + +#include "DeckLinkAPI.h" + + +// Interface ID Declarations + +#define IID_IDeckLinkDeckControlStatusCallback_v8_1 /* E5F693C1-4283-4716-B18F-C1431521955B */ (REFIID){0xE5,0xF6,0x93,0xC1,0x42,0x83,0x47,0x16,0xB1,0x8F,0xC1,0x43,0x15,0x21,0x95,0x5B} +#define IID_IDeckLinkDeckControl_v8_1 /* 522A9E39-0F3C-4742-94EE-D80DE335DA1D */ (REFIID){0x52,0x2A,0x9E,0x39,0x0F,0x3C,0x47,0x42,0x94,0xEE,0xD8,0x0D,0xE3,0x35,0xDA,0x1D} + + +/* Enum BMDDeckControlVTRControlState_v8_1 - VTR Control state */ + +typedef uint32_t BMDDeckControlVTRControlState_v8_1; +enum _BMDDeckControlVTRControlState_v8_1 { + bmdDeckControlNotInVTRControlMode_v8_1 = 'nvcm', + bmdDeckControlVTRControlPlaying_v8_1 = 'vtrp', + bmdDeckControlVTRControlRecording_v8_1 = 'vtrr', + bmdDeckControlVTRControlStill_v8_1 = 'vtra', + bmdDeckControlVTRControlSeeking_v8_1 = 'vtrs', + bmdDeckControlVTRControlStopped_v8_1 = 'vtro' +}; + + +/* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */ + +class BMD_PUBLIC IDeckLinkDeckControlStatusCallback_v8_1 : public IUnknown +{ +public: + virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; + virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState_v8_1 newState, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0; + +protected: + virtual ~IDeckLinkDeckControlStatusCallback_v8_1 () {}; // call Release method to drop reference count +}; + +/* Interface IDeckLinkDeckControl_v8_1 - Deck Control main interface */ + +class BMD_PUBLIC IDeckLinkDeckControl_v8_1 : public IUnknown +{ +public: + virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Close (/* in */ bool standbyOn) = 0; + virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState_v8_1 *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0; + virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0; + virtual HRESULT SendCommand (/* in */ uint8_t *inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t *outBuffer, /* out */ uint32_t *outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeString (/* out */ const char **currentTimeCode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0; + virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0; + virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0; + virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0; + virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0; + virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0; + virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0; + virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Abort (void) = 0; + virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback_v8_1 *callback) = 0; + +protected: + virtual ~IDeckLinkDeckControl_v8_1 () {}; // call Release method to drop reference count +}; + + +#endif // BMD_DECKLINKAPI_v8_1_H diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v9_2.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v9_2.h new file mode 100644 index 0000000000..c11c801292 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v9_2.h @@ -0,0 +1,96 @@ +/* -LICENSE-START- +** Copyright (c) 2012 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v9_2_H +#define BMD_DECKLINKAPI_v9_2_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" +#include "DeckLinkAPIVideoInput_v11_5_1.h" + + +// Interface ID Declarations + +#define IID_IDeckLinkInput_v9_2 /* 6D40EF78-28B9-4E21-990D-95BB7750A04F */ (REFIID){0x6D,0x40,0xEF,0x78,0x28,0xB9,0x4E,0x21,0x99,0x0D,0x95,0xBB,0x77,0x50,0xA0,0x4F} + + +#if defined(__cplusplus) + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v9_2 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1 *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v9_2 () {}; // call Release method to drop reference count +}; + + +#endif // defined(__cplusplus) +#endif // BMD_DECKLINKAPI_v9_2_H diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v9_9.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v9_9.h new file mode 100644 index 0000000000..16dc671344 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/DeckLinkAPI_v9_9.h @@ -0,0 +1,112 @@ +/* -LICENSE-START- +** Copyright (c) 2013 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v9_9_H +#define BMD_DECKLINKAPI_v9_9_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + + +// Interface ID Declarations + +#define IID_IDeckLinkOutput_v9_9 /* A3EF0963-0862-44ED-92A9-EE89ABF431C7 */ (REFIID){0xA3,0xEF,0x09,0x63,0x08,0x62,0x44,0xED,0x92,0xA9,0xEE,0x89,0xAB,0xF4,0x31,0xC7} + + +#if defined(__cplusplus) + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput_v9_9 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkOutput_v9_9 () {}; // call Release method to drop reference count +}; + +#endif // defined(__cplusplus) +#endif // BMD_DECKLINKAPI_v9_9_H diff --git a/subprojects/gst-plugins-bad/sys/decklink2/linux/LinuxCOM.h b/subprojects/gst-plugins-bad/sys/decklink2/linux/LinuxCOM.h new file mode 100644 index 0000000000..cad638c234 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/linux/LinuxCOM.h @@ -0,0 +1,116 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef __LINUX_COM_H_ +#define __LINUX_COM_H_ + +struct REFIID +{ + unsigned char byte0; + unsigned char byte1; + unsigned char byte2; + unsigned char byte3; + unsigned char byte4; + unsigned char byte5; + unsigned char byte6; + unsigned char byte7; + unsigned char byte8; + unsigned char byte9; + unsigned char byte10; + unsigned char byte11; + unsigned char byte12; + unsigned char byte13; + unsigned char byte14; + unsigned char byte15; +}; + +typedef REFIID CFUUIDBytes; +#define CFUUIDGetUUIDBytes(x) x + +typedef int HRESULT; +typedef unsigned long ULONG; +typedef void *LPVOID; + +#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) +#define FAILED(Status) ((HRESULT)(Status)<0) + +#define IS_ERROR(Status) ((unsigned long)(Status) >> 31 == SEVERITY_ERROR) +#define HRESULT_CODE(hr) ((hr) & 0xFFFF) +#define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) +#define HRESULT_SEVERITY(hr) (((hr) >> 31) & 0x1) +#define SEVERITY_SUCCESS 0 +#define SEVERITY_ERROR 1 + +#define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_UNEXPECTED ((HRESULT)0x8000FFFFL) +#define E_NOTIMPL ((HRESULT)0x80000001L) +#define E_OUTOFMEMORY ((HRESULT)0x80000002L) +#define E_INVALIDARG ((HRESULT)0x80000003L) +#define E_NOINTERFACE ((HRESULT)0x80000004L) +#define E_POINTER ((HRESULT)0x80000005L) +#define E_HANDLE ((HRESULT)0x80000006L) +#define E_ABORT ((HRESULT)0x80000007L) +#define E_FAIL ((HRESULT)0x80000008L) +#define E_ACCESSDENIED ((HRESULT)0x80000009L) + +#define STDMETHODCALLTYPE + +#define IID_IUnknown (REFIID){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} +#define IUnknownUUID IID_IUnknown + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +#ifdef __cplusplus +class BMD_PUBLIC IUnknown +{ + public: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) = 0; + virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; + virtual ULONG STDMETHODCALLTYPE Release(void) = 0; +}; +#endif + +#endif + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI.h new file mode 100644 index 0000000000..e9070c88dc --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI.h @@ -0,0 +1,1332 @@ +/* -LICENSE-START- + ** Copyright (c) 2022 Blackmagic Design + ** + ** Permission is hereby granted, free of charge, to any person or organization + ** obtaining a copy of the software and accompanying documentation (the + ** "Software") to use, reproduce, display, distribute, sub-license, execute, + ** and transmit the Software, and to prepare derivative works of the Software, + ** and to permit third-parties to whom the Software is furnished to do so, in + ** accordance with: + ** + ** (1) if the Software is obtained from Blackmagic Design, the End User License + ** Agreement for the Software Development Kit ("EULA") available at + ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + ** + ** (2) if the Software is obtained from any third party, such licensing terms + ** as notified by that third party, + ** + ** and all subject to the following: + ** + ** (3) the copyright notices in the Software and this entire statement, + ** including the above license grant, this restriction and the following + ** disclaimer, must be included in all copies of the Software, in whole or in + ** part, and all derivative works of the Software, unless such copies or + ** derivative works are solely in the form of machine-executable object code + ** generated by a source language processor. + ** + ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + ** DEALINGS IN THE SOFTWARE. + ** + ** A copy of the Software is available free of charge at + ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + ** + ** -LICENSE-END- + */ + + +#ifndef BMD_DECKLINKAPI_H +#define BMD_DECKLINKAPI_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +/* DeckLink API */ + +#include +#include +#include + +#include "DeckLinkAPITypes.h" +#include "DeckLinkAPIModes.h" +#include "DeckLinkAPIDiscovery.h" +#include "DeckLinkAPIConfiguration.h" +#include "DeckLinkAPIDeckControl.h" + +#include "DeckLinkAPIStreaming.h" + +#define BLACKMAGIC_DECKLINK_API_MAGIC 1 + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkVideoOutputCallback = /* 20AA5225-1958-47CB-820B-80A8D521A6EE */ { 0x20,0xAA,0x52,0x25,0x19,0x58,0x47,0xCB,0x82,0x0B,0x80,0xA8,0xD5,0x21,0xA6,0xEE }; +BMD_CONST REFIID IID_IDeckLinkInputCallback = /* C6FCE4C9-C4E4-4047-82FB-5D238232A902 */ { 0xC6,0xFC,0xE4,0xC9,0xC4,0xE4,0x40,0x47,0x82,0xFB,0x5D,0x23,0x82,0x32,0xA9,0x02 }; +BMD_CONST REFIID IID_IDeckLinkEncoderInputCallback = /* ACF13E61-F4A0-4974-A6A7-59AFF6268B31 */ { 0xAC,0xF1,0x3E,0x61,0xF4,0xA0,0x49,0x74,0xA6,0xA7,0x59,0xAF,0xF6,0x26,0x8B,0x31 }; +BMD_CONST REFIID IID_IDeckLinkMemoryAllocator = /* B36EB6E7-9D29-4AA8-92EF-843B87A289E8 */ { 0xB3,0x6E,0xB6,0xE7,0x9D,0x29,0x4A,0xA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8 }; +BMD_CONST REFIID IID_IDeckLinkAudioOutputCallback = /* 403C681B-7F46-4A12-B993-2BB127084EE6 */ { 0x40,0x3C,0x68,0x1B,0x7F,0x46,0x4A,0x12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6 }; +BMD_CONST REFIID IID_IDeckLinkIterator = /* 50FB36CD-3063-4B73-BDBB-958087F2D8BA */ { 0x50,0xFB,0x36,0xCD,0x30,0x63,0x4B,0x73,0xBD,0xBB,0x95,0x80,0x87,0xF2,0xD8,0xBA }; +BMD_CONST REFIID IID_IDeckLinkAPIInformation = /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ { 0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4 }; +BMD_CONST REFIID IID_IDeckLinkOutput = /* BE2D9020-461E-442F-84B7-E949CB953B9D */ { 0xBE,0x2D,0x90,0x20,0x46,0x1E,0x44,0x2F,0x84,0xB7,0xE9,0x49,0xCB,0x95,0x3B,0x9D }; +BMD_CONST REFIID IID_IDeckLinkInput = /* C21CDB6E-F414-46E4-A636-80A566E0ED37 */ { 0xC2,0x1C,0xDB,0x6E,0xF4,0x14,0x46,0xE4,0xA6,0x36,0x80,0xA5,0x66,0xE0,0xED,0x37 }; +BMD_CONST REFIID IID_IDeckLinkHDMIInputEDID = /* ABBBACBC-45BC-4665-9D92-ACE6E5A97902 */ { 0xAB,0xBB,0xAC,0xBC,0x45,0xBC,0x46,0x65,0x9D,0x92,0xAC,0xE6,0xE5,0xA9,0x79,0x02 }; +BMD_CONST REFIID IID_IDeckLinkEncoderInput = /* F222551D-13DF-4FD8-B587-9D4F19EC12C9 */ { 0xF2,0x22,0x55,0x1D,0x13,0xDF,0x4F,0xD8,0xB5,0x87,0x9D,0x4F,0x19,0xEC,0x12,0xC9 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrame = /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ { 0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17 }; +BMD_CONST REFIID IID_IDeckLinkMutableVideoFrame = /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ { 0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrame3DExtensions = /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ { 0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions = /* E232A5B7-4DB4-44C9-9152-F47C12E5F051 */ { 0xE2,0x32,0xA5,0xB7,0x4D,0xB4,0x44,0xC9,0x91,0x52,0xF4,0x7C,0x12,0xE5,0xF0,0x51 }; +BMD_CONST REFIID IID_IDeckLinkVideoInputFrame = /* 05CFE374-537C-4094-9A57-680525118F44 */ { 0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44 }; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacket = /* CC5BBF7E-029C-4D3B-9158-6000EF5E3670 */ { 0xCC,0x5B,0xBF,0x7E,0x02,0x9C,0x4D,0x3B,0x91,0x58,0x60,0x00,0xEF,0x5E,0x36,0x70 }; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacketIterator = /* 3FC8994B-88FB-4C17-968F-9AAB69D964A7 */ { 0x3F,0xC8,0x99,0x4B,0x88,0xFB,0x4C,0x17,0x96,0x8F,0x9A,0xAB,0x69,0xD9,0x64,0xA7 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillaryPackets = /* 6C186C0F-459E-41D8-AEE2-4812D81AEE68 */ { 0x6C,0x18,0x6C,0x0F,0x45,0x9E,0x41,0xD8,0xAE,0xE2,0x48,0x12,0xD8,0x1A,0xEE,0x68 }; +BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillary = /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ { 0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04 }; +BMD_CONST REFIID IID_IDeckLinkEncoderPacket = /* B693F36C-316E-4AF1-B6C2-F389A4BCA620 */ { 0xB6,0x93,0xF3,0x6C,0x31,0x6E,0x4A,0xF1,0xB6,0xC2,0xF3,0x89,0xA4,0xBC,0xA6,0x20 }; +BMD_CONST REFIID IID_IDeckLinkEncoderVideoPacket = /* 4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0 */ { 0x4E,0x7F,0xD9,0x44,0xE8,0xC7,0x4E,0xAC,0xB8,0xC0,0x7B,0x77,0xF8,0x0F,0x5A,0xE0 }; +BMD_CONST REFIID IID_IDeckLinkEncoderAudioPacket = /* 49E8EDC8-693B-4E14-8EF6-12C658F5A07A */ { 0x49,0xE8,0xED,0xC8,0x69,0x3B,0x4E,0x14,0x8E,0xF6,0x12,0xC6,0x58,0xF5,0xA0,0x7A }; +BMD_CONST REFIID IID_IDeckLinkH265NALPacket = /* 639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7 */ { 0x63,0x9C,0x8E,0x0B,0x68,0xD5,0x4B,0xDE,0xA6,0xD4,0x95,0xF3,0xAE,0xAF,0xF2,0xE7 }; +BMD_CONST REFIID IID_IDeckLinkAudioInputPacket = /* E43D5870-2894-11DE-8C30-0800200C9A66 */ { 0xE4,0x3D,0x58,0x70,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66 }; +BMD_CONST REFIID IID_IDeckLinkScreenPreviewCallback = /* B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438 */ { 0xB1,0xD3,0xF4,0x9A,0x85,0xFE,0x4C,0x5D,0x95,0xC8,0x0B,0x5D,0x5D,0xCC,0xD4,0x38 }; +BMD_CONST REFIID IID_IDeckLinkCocoaScreenPreviewCallback = /* D174152F-8F96-4C07-83A5-DD5F5AF0A2AA */ { 0xD1,0x74,0x15,0x2F,0x8F,0x96,0x4C,0x07,0x83,0xA5,0xDD,0x5F,0x5A,0xF0,0xA2,0xAA }; +BMD_CONST REFIID IID_IDeckLinkGLScreenPreviewHelper = /* 504E2209-CAC7-4C1A-9FB4-C5BB6274D22F */ { 0x50,0x4E,0x22,0x09,0xCA,0xC7,0x4C,0x1A,0x9F,0xB4,0xC5,0xBB,0x62,0x74,0xD2,0x2F }; +BMD_CONST REFIID IID_IDeckLinkMetalScreenPreviewHelper = /* 1AB252C5-DACB-4AE8-A58B-5320DE9CE373 */ { 0x1A,0xB2,0x52,0xC5,0xDA,0xCB,0x4A,0xE8,0xA5,0x8B,0x53,0x20,0xDE,0x9C,0xE3,0x73 }; +BMD_CONST REFIID IID_IDeckLinkNotificationCallback = /* B002A1EC-070D-4288-8289-BD5D36E5FF0D */ { 0xB0,0x02,0xA1,0xEC,0x07,0x0D,0x42,0x88,0x82,0x89,0xBD,0x5D,0x36,0xE5,0xFF,0x0D }; +BMD_CONST REFIID IID_IDeckLinkNotification = /* B85DF4C8-BDF5-47C1-8064-28162EBDD4EB */ { 0xB8,0x5D,0xF4,0xC8,0xBD,0xF5,0x47,0xC1,0x80,0x64,0x28,0x16,0x2E,0xBD,0xD4,0xEB }; +BMD_CONST REFIID IID_IDeckLinkProfileAttributes = /* 17D4BF8E-4911-473A-80A0-731CF6FF345B */ { 0x17,0xD4,0xBF,0x8E,0x49,0x11,0x47,0x3A,0x80,0xA0,0x73,0x1C,0xF6,0xFF,0x34,0x5B }; +BMD_CONST REFIID IID_IDeckLinkProfileIterator = /* 29E5A8C0-8BE4-46EB-93AC-31DAAB5B7BF2 */ { 0x29,0xE5,0xA8,0xC0,0x8B,0xE4,0x46,0xEB,0x93,0xAC,0x31,0xDA,0xAB,0x5B,0x7B,0xF2 }; +BMD_CONST REFIID IID_IDeckLinkProfile = /* 16093466-674A-432B-9DA0-1AC2C5A8241C */ { 0x16,0x09,0x34,0x66,0x67,0x4A,0x43,0x2B,0x9D,0xA0,0x1A,0xC2,0xC5,0xA8,0x24,0x1C }; +BMD_CONST REFIID IID_IDeckLinkProfileCallback = /* A4F9341E-97AA-4E04-8935-15F809898CEA */ { 0xA4,0xF9,0x34,0x1E,0x97,0xAA,0x4E,0x04,0x89,0x35,0x15,0xF8,0x09,0x89,0x8C,0xEA }; +BMD_CONST REFIID IID_IDeckLinkProfileManager = /* 30D41429-3998-4B6D-84F8-78C94A797C6E */ { 0x30,0xD4,0x14,0x29,0x39,0x98,0x4B,0x6D,0x84,0xF8,0x78,0xC9,0x4A,0x79,0x7C,0x6E }; +BMD_CONST REFIID IID_IDeckLinkStatus = /* 5F558200-4028-49BC-BEAC-DB3FA4A96E46 */ { 0x5F,0x55,0x82,0x00,0x40,0x28,0x49,0xBC,0xBE,0xAC,0xDB,0x3F,0xA4,0xA9,0x6E,0x46 }; +BMD_CONST REFIID IID_IDeckLinkKeyer = /* 89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3 */ { 0x89,0xAF,0xCA,0xF5,0x65,0xF8,0x42,0x1E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3 }; +BMD_CONST REFIID IID_IDeckLinkVideoConversion = /* 3BBCB8A2-DA2C-42D9-B5D8-88083644E99A */ { 0x3B,0xBC,0xB8,0xA2,0xDA,0x2C,0x42,0xD9,0xB5,0xD8,0x88,0x08,0x36,0x44,0xE9,0x9A }; +BMD_CONST REFIID IID_IDeckLinkDeviceNotificationCallback = /* 4997053B-0ADF-4CC8-AC70-7A50C4BE728F */ { 0x49,0x97,0x05,0x3B,0x0A,0xDF,0x4C,0xC8,0xAC,0x70,0x7A,0x50,0xC4,0xBE,0x72,0x8F }; +BMD_CONST REFIID IID_IDeckLinkDiscovery = /* CDBF631C-BC76-45FA-B44D-C55059BC6101 */ { 0xCD,0xBF,0x63,0x1C,0xBC,0x76,0x45,0xFA,0xB4,0x4D,0xC5,0x50,0x59,0xBC,0x61,0x01 }; + +/* Enum BMDVideoOutputFlags - Flags to control the output of ancillary data along with video. */ + +typedef uint32_t BMDVideoOutputFlags; +enum _BMDVideoOutputFlags { + bmdVideoOutputFlagDefault = 0, + bmdVideoOutputVANC = 1 << 0, + bmdVideoOutputVITC = 1 << 1, + bmdVideoOutputRP188 = 1 << 2, + bmdVideoOutputDualStream3D = 1 << 4, + bmdVideoOutputSynchronizeToPlaybackGroup = 1 << 6 +}; + +/* Enum BMDSupportedVideoModeFlags - Flags to describe supported video modes */ + +typedef uint32_t BMDSupportedVideoModeFlags; +enum _BMDSupportedVideoModeFlags { + bmdSupportedVideoModeDefault = 0, + bmdSupportedVideoModeKeying = 1 << 0, + bmdSupportedVideoModeDualStream3D = 1 << 1, + bmdSupportedVideoModeSDISingleLink = 1 << 2, + bmdSupportedVideoModeSDIDualLink = 1 << 3, + bmdSupportedVideoModeSDIQuadLink = 1 << 4, + bmdSupportedVideoModeInAnyProfile = 1 << 5 +}; + +/* Enum BMDPacketType - Type of packet */ + +typedef uint32_t BMDPacketType; +enum _BMDPacketType { + bmdPacketTypeStreamInterruptedMarker = /* 'sint' */ 0x73696E74, // A packet of this type marks the time when a video stream was interrupted, for example by a disconnected cable + bmdPacketTypeStreamData = /* 'sdat' */ 0x73646174 // Regular stream data +}; + +/* Enum BMDFrameFlags - Frame flags */ + +typedef uint32_t BMDFrameFlags; +enum _BMDFrameFlags { + bmdFrameFlagDefault = 0, + bmdFrameFlagFlipVertical = 1 << 0, + bmdFrameContainsHDRMetadata = 1 << 1, + + /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */ + + bmdFrameCapturedAsPsF = 1 << 30, + bmdFrameHasNoInputSource = 1 << 31 +}; + +/* Enum BMDVideoInputFlags - Flags applicable to video input */ + +typedef uint32_t BMDVideoInputFlags; +enum _BMDVideoInputFlags { + bmdVideoInputFlagDefault = 0, + bmdVideoInputEnableFormatDetection = 1 << 0, + bmdVideoInputDualStream3D = 1 << 1, + bmdVideoInputSynchronizeToCaptureGroup = 1 << 2 +}; + +/* Enum BMDVideoInputFormatChangedEvents - Bitmask passed to the VideoInputFormatChanged notification to identify the properties of the input signal that have changed */ + +typedef uint32_t BMDVideoInputFormatChangedEvents; +enum _BMDVideoInputFormatChangedEvents { + bmdVideoInputDisplayModeChanged = 1 << 0, + bmdVideoInputFieldDominanceChanged = 1 << 1, + bmdVideoInputColorspaceChanged = 1 << 2 +}; + +/* Enum BMDDetectedVideoInputFormatFlags - Flags passed to the VideoInputFormatChanged notification to describe the detected video input signal */ + +typedef uint32_t BMDDetectedVideoInputFormatFlags; +enum _BMDDetectedVideoInputFormatFlags { + bmdDetectedVideoInputYCbCr422 = 1 << 0, + bmdDetectedVideoInputRGB444 = 1 << 1, + bmdDetectedVideoInputDualStream3D = 1 << 2, + bmdDetectedVideoInput12BitDepth = 1 << 3, + bmdDetectedVideoInput10BitDepth = 1 << 4, + bmdDetectedVideoInput8BitDepth = 1 << 5 +}; + +/* Enum BMDDeckLinkCapturePassthroughMode - Enumerates whether the video output is electrically connected to the video input or if the clean switching mode is enabled */ + +typedef uint32_t BMDDeckLinkCapturePassthroughMode; +enum _BMDDeckLinkCapturePassthroughMode { + bmdDeckLinkCapturePassthroughModeDisabled = /* 'pdis' */ 0x70646973, + bmdDeckLinkCapturePassthroughModeDirect = /* 'pdir' */ 0x70646972, + bmdDeckLinkCapturePassthroughModeCleanSwitch = /* 'pcln' */ 0x70636C6E +}; + +/* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */ + +typedef uint32_t BMDOutputFrameCompletionResult; +enum _BMDOutputFrameCompletionResult { + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed +}; + +/* Enum BMDReferenceStatus - GenLock input status */ + +typedef uint32_t BMDReferenceStatus; +enum _BMDReferenceStatus { + bmdReferenceUnlocked = 0, + bmdReferenceNotSupportedByHardware = 1 << 0, + bmdReferenceLocked = 1 << 1 +}; + +/* Enum BMDAudioFormat - Audio Format */ + +typedef uint32_t BMDAudioFormat; +enum _BMDAudioFormat { + bmdAudioFormatPCM = /* 'lpcm' */ 0x6C70636D // Linear signed PCM samples +}; + +/* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */ + +typedef uint32_t BMDAudioSampleRate; +enum _BMDAudioSampleRate { + bmdAudioSampleRate48kHz = 48000 +}; + +/* Enum BMDAudioSampleType - Audio sample sizes supported for output/input */ + +typedef uint32_t BMDAudioSampleType; +enum _BMDAudioSampleType { + bmdAudioSampleType16bitInteger = 16, + bmdAudioSampleType32bitInteger = 32 +}; + +/* Enum BMDAudioOutputStreamType - Audio output stream type */ + +typedef uint32_t BMDAudioOutputStreamType; +enum _BMDAudioOutputStreamType { + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped +}; + +/* Enum BMDAncillaryPacketFormat - Ancillary packet format */ + +typedef uint32_t BMDAncillaryPacketFormat; +enum _BMDAncillaryPacketFormat { + bmdAncillaryPacketFormatUInt8 = /* 'ui08' */ 0x75693038, + bmdAncillaryPacketFormatUInt16 = /* 'ui16' */ 0x75693136, + bmdAncillaryPacketFormatYCbCr10 = /* 'v210' */ 0x76323130 +}; + +/* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ + +typedef uint32_t BMDTimecodeFormat; +enum _BMDTimecodeFormat { + bmdTimecodeRP188VITC1 = /* 'rpv1' */ 0x72707631, // RP188 timecode where DBB1 equals VITC1 (line 9) + bmdTimecodeRP188VITC2 = /* 'rp12' */ 0x72703132, // RP188 timecode where DBB1 equals VITC2 (line 9 for progressive or line 571 for interlaced/PsF) + bmdTimecodeRP188LTC = /* 'rplt' */ 0x72706C74, // RP188 timecode where DBB1 equals LTC (line 10) + bmdTimecodeRP188HighFrameRate = /* 'rphr' */ 0x72706872, // RP188 timecode where DBB1 is an HFRTC (SMPTE ST 12-3), the only timecode allowing the frame value to go above 30 + bmdTimecodeRP188Any = /* 'rp18' */ 0x72703138, // Convenience for capture, returning the first valid timecode in {HFRTC (if supported), VITC1, VITC2, LTC } + bmdTimecodeVITC = /* 'vitc' */ 0x76697463, + bmdTimecodeVITCField2 = /* 'vit2' */ 0x76697432, + bmdTimecodeSerial = /* 'seri' */ 0x73657269 +}; + +/* Enum BMDAnalogVideoFlags - Analog video display flags */ + +typedef uint32_t BMDAnalogVideoFlags; +enum _BMDAnalogVideoFlags { + bmdAnalogVideoFlagCompositeSetup75 = 1 << 0, + bmdAnalogVideoFlagComponentBetacamLevels = 1 << 1 +}; + +/* Enum BMDAudioOutputAnalogAESSwitch - Audio output Analog/AESEBU switch */ + +typedef uint32_t BMDAudioOutputAnalogAESSwitch; +enum _BMDAudioOutputAnalogAESSwitch { + bmdAudioOutputSwitchAESEBU = /* 'aes ' */ 0x61657320, + bmdAudioOutputSwitchAnalog = /* 'anlg' */ 0x616E6C67 +}; + +/* Enum BMDVideoOutputConversionMode - Video/audio conversion mode */ + +typedef uint32_t BMDVideoOutputConversionMode; +enum _BMDVideoOutputConversionMode { + bmdNoVideoOutputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoOutputLetterboxDownconversion = /* 'ltbx' */ 0x6C746278, + bmdVideoOutputAnamorphicDownconversion = /* 'amph' */ 0x616D7068, + bmdVideoOutputHD720toHD1080Conversion = /* '720c' */ 0x37323063, + bmdVideoOutputHardwareLetterboxDownconversion = /* 'HWlb' */ 0x48576C62, + bmdVideoOutputHardwareAnamorphicDownconversion = /* 'HWam' */ 0x4857616D, + bmdVideoOutputHardwareCenterCutDownconversion = /* 'HWcc' */ 0x48576363, + bmdVideoOutputHardware720p1080pCrossconversion = /* 'xcap' */ 0x78636170, + bmdVideoOutputHardwareAnamorphic720pUpconversion = /* 'ua7p' */ 0x75613770, + bmdVideoOutputHardwareAnamorphic1080iUpconversion = /* 'ua1i' */ 0x75613169, + bmdVideoOutputHardwareAnamorphic149To720pUpconversion = /* 'u47p' */ 0x75343770, + bmdVideoOutputHardwareAnamorphic149To1080iUpconversion = /* 'u41i' */ 0x75343169, + bmdVideoOutputHardwarePillarbox720pUpconversion = /* 'up7p' */ 0x75703770, + bmdVideoOutputHardwarePillarbox1080iUpconversion = /* 'up1i' */ 0x75703169 +}; + +/* Enum BMDVideoInputConversionMode - Video input conversion mode */ + +typedef uint32_t BMDVideoInputConversionMode; +enum _BMDVideoInputConversionMode { + bmdNoVideoInputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoInputLetterboxDownconversionFromHD1080 = /* '10lb' */ 0x31306C62, + bmdVideoInputAnamorphicDownconversionFromHD1080 = /* '10am' */ 0x3130616D, + bmdVideoInputLetterboxDownconversionFromHD720 = /* '72lb' */ 0x37326C62, + bmdVideoInputAnamorphicDownconversionFromHD720 = /* '72am' */ 0x3732616D, + bmdVideoInputLetterboxUpconversion = /* 'lbup' */ 0x6C627570, + bmdVideoInputAnamorphicUpconversion = /* 'amup' */ 0x616D7570 +}; + +/* Enum BMDVideo3DPackingFormat - Video 3D packing format */ + +typedef uint32_t BMDVideo3DPackingFormat; +enum _BMDVideo3DPackingFormat { + bmdVideo3DPackingSidebySideHalf = /* 'sbsh' */ 0x73627368, + bmdVideo3DPackingLinebyLine = /* 'lbyl' */ 0x6C62796C, + bmdVideo3DPackingTopAndBottom = /* 'tabo' */ 0x7461626F, + bmdVideo3DPackingFramePacking = /* 'frpk' */ 0x6672706B, + bmdVideo3DPackingLeftOnly = /* 'left' */ 0x6C656674, + bmdVideo3DPackingRightOnly = /* 'righ' */ 0x72696768 +}; + +/* Enum BMDIdleVideoOutputOperation - Video output operation when not playing video */ + +typedef uint32_t BMDIdleVideoOutputOperation; +enum _BMDIdleVideoOutputOperation { + bmdIdleVideoOutputBlack = /* 'blac' */ 0x626C6163, + bmdIdleVideoOutputLastFrame = /* 'lafa' */ 0x6C616661 +}; + +/* Enum BMDVideoEncoderFrameCodingMode - Video frame coding mode */ + +typedef uint32_t BMDVideoEncoderFrameCodingMode; +enum _BMDVideoEncoderFrameCodingMode { + bmdVideoEncoderFrameCodingModeInter = /* 'inte' */ 0x696E7465, + bmdVideoEncoderFrameCodingModeIntra = /* 'intr' */ 0x696E7472 +}; + +/* Enum BMDDNxHRLevel - DNxHR Levels */ + +typedef uint32_t BMDDNxHRLevel; +enum _BMDDNxHRLevel { + bmdDNxHRLevelSQ = /* 'dnsq' */ 0x646E7371, + bmdDNxHRLevelLB = /* 'dnlb' */ 0x646E6C62, + bmdDNxHRLevelHQ = /* 'dnhq' */ 0x646E6871, + bmdDNxHRLevelHQX = /* 'dhqx' */ 0x64687178, + bmdDNxHRLevel444 = /* 'd444' */ 0x64343434 +}; + +/* Enum BMDLinkConfiguration - Video link configuration */ + +typedef uint32_t BMDLinkConfiguration; +enum _BMDLinkConfiguration { + bmdLinkConfigurationSingleLink = /* 'lcsl' */ 0x6C63736C, + bmdLinkConfigurationDualLink = /* 'lcdl' */ 0x6C63646C, + bmdLinkConfigurationQuadLink = /* 'lcql' */ 0x6C63716C +}; + +/* Enum BMDDeviceInterface - Device interface type */ + +typedef uint32_t BMDDeviceInterface; +enum _BMDDeviceInterface { + bmdDeviceInterfacePCI = /* 'pci ' */ 0x70636920, + bmdDeviceInterfaceUSB = /* 'usb ' */ 0x75736220, + bmdDeviceInterfaceThunderbolt = /* 'thun' */ 0x7468756E +}; + +/* Enum BMDColorspace - Colorspace */ + +typedef uint32_t BMDColorspace; +enum _BMDColorspace { + bmdColorspaceRec601 = /* 'r601' */ 0x72363031, + bmdColorspaceRec709 = /* 'r709' */ 0x72373039, + bmdColorspaceRec2020 = /* '2020' */ 0x32303230 +}; + +/* Enum BMDDynamicRange - SDR or HDR */ + +typedef uint32_t BMDDynamicRange; +enum _BMDDynamicRange { + bmdDynamicRangeSDR = 0, // Standard Dynamic Range in accordance with SMPTE ST 2036-1 + bmdDynamicRangeHDRStaticPQ = 1 << 29, // High Dynamic Range PQ in accordance with SMPTE ST 2084 + bmdDynamicRangeHDRStaticHLG = 1 << 30 // High Dynamic Range HLG in accordance with ITU-R BT.2100-0 +}; + +/* Enum BMDDeckLinkHDMIInputEDIDID - DeckLink HDMI Input EDID ID */ + +typedef uint32_t BMDDeckLinkHDMIInputEDIDID; +enum _BMDDeckLinkHDMIInputEDIDID { + + /* Integers */ + + bmdDeckLinkHDMIInputEDIDDynamicRange = /* 'HIDy' */ 0x48494479 // Parameter is of type BMDDynamicRange. Default is (bmdDynamicRangeSDR|bmdDynamicRangeHDRStaticPQ) +}; + +/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ + +typedef uint32_t BMDDeckLinkFrameMetadataID; +enum _BMDDeckLinkFrameMetadataID { + + /* Colorspace Metadata - Integers */ + + bmdDeckLinkFrameMetadataColorspace = /* 'cspc' */ 0x63737063, // Colorspace of video frame (see BMDColorspace) + + /* HDR Metadata - Integers */ + + bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc = /* 'eotf' */ 0x656F7466, // EOTF in range 0-7 as per CEA 861.3 + + /* HDR Metadata - Floats */ + + bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX = /* 'hdrx' */ 0x68647278, // Red display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY = /* 'hdry' */ 0x68647279, // Red display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX = /* 'hdgx' */ 0x68646778, // Green display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenY = /* 'hdgy' */ 0x68646779, // Green display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueX = /* 'hdbx' */ 0x68646278, // Blue display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueY = /* 'hdby' */ 0x68646279, // Blue display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRWhitePointX = /* 'hdwx' */ 0x68647778, // White point in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRWhitePointY = /* 'hdwy' */ 0x68647779, // White point in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance = /* 'hdml' */ 0x68646D6C, // Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance = /* 'hmil' */ 0x686D696C, // Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel = /* 'mcll' */ 0x6D636C6C, // Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 +}; + +/* Enum BMDProfileID - Identifies a profile */ + +typedef uint32_t BMDProfileID; +enum _BMDProfileID { + bmdProfileOneSubDeviceFullDuplex = /* '1dfd' */ 0x31646664, + bmdProfileOneSubDeviceHalfDuplex = /* '1dhd' */ 0x31646864, + bmdProfileTwoSubDevicesFullDuplex = /* '2dfd' */ 0x32646664, + bmdProfileTwoSubDevicesHalfDuplex = /* '2dhd' */ 0x32646864, + bmdProfileFourSubDevicesHalfDuplex = /* '4dhd' */ 0x34646864 +}; + +/* Enum BMDHDMITimecodePacking - Packing form of timecode on HDMI */ + +typedef uint32_t BMDHDMITimecodePacking; +enum _BMDHDMITimecodePacking { + bmdHDMITimecodePackingIEEEOUI000085 = 0x00008500, + bmdHDMITimecodePackingIEEEOUI080046 = 0x08004601, + bmdHDMITimecodePackingIEEEOUI5CF9F0 = 0x5CF9F003 +}; + +/* Enum BMDInternalKeyingAncillaryDataSource - Source for VANC and timecode data when performing internal keying */ + +typedef uint32_t BMDInternalKeyingAncillaryDataSource; +enum _BMDInternalKeyingAncillaryDataSource { + bmdInternalKeyingUsesAncillaryDataFromInputSignal = /* 'ikai' */ 0x696B6169, + bmdInternalKeyingUsesAncillaryDataFromKeyFrame = /* 'ikak' */ 0x696B616B +}; + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkAttributeID; +enum _BMDDeckLinkAttributeID { + + /* Flags */ + + BMDDeckLinkSupportsInternalKeying = /* 'keyi' */ 0x6B657969, + BMDDeckLinkSupportsExternalKeying = /* 'keye' */ 0x6B657965, + BMDDeckLinkSupportsInputFormatDetection = /* 'infd' */ 0x696E6664, + BMDDeckLinkHasReferenceInput = /* 'hrin' */ 0x6872696E, + BMDDeckLinkHasSerialPort = /* 'hspt' */ 0x68737074, + BMDDeckLinkHasAnalogVideoOutputGain = /* 'avog' */ 0x61766F67, + BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain = /* 'ovog' */ 0x6F766F67, + BMDDeckLinkHasVideoInputAntiAliasingFilter = /* 'aafl' */ 0x6161666C, + BMDDeckLinkHasBypass = /* 'byps' */ 0x62797073, + BMDDeckLinkSupportsClockTimingAdjustment = /* 'ctad' */ 0x63746164, + BMDDeckLinkSupportsFullFrameReferenceInputTimingOffset = /* 'frin' */ 0x6672696E, + BMDDeckLinkSupportsSMPTELevelAOutput = /* 'lvla' */ 0x6C766C61, + BMDDeckLinkSupportsAutoSwitchingPPsFOnInput = /* 'apsf' */ 0x61707366, + BMDDeckLinkSupportsDualLinkSDI = /* 'sdls' */ 0x73646C73, + BMDDeckLinkSupportsQuadLinkSDI = /* 'sqls' */ 0x73716C73, + BMDDeckLinkSupportsIdleOutput = /* 'idou' */ 0x69646F75, + BMDDeckLinkVANCRequires10BitYUVVideoFrames = /* 'vioY' */ 0x76696F59, // Legacy product requires v210 active picture for IDeckLinkVideoFrameAncillaryPackets or 10-bit VANC + BMDDeckLinkHasLTCTimecodeInput = /* 'hltc' */ 0x686C7463, + BMDDeckLinkSupportsHDRMetadata = /* 'hdrm' */ 0x6864726D, + BMDDeckLinkSupportsColorspaceMetadata = /* 'cmet' */ 0x636D6574, + BMDDeckLinkSupportsHDMITimecode = /* 'htim' */ 0x6874696D, + BMDDeckLinkSupportsHighFrameRateTimecode = /* 'HFRT' */ 0x48465254, + BMDDeckLinkSupportsSynchronizeToCaptureGroup = /* 'stcg' */ 0x73746367, + BMDDeckLinkSupportsSynchronizeToPlaybackGroup = /* 'stpg' */ 0x73747067, + + /* Integers */ + + BMDDeckLinkMaximumAudioChannels = /* 'mach' */ 0x6D616368, + BMDDeckLinkMaximumAnalogAudioInputChannels = /* 'iach' */ 0x69616368, + BMDDeckLinkMaximumAnalogAudioOutputChannels = /* 'aach' */ 0x61616368, + BMDDeckLinkNumberOfSubDevices = /* 'nsbd' */ 0x6E736264, + BMDDeckLinkSubDeviceIndex = /* 'subi' */ 0x73756269, + BMDDeckLinkPersistentID = /* 'peid' */ 0x70656964, + BMDDeckLinkDeviceGroupID = /* 'dgid' */ 0x64676964, + BMDDeckLinkTopologicalID = /* 'toid' */ 0x746F6964, + BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkVideoIOSupport = /* 'vios' */ 0x76696F73, // Returns a BMDVideoIOSupport bit field + BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, // Returns a BMDDeckControlConnection bit field + BMDDeckLinkDeviceInterface = /* 'dbus' */ 0x64627573, // Returns a BMDDeviceInterface + BMDDeckLinkAudioInputRCAChannelCount = /* 'airc' */ 0x61697263, + BMDDeckLinkAudioInputXLRChannelCount = /* 'aixc' */ 0x61697863, + BMDDeckLinkAudioOutputRCAChannelCount = /* 'aorc' */ 0x616F7263, + BMDDeckLinkAudioOutputXLRChannelCount = /* 'aoxc' */ 0x616F7863, + BMDDeckLinkProfileID = /* 'prid' */ 0x70726964, // Returns a BMDProfileID + BMDDeckLinkDuplex = /* 'dupx' */ 0x64757078, + BMDDeckLinkMinimumPrerollFrames = /* 'mprf' */ 0x6D707266, + BMDDeckLinkSupportedDynamicRange = /* 'sudr' */ 0x73756472, + + /* Floats */ + + BMDDeckLinkVideoInputGainMinimum = /* 'vigm' */ 0x7669676D, + BMDDeckLinkVideoInputGainMaximum = /* 'vigx' */ 0x76696778, + BMDDeckLinkVideoOutputGainMinimum = /* 'vogm' */ 0x766F676D, + BMDDeckLinkVideoOutputGainMaximum = /* 'vogx' */ 0x766F6778, + BMDDeckLinkMicrophoneInputGainMinimum = /* 'migm' */ 0x6D69676D, + BMDDeckLinkMicrophoneInputGainMaximum = /* 'migx' */ 0x6D696778, + + /* Strings */ + + BMDDeckLinkSerialPortDeviceName = /* 'slpn' */ 0x736C706E, + BMDDeckLinkVendorName = /* 'vndr' */ 0x766E6472, + BMDDeckLinkDisplayName = /* 'dspn' */ 0x6473706E, + BMDDeckLinkModelName = /* 'mdln' */ 0x6D646C6E, + BMDDeckLinkDeviceHandle = /* 'devh' */ 0x64657668 +}; + +/* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */ + +typedef uint32_t BMDDeckLinkAPIInformationID; +enum _BMDDeckLinkAPIInformationID { + + /* Integer or String */ + + BMDDeckLinkAPIVersion = /* 'vers' */ 0x76657273 +}; + +/* Enum BMDDeckLinkStatusID - DeckLink Status ID */ + +typedef uint32_t BMDDeckLinkStatusID; +enum _BMDDeckLinkStatusID { + + /* Integers */ + + bmdDeckLinkStatusDetectedVideoInputMode = /* 'dvim' */ 0x6476696D, + bmdDeckLinkStatusDetectedVideoInputFormatFlags = /* 'dvff' */ 0x64766666, + bmdDeckLinkStatusDetectedVideoInputFieldDominance = /* 'dvfd' */ 0x64766664, + bmdDeckLinkStatusDetectedVideoInputColorspace = /* 'dscl' */ 0x6473636C, + bmdDeckLinkStatusDetectedVideoInputDynamicRange = /* 'dsdr' */ 0x64736472, + bmdDeckLinkStatusDetectedSDILinkConfiguration = /* 'dslc' */ 0x64736C63, + bmdDeckLinkStatusCurrentVideoInputMode = /* 'cvim' */ 0x6376696D, + bmdDeckLinkStatusCurrentVideoInputPixelFormat = /* 'cvip' */ 0x63766970, + bmdDeckLinkStatusCurrentVideoInputFlags = /* 'cvif' */ 0x63766966, + bmdDeckLinkStatusCurrentVideoOutputMode = /* 'cvom' */ 0x63766F6D, + bmdDeckLinkStatusCurrentVideoOutputFlags = /* 'cvof' */ 0x63766F66, + bmdDeckLinkStatusPCIExpressLinkWidth = /* 'pwid' */ 0x70776964, + bmdDeckLinkStatusPCIExpressLinkSpeed = /* 'plnk' */ 0x706C6E6B, + bmdDeckLinkStatusLastVideoOutputPixelFormat = /* 'opix' */ 0x6F706978, + bmdDeckLinkStatusReferenceSignalMode = /* 'refm' */ 0x7265666D, + bmdDeckLinkStatusReferenceSignalFlags = /* 'reff' */ 0x72656666, + bmdDeckLinkStatusBusy = /* 'busy' */ 0x62757379, + bmdDeckLinkStatusInterchangeablePanelType = /* 'icpt' */ 0x69637074, + bmdDeckLinkStatusDeviceTemperature = /* 'dtmp' */ 0x64746D70, + + /* Flags */ + + bmdDeckLinkStatusVideoInputSignalLocked = /* 'visl' */ 0x7669736C, + bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C, + + /* Bytes */ + + bmdDeckLinkStatusReceivedEDID = /* 'edid' */ 0x65646964 +}; + +/* Enum BMDDeckLinkVideoStatusFlags - */ + +typedef uint32_t BMDDeckLinkVideoStatusFlags; +enum _BMDDeckLinkVideoStatusFlags { + bmdDeckLinkVideoStatusPsF = 1 << 0, + bmdDeckLinkVideoStatusDualStream3D = 1 << 1 +}; + +/* Enum BMDDuplexMode - Duplex of the device */ + +typedef uint32_t BMDDuplexMode; +enum _BMDDuplexMode { + bmdDuplexFull = /* 'dxfu' */ 0x64786675, + bmdDuplexHalf = /* 'dxha' */ 0x64786861, + bmdDuplexSimplex = /* 'dxsp' */ 0x64787370, + bmdDuplexInactive = /* 'dxin' */ 0x6478696E +}; + +/* Enum BMDPanelType - The type of interchangeable panel */ + +typedef uint32_t BMDPanelType; +enum _BMDPanelType { + bmdPanelNotDetected = /* 'npnl' */ 0x6E706E6C, + bmdPanelTeranexMiniSmartPanel = /* 'tmsm' */ 0x746D736D +}; + +/* Enum BMDDeviceBusyState - Current device busy state */ + +typedef uint32_t BMDDeviceBusyState; +enum _BMDDeviceBusyState { + bmdDeviceCaptureBusy = 1 << 0, + bmdDevicePlaybackBusy = 1 << 1, + bmdDeviceSerialPortBusy = 1 << 2 +}; + +/* Enum BMDVideoIOSupport - Device video input/output support */ + +typedef uint32_t BMDVideoIOSupport; +enum _BMDVideoIOSupport { + bmdDeviceSupportsCapture = 1 << 0, + bmdDeviceSupportsPlayback = 1 << 1 +}; + +/* Enum BMD3DPreviewFormat - Linked Frame preview format */ + +typedef uint32_t BMD3DPreviewFormat; +enum _BMD3DPreviewFormat { + bmd3DPreviewFormatDefault = /* 'defa' */ 0x64656661, + bmd3DPreviewFormatLeftOnly = /* 'left' */ 0x6C656674, + bmd3DPreviewFormatRightOnly = /* 'righ' */ 0x72696768, + bmd3DPreviewFormatSideBySide = /* 'side' */ 0x73696465, + bmd3DPreviewFormatTopBottom = /* 'topb' */ 0x746F7062 +}; + +/* Enum BMDNotifications - Events that can be subscribed through IDeckLinkNotification */ + +typedef uint32_t BMDNotifications; +enum _BMDNotifications { + bmdPreferencesChanged = /* 'pref' */ 0x70726566, + bmdStatusChanged = /* 'stat' */ 0x73746174 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkVideoOutputCallback; +class IDeckLinkInputCallback; +class IDeckLinkEncoderInputCallback; +class IDeckLinkMemoryAllocator; +class IDeckLinkAudioOutputCallback; +class IDeckLinkIterator; +class IDeckLinkAPIInformation; +class IDeckLinkOutput; +class IDeckLinkInput; +class IDeckLinkHDMIInputEDID; +class IDeckLinkEncoderInput; +class IDeckLinkVideoFrame; +class IDeckLinkMutableVideoFrame; +class IDeckLinkVideoFrame3DExtensions; +class IDeckLinkVideoFrameMetadataExtensions; +class IDeckLinkVideoInputFrame; +class IDeckLinkAncillaryPacket; +class IDeckLinkAncillaryPacketIterator; +class IDeckLinkVideoFrameAncillaryPackets; +class IDeckLinkVideoFrameAncillary; +class IDeckLinkEncoderPacket; +class IDeckLinkEncoderVideoPacket; +class IDeckLinkEncoderAudioPacket; +class IDeckLinkH265NALPacket; +class IDeckLinkAudioInputPacket; +class IDeckLinkScreenPreviewCallback; +class IDeckLinkCocoaScreenPreviewCallback; +class IDeckLinkGLScreenPreviewHelper; +class IDeckLinkMetalScreenPreviewHelper; +class IDeckLinkNotificationCallback; +class IDeckLinkNotification; +class IDeckLinkProfileAttributes; +class IDeckLinkProfileIterator; +class IDeckLinkProfile; +class IDeckLinkProfileCallback; +class IDeckLinkProfileManager; +class IDeckLinkStatus; +class IDeckLinkKeyer; +class IDeckLinkVideoConversion; +class IDeckLinkDeviceNotificationCallback; +class IDeckLinkDiscovery; + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +class BMD_PUBLIC IDeckLinkVideoOutputCallback : public IUnknown +{ +public: + virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame* completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; + virtual HRESULT ScheduledPlaybackHasStopped (void) = 0; + +protected: + virtual ~IDeckLinkVideoOutputCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkInputCallback : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode* newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkEncoderInputCallback : public IUnknown +{ +public: + virtual HRESULT VideoInputSignalChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode* newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoPacketArrived (/* in */ IDeckLinkEncoderVideoPacket* videoPacket) = 0; + virtual HRESULT AudioPacketArrived (/* in */ IDeckLinkEncoderAudioPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkEncoderInputCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */ + +class BMD_PUBLIC IDeckLinkMemoryAllocator : public IUnknown +{ +public: + virtual HRESULT AllocateBuffer (/* in */ uint32_t bufferSize, /* out */ void** allocatedBuffer) = 0; + virtual HRESULT ReleaseBuffer (/* in */ void* buffer) = 0; + virtual HRESULT Commit (void) = 0; + virtual HRESULT Decommit (void) = 0; +}; + +/* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */ + +class BMD_PUBLIC IDeckLinkAudioOutputCallback : public IUnknown +{ +public: + virtual HRESULT RenderAudioSamples (/* in */ bool preroll) = 0; +}; + +/* Interface IDeckLinkIterator - Enumerates installed DeckLink hardware */ + +class BMD_PUBLIC IDeckLinkIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLink** deckLinkInstance) = 0; +}; + +/* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */ + +class BMD_PUBLIC IDeckLinkAPIInformation : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ CFStringRef* value) = 0; + +protected: + virtual ~IDeckLinkAPIInformation () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDVideoOutputConversionMode conversionMode, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame** outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary** outBuffer) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback* theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t* bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + virtual HRESULT WriteAudioSamplesSync (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t* bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback* theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue* actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool* active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* streamTime, /* out */ double* playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus* referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + virtual HRESULT GetFrameCompletionReferenceTimestamp (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* frameCompletionTimestamp) = 0; + +protected: + virtual ~IDeckLinkOutput () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDVideoInputConversionMode conversionMode, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t* availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkHDMIInputEDID - Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default */ + +class BMD_PUBLIC IDeckLinkHDMIInputEDID : public IUnknown +{ +public: + virtual HRESULT SetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT WriteToEDID (void) = 0; + +protected: + virtual ~IDeckLinkHDMIInputEDID () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkEncoderInput : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedCodec, /* in */ uint32_t requestedCodecProfile, /* in */ BMDSupportedVideoModeFlags flags, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailablePacketsCount (/* out */ uint32_t* availablePacketsCount) = 0; + virtual HRESULT SetMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioFormat audioFormat, /* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkEncoderInputCallback* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkEncoderInput () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +class BMD_PUBLIC IDeckLinkVideoFrame : public IUnknown +{ +public: + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual long GetRowBytes (void) = 0; + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual BMDFrameFlags GetFlags (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode** timecode) = 0; + virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary** ancillary) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + +protected: + virtual ~IDeckLinkVideoFrame () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +class BMD_PUBLIC IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame +{ +public: + virtual HRESULT SetFlags (/* in */ BMDFrameFlags newFlags) = 0; + virtual HRESULT SetTimecode (/* in */ BMDTimecodeFormat format, /* in */ IDeckLinkTimecode* timecode) = 0; + virtual HRESULT SetTimecodeFromComponents (/* in */ BMDTimecodeFormat format, /* in */ uint8_t hours, /* in */ uint8_t minutes, /* in */ uint8_t seconds, /* in */ uint8_t frames, /* in */ BMDTimecodeFlags flags) = 0; + virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary* ancillary) = 0; + virtual HRESULT SetTimecodeUserBits (/* in */ BMDTimecodeFormat format, /* in */ BMDTimecodeUserBits userBits) = 0; + +protected: + virtual ~IDeckLinkMutableVideoFrame () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrame3DExtensions - Optional interface implemented on IDeckLinkVideoFrame to support 3D frames */ + +class BMD_PUBLIC IDeckLinkVideoFrame3DExtensions : public IUnknown +{ +public: + virtual BMDVideo3DPackingFormat Get3DPackingFormat (void) = 0; + virtual HRESULT GetFrameForRightEye (/* out */ IDeckLinkVideoFrame** rightEyeFrame) = 0; + +protected: + virtual ~IDeckLinkVideoFrame3DExtensions () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDR information */ + +class BMD_PUBLIC IDeckLinkVideoFrameMetadataExtensions : public IUnknown +{ +public: + virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ double* value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ bool* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ CFStringRef* value) = 0; + virtual HRESULT GetBytes (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ void* buffer /* optional */, /* in, out */ uint32_t* bufferSize) = 0; + +protected: + virtual ~IDeckLinkVideoFrameMetadataExtensions () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame +{ +public: + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue* frameTime, /* out */ BMDTimeValue* frameDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue* frameTime, /* out */ BMDTimeValue* frameDuration) = 0; + +protected: + virtual ~IDeckLinkVideoInputFrame () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAncillaryPacket - On output, user needs to implement this interface */ + +class BMD_PUBLIC IDeckLinkAncillaryPacket : public IUnknown +{ +public: + virtual HRESULT GetBytes (/* in */ BMDAncillaryPacketFormat format /* For output, only one format need be offered */, /* out */ const void** data /* Optional */, /* out */ uint32_t* size /* Optional */) = 0; + virtual uint8_t GetDID (void) = 0; + virtual uint8_t GetSDID (void) = 0; + virtual uint32_t GetLineNumber (void) = 0; // On output, zero is auto + virtual uint8_t GetDataStreamIndex (void) = 0; // Usually zero. Can only be 1 if non-SD and the first data stream is completely full + +protected: + virtual ~IDeckLinkAncillaryPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAncillaryPacketIterator - Enumerates ancillary packets */ + +class BMD_PUBLIC IDeckLinkAncillaryPacketIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkAncillaryPacket** packet) = 0; + +protected: + virtual ~IDeckLinkAncillaryPacketIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillaryPackets - Obtained through QueryInterface on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets : public IUnknown +{ +public: + virtual HRESULT GetPacketIterator (/* out */ IDeckLinkAncillaryPacketIterator** iterator) = 0; + virtual HRESULT GetFirstPacketByID (/* in */ uint8_t DID, /* in */ uint8_t SDID, /* out */ IDeckLinkAncillaryPacket** packet) = 0; + virtual HRESULT AttachPacket (/* in */ IDeckLinkAncillaryPacket* packet) = 0; // Implement IDeckLinkAncillaryPacket to output your own + virtual HRESULT DetachPacket (/* in */ IDeckLinkAncillaryPacket* packet) = 0; + virtual HRESULT DetachAllPackets (void) = 0; + +protected: + virtual ~IDeckLinkVideoFrameAncillaryPackets () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillary - Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillary : public IUnknown +{ +public: + virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void** buffer) = 0; // Pixels/rowbytes is same as display mode, except for above HD where it's 1920 pixels for UHD modes and 2048 pixels for DCI modes + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual BMDDisplayMode GetDisplayMode (void) = 0; + +protected: + virtual ~IDeckLinkVideoFrameAncillary () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */ + +class BMD_PUBLIC IDeckLinkEncoderPacket : public IUnknown +{ +public: + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual long GetSize (void) = 0; + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue* frameTime, /* in */ BMDTimeScale timeScale) = 0; + virtual BMDPacketType GetPacketType (void) = 0; + +protected: + virtual ~IDeckLinkEncoderPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */ + +class BMD_PUBLIC IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket +{ +public: + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual HRESULT GetHardwareReferenceTimestamp (/* in */ BMDTimeScale timeScale, /* out */ BMDTimeValue* frameTime, /* out */ BMDTimeValue* frameDuration) = 0; + virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode** timecode) = 0; + +protected: + virtual ~IDeckLinkEncoderVideoPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */ + +class BMD_PUBLIC IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket +{ +public: + virtual BMDAudioFormat GetAudioFormat (void) = 0; + +protected: + virtual ~IDeckLinkEncoderAudioPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface on an IDeckLinkEncoderVideoPacket object */ + +class BMD_PUBLIC IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket +{ +public: + virtual HRESULT GetUnitType (/* out */ uint8_t* unitType) = 0; + virtual HRESULT GetBytesNoPrefix (/* out */ void** buffer) = 0; + virtual long GetSizeNoPrefix (void) = 0; + +protected: + virtual ~IDeckLinkH265NALPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */ + +class BMD_PUBLIC IDeckLinkAudioInputPacket : public IUnknown +{ +public: + virtual long GetSampleFrameCount (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual HRESULT GetPacketTime (/* out */ BMDTimeValue* packetTime, /* in */ BMDTimeScale timeScale) = 0; + +protected: + virtual ~IDeckLinkAudioInputPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +class BMD_PUBLIC IDeckLinkScreenPreviewCallback : public IUnknown +{ +public: + virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + +protected: + virtual ~IDeckLinkScreenPreviewCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkCocoaScreenPreviewCallback - Screen preview callback for Cocoa-based applications. Created with CreateCocoaScreenPreview */ + +class BMD_PUBLIC IDeckLinkCocoaScreenPreviewCallback : public IDeckLinkScreenPreviewCallback +{ +public: + +protected: + virtual ~IDeckLinkCocoaScreenPreviewCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance on platforms with native COM support or from CreateOpenGLScreenPreviewHelper/CreateOpenGL3ScreenPreviewHelper on other platforms. */ + +class BMD_PUBLIC IDeckLinkGLScreenPreviewHelper : public IUnknown +{ +public: + + /* Methods must be called with OpenGL context set */ + + virtual HRESULT InitializeGL (void) = 0; + virtual HRESULT PaintGL (void) = 0; + virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT Set3DPreviewFormat (/* in */ BMD3DPreviewFormat previewFormat) = 0; + +protected: + virtual ~IDeckLinkGLScreenPreviewHelper () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkMetalScreenPreviewHelper - Created with CreateMetalScreenPreviewHelper(). */ + +class BMD_PUBLIC IDeckLinkMetalScreenPreviewHelper : public IUnknown +{ +public: + virtual HRESULT Initialize (/* in */ void* device) = 0; + virtual HRESULT Draw (/* in */ void* cmdBuffer, /* in */ void* renderPassDescriptor, /* in */ void* viewport) = 0; + virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT Set3DPreviewFormat (/* in */ BMD3DPreviewFormat previewFormat) = 0; + +protected: + virtual ~IDeckLinkMetalScreenPreviewHelper () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkNotificationCallback - DeckLink Notification Callback Interface */ + +class BMD_PUBLIC IDeckLinkNotificationCallback : public IUnknown +{ +public: + virtual HRESULT Notify (/* in */ BMDNotifications topic, /* in */ uint64_t param1, /* in */ uint64_t param2) = 0; +}; + +/* Interface IDeckLinkNotification - DeckLink Notification interface */ + +class BMD_PUBLIC IDeckLinkNotification : public IUnknown +{ +public: + virtual HRESULT Subscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback* theCallback) = 0; + virtual HRESULT Unsubscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback* theCallback) = 0; + +protected: + virtual ~IDeckLinkNotification () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileAttributes - Created by QueryInterface from an IDeckLinkProfile, or from IDeckLink. When queried from IDeckLink, interrogates the active profile */ + +class BMD_PUBLIC IDeckLinkProfileAttributes : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ CFStringRef* value) = 0; + +protected: + virtual ~IDeckLinkProfileAttributes () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileIterator - Enumerates IDeckLinkProfile interfaces */ + +class BMD_PUBLIC IDeckLinkProfileIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkProfile** profile) = 0; + +protected: + virtual ~IDeckLinkProfileIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfile - Represents the active profile when queried from IDeckLink */ + +class BMD_PUBLIC IDeckLinkProfile : public IUnknown +{ +public: + virtual HRESULT GetDevice (/* out */ IDeckLink** device) = 0; // Device affected when this profile becomes active + virtual HRESULT IsActive (/* out */ bool* isActive) = 0; + virtual HRESULT SetActive (void) = 0; // Activating a profile will also change the profile on all devices enumerated by GetPeers. Activation is not complete until IDeckLinkProfileCallback::ProfileActivated is called + virtual HRESULT GetPeers (/* out */ IDeckLinkProfileIterator** profileIterator) = 0; // Profiles of other devices activated with this profile + +protected: + virtual ~IDeckLinkProfile () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileCallback - Receive notifications about profiles related to this device */ + +class BMD_PUBLIC IDeckLinkProfileCallback : public IUnknown +{ +public: + virtual HRESULT ProfileChanging (/* in */ IDeckLinkProfile* profileToBeActivated, /* in */ bool streamsWillBeForcedToStop) = 0; // Called before this device changes profile. User has an opportunity for teardown if streamsWillBeForcedToStop + virtual HRESULT ProfileActivated (/* in */ IDeckLinkProfile* activatedProfile) = 0; // Called after this device has been activated with a new profile + +protected: + virtual ~IDeckLinkProfileCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkProfileManager - Created by QueryInterface from IDeckLink when a device has multiple optional profiles */ + +class BMD_PUBLIC IDeckLinkProfileManager : public IUnknown +{ +public: + virtual HRESULT GetProfiles (/* out */ IDeckLinkProfileIterator** profileIterator) = 0; // All available profiles for this device + virtual HRESULT GetProfile (/* in */ BMDProfileID profileID, /* out */ IDeckLinkProfile** profile) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkProfileCallback* callback) = 0; + +protected: + virtual ~IDeckLinkProfileManager () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkStatus - DeckLink Status interface */ + +class BMD_PUBLIC IDeckLinkStatus : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkStatusID statusID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkStatusID statusID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkStatusID statusID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkStatusID statusID, /* out */ CFStringRef* value) = 0; + virtual HRESULT GetBytes (/* in */ BMDDeckLinkStatusID statusID, /* out */ void* buffer, /* in, out */ uint32_t* bufferSize) = 0; + +protected: + virtual ~IDeckLinkStatus () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkKeyer - DeckLink Keyer interface */ + +class BMD_PUBLIC IDeckLinkKeyer : public IUnknown +{ +public: + virtual HRESULT Enable (/* in */ bool isExternal) = 0; + virtual HRESULT SetLevel (/* in */ uint8_t level) = 0; + virtual HRESULT RampUp (/* in */ uint32_t numberOfFrames) = 0; + virtual HRESULT RampDown (/* in */ uint32_t numberOfFrames) = 0; + virtual HRESULT Disable (void) = 0; + +protected: + virtual ~IDeckLinkKeyer () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance. */ + +class BMD_PUBLIC IDeckLinkVideoConversion : public IUnknown +{ +public: + virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame* srcFrame, /* in */ IDeckLinkVideoFrame* dstFrame) = 0; + +protected: + virtual ~IDeckLinkVideoConversion () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDeviceNotificationCallback - DeckLink device arrival/removal notification callbacks */ + +class BMD_PUBLIC IDeckLinkDeviceNotificationCallback : public IUnknown +{ +public: + virtual HRESULT DeckLinkDeviceArrived (/* in */ IDeckLink* deckLinkDevice) = 0; + virtual HRESULT DeckLinkDeviceRemoved (/* in */ IDeckLink* deckLinkDevice) = 0; + +protected: + virtual ~IDeckLinkDeviceNotificationCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDiscovery - DeckLink device discovery */ + +class BMD_PUBLIC IDeckLinkDiscovery : public IUnknown +{ +public: + virtual HRESULT InstallDeviceNotifications (/* in */ IDeckLinkDeviceNotificationCallback* deviceNotificationCallback) = 0; + virtual HRESULT UninstallDeviceNotifications (void) = 0; + +protected: + virtual ~IDeckLinkDiscovery () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + BMD_PUBLIC IDeckLinkIterator* CreateDeckLinkIteratorInstance(void); + BMD_PUBLIC IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance(void); + BMD_PUBLIC IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance(void); + BMD_PUBLIC IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper(void); + BMD_PUBLIC IDeckLinkGLScreenPreviewHelper* CreateOpenGL3ScreenPreviewHelper(void); // Requires OpenGL 3.2 support and provides improved performance and color handling + BMD_PUBLIC IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview(/* in */ void* /* (NSView*)*/ parentView); + BMD_PUBLIC IDeckLinkMetalScreenPreviewHelper* CreateMetalScreenPreviewHelper(void); + BMD_PUBLIC IDeckLinkVideoConversion* CreateVideoConversionInstance(void); + BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance(void); // For use when creating a custom IDeckLinkVideoFrame without wrapping IDeckLinkOutput::CreateVideoFrame + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPI_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration.h new file mode 100644 index 0000000000..9f2a145307 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration.h @@ -0,0 +1,269 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_H +#define BMD_DECKLINKAPICONFIGURATION_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration = /* 912F634B-2D4E-40A4-8AAB-8D80B73F1289 */ { 0x91,0x2F,0x63,0x4B,0x2D,0x4E,0x40,0xA4,0x8A,0xAB,0x8D,0x80,0xB7,0x3F,0x12,0x89 }; +BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration = /* 138050E5-C60A-4552-BF3F-0F358049327E */ { 0x13,0x80,0x50,0xE5,0xC6,0x0A,0x45,0x52,0xBF,0x3F,0x0F,0x35,0x80,0x49,0x32,0x7E }; + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID; +enum _BMDDeckLinkConfigurationID { + + /* Serial port Flags */ + + bmdDeckLinkConfigSwapSerialRxTx = /* 'ssrt' */ 0x73737274, + + /* Video Input/Output Integers */ + + bmdDeckLinkConfigHDMI3DPackingFormat = /* '3dpf' */ 0x33647066, + bmdDeckLinkConfigBypass = /* 'byps' */ 0x62797073, + bmdDeckLinkConfigClockTimingAdjustment = /* 'ctad' */ 0x63746164, + + /* Audio Input/Output Flags */ + + bmdDeckLinkConfigAnalogAudioConsumerLevels = /* 'aacl' */ 0x6161636C, + bmdDeckLinkConfigSwapHDMICh3AndCh4OnInput = /* 'hi34' */ 0x68693334, + bmdDeckLinkConfigSwapHDMICh3AndCh4OnOutput = /* 'ho34' */ 0x686F3334, + + /* Video Output Flags */ + + bmdDeckLinkConfigFieldFlickerRemoval = /* 'fdfr' */ 0x66646672, + bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion = /* 'to59' */ 0x746F3539, + bmdDeckLinkConfig444SDIVideoOutput = /* '444o' */ 0x3434346F, + bmdDeckLinkConfigBlackVideoOutputDuringCapture = /* 'bvoc' */ 0x62766F63, + bmdDeckLinkConfigLowLatencyVideoOutput = /* 'llvo' */ 0x6C6C766F, + bmdDeckLinkConfigDownConversionOnAllAnalogOutput = /* 'caao' */ 0x6361616F, + bmdDeckLinkConfigSMPTELevelAOutput = /* 'smta' */ 0x736D7461, + bmdDeckLinkConfigRec2020Output = /* 'rec2' */ 0x72656332, // Ensure output is Rec.2020 colorspace + bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit = /* 'SDQS' */ 0x53445153, + bmdDeckLinkConfigOutput1080pAsPsF = /* 'pfpr' */ 0x70667072, + + /* Video Output Integers */ + + bmdDeckLinkConfigVideoOutputConnection = /* 'vocn' */ 0x766F636E, + bmdDeckLinkConfigVideoOutputConversionMode = /* 'vocm' */ 0x766F636D, + bmdDeckLinkConfigAnalogVideoOutputFlags = /* 'avof' */ 0x61766F66, + bmdDeckLinkConfigReferenceInputTimingOffset = /* 'glot' */ 0x676C6F74, + bmdDeckLinkConfigVideoOutputIdleOperation = /* 'voio' */ 0x766F696F, + bmdDeckLinkConfigDefaultVideoOutputMode = /* 'dvom' */ 0x64766F6D, + bmdDeckLinkConfigDefaultVideoOutputModeFlags = /* 'dvof' */ 0x64766F66, + bmdDeckLinkConfigSDIOutputLinkConfiguration = /* 'solc' */ 0x736F6C63, + bmdDeckLinkConfigHDMITimecodePacking = /* 'htpk' */ 0x6874706B, + bmdDeckLinkConfigPlaybackGroup = /* 'plgr' */ 0x706C6772, + + /* Video Output Floats */ + + bmdDeckLinkConfigVideoOutputComponentLumaGain = /* 'oclg' */ 0x6F636C67, + bmdDeckLinkConfigVideoOutputComponentChromaBlueGain = /* 'occb' */ 0x6F636362, + bmdDeckLinkConfigVideoOutputComponentChromaRedGain = /* 'occr' */ 0x6F636372, + bmdDeckLinkConfigVideoOutputCompositeLumaGain = /* 'oilg' */ 0x6F696C67, + bmdDeckLinkConfigVideoOutputCompositeChromaGain = /* 'oicg' */ 0x6F696367, + bmdDeckLinkConfigVideoOutputSVideoLumaGain = /* 'oslg' */ 0x6F736C67, + bmdDeckLinkConfigVideoOutputSVideoChromaGain = /* 'oscg' */ 0x6F736367, + + /* Video Input Flags */ + + bmdDeckLinkConfigVideoInputScanning = /* 'visc' */ 0x76697363, // Applicable to H264 Pro Recorder only + bmdDeckLinkConfigUseDedicatedLTCInput = /* 'dltc' */ 0x646C7463, // Use timecode from LTC input instead of SDI stream + bmdDeckLinkConfigSDIInput3DPayloadOverride = /* '3dds' */ 0x33646473, + bmdDeckLinkConfigCapture1080pAsPsF = /* 'cfpr' */ 0x63667072, + + /* Video Input Integers */ + + bmdDeckLinkConfigVideoInputConnection = /* 'vicn' */ 0x7669636E, + bmdDeckLinkConfigAnalogVideoInputFlags = /* 'avif' */ 0x61766966, + bmdDeckLinkConfigVideoInputConversionMode = /* 'vicm' */ 0x7669636D, + bmdDeckLinkConfig32PulldownSequenceInitialTimecodeFrame = /* 'pdif' */ 0x70646966, + bmdDeckLinkConfigVANCSourceLine1Mapping = /* 'vsl1' */ 0x76736C31, + bmdDeckLinkConfigVANCSourceLine2Mapping = /* 'vsl2' */ 0x76736C32, + bmdDeckLinkConfigVANCSourceLine3Mapping = /* 'vsl3' */ 0x76736C33, + bmdDeckLinkConfigCapturePassThroughMode = /* 'cptm' */ 0x6370746D, + bmdDeckLinkConfigCaptureGroup = /* 'cpgr' */ 0x63706772, + + /* Video Input Floats */ + + bmdDeckLinkConfigVideoInputComponentLumaGain = /* 'iclg' */ 0x69636C67, + bmdDeckLinkConfigVideoInputComponentChromaBlueGain = /* 'iccb' */ 0x69636362, + bmdDeckLinkConfigVideoInputComponentChromaRedGain = /* 'iccr' */ 0x69636372, + bmdDeckLinkConfigVideoInputCompositeLumaGain = /* 'iilg' */ 0x69696C67, + bmdDeckLinkConfigVideoInputCompositeChromaGain = /* 'iicg' */ 0x69696367, + bmdDeckLinkConfigVideoInputSVideoLumaGain = /* 'islg' */ 0x69736C67, + bmdDeckLinkConfigVideoInputSVideoChromaGain = /* 'iscg' */ 0x69736367, + + /* Keying Integers */ + + bmdDeckLinkConfigInternalKeyingAncillaryDataSource = /* 'ikas' */ 0x696B6173, + + /* Audio Input Flags */ + + bmdDeckLinkConfigMicrophonePhantomPower = /* 'mphp' */ 0x6D706870, + + /* Audio Input Integers */ + + bmdDeckLinkConfigAudioInputConnection = /* 'aicn' */ 0x6169636E, + + /* Audio Input Floats */ + + bmdDeckLinkConfigAnalogAudioInputScaleChannel1 = /* 'ais1' */ 0x61697331, + bmdDeckLinkConfigAnalogAudioInputScaleChannel2 = /* 'ais2' */ 0x61697332, + bmdDeckLinkConfigAnalogAudioInputScaleChannel3 = /* 'ais3' */ 0x61697333, + bmdDeckLinkConfigAnalogAudioInputScaleChannel4 = /* 'ais4' */ 0x61697334, + bmdDeckLinkConfigDigitalAudioInputScale = /* 'dais' */ 0x64616973, + bmdDeckLinkConfigMicrophoneInputGain = /* 'micg' */ 0x6D696367, + + /* Audio Output Integers */ + + bmdDeckLinkConfigAudioOutputAESAnalogSwitch = /* 'aoaa' */ 0x616F6161, + + /* Audio Output Floats */ + + bmdDeckLinkConfigAnalogAudioOutputScaleChannel1 = /* 'aos1' */ 0x616F7331, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel2 = /* 'aos2' */ 0x616F7332, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel3 = /* 'aos3' */ 0x616F7333, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel4 = /* 'aos4' */ 0x616F7334, + bmdDeckLinkConfigDigitalAudioOutputScale = /* 'daos' */ 0x64616F73, + bmdDeckLinkConfigHeadphoneVolume = /* 'hvol' */ 0x68766F6C, + + /* Device Information Strings */ + + bmdDeckLinkConfigDeviceInformationLabel = /* 'dila' */ 0x64696C61, + bmdDeckLinkConfigDeviceInformationSerialNumber = /* 'disn' */ 0x6469736E, + bmdDeckLinkConfigDeviceInformationCompany = /* 'dico' */ 0x6469636F, + bmdDeckLinkConfigDeviceInformationPhone = /* 'diph' */ 0x64697068, + bmdDeckLinkConfigDeviceInformationEmail = /* 'diem' */ 0x6469656D, + bmdDeckLinkConfigDeviceInformationDate = /* 'dida' */ 0x64696461, + + /* Deck Control Integers */ + + bmdDeckLinkConfigDeckControlConnection = /* 'dcco' */ 0x6463636F +}; + +/* Enum BMDDeckLinkEncoderConfigurationID - DeckLink Encoder Configuration ID */ + +typedef uint32_t BMDDeckLinkEncoderConfigurationID; +enum _BMDDeckLinkEncoderConfigurationID { + + /* Video Encoder Integers */ + + bmdDeckLinkEncoderConfigPreferredBitDepth = /* 'epbr' */ 0x65706272, + bmdDeckLinkEncoderConfigFrameCodingMode = /* 'efcm' */ 0x6566636D, + + /* HEVC/H.265 Encoder Integers */ + + bmdDeckLinkEncoderConfigH265TargetBitrate = /* 'htbr' */ 0x68746272, + + /* DNxHR/DNxHD Compression ID */ + + bmdDeckLinkEncoderConfigDNxHRCompressionID = /* 'dcid' */ 0x64636964, + + /* DNxHR/DNxHD Level */ + + bmdDeckLinkEncoderConfigDNxHRLevel = /* 'dlev' */ 0x646C6576, + + /* Encoded Sample Decriptions */ + + bmdDeckLinkEncoderConfigMPEG4SampleDescription = /* 'stsE' */ 0x73747345, // Full MPEG4 sample description (aka SampleEntry of an 'stsd' atom-box). Useful for MediaFoundation, QuickTime, MKV and more + bmdDeckLinkEncoderConfigMPEG4CodecSpecificDesc = /* 'esds' */ 0x65736473 // Sample description extensions only (atom stream, each with size and fourCC header). Useful for AVFoundation, VideoToolbox, MKV and more +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkConfiguration; +class IDeckLinkEncoderConfiguration; + +/* Interface IDeckLinkConfiguration - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool* value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double* value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef* value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ + +class BMD_PUBLIC IDeckLinkEncoderConfiguration : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool* value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double* value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ CFStringRef* value) = 0; + virtual HRESULT GetBytes (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ void* buffer /* optional */, /* in, out */ uint32_t* bufferSize) = 0; + +protected: + virtual ~IDeckLinkEncoderConfiguration () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_11.h new file mode 100644 index 0000000000..ea19f8db24 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_11.h @@ -0,0 +1,84 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_11_H +#define BMD_DECKLINKAPICONFIGURATION_v10_11_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_11 = /* EF90380B-4AE5-4346-9077-E288E149F129 */ {0xEF,0x90,0x38,0x0B,0x4A,0xE5,0x43,0x46,0x90,0x77,0xE2,0x88,0xE1,0x49,0xF1,0x29}; + +/* Enum BMDDeckLinkConfigurationID_v10_11 - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_11; +enum _BMDDeckLinkConfigurationID_v10_11 { + + /* Video Input/Output Integers */ + + bmdDeckLinkConfigDuplexMode_v10_11 = 'dupx', +}; + +// Forward Declarations + +class IDeckLinkConfiguration_v10_11; + +/* Interface IDeckLinkConfiguration_v10_11 - DeckLink Configuration interface */ + +class IDeckLinkConfiguration_v10_11 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_11 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_2.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_2.h new file mode 100644 index 0000000000..b0e0dbc9e8 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_2.h @@ -0,0 +1,73 @@ +/* -LICENSE-START- +** Copyright (c) 2014 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_2_H +#define BMD_DECKLINKAPICONFIGURATION_v10_2_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_2 = /* C679A35B-610C-4D09-B748-1D0478100FC0 */ {0xC6,0x79,0xA3,0x5B,0x61,0x0C,0x4D,0x09,0xB7,0x48,0x1D,0x04,0x78,0x10,0x0F,0xC0}; + +// Forward Declarations + +class IDeckLinkConfiguration_v10_2; + +/* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */ + +class IDeckLinkConfiguration_v10_2 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_2 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_2_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_4.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_4.h new file mode 100644 index 0000000000..7d3215de90 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_4.h @@ -0,0 +1,75 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_4_H +#define BMD_DECKLINKAPICONFIGURATION_v10_4_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_4 = /* 1E69FCF6-4203-4936-8076-2A9F4CFD50CB */ {0x1E,0x69,0xFC,0xF6,0x42,0x03,0x49,0x36,0x80,0x76,0x2A,0x9F,0x4C,0xFD,0x50,0xCB}; + +// +// Forward Declarations + +class IDeckLinkConfiguration_v10_4; + +/* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */ + +class IDeckLinkConfiguration_v10_4 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_4 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_5.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_5.h new file mode 100644 index 0000000000..b67572d4d9 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_5.h @@ -0,0 +1,73 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_5_H +#define BMD_DECKLINKAPICONFIGURATION_v10_5_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration_v10_5 = /* 67455668-0848-45DF-8D8E-350A77C9A028 */ {0x67,0x45,0x56,0x68,0x08,0x48,0x45,0xDF,0x8D,0x8E,0x35,0x0A,0x77,0xC9,0xA0,0x28}; + +// Forward Declarations + +class IDeckLinkConfiguration_v10_5; + +/* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ + +class IDeckLinkEncoderConfiguration_v10_5 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* out */ CFStringRef *value) = 0; + virtual HRESULT GetDecoderConfigurationInfo (/* out */ void *buffer, /* in */ long bufferSize, /* out */ long *returnedSize) = 0; + +protected: + virtual ~IDeckLinkEncoderConfiguration_v10_5 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_5_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_9.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_9.h new file mode 100644 index 0000000000..04a6a45ce8 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIConfiguration_v10_9.h @@ -0,0 +1,75 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_9_H +#define BMD_DECKLINKAPICONFIGURATION_v10_9_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_9 = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2}; + +// +// Forward Declarations + +class IDeckLinkConfiguration_v10_9; + +/* Interface IDeckLinkConfiguration_v10_9 - DeckLink Configuration interface */ + +class IDeckLinkConfiguration_v10_9 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_9 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_9_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDeckControl.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDeckControl.h new file mode 100644 index 0000000000..f946af20dc --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDeckControl.h @@ -0,0 +1,223 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIDECKCONTROL_H +#define BMD_DECKLINKAPIDECKCONTROL_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkDeckControlStatusCallback = /* 53436FFB-B434-4906-BADC-AE3060FFE8EF */ { 0x53,0x43,0x6F,0xFB,0xB4,0x34,0x49,0x06,0xBA,0xDC,0xAE,0x30,0x60,0xFF,0xE8,0xEF }; +BMD_CONST REFIID IID_IDeckLinkDeckControl = /* 8E1C3ACE-19C7-4E00-8B92-D80431D958BE */ { 0x8E,0x1C,0x3A,0xCE,0x19,0xC7,0x4E,0x00,0x8B,0x92,0xD8,0x04,0x31,0xD9,0x58,0xBE }; + +/* Enum BMDDeckControlMode - DeckControl mode */ + +typedef uint32_t BMDDeckControlMode; +enum _BMDDeckControlMode { + bmdDeckControlNotOpened = /* 'ntop' */ 0x6E746F70, + bmdDeckControlVTRControlMode = /* 'vtrc' */ 0x76747263, + bmdDeckControlExportMode = /* 'expm' */ 0x6578706D, + bmdDeckControlCaptureMode = /* 'capm' */ 0x6361706D +}; + +/* Enum BMDDeckControlEvent - DeckControl event */ + +typedef uint32_t BMDDeckControlEvent; +enum _BMDDeckControlEvent { + bmdDeckControlAbortedEvent = /* 'abte' */ 0x61627465, // This event is triggered when a capture or edit-to-tape operation is aborted. + + /* Export-To-Tape events */ + + bmdDeckControlPrepareForExportEvent = /* 'pfee' */ 0x70666565, // This event is triggered a few frames before reaching the in-point. IDeckLinkInput::StartScheduledPlayback should be called at this point. + bmdDeckControlExportCompleteEvent = /* 'exce' */ 0x65786365, // This event is triggered a few frames after reaching the out-point. At this point, it is safe to stop playback. Upon reception of this event the deck's control mode is set back to bmdDeckControlVTRControlMode. + + /* Capture events */ + + bmdDeckControlPrepareForCaptureEvent = /* 'pfce' */ 0x70666365, // This event is triggered a few frames before reaching the in-point. The serial timecode attached to IDeckLinkVideoInputFrames is now valid. + bmdDeckControlCaptureCompleteEvent = /* 'ccev' */ 0x63636576 // This event is triggered a few frames after reaching the out-point. Upon reception of this event the deck's control mode is set back to bmdDeckControlVTRControlMode. +}; + +/* Enum BMDDeckControlVTRControlState - VTR Control state */ + +typedef uint32_t BMDDeckControlVTRControlState; +enum _BMDDeckControlVTRControlState { + bmdDeckControlNotInVTRControlMode = /* 'nvcm' */ 0x6E76636D, + bmdDeckControlVTRControlPlaying = /* 'vtrp' */ 0x76747270, + bmdDeckControlVTRControlRecording = /* 'vtrr' */ 0x76747272, + bmdDeckControlVTRControlStill = /* 'vtra' */ 0x76747261, + bmdDeckControlVTRControlShuttleForward = /* 'vtsf' */ 0x76747366, + bmdDeckControlVTRControlShuttleReverse = /* 'vtsr' */ 0x76747372, + bmdDeckControlVTRControlJogForward = /* 'vtjf' */ 0x76746A66, + bmdDeckControlVTRControlJogReverse = /* 'vtjr' */ 0x76746A72, + bmdDeckControlVTRControlStopped = /* 'vtro' */ 0x7674726F +}; + +/* Enum BMDDeckControlStatusFlags - Deck Control status flags */ + +typedef uint32_t BMDDeckControlStatusFlags; +enum _BMDDeckControlStatusFlags { + bmdDeckControlStatusDeckConnected = 1 << 0, + bmdDeckControlStatusRemoteMode = 1 << 1, + bmdDeckControlStatusRecordInhibited = 1 << 2, + bmdDeckControlStatusCassetteOut = 1 << 3 +}; + +/* Enum BMDDeckControlExportModeOpsFlags - Export mode flags */ + +typedef uint32_t BMDDeckControlExportModeOpsFlags; +enum _BMDDeckControlExportModeOpsFlags { + bmdDeckControlExportModeInsertVideo = 1 << 0, + bmdDeckControlExportModeInsertAudio1 = 1 << 1, + bmdDeckControlExportModeInsertAudio2 = 1 << 2, + bmdDeckControlExportModeInsertAudio3 = 1 << 3, + bmdDeckControlExportModeInsertAudio4 = 1 << 4, + bmdDeckControlExportModeInsertAudio5 = 1 << 5, + bmdDeckControlExportModeInsertAudio6 = 1 << 6, + bmdDeckControlExportModeInsertAudio7 = 1 << 7, + bmdDeckControlExportModeInsertAudio8 = 1 << 8, + bmdDeckControlExportModeInsertAudio9 = 1 << 9, + bmdDeckControlExportModeInsertAudio10 = 1 << 10, + bmdDeckControlExportModeInsertAudio11 = 1 << 11, + bmdDeckControlExportModeInsertAudio12 = 1 << 12, + bmdDeckControlExportModeInsertTimeCode = 1 << 13, + bmdDeckControlExportModeInsertAssemble = 1 << 14, + bmdDeckControlExportModeInsertPreview = 1 << 15, + bmdDeckControlUseManualExport = 1 << 16 +}; + +/* Enum BMDDeckControlError - Deck Control error */ + +typedef uint32_t BMDDeckControlError; +enum _BMDDeckControlError { + bmdDeckControlNoError = /* 'noer' */ 0x6E6F6572, + bmdDeckControlModeError = /* 'moer' */ 0x6D6F6572, + bmdDeckControlMissedInPointError = /* 'mier' */ 0x6D696572, + bmdDeckControlDeckTimeoutError = /* 'dter' */ 0x64746572, + bmdDeckControlCommandFailedError = /* 'cfer' */ 0x63666572, + bmdDeckControlDeviceAlreadyOpenedError = /* 'dalo' */ 0x64616C6F, + bmdDeckControlFailedToOpenDeviceError = /* 'fder' */ 0x66646572, + bmdDeckControlInLocalModeError = /* 'lmer' */ 0x6C6D6572, + bmdDeckControlEndOfTapeError = /* 'eter' */ 0x65746572, + bmdDeckControlUserAbortError = /* 'uaer' */ 0x75616572, + bmdDeckControlNoTapeInDeckError = /* 'nter' */ 0x6E746572, + bmdDeckControlNoVideoFromCardError = /* 'nvfc' */ 0x6E766663, + bmdDeckControlNoCommunicationError = /* 'ncom' */ 0x6E636F6D, + bmdDeckControlBufferTooSmallError = /* 'btsm' */ 0x6274736D, + bmdDeckControlBadChecksumError = /* 'chks' */ 0x63686B73, + bmdDeckControlUnknownError = /* 'uner' */ 0x756E6572 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkDeckControlStatusCallback; +class IDeckLinkDeckControl; + +/* Interface IDeckLinkDeckControlStatusCallback - Deck control state change callback. */ + +class BMD_PUBLIC IDeckLinkDeckControlStatusCallback : public IUnknown +{ +public: + virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; + virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState newState, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0; + +protected: + virtual ~IDeckLinkDeckControlStatusCallback () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDeckControl - Deck Control main interface */ + +class BMD_PUBLIC IDeckLinkDeckControl : public IUnknown +{ +public: + virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Close (/* in */ bool standbyOn) = 0; + virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode* mode, /* out */ BMDDeckControlVTRControlState* vtrControlState, /* out */ BMDDeckControlStatusFlags* flags) = 0; + virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0; + virtual HRESULT SendCommand (/* in */ uint8_t* inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t* outBuffer, /* out */ uint32_t* outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Play (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Stop (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Eject (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT StepForward (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT StepBack (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetTimecodeString (/* out */ CFStringRef* currentTimeCode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode** currentTimecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD* currentTimecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0; + virtual HRESULT GetPreroll (/* out */ uint32_t* prerollSeconds) = 0; + virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0; + virtual HRESULT GetExportOffset (/* out */ int32_t* exportOffsetFields) = 0; + virtual HRESULT GetManualExportOffset (/* out */ int32_t* deckManualExportOffsetFields) = 0; + virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0; + virtual HRESULT GetCaptureOffset (/* out */ int32_t* captureOffsetFields) = 0; + virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT GetDeviceID (/* out */ uint16_t* deviceId, /* out */ BMDDeckControlError* error) = 0; + virtual HRESULT Abort (void) = 0; + virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError* error) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback* callback) = 0; + +protected: + virtual ~IDeckLinkDeckControl () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPIDECKCONTROL_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDiscovery.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDiscovery.h new file mode 100644 index 0000000000..d0ac6ddf1f --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDiscovery.h @@ -0,0 +1,79 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIDISCOVERY_H +#define BMD_DECKLINKAPIDISCOVERY_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLink = /* C418FBDD-0587-48ED-8FE5-640F0A14AF91 */ { 0xC4,0x18,0xFB,0xDD,0x05,0x87,0x48,0xED,0x8F,0xE5,0x64,0x0F,0x0A,0x14,0xAF,0x91 }; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLink; + +/* Interface IDeckLink - Represents a DeckLink device */ + +class BMD_PUBLIC IDeckLink : public IUnknown +{ +public: + virtual HRESULT GetModelName (/* out */ CFStringRef* modelName) = 0; + virtual HRESULT GetDisplayName (/* out */ CFStringRef* displayName) = 0; + +protected: + virtual ~IDeckLink () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPIDISCOVERY_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch.cpp b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch.cpp new file mode 100644 index 0000000000..abb03ac215 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch.cpp @@ -0,0 +1,245 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPIDispatch.cpp */ + +#include "DeckLinkAPI.h" +#include + +#if BLACKMAGIC_DECKLINK_API_MAGIC != 1 + #error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h +#endif + +#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" + + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGL3ScreenPreviewHelperFunc)(void); +typedef IDeckLinkMetalScreenPreviewHelper* (*CreateMetalScreenPreviewHelperFunc)(void); +typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); +typedef IDeckLinkVideoFrameAncillaryPackets* (*CreateVideoFrameAncillaryPacketsInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gDeckLinkAPIBundleRef = NULL; +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateOpenGL3ScreenPreviewHelperFunc gCreateOpenGL3PreviewFunc = NULL; +static CreateMetalScreenPreviewHelperFunc gCreateMetalPreviewFunc = NULL; +static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc= NULL; +static CreateVideoFrameAncillaryPacketsInstanceFunc gCreateVideoFrameAncillaryPacketsFunc = NULL; + + +static void InitDeckLinkAPI (void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gDeckLinkAPIBundleRef != NULL) + { + gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0004")); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); + gCreateOpenGL3PreviewFunc = (CreateOpenGL3ScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGL3ScreenPreviewHelper_0001")); + gCreateMetalPreviewFunc = (CreateMetalScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateMetalScreenPreviewHelper_0001")); + gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0003")); + gCreateVideoFrameAncillaryPacketsFunc = (CreateVideoFrameAncillaryPacketsInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoFrameAncillaryPacketsInstance_0001")); + } + CFRelease(bundleURL); + } +} + +bool IsDeckLinkAPIPresent (void) +{ + // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller + if (gDeckLinkAPIBundleRef != NULL) + return true; + + return false; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGL3ScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateOpenGL3PreviewFunc == NULL) + return NULL; + + return gCreateOpenGL3PreviewFunc(); +} + +IDeckLinkMetalScreenPreviewHelper* CreateMetalScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateMetalPreviewFunc == NULL) + return NULL; + + return gCreateMetalPreviewFunc(); +} + +IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* parentView) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateCocoaPreviewFunc == NULL) + return NULL; + + return gCreateCocoaPreviewFunc(parentView); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + + return gCreateDeckLinkDiscoveryFunc(); +} + +IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoFrameAncillaryPacketsFunc == NULL) + return NULL; + + return gCreateVideoFrameAncillaryPacketsFunc(); +} + + +#define kBMDStreamingAPI_BundlePath "/Library/Application Support/Blackmagic Design/Streaming/BMDStreamingAPI.bundle" + +typedef IBMDStreamingDiscovery* (*CreateDiscoveryFunc)(void); +typedef IBMDStreamingH264NALParser* (*CreateNALParserFunc)(void); + +static pthread_once_t gBMDStreamingOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gBMDStreamingAPIBundleRef = NULL; +static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL; +static CreateNALParserFunc gCreateNALParserFunc = NULL; + +static void InitBMDStreamingAPI(void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kBMDStreamingAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gBMDStreamingAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gBMDStreamingAPIBundleRef != NULL) + { + gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0002")); + gCreateNALParserFunc = (CreateNALParserFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingH264NALParser_0001")); + } + + CFRelease(bundleURL); + } +} + +IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateDiscoveryFunc == NULL) + return NULL; + + return gCreateDiscoveryFunc(); +} + +IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateNALParserFunc == NULL) + return NULL; + + return gCreateNALParserFunc(); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v10_11.cpp b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v10_11.cpp new file mode 100644 index 0000000000..b7afbeb4eb --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v10_11.cpp @@ -0,0 +1,219 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPIDispatch.cpp */ + +#include "DeckLinkAPI_v10_11.h" +#include + +#if BLACKMAGIC_DECKLINK_API_MAGIC != 1 + #error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h +#endif + +#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" + + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); +typedef IDeckLinkVideoFrameAncillaryPackets* (*CreateVideoFrameAncillaryPacketsInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gDeckLinkAPIBundleRef = NULL; +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc= NULL; +static CreateVideoFrameAncillaryPacketsInstanceFunc gCreateVideoFrameAncillaryPacketsFunc = NULL; + + +static void InitDeckLinkAPI (void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gDeckLinkAPIBundleRef != NULL) + { + gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0003")); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); + gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0002")); + gCreateVideoFrameAncillaryPacketsFunc = (CreateVideoFrameAncillaryPacketsInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoFrameAncillaryPacketsInstance_0001")); + } + CFRelease(bundleURL); + } +} + +bool IsDeckLinkAPIPresent_v10_11 (void) +{ + // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller + if (gDeckLinkAPIBundleRef != NULL) + return true; + + return false; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview_v10_11 (void* parentView) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateCocoaPreviewFunc == NULL) + return NULL; + + return gCreateCocoaPreviewFunc(parentView); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + + return gCreateDeckLinkDiscoveryFunc(); +} + +IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance_v10_11 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoFrameAncillaryPacketsFunc == NULL) + return NULL; + + return gCreateVideoFrameAncillaryPacketsFunc(); +} + + +#define kBMDStreamingAPI_BundlePath "/Library/Application Support/Blackmagic Design/Streaming/BMDStreamingAPI.bundle" + +typedef IBMDStreamingDiscovery* (*CreateDiscoveryFunc)(void); +typedef IBMDStreamingH264NALParser* (*CreateNALParserFunc)(void); + +static pthread_once_t gBMDStreamingOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gBMDStreamingAPIBundleRef = NULL; +static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL; +static CreateNALParserFunc gCreateNALParserFunc = NULL; + +static void InitBMDStreamingAPI(void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kBMDStreamingAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gBMDStreamingAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gBMDStreamingAPIBundleRef != NULL) + { + gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0002")); + gCreateNALParserFunc = (CreateNALParserFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingH264NALParser_0001")); + } + + CFRelease(bundleURL); + } +} + +IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance_v10_11() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateDiscoveryFunc == NULL) + return NULL; + + return gCreateDiscoveryFunc(); +} + +IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser_v10_11() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateNALParserFunc == NULL) + return NULL; + + return gCreateNALParserFunc(); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v10_8.cpp b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v10_8.cpp new file mode 100644 index 0000000000..2da795ad41 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v10_8.cpp @@ -0,0 +1,206 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPIDispatch.cpp */ + +#include "DeckLinkAPI.h" +#include + +#if BLACKMAGIC_DECKLINK_API_MAGIC != 1 +#error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h +#endif + +#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" + + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gDeckLinkAPIBundleRef = NULL; +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; + + +static void InitDeckLinkAPI(void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gDeckLinkAPIBundleRef != NULL) + { + gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0002")); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); + gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0001")); + } + CFRelease(bundleURL); + } +} + +bool IsDeckLinkAPIPresent(void) +{ + // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller + if (gDeckLinkAPIBundleRef != NULL) + return true; + + return false; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview(void* parentView) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateCocoaPreviewFunc == NULL) + return NULL; + + return gCreateCocoaPreviewFunc(parentView); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + + return gCreateDeckLinkDiscoveryFunc(); +} + + +#define kBMDStreamingAPI_BundlePath "/Library/Application Support/Blackmagic Design/Streaming/BMDStreamingAPI.bundle" + +typedef IBMDStreamingDiscovery* (*CreateDiscoveryFunc)(void); +typedef IBMDStreamingH264NALParser* (*CreateNALParserFunc)(void); + +static pthread_once_t gBMDStreamingOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gBMDStreamingAPIBundleRef = NULL; +static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL; +static CreateNALParserFunc gCreateNALParserFunc = NULL; + +static void InitBMDStreamingAPI(void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kBMDStreamingAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gBMDStreamingAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gBMDStreamingAPIBundleRef != NULL) + { + gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0001")); + gCreateNALParserFunc = (CreateNALParserFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingH264NALParser_0001")); + } + + CFRelease(bundleURL); + } +} + +IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateDiscoveryFunc == NULL) + return NULL; + + return gCreateDiscoveryFunc(); +} + +IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateNALParserFunc == NULL) + return NULL; + + return gCreateNALParserFunc(); +} diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v7_6.cpp b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v7_6.cpp new file mode 100644 index 0000000000..0ee2d73ceb --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v7_6.cpp @@ -0,0 +1,118 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPIDispatch_v7_6.cpp */ + +#include "DeckLinkAPI_v7_6.h" +#include + +#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" + +typedef IDeckLinkIterator* (*CreateIteratorFunc_v7_6)(void); +typedef IDeckLinkGLScreenPreviewHelper_v7_6* (*CreateOpenGLScreenPreviewHelperFunc_v7_6)(void); +typedef IDeckLinkCocoaScreenPreviewCallback_v7_6* (*CreateCocoaScreenPreviewFunc_v7_6)(void*); +typedef IDeckLinkVideoConversion_v7_6* (*CreateVideoConversionInstanceFunc_v7_6)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gBundleRef = NULL; +static CreateIteratorFunc_v7_6 gCreateIteratorFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc_v7_6 gCreateOpenGLPreviewFunc = NULL; +static CreateCocoaScreenPreviewFunc_v7_6 gCreateCocoaPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc_v7_6 gCreateVideoConversionFunc = NULL; + + +static void InitDeckLinkAPI_v7_6 (void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gBundleRef != NULL) + { + gCreateIteratorFunc = (CreateIteratorFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateDeckLinkIteratorInstance")); + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper")); + gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateCocoaScreenPreview")); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc_v7_6)CFBundleGetFunctionPointerForName(gBundleRef, CFSTR("CreateVideoConversionInstance")); + } + CFRelease(bundleURL); + } +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + + if (gCreateIteratorFunc == NULL) + return NULL; + + return gCreateIteratorFunc(); +} + +IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkCocoaScreenPreviewCallback_v7_6* CreateCocoaScreenPreview_v7_6 (void* parentView) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + + if (gCreateCocoaPreviewFunc == NULL) + return NULL; + + return gCreateCocoaPreviewFunc(parentView); +} + +IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + + return gCreateVideoConversionFunc(); +} + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v8_0.cpp b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v8_0.cpp new file mode 100644 index 0000000000..af16c219ae --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIDispatch_v8_0.cpp @@ -0,0 +1,144 @@ +/* -LICENSE-START- +** Copyright (c) 2011 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPIDispatch.cpp */ + +#include "DeckLinkAPI_v8_0.h" +#include + +#if BLACKMAGIC_DECKLINK_API_MAGIC != 1 + #error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h +#endif + +#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" + +typedef IDeckLinkIterator_v8_0* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gDeckLinkAPIBundleRef = NULL; +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; + + +static void InitDeckLinkAPI (void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gDeckLinkAPIBundleRef != NULL) + { + gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0001")); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); + gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); + } + CFRelease(bundleURL); + } +} + +bool IsDeckLinkAPIPresent (void) +{ + // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller + if (gDeckLinkAPIBundleRef != NULL) + return true; + + return false; +} + +IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* parentView) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateCocoaPreviewFunc == NULL) + return NULL; + + return gCreateCocoaPreviewFunc(parentView); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + + return gCreateVideoConversionFunc(); +} + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIModes.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIModes.h new file mode 100644 index 0000000000..4b0fb1ae1a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIModes.h @@ -0,0 +1,289 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIMODES_H +#define BMD_DECKLINKAPIMODES_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkDisplayModeIterator = /* 9C88499F-F601-4021-B80B-032E4EB41C35 */ { 0x9C,0x88,0x49,0x9F,0xF6,0x01,0x40,0x21,0xB8,0x0B,0x03,0x2E,0x4E,0xB4,0x1C,0x35 }; +BMD_CONST REFIID IID_IDeckLinkDisplayMode = /* 3EB2C1AB-0A3D-4523-A3AD-F40D7FB14E78 */ { 0x3E,0xB2,0xC1,0xAB,0x0A,0x3D,0x45,0x23,0xA3,0xAD,0xF4,0x0D,0x7F,0xB1,0x4E,0x78 }; + +/* Enum BMDDisplayMode - BMDDisplayMode enumerates the video modes supported. */ + +typedef uint32_t BMDDisplayMode; +enum _BMDDisplayMode { + + /* SD Modes */ + + bmdModeNTSC = /* 'ntsc' */ 0x6E747363, + bmdModeNTSC2398 = /* 'nt23' */ 0x6E743233, // 3:2 pulldown + bmdModePAL = /* 'pal ' */ 0x70616C20, + bmdModeNTSCp = /* 'ntsp' */ 0x6E747370, + bmdModePALp = /* 'palp' */ 0x70616C70, + + /* HD 1080 Modes */ + + bmdModeHD1080p2398 = /* '23ps' */ 0x32337073, + bmdModeHD1080p24 = /* '24ps' */ 0x32347073, + bmdModeHD1080p25 = /* 'Hp25' */ 0x48703235, + bmdModeHD1080p2997 = /* 'Hp29' */ 0x48703239, + bmdModeHD1080p30 = /* 'Hp30' */ 0x48703330, + bmdModeHD1080p4795 = /* 'Hp47' */ 0x48703437, + bmdModeHD1080p48 = /* 'Hp48' */ 0x48703438, + bmdModeHD1080p50 = /* 'Hp50' */ 0x48703530, + bmdModeHD1080p5994 = /* 'Hp59' */ 0x48703539, + bmdModeHD1080p6000 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080p9590 = /* 'Hp95' */ 0x48703935, + bmdModeHD1080p96 = /* 'Hp96' */ 0x48703936, + bmdModeHD1080p100 = /* 'Hp10' */ 0x48703130, + bmdModeHD1080p11988 = /* 'Hp11' */ 0x48703131, + bmdModeHD1080p120 = /* 'Hp12' */ 0x48703132, + bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, + bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, + bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. + + /* HD 720 Modes */ + + bmdModeHD720p50 = /* 'hp50' */ 0x68703530, + bmdModeHD720p5994 = /* 'hp59' */ 0x68703539, + bmdModeHD720p60 = /* 'hp60' */ 0x68703630, + + /* 2K Modes */ + + bmdMode2k2398 = /* '2k23' */ 0x326B3233, + bmdMode2k24 = /* '2k24' */ 0x326B3234, + bmdMode2k25 = /* '2k25' */ 0x326B3235, + + /* 2K DCI Modes */ + + bmdMode2kDCI2398 = /* '2d23' */ 0x32643233, + bmdMode2kDCI24 = /* '2d24' */ 0x32643234, + bmdMode2kDCI25 = /* '2d25' */ 0x32643235, + bmdMode2kDCI2997 = /* '2d29' */ 0x32643239, + bmdMode2kDCI30 = /* '2d30' */ 0x32643330, + bmdMode2kDCI4795 = /* '2d47' */ 0x32643437, + bmdMode2kDCI48 = /* '2d48' */ 0x32643438, + bmdMode2kDCI50 = /* '2d50' */ 0x32643530, + bmdMode2kDCI5994 = /* '2d59' */ 0x32643539, + bmdMode2kDCI60 = /* '2d60' */ 0x32643630, + bmdMode2kDCI9590 = /* '2d95' */ 0x32643935, + bmdMode2kDCI96 = /* '2d96' */ 0x32643936, + bmdMode2kDCI100 = /* '2d10' */ 0x32643130, + bmdMode2kDCI11988 = /* '2d11' */ 0x32643131, + bmdMode2kDCI120 = /* '2d12' */ 0x32643132, + + /* 4K UHD Modes */ + + bmdMode4K2160p2398 = /* '4k23' */ 0x346B3233, + bmdMode4K2160p24 = /* '4k24' */ 0x346B3234, + bmdMode4K2160p25 = /* '4k25' */ 0x346B3235, + bmdMode4K2160p2997 = /* '4k29' */ 0x346B3239, + bmdMode4K2160p30 = /* '4k30' */ 0x346B3330, + bmdMode4K2160p4795 = /* '4k47' */ 0x346B3437, + bmdMode4K2160p48 = /* '4k48' */ 0x346B3438, + bmdMode4K2160p50 = /* '4k50' */ 0x346B3530, + bmdMode4K2160p5994 = /* '4k59' */ 0x346B3539, + bmdMode4K2160p60 = /* '4k60' */ 0x346B3630, + bmdMode4K2160p9590 = /* '4k95' */ 0x346B3935, + bmdMode4K2160p96 = /* '4k96' */ 0x346B3936, + bmdMode4K2160p100 = /* '4k10' */ 0x346B3130, + bmdMode4K2160p11988 = /* '4k11' */ 0x346B3131, + bmdMode4K2160p120 = /* '4k12' */ 0x346B3132, + + /* 4K DCI Modes */ + + bmdMode4kDCI2398 = /* '4d23' */ 0x34643233, + bmdMode4kDCI24 = /* '4d24' */ 0x34643234, + bmdMode4kDCI25 = /* '4d25' */ 0x34643235, + bmdMode4kDCI2997 = /* '4d29' */ 0x34643239, + bmdMode4kDCI30 = /* '4d30' */ 0x34643330, + bmdMode4kDCI4795 = /* '4d47' */ 0x34643437, + bmdMode4kDCI48 = /* '4d48' */ 0x34643438, + bmdMode4kDCI50 = /* '4d50' */ 0x34643530, + bmdMode4kDCI5994 = /* '4d59' */ 0x34643539, + bmdMode4kDCI60 = /* '4d60' */ 0x34643630, + bmdMode4kDCI9590 = /* '4d95' */ 0x34643935, + bmdMode4kDCI96 = /* '4d96' */ 0x34643936, + bmdMode4kDCI100 = /* '4d10' */ 0x34643130, + bmdMode4kDCI11988 = /* '4d11' */ 0x34643131, + bmdMode4kDCI120 = /* '4d12' */ 0x34643132, + + /* 8K UHD Modes */ + + bmdMode8K4320p2398 = /* '8k23' */ 0x386B3233, + bmdMode8K4320p24 = /* '8k24' */ 0x386B3234, + bmdMode8K4320p25 = /* '8k25' */ 0x386B3235, + bmdMode8K4320p2997 = /* '8k29' */ 0x386B3239, + bmdMode8K4320p30 = /* '8k30' */ 0x386B3330, + bmdMode8K4320p4795 = /* '8k47' */ 0x386B3437, + bmdMode8K4320p48 = /* '8k48' */ 0x386B3438, + bmdMode8K4320p50 = /* '8k50' */ 0x386B3530, + bmdMode8K4320p5994 = /* '8k59' */ 0x386B3539, + bmdMode8K4320p60 = /* '8k60' */ 0x386B3630, + + /* 8K DCI Modes */ + + bmdMode8kDCI2398 = /* '8d23' */ 0x38643233, + bmdMode8kDCI24 = /* '8d24' */ 0x38643234, + bmdMode8kDCI25 = /* '8d25' */ 0x38643235, + bmdMode8kDCI2997 = /* '8d29' */ 0x38643239, + bmdMode8kDCI30 = /* '8d30' */ 0x38643330, + bmdMode8kDCI4795 = /* '8d47' */ 0x38643437, + bmdMode8kDCI48 = /* '8d48' */ 0x38643438, + bmdMode8kDCI50 = /* '8d50' */ 0x38643530, + bmdMode8kDCI5994 = /* '8d59' */ 0x38643539, + bmdMode8kDCI60 = /* '8d60' */ 0x38643630, + + /* PC Modes */ + + bmdMode640x480p60 = /* 'vga6' */ 0x76676136, + bmdMode800x600p60 = /* 'svg6' */ 0x73766736, + bmdMode1440x900p50 = /* 'wxg5' */ 0x77786735, + bmdMode1440x900p60 = /* 'wxg6' */ 0x77786736, + bmdMode1440x1080p50 = /* 'sxg5' */ 0x73786735, + bmdMode1440x1080p60 = /* 'sxg6' */ 0x73786736, + bmdMode1600x1200p50 = /* 'uxg5' */ 0x75786735, + bmdMode1600x1200p60 = /* 'uxg6' */ 0x75786736, + bmdMode1920x1200p50 = /* 'wux5' */ 0x77757835, + bmdMode1920x1200p60 = /* 'wux6' */ 0x77757836, + bmdMode1920x1440p50 = /* '1945' */ 0x31393435, + bmdMode1920x1440p60 = /* '1946' */ 0x31393436, + bmdMode2560x1440p50 = /* 'wqh5' */ 0x77716835, + bmdMode2560x1440p60 = /* 'wqh6' */ 0x77716836, + bmdMode2560x1600p50 = /* 'wqx5' */ 0x77717835, + bmdMode2560x1600p60 = /* 'wqx6' */ 0x77717836, + + /* Special Modes */ + + bmdModeUnknown = /* 'iunk' */ 0x69756E6B +}; + +/* Enum BMDFieldDominance - BMDFieldDominance enumerates settings applicable to video fields. */ + +typedef uint32_t BMDFieldDominance; +enum _BMDFieldDominance { + bmdUnknownFieldDominance = 0, + bmdLowerFieldFirst = /* 'lowr' */ 0x6C6F7772, + bmdUpperFieldFirst = /* 'uppr' */ 0x75707072, + bmdProgressiveFrame = /* 'prog' */ 0x70726F67, + bmdProgressiveSegmentedFrame = /* 'psf ' */ 0x70736620 +}; + +/* Enum BMDPixelFormat - Video pixel formats supported for output/input */ + +typedef uint32_t BMDPixelFormat; +enum _BMDPixelFormat { + bmdFormatUnspecified = 0, + bmdFormat8BitYUV = /* '2vuy' */ 0x32767579, + bmdFormat10BitYUV = /* 'v210' */ 0x76323130, + bmdFormat8BitARGB = 32, + bmdFormat8BitBGRA = /* 'BGRA' */ 0x42475241, + bmdFormat10BitRGB = /* 'r210' */ 0x72323130, // Big-endian RGB 10-bit per component with SMPTE video levels (64-960). Packed as 2:10:10:10 + bmdFormat12BitRGB = /* 'R12B' */ 0x52313242, // Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component + bmdFormat12BitRGBLE = /* 'R12L' */ 0x5231324C, // Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component + bmdFormat10BitRGBXLE = /* 'R10l' */ 0x5231306C, // Little-endian 10-bit RGB with SMPTE video levels (64-940) + bmdFormat10BitRGBX = /* 'R10b' */ 0x52313062, // Big-endian 10-bit RGB with SMPTE video levels (64-940) + bmdFormatH265 = /* 'hev1' */ 0x68657631, // High Efficiency Video Coding (HEVC/h.265) + + /* AVID DNxHR */ + + bmdFormatDNxHR = /* 'AVdh' */ 0x41566468 +}; + +/* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */ + +typedef uint32_t BMDDisplayModeFlags; +enum _BMDDisplayModeFlags { + bmdDisplayModeSupports3D = 1 << 0, + bmdDisplayModeColorspaceRec601 = 1 << 1, + bmdDisplayModeColorspaceRec709 = 1 << 2, + bmdDisplayModeColorspaceRec2020 = 1 << 3 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkDisplayModeIterator; +class IDeckLinkDisplayMode; + +/* Interface IDeckLinkDisplayModeIterator - Enumerates over supported input/output display modes. */ + +class BMD_PUBLIC IDeckLinkDisplayModeIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkDisplayMode** deckLinkDisplayMode) = 0; + +protected: + virtual ~IDeckLinkDisplayModeIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkDisplayMode - Represents a display mode */ + +class BMD_PUBLIC IDeckLinkDisplayMode : public IUnknown +{ +public: + virtual HRESULT GetName (/* out */ CFStringRef* name) = 0; + virtual BMDDisplayMode GetDisplayMode (void) = 0; + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual HRESULT GetFrameRate (/* out */ BMDTimeValue* frameDuration, /* out */ BMDTimeScale* timeScale) = 0; + virtual BMDFieldDominance GetFieldDominance (void) = 0; + virtual BMDDisplayModeFlags GetFlags (void) = 0; + +protected: + virtual ~IDeckLinkDisplayMode () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPIMODES_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIStreaming.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIStreaming.h new file mode 100644 index 0000000000..5ef156e7d5 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIStreaming.h @@ -0,0 +1,383 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPISTREAMING_H +#define BMD_DECKLINKAPISTREAMING_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + + +// Interface ID Declarations + +BMD_CONST REFIID IID_IBMDStreamingDeviceNotificationCallback = /* F9531D64-3305-4B29-A387-7F74BB0D0E84 */ { 0xF9,0x53,0x1D,0x64,0x33,0x05,0x4B,0x29,0xA3,0x87,0x7F,0x74,0xBB,0x0D,0x0E,0x84 }; +BMD_CONST REFIID IID_IBMDStreamingH264InputCallback = /* 823C475F-55AE-46F9-890C-537CC5CEDCCA */ { 0x82,0x3C,0x47,0x5F,0x55,0xAE,0x46,0xF9,0x89,0x0C,0x53,0x7C,0xC5,0xCE,0xDC,0xCA }; +BMD_CONST REFIID IID_IBMDStreamingDiscovery = /* 2C837444-F989-4D87-901A-47C8A36D096D */ { 0x2C,0x83,0x74,0x44,0xF9,0x89,0x4D,0x87,0x90,0x1A,0x47,0xC8,0xA3,0x6D,0x09,0x6D }; +BMD_CONST REFIID IID_IBMDStreamingVideoEncodingMode = /* 1AB8035B-CD13-458D-B6DF-5E8F7C2141D9 */ { 0x1A,0xB8,0x03,0x5B,0xCD,0x13,0x45,0x8D,0xB6,0xDF,0x5E,0x8F,0x7C,0x21,0x41,0xD9 }; +BMD_CONST REFIID IID_IBMDStreamingMutableVideoEncodingMode = /* 19BF7D90-1E0A-400D-B2C6-FFC4E78AD49D */ { 0x19,0xBF,0x7D,0x90,0x1E,0x0A,0x40,0x0D,0xB2,0xC6,0xFF,0xC4,0xE7,0x8A,0xD4,0x9D }; +BMD_CONST REFIID IID_IBMDStreamingVideoEncodingModePresetIterator = /* 7AC731A3-C950-4AD0-804A-8377AA51C6C4 */ { 0x7A,0xC7,0x31,0xA3,0xC9,0x50,0x4A,0xD0,0x80,0x4A,0x83,0x77,0xAA,0x51,0xC6,0xC4 }; +BMD_CONST REFIID IID_IBMDStreamingDeviceInput = /* 24B6B6EC-1727-44BB-9818-34FF086ACF98 */ { 0x24,0xB6,0xB6,0xEC,0x17,0x27,0x44,0xBB,0x98,0x18,0x34,0xFF,0x08,0x6A,0xCF,0x98 }; +BMD_CONST REFIID IID_IBMDStreamingH264NALPacket = /* E260E955-14BE-4395-9775-9F02CC0A9D89 */ { 0xE2,0x60,0xE9,0x55,0x14,0xBE,0x43,0x95,0x97,0x75,0x9F,0x02,0xCC,0x0A,0x9D,0x89 }; +BMD_CONST REFIID IID_IBMDStreamingAudioPacket = /* D9EB5902-1AD2-43F4-9E2C-3CFA50B5EE19 */ { 0xD9,0xEB,0x59,0x02,0x1A,0xD2,0x43,0xF4,0x9E,0x2C,0x3C,0xFA,0x50,0xB5,0xEE,0x19 }; +BMD_CONST REFIID IID_IBMDStreamingMPEG2TSPacket = /* 91810D1C-4FB3-4AAA-AE56-FA301D3DFA4C */ { 0x91,0x81,0x0D,0x1C,0x4F,0xB3,0x4A,0xAA,0xAE,0x56,0xFA,0x30,0x1D,0x3D,0xFA,0x4C }; +BMD_CONST REFIID IID_IBMDStreamingH264NALParser = /* 5867F18C-5BFA-4CCC-B2A7-9DFD140417D2 */ { 0x58,0x67,0xF1,0x8C,0x5B,0xFA,0x4C,0xCC,0xB2,0xA7,0x9D,0xFD,0x14,0x04,0x17,0xD2 }; + +/* Enum BMDStreamingDeviceMode - Device modes */ + +typedef uint32_t BMDStreamingDeviceMode; +enum _BMDStreamingDeviceMode { + bmdStreamingDeviceIdle = /* 'idle' */ 0x69646C65, + bmdStreamingDeviceEncoding = /* 'enco' */ 0x656E636F, + bmdStreamingDeviceStopping = /* 'stop' */ 0x73746F70, + bmdStreamingDeviceUnknown = /* 'munk' */ 0x6D756E6B +}; + +/* Enum BMDStreamingEncodingFrameRate - Encoded frame rates */ + +typedef uint32_t BMDStreamingEncodingFrameRate; +enum _BMDStreamingEncodingFrameRate { + + /* Interlaced rates */ + + bmdStreamingEncodedFrameRate50i = /* 'e50i' */ 0x65353069, + bmdStreamingEncodedFrameRate5994i = /* 'e59i' */ 0x65353969, + bmdStreamingEncodedFrameRate60i = /* 'e60i' */ 0x65363069, + + /* Progressive rates */ + + bmdStreamingEncodedFrameRate2398p = /* 'e23p' */ 0x65323370, + bmdStreamingEncodedFrameRate24p = /* 'e24p' */ 0x65323470, + bmdStreamingEncodedFrameRate25p = /* 'e25p' */ 0x65323570, + bmdStreamingEncodedFrameRate2997p = /* 'e29p' */ 0x65323970, + bmdStreamingEncodedFrameRate30p = /* 'e30p' */ 0x65333070, + bmdStreamingEncodedFrameRate50p = /* 'e50p' */ 0x65353070, + bmdStreamingEncodedFrameRate5994p = /* 'e59p' */ 0x65353970, + bmdStreamingEncodedFrameRate60p = /* 'e60p' */ 0x65363070 +}; + +/* Enum BMDStreamingEncodingSupport - Output encoding mode supported flag */ + +typedef uint32_t BMDStreamingEncodingSupport; +enum _BMDStreamingEncodingSupport { + bmdStreamingEncodingModeNotSupported = 0, + bmdStreamingEncodingModeSupported, + bmdStreamingEncodingModeSupportedWithChanges +}; + +/* Enum BMDStreamingVideoCodec - Video codecs */ + +typedef uint32_t BMDStreamingVideoCodec; +enum _BMDStreamingVideoCodec { + bmdStreamingVideoCodecH264 = /* 'H264' */ 0x48323634 +}; + +/* Enum BMDStreamingH264Profile - H264 encoding profile */ + +typedef uint32_t BMDStreamingH264Profile; +enum _BMDStreamingH264Profile { + bmdStreamingH264ProfileHigh = /* 'high' */ 0x68696768, + bmdStreamingH264ProfileMain = /* 'main' */ 0x6D61696E, + bmdStreamingH264ProfileBaseline = /* 'base' */ 0x62617365 +}; + +/* Enum BMDStreamingH264Level - H264 encoding level */ + +typedef uint32_t BMDStreamingH264Level; +enum _BMDStreamingH264Level { + bmdStreamingH264Level12 = /* 'lv12' */ 0x6C763132, + bmdStreamingH264Level13 = /* 'lv13' */ 0x6C763133, + bmdStreamingH264Level2 = /* 'lv2 ' */ 0x6C763220, + bmdStreamingH264Level21 = /* 'lv21' */ 0x6C763231, + bmdStreamingH264Level22 = /* 'lv22' */ 0x6C763232, + bmdStreamingH264Level3 = /* 'lv3 ' */ 0x6C763320, + bmdStreamingH264Level31 = /* 'lv31' */ 0x6C763331, + bmdStreamingH264Level32 = /* 'lv32' */ 0x6C763332, + bmdStreamingH264Level4 = /* 'lv4 ' */ 0x6C763420, + bmdStreamingH264Level41 = /* 'lv41' */ 0x6C763431, + bmdStreamingH264Level42 = /* 'lv42' */ 0x6C763432 +}; + +/* Enum BMDStreamingH264EntropyCoding - H264 entropy coding */ + +typedef uint32_t BMDStreamingH264EntropyCoding; +enum _BMDStreamingH264EntropyCoding { + bmdStreamingH264EntropyCodingCAVLC = /* 'EVLC' */ 0x45564C43, + bmdStreamingH264EntropyCodingCABAC = /* 'EBAC' */ 0x45424143 +}; + +/* Enum BMDStreamingAudioCodec - Audio codecs */ + +typedef uint32_t BMDStreamingAudioCodec; +enum _BMDStreamingAudioCodec { + bmdStreamingAudioCodecAAC = /* 'AAC ' */ 0x41414320 +}; + +/* Enum BMDStreamingEncodingModePropertyID - Encoding mode properties */ + +typedef uint32_t BMDStreamingEncodingModePropertyID; +enum _BMDStreamingEncodingModePropertyID { + + /* Integers, Video Properties */ + + bmdStreamingEncodingPropertyVideoFrameRate = /* 'vfrt' */ 0x76667274, // Uses values of type BMDStreamingEncodingFrameRate + bmdStreamingEncodingPropertyVideoBitRateKbps = /* 'vbrt' */ 0x76627274, + + /* Integers, H264 Properties */ + + bmdStreamingEncodingPropertyH264Profile = /* 'hprf' */ 0x68707266, + bmdStreamingEncodingPropertyH264Level = /* 'hlvl' */ 0x686C766C, + bmdStreamingEncodingPropertyH264EntropyCoding = /* 'hent' */ 0x68656E74, + + /* Flags, H264 Properties */ + + bmdStreamingEncodingPropertyH264HasBFrames = /* 'hBfr' */ 0x68426672, + + /* Integers, Audio Properties */ + + bmdStreamingEncodingPropertyAudioCodec = /* 'acdc' */ 0x61636463, + bmdStreamingEncodingPropertyAudioSampleRate = /* 'asrt' */ 0x61737274, + bmdStreamingEncodingPropertyAudioChannelCount = /* 'achc' */ 0x61636863, + bmdStreamingEncodingPropertyAudioBitRateKbps = /* 'abrt' */ 0x61627274 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IBMDStreamingDeviceNotificationCallback; +class IBMDStreamingH264InputCallback; +class IBMDStreamingDiscovery; +class IBMDStreamingVideoEncodingMode; +class IBMDStreamingMutableVideoEncodingMode; +class IBMDStreamingVideoEncodingModePresetIterator; +class IBMDStreamingDeviceInput; +class IBMDStreamingH264NALPacket; +class IBMDStreamingAudioPacket; +class IBMDStreamingMPEG2TSPacket; +class IBMDStreamingH264NALParser; + +/* Interface IBMDStreamingDeviceNotificationCallback - Device notification callbacks. */ + +class BMD_PUBLIC IBMDStreamingDeviceNotificationCallback : public IUnknown +{ +public: + virtual HRESULT StreamingDeviceArrived (/* in */ IDeckLink* device) = 0; + virtual HRESULT StreamingDeviceRemoved (/* in */ IDeckLink* device) = 0; + virtual HRESULT StreamingDeviceModeChanged (/* in */ IDeckLink* device, /* in */ BMDStreamingDeviceMode mode) = 0; + +protected: + virtual ~IBMDStreamingDeviceNotificationCallback () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingH264InputCallback - H264 input callbacks. */ + +class BMD_PUBLIC IBMDStreamingH264InputCallback : public IUnknown +{ +public: + virtual HRESULT H264NALPacketArrived (/* in */ IBMDStreamingH264NALPacket* nalPacket) = 0; + virtual HRESULT H264AudioPacketArrived (/* in */ IBMDStreamingAudioPacket* audioPacket) = 0; + virtual HRESULT MPEG2TSPacketArrived (/* in */ IBMDStreamingMPEG2TSPacket* tsPacket) = 0; + virtual HRESULT H264VideoInputConnectorScanningChanged (void) = 0; + virtual HRESULT H264VideoInputConnectorChanged (void) = 0; + virtual HRESULT H264VideoInputModeChanged (void) = 0; + +protected: + virtual ~IBMDStreamingH264InputCallback () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingDiscovery - Installs device notifications */ + +class BMD_PUBLIC IBMDStreamingDiscovery : public IUnknown +{ +public: + virtual HRESULT InstallDeviceNotifications (/* in */ IBMDStreamingDeviceNotificationCallback* theCallback) = 0; + virtual HRESULT UninstallDeviceNotifications (void) = 0; + +protected: + virtual ~IBMDStreamingDiscovery () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingVideoEncodingMode - Represents an encoded video mode. */ + +class BMD_PUBLIC IBMDStreamingVideoEncodingMode : public IUnknown +{ +public: + virtual HRESULT GetName (/* out */ CFStringRef* name) = 0; + virtual unsigned int GetPresetID (void) = 0; + virtual unsigned int GetSourcePositionX (void) = 0; + virtual unsigned int GetSourcePositionY (void) = 0; + virtual unsigned int GetSourceWidth (void) = 0; + virtual unsigned int GetSourceHeight (void) = 0; + virtual unsigned int GetDestWidth (void) = 0; + virtual unsigned int GetDestHeight (void) = 0; + virtual HRESULT GetFlag (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* out */ bool* value) = 0; + virtual HRESULT GetInt (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* out */ int64_t* value) = 0; + virtual HRESULT GetFloat (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* out */ double* value) = 0; + virtual HRESULT GetString (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* out */ CFStringRef* value) = 0; + virtual HRESULT CreateMutableVideoEncodingMode (/* out */ IBMDStreamingMutableVideoEncodingMode** newEncodingMode) = 0; // Creates a mutable copy of the encoding mode + +protected: + virtual ~IBMDStreamingVideoEncodingMode () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingMutableVideoEncodingMode - Represents a mutable encoded video mode. */ + +class BMD_PUBLIC IBMDStreamingMutableVideoEncodingMode : public IBMDStreamingVideoEncodingMode +{ +public: + virtual HRESULT SetSourceRect (/* in */ uint32_t posX, /* in */ uint32_t posY, /* in */ uint32_t width, /* in */ uint32_t height) = 0; + virtual HRESULT SetDestSize (/* in */ uint32_t width, /* in */ uint32_t height) = 0; + virtual HRESULT SetFlag (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* in */ bool value) = 0; + virtual HRESULT SetInt (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT SetFloat (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* in */ double value) = 0; + virtual HRESULT SetString (/* in */ BMDStreamingEncodingModePropertyID cfgID, /* in */ CFStringRef value) = 0; + +protected: + virtual ~IBMDStreamingMutableVideoEncodingMode () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingVideoEncodingModePresetIterator - Enumerates encoding mode presets */ + +class BMD_PUBLIC IBMDStreamingVideoEncodingModePresetIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IBMDStreamingVideoEncodingMode** videoEncodingMode) = 0; + +protected: + virtual ~IBMDStreamingVideoEncodingModePresetIterator () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingDeviceInput - Created by QueryInterface from IDeckLink */ + +class BMD_PUBLIC IBMDStreamingDeviceInput : public IUnknown +{ +public: + + /* Input modes */ + + virtual HRESULT DoesSupportVideoInputMode (/* in */ BMDDisplayMode inputMode, /* out */ bool* result) = 0; + virtual HRESULT GetVideoInputModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetVideoInputMode (/* in */ BMDDisplayMode inputMode) = 0; + virtual HRESULT GetCurrentDetectedVideoInputMode (/* out */ BMDDisplayMode* detectedMode) = 0; + + /* Capture modes */ + + virtual HRESULT GetVideoEncodingMode (/* out */ IBMDStreamingVideoEncodingMode** encodingMode) = 0; + virtual HRESULT GetVideoEncodingModePresetIterator (/* in */ BMDDisplayMode inputMode, /* out */ IBMDStreamingVideoEncodingModePresetIterator** iterator) = 0; + virtual HRESULT DoesSupportVideoEncodingMode (/* in */ BMDDisplayMode inputMode, /* in */ IBMDStreamingVideoEncodingMode* encodingMode, /* out */ BMDStreamingEncodingSupport* result, /* out */ IBMDStreamingVideoEncodingMode** changedEncodingMode) = 0; + virtual HRESULT SetVideoEncodingMode (/* in */ IBMDStreamingVideoEncodingMode* encodingMode) = 0; + + /* Input control */ + + virtual HRESULT StartCapture (void) = 0; + virtual HRESULT StopCapture (void) = 0; + virtual HRESULT SetCallback (/* in */ IUnknown* theCallback) = 0; + +protected: + virtual ~IBMDStreamingDeviceInput () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingH264NALPacket - Represent an H.264 NAL packet */ + +class BMD_PUBLIC IBMDStreamingH264NALPacket : public IUnknown +{ +public: + virtual long GetPayloadSize (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual HRESULT GetBytesWithSizePrefix (/* out */ void** buffer) = 0; // Contains a 32-bit unsigned big endian size prefix + virtual HRESULT GetDisplayTime (/* in */ uint64_t requestedTimeScale, /* out */ uint64_t* displayTime) = 0; + virtual HRESULT GetPacketIndex (/* out */ uint32_t* packetIndex) = 0; // Deprecated + +protected: + virtual ~IBMDStreamingH264NALPacket () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingAudioPacket - Represents a chunk of audio data */ + +class BMD_PUBLIC IBMDStreamingAudioPacket : public IUnknown +{ +public: + virtual BMDStreamingAudioCodec GetCodec (void) = 0; + virtual long GetPayloadSize (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + virtual HRESULT GetPlayTime (/* in */ uint64_t requestedTimeScale, /* out */ uint64_t* playTime) = 0; + virtual HRESULT GetPacketIndex (/* out */ uint32_t* packetIndex) = 0; // Deprecated + +protected: + virtual ~IBMDStreamingAudioPacket () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingMPEG2TSPacket - Represent an MPEG2 Transport Stream packet */ + +class BMD_PUBLIC IBMDStreamingMPEG2TSPacket : public IUnknown +{ +public: + virtual long GetPayloadSize (void) = 0; + virtual HRESULT GetBytes (/* out */ void** buffer) = 0; + +protected: + virtual ~IBMDStreamingMPEG2TSPacket () {} // call Release method to drop reference count +}; + +/* Interface IBMDStreamingH264NALParser - For basic NAL parsing */ + +class BMD_PUBLIC IBMDStreamingH264NALParser : public IUnknown +{ +public: + virtual HRESULT IsNALSequenceParameterSet (/* in */ IBMDStreamingH264NALPacket* nal) = 0; + virtual HRESULT IsNALPictureParameterSet (/* in */ IBMDStreamingH264NALPacket* nal) = 0; + virtual HRESULT GetProfileAndLevelFromSPS (/* in */ IBMDStreamingH264NALPacket* nal, /* out */ uint32_t* profileIdc, /* out */ uint32_t* profileCompatability, /* out */ uint32_t* levelIdc) = 0; + +protected: + virtual ~IBMDStreamingH264NALParser () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + BMD_PUBLIC IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance(void); + BMD_PUBLIC IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser(void); + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPISTREAMING_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIStreaming_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIStreaming_v10_11.h new file mode 100644 index 0000000000..9ac9e499d9 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIStreaming_v10_11.h @@ -0,0 +1,59 @@ +/* -LICENSE-START- +** Copyright (c) 2018 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPISTREAMING_H +#define BMD_DECKLINKAPISTREAMING_H + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + + +/* Functions */ + +extern "C" { + + IBMDStreamingDiscovery* BMD_PUBLIC CreateBMDStreamingDiscoveryInstance_v10_11 (void); + IBMDStreamingH264NALParser* BMD_PUBLIC CreateBMDStreamingH264NALParser_v10_11 (void); + +} + + +#endif /* defined(BMD_DECKLINKAPISTREAMING_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPITypes.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPITypes.h new file mode 100644 index 0000000000..8437eb4c2a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPITypes.h @@ -0,0 +1,132 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPITYPES_H +#define BMD_DECKLINKAPITYPES_H + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + +// Type Declarations + +typedef int64_t BMDTimeValue; +typedef int64_t BMDTimeScale; +typedef uint32_t BMDTimecodeBCD; +typedef uint32_t BMDTimecodeUserBits; + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkTimecode = /* BC6CFBD3-8317-4325-AC1C-1216391E9340 */ { 0xBC,0x6C,0xFB,0xD3,0x83,0x17,0x43,0x25,0xAC,0x1C,0x12,0x16,0x39,0x1E,0x93,0x40 }; + +/* Enum BMDTimecodeFlags - Timecode flags */ + +typedef uint32_t BMDTimecodeFlags; +enum _BMDTimecodeFlags { + bmdTimecodeFlagDefault = 0, + bmdTimecodeIsDropFrame = 1 << 0, + bmdTimecodeFieldMark = 1 << 1, + bmdTimecodeColorFrame = 1 << 2, + bmdTimecodeEmbedRecordingTrigger = 1 << 3, // On SDI recording trigger utilises a user-bit. + bmdTimecodeRecordingTriggered = 1 << 4 +}; + +/* Enum BMDVideoConnection - Video connection types */ + +typedef uint32_t BMDVideoConnection; +enum _BMDVideoConnection { + bmdVideoConnectionUnspecified = 0, + bmdVideoConnectionSDI = 1 << 0, + bmdVideoConnectionHDMI = 1 << 1, + bmdVideoConnectionOpticalSDI = 1 << 2, + bmdVideoConnectionComponent = 1 << 3, + bmdVideoConnectionComposite = 1 << 4, + bmdVideoConnectionSVideo = 1 << 5 +}; + +/* Enum BMDAudioConnection - Audio connection types */ + +typedef uint32_t BMDAudioConnection; +enum _BMDAudioConnection { + bmdAudioConnectionEmbedded = 1 << 0, + bmdAudioConnectionAESEBU = 1 << 1, + bmdAudioConnectionAnalog = 1 << 2, + bmdAudioConnectionAnalogXLR = 1 << 3, + bmdAudioConnectionAnalogRCA = 1 << 4, + bmdAudioConnectionMicrophone = 1 << 5, + bmdAudioConnectionHeadphones = 1 << 6 +}; + +/* Enum BMDDeckControlConnection - Deck control connections */ + +typedef uint32_t BMDDeckControlConnection; +enum _BMDDeckControlConnection { + bmdDeckControlConnectionRS422Remote1 = 1 << 0, + bmdDeckControlConnectionRS422Remote2 = 1 << 1 +}; + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkTimecode; + +/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ + +class BMD_PUBLIC IDeckLinkTimecode : public IUnknown +{ +public: + virtual BMDTimecodeBCD GetBCD (void) = 0; + virtual HRESULT GetComponents (/* out */ uint8_t* hours, /* out */ uint8_t* minutes, /* out */ uint8_t* seconds, /* out */ uint8_t* frames) = 0; + virtual HRESULT GetString (/* out */ CFStringRef* timecode) = 0; + virtual BMDTimecodeFlags GetFlags (void) = 0; + virtual HRESULT GetTimecodeUserBits (/* out */ BMDTimecodeUserBits* userBits) = 0; + +protected: + virtual ~IDeckLinkTimecode () {} // call Release method to drop reference count +}; + +/* Functions */ + +extern "C" { + + +} + + + +#endif /* defined(__cplusplus) */ +#endif /* defined(BMD_DECKLINKAPITYPES_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVersion.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVersion.h new file mode 100644 index 0000000000..679ef92584 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVersion.h @@ -0,0 +1,50 @@ +/* -LICENSE-START- + * ** Copyright (c) 2014 Blackmagic Design + * ** + * ** Permission is hereby granted, free of charge, to any person or organization + * ** obtaining a copy of the software and accompanying documentation (the + * ** "Software") to use, reproduce, display, distribute, sub-license, execute, + * ** and transmit the Software, and to prepare derivative works of the Software, + * ** and to permit third-parties to whom the Software is furnished to do so, in + * ** accordance with: + * ** + * ** (1) if the Software is obtained from Blackmagic Design, the End User License + * ** Agreement for the Software Development Kit (“EULA”) available at + * ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + * ** + * ** (2) if the Software is obtained from any third party, such licensing terms + * ** as notified by that third party, + * ** + * ** and all subject to the following: + * ** + * ** (3) the copyright notices in the Software and this entire statement, + * ** including the above license grant, this restriction and the following + * ** disclaimer, must be included in all copies of the Software, in whole or in + * ** part, and all derivative works of the Software, unless such copies or + * ** derivative works are solely in the form of machine-executable object code + * ** generated by a source language processor. + * ** + * ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * ** DEALINGS IN THE SOFTWARE. + * ** + * ** A copy of the Software is available free of charge at + * ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + * ** + * ** -LICENSE-END- + * */ + +/* DeckLinkAPIVersion.h */ + +#ifndef __DeckLink_API_Version_h__ +#define __DeckLink_API_Version_h__ + +#define BLACKMAGIC_DECKLINK_API_VERSION 0x0c040200 +#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "12.4.2" + +#endif // __DeckLink_API_Version_h__ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoEncoderInput_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoEncoderInput_v10_11.h new file mode 100644 index 0000000000..8921b35333 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoEncoderInput_v10_11.h @@ -0,0 +1,88 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOENCODERINPUT_v10_11_H +#define BMD_DECKLINKAPIVIDEOENCODERINPUT_v10_11_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkEncoderInput_v10_11 = /* 270587DA-6B7D-42E7-A1F0-6D853F581185 */ {0x27,0x05,0x87,0xDA,0x6B,0x7D,0x42,0xE7,0xA1,0xF0,0x6D,0x85,0x3F,0x58,0x11,0x85}; + +/* Interface IDeckLinkEncoderInput_v10_11 - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkEncoderInput_v10_11 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailablePacketsCount (/* out */ uint32_t *availablePacketsCount) = 0; + virtual HRESULT SetMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioFormat audioFormat, /* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkEncoderInputCallback *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkEncoderInput_v10_11 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOENCODERINPUT_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v10_11.h new file mode 100644 index 0000000000..0a287f8cdf --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v10_11.h @@ -0,0 +1,91 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOINPUT_v10_11_H +#define BMD_DECKLINKAPIVIDEOINPUT_v10_11_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" +#include "DeckLinkAPIVideoInput_v11_5_1.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkInput_v10_11 = /* AF22762B-DFAC-4846-AA79-FA8883560995 */ {0xAF,0x22,0x76,0x2B,0xDF,0xAC,0x48,0x46,0xAA,0x79,0xFA,0x88,0x83,0x56,0x09,0x95}; + +/* Interface IDeckLinkInput_v10_11 - DeckLink input interface. */ + +class IDeckLinkInput_v10_11 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1 *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v10_11 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOINPUT_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v11_4.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v11_4.h new file mode 100644 index 0000000000..4879fc2a18 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v11_4.h @@ -0,0 +1,90 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOINPUT_v11_4_H +#define BMD_DECKLINKAPIVIDEOINPUT_v11_4_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPIVideoInput_v11_5_1.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkInput_v11_4 = /* 2A88CF76-F494-4216-A7EF-DC74EEB83882 */ { 0x2A,0x88,0xCF,0x76,0xF4,0x94,0x42,0x16,0xA7,0xEF,0xDC,0x74,0xEE,0xB8,0x38,0x82 }; + +/* Interface IDeckLinkInput_v11_4 - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v11_4 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of 0 is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDSupportedVideoModeFlags flags, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t* availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v11_4 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOINPUT_v11_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v11_5_1.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v11_5_1.h new file mode 100644 index 0000000000..51fb5172ac --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoInput_v11_5_1.h @@ -0,0 +1,102 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOINPUT_v11_5_1_H +#define BMD_DECKLINKAPIVIDEOINPUT_v11_5_1_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkInputCallback_v11_5_1 = /* DD04E5EC-7415-42AB-AE4A-E80C4DFC044A */ { 0xDD, 0x04, 0xE5, 0xEC, 0x74, 0x15, 0x42, 0xAB, 0xAE, 0x4A, 0xE8, 0x0C, 0x4D, 0xFC, 0x04, 0x4A }; +BMD_CONST REFIID IID_IDeckLinkInput_v11_5_1 = /* 9434C6E4-B15D-4B1C-979E-661E3DDCB4B9 */ { 0x94, 0x34, 0xC6, 0xE4, 0xB1, 0x5D, 0x4B, 0x1C, 0x97, 0x9E, 0x66, 0x1E, 0x3D, 0xDC, 0xB4, 0xB9 }; + +/* Interface IDeckLinkInputCallback_v11_5_1 - Frame arrival callback. */ + +class BMD_PUBLIC IDeckLinkInputCallback_v11_5_1 : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode* newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback_v11_5_1 () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkInput_v11_5_1 - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkInput_v11_5_1 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDVideoInputConversionMode conversionMode, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t* availableFrameCount) = 0; + virtual HRESULT SetVideoInputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t* availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1* theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v11_5_1 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOINPUT_v11_5_1_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoOutput_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoOutput_v10_11.h new file mode 100644 index 0000000000..22a13a5dcc --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoOutput_v10_11.h @@ -0,0 +1,108 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOOUTPUT_v10_11_H +#define BMD_DECKLINKAPIVIDEOOUTPUT_v10_11_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkOutput_v10_11 = /* CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564 */ {0xCC,0x5C,0x8A,0x6E,0x3F,0x2F,0x4B,0x3A,0x87,0xEA,0xFD,0x78,0xAF,0x30,0x05,0x64}; + +/* Interface IDeckLinkOutput_v10_11 - DeckLink output interface. */ + +class IDeckLinkOutput_v10_11 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + virtual HRESULT GetFrameCompletionReferenceTimestamp (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *frameCompletionTimestamp) = 0; + +protected: + virtual ~IDeckLinkOutput_v10_11 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOOUTPUT_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoOutput_v11_4.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoOutput_v11_4.h new file mode 100644 index 0000000000..14d65ac24c --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPIVideoOutput_v11_4.h @@ -0,0 +1,101 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPIVIDEOOUTPUT_v11_4_H +#define BMD_DECKLINKAPIVIDEOOUTPUT_v11_4_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +BMD_CONST REFIID IID_IDeckLinkOutput_v11_4 = /* 065A0F6C-C508-4D0D-B919-F5EB0EBFC96B */ { 0x06,0x5A,0x0F,0x6C,0xC5,0x08,0x4D,0x0D,0xB9,0x19,0xF5,0xEB,0x0E,0xBF,0xC9,0x6B }; + +/* Interface IDeckLinkOutput_v11_4 - Created by QueryInterface from IDeckLink. */ + +class BMD_PUBLIC IDeckLinkOutput_v11_4 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDVideoConnection connection /* If a value of 0 is specified, the caller does not care about the connection */, /* in */ BMDDisplayMode requestedMode, /* in */ BMDPixelFormat requestedPixelFormat, /* in */ BMDSupportedVideoModeFlags flags, /* out */ BMDDisplayMode* actualMode, /* out */ bool* supported) = 0; + virtual HRESULT GetDisplayMode (/* in */ BMDDisplayMode displayMode, /* out */ IDeckLinkDisplayMode** resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator** iterator) = 0; + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback* previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator* theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame** outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary** outBuffer) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame* theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback* theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t* bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + virtual HRESULT WriteAudioSamplesSync (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void* buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t* sampleFramesWritten) = 0; + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t* bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback* theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue* actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool* active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* streamTime, /* out */ double* playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus* referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* hardwareTime, /* out */ BMDTimeValue* timeInFrame, /* out */ BMDTimeValue* ticksPerFrame) = 0; + virtual HRESULT GetFrameCompletionReferenceTimestamp (/* in */ IDeckLinkVideoFrame* theFrame, /* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue* frameCompletionTimestamp) = 0; + +protected: + virtual ~IDeckLinkOutput_v11_4 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPIVIDEOOUTPUT_v11_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_11.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_11.h new file mode 100644 index 0000000000..d9ef54e525 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_11.h @@ -0,0 +1,135 @@ +/* -LICENSE-START- +** Copyright (c) 2018 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_11_H +#define BMD_DECKLINKAPI_v10_11_H + +#include "DeckLinkAPI.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkAttributes_v10_11 = /* ABC11843-D966-44CB-96E2-A1CB5D3135C4 */ {0xAB,0xC1,0x18,0x43,0xD9,0x66,0x44,0xCB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4}; +BMD_CONST REFIID IID_IDeckLinkNotification_v10_11 = /* 0A1FB207-E215-441B-9B19-6FA1575946C5 */ {0x0A,0x1F,0xB2,0x07,0xE2,0x15,0x44,0x1B,0x9B,0x19,0x6F,0xA1,0x57,0x59,0x46,0xC5}; + +/* Enum BMDDisplayModeSupport_v10_11 - Output mode supported flags */ + +typedef uint32_t BMDDisplayModeSupport_v10_11; +enum _BMDDisplayModeSupport_v10_11 { + bmdDisplayModeNotSupported_v10_11 = 0, + bmdDisplayModeSupported_v10_11, + bmdDisplayModeSupportedWithConversion_v10_11 +}; + +/* Enum BMDDuplexMode_v10_11 - Duplex for configurable ports */ + +typedef uint32_t BMDDuplexMode_v10_11; +enum _BMDDuplexMode_v10_11 { + bmdDuplexModeFull_v10_11 = 'fdup', + bmdDuplexModeHalf_v10_11 = 'hdup' +}; + +/* Enum BMDDeckLinkAttributeID_v10_11 - DeckLink Attribute ID */ + +enum _BMDDeckLinkAttributeID_v10_11 { + + /* Flags */ + + BMDDeckLinkSupportsDuplexModeConfiguration_v10_11 = 'dupx', + BMDDeckLinkSupportsHDKeying_v10_11 = 'keyh', + + /* Integers */ + + BMDDeckLinkPairedDevicePersistentID_v10_11 = 'ppid', + BMDDeckLinkSupportsFullDuplex_v10_11 = 'fdup', +}; + +enum _BMDDeckLinkStatusID_v10_11 { + bmdDeckLinkStatusDuplexMode_v10_11 = 'dupx', +}; + +typedef uint32_t BMDDuplexStatus_v10_11; +enum _BMDDuplexStatus_v10_11 { + bmdDuplexFullDuplex_v10_11 = 'fdup', + bmdDuplexHalfDuplex_v10_11 = 'hdup', + bmdDuplexSimplex_v10_11 = 'splx', + bmdDuplexInactive_v10_11 = 'inac', +}; + +#if defined(__cplusplus) + +/* Interface IDeckLinkAttributes_v10_11 - DeckLink Attribute interface */ + +class BMD_PUBLIC IDeckLinkAttributes_v10_11 : public IUnknown +{ +public: + virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool *value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ double *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ CFStringRef *value) = 0; + +protected: + virtual ~IDeckLinkAttributes_v10_11 () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkNotification_v10_11 - DeckLink Notification interface */ + +class BMD_PUBLIC IDeckLinkNotification_v10_11 : public IUnknown +{ +public: + virtual HRESULT Subscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback *theCallback) = 0; + virtual HRESULT Unsubscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback *theCallback) = 0; +}; + +/* Functions */ + +extern "C" { + + IDeckLinkIterator* BMD_PUBLIC CreateDeckLinkIteratorInstance_v10_11 (void); + IDeckLinkDiscovery* BMD_PUBLIC CreateDeckLinkDiscoveryInstance_v10_11 (void); + IDeckLinkAPIInformation* BMD_PUBLIC CreateDeckLinkAPIInformationInstance_v10_11 (void); + IDeckLinkGLScreenPreviewHelper* BMD_PUBLIC CreateOpenGLScreenPreviewHelper_v10_11 (void); + IDeckLinkCocoaScreenPreviewCallback* BMD_PUBLIC CreateCocoaScreenPreview_v10_11 (void* /* (NSView*) */ parentView); + IDeckLinkVideoConversion* BMD_PUBLIC CreateVideoConversionInstance_v10_11 (void); + IDeckLinkVideoFrameAncillaryPackets* BMD_PUBLIC CreateVideoFrameAncillaryPacketsInstance_v10_11 (void); // For use when creating a custom IDeckLinkVideoFrame without wrapping IDeckLinkOutput::CreateVideoFrame + +} + +#endif // defined(__cplusplus) +#endif /* defined(BMD_DECKLINKAPI_v10_11_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_2.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_2.h new file mode 100644 index 0000000000..20eedd28cd --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_2.h @@ -0,0 +1,68 @@ +/* -LICENSE-START- +** Copyright (c) 2014 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_2_H +#define BMD_DECKLINKAPI_v10_2_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_2; +enum _BMDDeckLinkConfigurationID_v10_2 { + /* Video output flags */ + + bmdDeckLinkConfig3GBpsVideoOutput_v10_2 = '3gbs', +}; + +/* Enum BMDAudioConnection_v10_2 - Audio connection types */ + +typedef uint32_t BMDAudioConnection_v10_2; +enum _BMDAudioConnection_v10_2 { + bmdAudioConnectionEmbedded_v10_2 = 'embd', + bmdAudioConnectionAESEBU_v10_2 = 'aes ', + bmdAudioConnectionAnalog_v10_2 = 'anlg', + bmdAudioConnectionAnalogXLR_v10_2 = 'axlr', + bmdAudioConnectionAnalogRCA_v10_2 = 'arca' +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_2_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_4.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_4.h new file mode 100644 index 0000000000..fa5892dd0a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_4.h @@ -0,0 +1,58 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_4_H +#define BMD_DECKLINKAPI_v10_4_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_4; +enum _BMDDeckLinkConfigurationID_v10_4 { + + /* Video output flags */ + + bmdDeckLinkConfigSingleLinkVideoOutput_v10_4 = /* 'sglo' */ 0x73676C6F, +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_4_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_5.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_5.h new file mode 100644 index 0000000000..40ce330f09 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_5.h @@ -0,0 +1,59 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_5_H +#define BMD_DECKLINKAPI_v10_5_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkAttributeID_v10_5; +enum _BMDDeckLinkAttributeID_v10_5 { + + /* Integers */ + + BMDDeckLinkDeviceBusyState_v10_5 = /* 'dbst' */ 0x64627374, +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_5_H) */ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_6.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_6.h new file mode 100644 index 0000000000..67082779d9 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_6.h @@ -0,0 +1,64 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_6_H +#define BMD_DECKLINKAPI_v10_6_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkAttributeID_c10_6; +enum _BMDDeckLinkAttributeID_v10_6 { + + /* Flags */ + + BMDDeckLinkSupportsDesktopDisplay_v10_6 = 'extd', +}; + +typedef uint32_t BMDIdleVideoOutputOperation_v10_6; +enum _BMDIdleVideoOutputOperation_v10_6 { + bmdIdleVideoOutputDesktop_v10_6 = 'desk' +}; + + +#endif /* defined(BMD_DECKLINKAPI_v10_6_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_9.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_9.h new file mode 100644 index 0000000000..8b6b4b208f --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v10_9.h @@ -0,0 +1,58 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_9_H +#define BMD_DECKLINKAPI_v10_9_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_9; +enum _BMDDeckLinkConfigurationID_v10_9 { + + /* Flags */ + + bmdDeckLinkConfig1080pNotPsF_v10_9 = 'fpro', +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_9_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v11_5.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v11_5.h new file mode 100644 index 0000000000..a7115ae336 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v11_5.h @@ -0,0 +1,113 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v11_5_H +#define BMD_DECKLINKAPI_v11_5_H + +#include "DeckLinkAPI.h" + +BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions_v11_5 = /* D5973DC9-6432-46D0-8F0B-2496F8A1238F */ {0xD5,0x97,0x3D,0xC9,0x64,0x32,0x46,0xD0,0x8F,0x0B,0x24,0x96,0xF8,0xA1,0x23,0x8F}; + +/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ + +typedef uint32_t BMDDeckLinkFrameMetadataID_v11_5; +enum _BMDDeckLinkFrameMetadataID_v11_5 { + bmdDeckLinkFrameMetadataCintelFilmType_v11_5 = /* 'cfty' */ 0x63667479, // Current film type + bmdDeckLinkFrameMetadataCintelFilmGauge_v11_5 = /* 'cfga' */ 0x63666761, // Current film gauge + bmdDeckLinkFrameMetadataCintelKeykodeLow_v11_5 = /* 'ckkl' */ 0x636B6B6C, // Raw keykode value - low 64 bits + bmdDeckLinkFrameMetadataCintelKeykodeHigh_v11_5 = /* 'ckkh' */ 0x636B6B68, // Raw keykode value - high 64 bits + bmdDeckLinkFrameMetadataCintelTile1Size_v11_5 = /* 'ct1s' */ 0x63743173, // Size in bytes of compressed raw tile 1 + bmdDeckLinkFrameMetadataCintelTile2Size_v11_5 = /* 'ct2s' */ 0x63743273, // Size in bytes of compressed raw tile 2 + bmdDeckLinkFrameMetadataCintelTile3Size_v11_5 = /* 'ct3s' */ 0x63743373, // Size in bytes of compressed raw tile 3 + bmdDeckLinkFrameMetadataCintelTile4Size_v11_5 = /* 'ct4s' */ 0x63743473, // Size in bytes of compressed raw tile 4 + bmdDeckLinkFrameMetadataCintelImageWidth_v11_5 = /* 'IWPx' */ 0x49575078, // Width in pixels of image + bmdDeckLinkFrameMetadataCintelImageHeight_v11_5 = /* 'IHPx' */ 0x49485078, // Height in pixels of image + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInRed_v11_5 = /* 'mrir' */ 0x6D726972, // Red in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInRed_v11_5 = /* 'mgir' */ 0x6D676972, // Green in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInRed_v11_5 = /* 'mbir' */ 0x6D626972, // Blue in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInGreen_v11_5 = /* 'mrig' */ 0x6D726967, // Red in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInGreen_v11_5 = /* 'mgig' */ 0x6D676967, // Green in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInGreen_v11_5 = /* 'mbig' */ 0x6D626967, // Blue in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInBlue_v11_5 = /* 'mrib' */ 0x6D726962, // Red in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInBlue_v11_5 = /* 'mgib' */ 0x6D676962, // Green in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInBlue_v11_5 = /* 'mbib' */ 0x6D626962, // Blue in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInRed_v11_5 = /* 'mlrr' */ 0x6D6C7272, // Red in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInRed_v11_5 = /* 'mlgr' */ 0x6D6C6772, // Green in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInRed_v11_5 = /* 'mlbr' */ 0x6D6C6272, // Blue in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInGreen_v11_5 = /* 'mlrg' */ 0x6D6C7267, // Red in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInGreen_v11_5 = /* 'mlgg' */ 0x6D6C6767, // Green in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInGreen_v11_5 = /* 'mlbg' */ 0x6D6C6267, // Blue in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInBlue_v11_5 = /* 'mlrb' */ 0x6D6C7262, // Red in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInBlue_v11_5 = /* 'mlgb' */ 0x6D6C6762, // Green in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInBlue_v11_5 = /* 'mlbb' */ 0x6D6C6262, // Blue in blue log masking parameter + bmdDeckLinkFrameMetadataCintelFilmFrameRate_v11_5 = /* 'cffr' */ 0x63666672, // Film frame rate + bmdDeckLinkFrameMetadataCintelOffsetToApplyHorizontal_v11_5 = /* 'otah' */ 0x6F746168, // Horizontal offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelOffsetToApplyVertical_v11_5 = /* 'otav' */ 0x6F746176, // Vertical offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelGainRed_v11_5 = /* 'LfRd' */ 0x4C665264, // Red gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainGreen_v11_5 = /* 'LfGr' */ 0x4C664772, // Green gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainBlue_v11_5 = /* 'LfBl' */ 0x4C66426C, // Blue gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelLiftRed_v11_5 = /* 'GnRd' */ 0x476E5264, // Red lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftGreen_v11_5 = /* 'GnGr' */ 0x476E4772, // Green lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftBlue_v11_5 = /* 'GnBl' */ 0x476E426C, // Blue lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelHDRGainRed_v11_5 = /* 'HGRd' */ 0x48475264, // Red gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintelHDRGainGreen_v11_5 = /* 'HGGr' */ 0x48474772, // Green gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintelHDRGainBlue_v11_5 = /* 'HGBl' */ 0x4847426C, // Blue gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintel16mmCropRequired_v11_5 = /* 'c16c' */ 0x63313663, // The image should be cropped to 16mm size + bmdDeckLinkFrameMetadataCintelInversionRequired_v11_5 = /* 'cinv' */ 0x63696E76, // The image should be colour inverted + bmdDeckLinkFrameMetadataCintelFlipRequired_v11_5 = /* 'cflr' */ 0x63666C72, // The image should be flipped horizontally + bmdDeckLinkFrameMetadataCintelFocusAssistEnabled_v11_5 = /* 'cfae' */ 0x63666165, // Focus Assist is currently enabled + bmdDeckLinkFrameMetadataCintelKeykodeIsInterpolated_v11_5 = /* 'kkii' */ 0x6B6B6969 // The keykode for this frame is interpolated from nearby keykodes +}; + +/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */ + +class BMD_PUBLIC IDeckLinkVideoFrameMetadataExtensions_v11_5 : public IUnknown +{ +public: + virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ int64_t *value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ double *value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ bool *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkFrameMetadataID_v11_5 metadataID, /* out */ CFStringRef *value) = 0; + +protected: + virtual ~IDeckLinkVideoFrameMetadataExtensions_v11_5 () {} // call Release method to drop reference count +}; + +#endif /* defined(BMD_DECKLINKAPI_v11_5_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v11_5_1.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v11_5_1.h new file mode 100644 index 0000000000..a406f000e1 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v11_5_1.h @@ -0,0 +1,57 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v11_5_1_H +#define BMD_DECKLINKAPI_v11_5_1_H + +#include "DeckLinkAPI.h" + +/* Enum BMDDeckLinkStatusID - DeckLink Status ID */ + +typedef uint32_t BMDDeckLinkStatusID_v11_5_1; +enum _BMDDeckLinkStatusID_v11_5_1 { + + /* Video output flags */ + + bmdDeckLinkStatusDetectedVideoInputFlags_v11_5_1 = /* 'dvif' */ 0x64766966, + +}; + +#endif /* defined(BMD_DECKLINKAPI_v11_5_1_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_1.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_1.h new file mode 100644 index 0000000000..5f4f135331 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_1.h @@ -0,0 +1,212 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v7_1.h */ + +#ifndef __DeckLink_API_v7_1_h__ +#define __DeckLink_API_v7_1_h__ + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// "B28131B6-59AC-4857-B5AC-CD75D5883E2F" +#define IID_IDeckLinkDisplayModeIterator_v7_1 (REFIID){0xB2,0x81,0x31,0xB6,0x59,0xAC,0x48,0x57,0xB5,0xAC,0xCD,0x75,0xD5,0x88,0x3E,0x2F} + +// "AF0CD6D5-8376-435E-8433-54F9DD530AC3" +#define IID_IDeckLinkDisplayMode_v7_1 (REFIID){0xAF,0x0C,0xD6,0xD5,0x83,0x76,0x43,0x5E,0x84,0x33,0x54,0xF9,0xDD,0x53,0x0A,0xC3} + +// "EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9" +#define IID_IDeckLinkVideoOutputCallback_v7_1 (REFIID){0xEB,0xD0,0x1A,0xFA,0xE4,0xB0,0x49,0xC6,0xA0,0x1D,0xED,0xB9,0xD1,0xB5,0x5F,0xD9} + +// "7F94F328-5ED4-4E9F-9729-76A86BDC99CC" +#define IID_IDeckLinkInputCallback_v7_1 (REFIID){0x7F,0x94,0xF3,0x28,0x5E,0xD4,0x4E,0x9F,0x97,0x29,0x76,0xA8,0x6B,0xDC,0x99,0xCC} + +// "AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5" +#define IID_IDeckLinkOutput_v7_1 (REFIID){0xAE,0x5B,0x3E,0x9B,0x4E,0x1E,0x45,0x35,0xB6,0xE8,0x48,0x0F,0xF5,0x2F,0x6C,0xE5} + +// "2B54EDEF-5B32-429F-BA11-BB990596EACD" +#define IID_IDeckLinkInput_v7_1 (REFIID){0x2B,0x54,0xED,0xEF,0x5B,0x32,0x42,0x9F,0xBA,0x11,0xBB,0x99,0x05,0x96,0xEA,0xCD} + +// "333F3A10-8C2D-43CF-B79D-46560FEEA1CE" +#define IID_IDeckLinkVideoFrame_v7_1 (REFIID){0x33,0x3F,0x3A,0x10,0x8C,0x2D,0x43,0xCF,0xB7,0x9D,0x46,0x56,0x0F,0xEE,0xA1,0xCE} + +// "C8B41D95-8848-40EE-9B37-6E3417FB114B" +#define IID_IDeckLinkVideoInputFrame_v7_1 (REFIID){0xC8,0xB4,0x1D,0x95,0x88,0x48,0x40,0xEE,0x9B,0x37,0x6E,0x34,0x17,0xFB,0x11,0x4B} + +// "C86DE4F6-A29F-42E3-AB3A-1363E29F0788" +#define IID_IDeckLinkAudioInputPacket_v7_1 (REFIID){0xC8,0x6D,0xE4,0xF6,0xA2,0x9F,0x42,0xE3,0xAB,0x3A,0x13,0x63,0xE2,0x9F,0x07,0x88} + +#if defined(__cplusplus) + +class IDeckLinkVideoFrame_v7_1; +class IDeckLinkDisplayModeIterator_v7_1; +class IDeckLinkDisplayMode_v7_1; +class IDeckLinkVideoInputFrame_v7_1; +class IDeckLinkAudioInputPacket_v7_1; + +class IDeckLinkDisplayModeIterator_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE Next (IDeckLinkDisplayMode_v7_1* *deckLinkDisplayMode) = 0; +}; + + +class IDeckLinkDisplayMode_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetName (CFStringRef* name) = 0; + virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode () = 0; + virtual long STDMETHODCALLTYPE GetWidth () = 0; + virtual long STDMETHODCALLTYPE GetHeight () = 0; + virtual HRESULT STDMETHODCALLTYPE GetFrameRate (BMDTimeValue *frameDuration, BMDTimeScale *timeScale) = 0; +}; + +class IDeckLinkVideoOutputCallback_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted (IDeckLinkVideoFrame_v7_1* completedFrame, BMDOutputFrameCompletionResult result) = 0; +}; + +class IDeckLinkInputCallback_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived (IDeckLinkVideoInputFrame_v7_1* videoFrame, IDeckLinkAudioInputPacket_v7_1* audioPacket) = 0; +}; + +// IDeckLinkOutput_v7_1. Created by QueryInterface from IDeckLink. +class IDeckLinkOutput_v7_1 : public IUnknown +{ +public: + // Display mode predicates + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1* *iterator) = 0; + + + // Video output + virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput (BMDDisplayMode displayMode) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput () = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator (IDeckLinkMemoryAllocator* theAllocator) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrameFromBuffer (void* buffer, int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame) = 0; + virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0; + virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback (IDeckLinkVideoOutputCallback_v7_1* theCallback) = 0; + + + // Audio output + virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput () = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll () = 0; + virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll () = 0; + virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples (void* buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; + virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples () = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback (IDeckLinkAudioOutputCallback* theCallback) = 0; + + + // Output control + virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0; + virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0; + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0; +}; + +// IDeckLinkInput_v7_1. Created by QueryInterface from IDeckLink. +class IDeckLinkInput_v7_1 : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0; + + // Video input + virtual HRESULT STDMETHODCALLTYPE EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableVideoInput () = 0; + + // Audio input + virtual HRESULT STDMETHODCALLTYPE EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; + virtual HRESULT STDMETHODCALLTYPE DisableAudioInput () = 0; + virtual HRESULT STDMETHODCALLTYPE ReadAudioSamples (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesRead, BMDTimeValue *audioPacketTime, BMDTimeScale timeScale) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; + + // Input control + virtual HRESULT STDMETHODCALLTYPE StartStreams () = 0; + virtual HRESULT STDMETHODCALLTYPE StopStreams () = 0; + virtual HRESULT STDMETHODCALLTYPE PauseStreams () = 0; + virtual HRESULT STDMETHODCALLTYPE SetCallback (IDeckLinkInputCallback_v7_1* theCallback) = 0; +}; + +// IDeckLinkVideoFrame_v7_1. Created by IDeckLinkOutput::CreateVideoFrame. +class IDeckLinkVideoFrame_v7_1 : public IUnknown +{ +public: + virtual long STDMETHODCALLTYPE GetWidth () = 0; + virtual long STDMETHODCALLTYPE GetHeight () = 0; + virtual long STDMETHODCALLTYPE GetRowBytes () = 0; + virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat () = 0; + virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags () = 0; + virtual HRESULT STDMETHODCALLTYPE GetBytes (void* *buffer) = 0; +}; + +// IDeckLinkVideoInputFrame_v7_1. Provided by the IDeckLinkInput_v7_1 frame arrival callback. +class IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1 +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; +}; + +// IDeckLinkAudioInputPacket_v7_1. Provided by the IDeckLinkInput_v7_1 callback. +class IDeckLinkAudioInputPacket_v7_1 : public IUnknown +{ +public: + virtual long STDMETHODCALLTYPE GetSampleCount () = 0; + virtual HRESULT STDMETHODCALLTYPE GetBytes (void* *buffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale) = 0; +}; + +#endif // defined(__cplusplus) + +#endif // __DeckLink_API_v7_1_h__ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_3.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_3.h new file mode 100644 index 0000000000..8634e9c809 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_3.h @@ -0,0 +1,186 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v7_3.h */ + +#ifndef __DeckLink_API_v7_3_h__ +#define __DeckLink_API_v7_3_h__ + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v7_6.h" + +/* Interface ID Declarations */ + +#define IID_IDeckLinkInputCallback_v7_3 /* FD6F311D-4D00-444B-9ED4-1F25B5730AD0 */ (REFIID){0xFD,0x6F,0x31,0x1D,0x4D,0x00,0x44,0x4B,0x9E,0xD4,0x1F,0x25,0xB5,0x73,0x0A,0xD0} +#define IID_IDeckLinkOutput_v7_3 /* 271C65E3-C323-4344-A30F-D908BCB20AA3 */ (REFIID){0x27,0x1C,0x65,0xE3,0xC3,0x23,0x43,0x44,0xA3,0x0F,0xD9,0x08,0xBC,0xB2,0x0A,0xA3} +#define IID_IDeckLinkInput_v7_3 /* 4973F012-9925-458C-871C-18774CDBBECB */ (REFIID){0x49,0x73,0xF0,0x12,0x99,0x25,0x45,0x8C,0x87,0x1C,0x18,0x77,0x4C,0xDB,0xBE,0xCB} +#define IID_IDeckLinkVideoInputFrame_v7_3 /* CF317790-2894-11DE-8C30-0800200C9A66 */ (REFIID){0xCF,0x31,0x77,0x90,0x28,0x94,0x11,0xDE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66} + +/* End Interface ID Declarations */ + +#if defined(__cplusplus) + +/* Forward Declarations */ + +class IDeckLinkVideoInputFrame_v7_3; + +/* End Forward Declarations */ + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkOutput_v7_3 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (BMDDisplayMode displayMode, BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0; + virtual HRESULT CreateAncillaryData (BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount, BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0; + +protected: + virtual ~IDeckLinkOutput_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkOutput */ + + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +class IDeckLinkInputCallback_v7_3 : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_3 *videoFrame, /* in */ IDeckLinkAudioInputPacket *audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkInputCallback */ + + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkInput_v7_3 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_3 *theCallback) = 0; + +protected: + virtual ~IDeckLinkInput_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkInput */ + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +class IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame_v7_6 +{ +public: + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; + +protected: + virtual ~IDeckLinkVideoInputFrame_v7_3 () {}; // call Release method to drop reference count +}; + +/* End Interface IDeckLinkVideoInputFrame */ + +#endif // defined(__cplusplus) +#endif // __DeckLink_API_v7_3_h__ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_6.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_6.h new file mode 100644 index 0000000000..df9e00712c --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_6.h @@ -0,0 +1,435 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v7_6.h */ + +#ifndef __DeckLink_API_v7_6_h__ +#define __DeckLink_API_v7_6_h__ + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Interface ID Declarations + +#define IID_IDeckLinkVideoOutputCallback_v7_6 /* E763A626-4A3C-49D1-BF13-E7AD3692AE52 */ (REFIID){0xE7,0x63,0xA6,0x26,0x4A,0x3C,0x49,0xD1,0xBF,0x13,0xE7,0xAD,0x36,0x92,0xAE,0x52} +#define IID_IDeckLinkInputCallback_v7_6 /* 31D28EE7-88B6-4CB1-897A-CDBF79A26414 */ (REFIID){0x31,0xD2,0x8E,0xE7,0x88,0xB6,0x4C,0xB1,0x89,0x7A,0xCD,0xBF,0x79,0xA2,0x64,0x14} +#define IID_IDeckLinkDisplayModeIterator_v7_6 /* 455D741F-1779-4800-86F5-0B5D13D79751 */ (REFIID){0x45,0x5D,0x74,0x1F,0x17,0x79,0x48,0x00,0x86,0xF5,0x0B,0x5D,0x13,0xD7,0x97,0x51} +#define IID_IDeckLinkDisplayMode_v7_6 /* 87451E84-2B7E-439E-A629-4393EA4A8550 */ (REFIID){0x87,0x45,0x1E,0x84,0x2B,0x7E,0x43,0x9E,0xA6,0x29,0x43,0x93,0xEA,0x4A,0x85,0x50} +#define IID_IDeckLinkOutput_v7_6 /* 29228142-EB8C-4141-A621-F74026450955 */ (REFIID){0x29,0x22,0x81,0x42,0xEB,0x8C,0x41,0x41,0xA6,0x21,0xF7,0x40,0x26,0x45,0x09,0x55} +#define IID_IDeckLinkInput_v7_6 /* 300C135A-9F43-48E2-9906-6D7911D93CF1 */ (REFIID){0x30,0x0C,0x13,0x5A,0x9F,0x43,0x48,0xE2,0x99,0x06,0x6D,0x79,0x11,0xD9,0x3C,0xF1} +#define IID_IDeckLinkTimecode_v7_6 /* EFB9BCA6-A521-44F7-BD69-2332F24D9EE6 */ (REFIID){0xEF,0xB9,0xBC,0xA6,0xA5,0x21,0x44,0xF7,0xBD,0x69,0x23,0x32,0xF2,0x4D,0x9E,0xE6} +#define IID_IDeckLinkVideoFrame_v7_6 /* A8D8238E-6B18-4196-99E1-5AF717B83D32 */ (REFIID){0xA8,0xD8,0x23,0x8E,0x6B,0x18,0x41,0x96,0x99,0xE1,0x5A,0xF7,0x17,0xB8,0x3D,0x32} +#define IID_IDeckLinkMutableVideoFrame_v7_6 /* 46FCEE00-B4E6-43D0-91C0-023A7FCEB34F */ (REFIID){0x46,0xFC,0xEE,0x00,0xB4,0xE6,0x43,0xD0,0x91,0xC0,0x02,0x3A,0x7F,0xCE,0xB3,0x4F} +#define IID_IDeckLinkVideoInputFrame_v7_6 /* 9A74FA41-AE9F-47AC-8CF4-01F42DD59965 */ (REFIID){0x9A,0x74,0xFA,0x41,0xAE,0x9F,0x47,0xAC,0x8C,0xF4,0x01,0xF4,0x2D,0xD5,0x99,0x65} +#define IID_IDeckLinkScreenPreviewCallback_v7_6 /* 373F499D-4B4D-4518-AD22-6354E5A5825E */ (REFIID){0x37,0x3F,0x49,0x9D,0x4B,0x4D,0x45,0x18,0xAD,0x22,0x63,0x54,0xE5,0xA5,0x82,0x5E} +#define IID_IDeckLinkCocoaScreenPreviewCallback_v7_6 /* D174152F-8F96-4C07-83A5-DD5F5AF0A2AA */ (REFIID){0xD1,0x74,0x15,0x2F,0x8F,0x96,0x4C,0x07,0x83,0xA5,0xDD,0x5F,0x5A,0xF0,0xA2,0xAA} +#define IID_IDeckLinkGLScreenPreviewHelper_v7_6 /* BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA */ (REFIID){0xBA,0x57,0x5C,0xD9,0xA1,0x5E,0x49,0x7B,0xB2,0xC2,0xF9,0xAF,0xE7,0xBE,0x4E,0xBA} +#define IID_IDeckLinkVideoConversion_v7_6 /* 3EB504C9-F97D-40FE-A158-D407D48CB53B */ (REFIID){0x3E,0xB5,0x04,0xC9,0xF9,0x7D,0x40,0xFE,0xA1,0x58,0xD4,0x07,0xD4,0x8C,0xB5,0x3B} +#define IID_IDeckLinkConfiguration_v7_6 /* B8EAD569-B764-47F0-A73F-AE40DF6CBF10 */ (REFIID){0xB8,0xEA,0xD5,0x69,0xB7,0x64,0x47,0xF0,0xA7,0x3F,0xAE,0x40,0xDF,0x6C,0xBF,0x10} + + +#if defined(__cplusplus) + +/* Enum BMDVideoConnection - Video connection types */ + +typedef uint32_t BMDVideoConnection_v7_6; +enum _BMDVideoConnection_v7_6 { + bmdVideoConnectionSDI_v7_6 = 'sdi ', + bmdVideoConnectionHDMI_v7_6 = 'hdmi', + bmdVideoConnectionOpticalSDI_v7_6 = 'opti', + bmdVideoConnectionComponent_v7_6 = 'cpnt', + bmdVideoConnectionComposite_v7_6 = 'cmst', + bmdVideoConnectionSVideo_v7_6 = 'svid' +}; + + +// Forward Declarations + +class IDeckLinkVideoOutputCallback_v7_6; +class IDeckLinkInputCallback_v7_6; +class IDeckLinkDisplayModeIterator_v7_6; +class IDeckLinkDisplayMode_v7_6; +class IDeckLinkOutput_v7_6; +class IDeckLinkInput_v7_6; +class IDeckLinkTimecode_v7_6; +class IDeckLinkVideoFrame_v7_6; +class IDeckLinkMutableVideoFrame_v7_6; +class IDeckLinkVideoInputFrame_v7_6; +class IDeckLinkScreenPreviewCallback_v7_6; +class IDeckLinkCocoaScreenPreviewCallback_v7_6; +class IDeckLinkGLScreenPreviewHelper_v7_6; +class IDeckLinkVideoConversion_v7_6; + + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +class IDeckLinkVideoOutputCallback_v7_6 : public IUnknown +{ +public: + virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame_v7_6 *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; + virtual HRESULT ScheduledPlaybackHasStopped (void) = 0; + +protected: + virtual ~IDeckLinkVideoOutputCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +class IDeckLinkInputCallback_v7_6 : public IUnknown +{ +public: + virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + virtual HRESULT VideoInputFrameArrived (/* in */ IDeckLinkVideoInputFrame_v7_6* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket) = 0; + +protected: + virtual ~IDeckLinkInputCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ + +class IDeckLinkDisplayModeIterator_v7_6 : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode) = 0; + +protected: + virtual ~IDeckLinkDisplayModeIterator_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkDisplayMode - represents a display mode */ + +class IDeckLinkDisplayMode_v7_6 : public IUnknown +{ +public: + virtual HRESULT GetName (/* out */ CFStringRef *name) = 0; + virtual BMDDisplayMode GetDisplayMode (void) = 0; + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual HRESULT GetFrameRate (/* out */ BMDTimeValue *frameDuration, /* out */ BMDTimeScale *timeScale) = 0; + virtual BMDFieldDominance GetFieldDominance (void) = 0; + +protected: + virtual ~IDeckLinkDisplayMode_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkOutput_v7_6 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame_v7_6 **outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback_v7_6 *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkOutput_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkInput_v7_6 - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkInput_v7_6 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport_v10_11 *result) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator_v7_6 **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback_v7_6 *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v7_6 *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ + +class IDeckLinkTimecode_v7_6 : public IUnknown +{ +public: + virtual BMDTimecodeBCD GetBCD (void) = 0; + virtual HRESULT GetComponents (/* out */ uint8_t *hours, /* out */ uint8_t *minutes, /* out */ uint8_t *seconds, /* out */ uint8_t *frames) = 0; + virtual HRESULT GetString (/* out */ CFStringRef *timecode) = 0; + virtual BMDTimecodeFlags GetFlags (void) = 0; + +protected: + virtual ~IDeckLinkTimecode_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +class IDeckLinkVideoFrame_v7_6 : public IUnknown +{ +public: + virtual long GetWidth (void) = 0; + virtual long GetHeight (void) = 0; + virtual long GetRowBytes (void) = 0; + virtual BMDPixelFormat GetPixelFormat (void) = 0; + virtual BMDFrameFlags GetFlags (void) = 0; + virtual HRESULT GetBytes (/* out */ void **buffer) = 0; + + virtual HRESULT GetTimecode (BMDTimecodeFormat format, /* out */ IDeckLinkTimecode_v7_6 **timecode) = 0; + virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0; + +protected: + virtual ~IDeckLinkVideoFrame_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +class IDeckLinkMutableVideoFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 +{ +public: + virtual HRESULT SetFlags (BMDFrameFlags newFlags) = 0; + + virtual HRESULT SetTimecode (BMDTimecodeFormat format, /* in */ IDeckLinkTimecode_v7_6 *timecode) = 0; + virtual HRESULT SetTimecodeFromComponents (BMDTimecodeFormat format, uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t frames, BMDTimecodeFlags flags) = 0; + virtual HRESULT SetAncillaryData (/* in */ IDeckLinkVideoFrameAncillary *ancillary) = 0; + +protected: + virtual ~IDeckLinkMutableVideoFrame_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +class IDeckLinkVideoInputFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 +{ +public: + virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; + virtual HRESULT GetHardwareReferenceTimestamp (BMDTimeScale timeScale, /* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration) = 0; + +protected: + virtual ~IDeckLinkVideoInputFrame_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +class IDeckLinkScreenPreviewCallback_v7_6 : public IUnknown +{ +public: + virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + +protected: + virtual ~IDeckLinkScreenPreviewCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkCocoaScreenPreviewCallback - Screen preview callback for Cocoa-based applications */ + +class IDeckLinkCocoaScreenPreviewCallback_v7_6 : public IDeckLinkScreenPreviewCallback_v7_6 +{ +public: + +protected: + virtual ~IDeckLinkCocoaScreenPreviewCallback_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ + +class IDeckLinkGLScreenPreviewHelper_v7_6 : public IUnknown +{ +public: + + /* Methods must be called with OpenGL context set */ + + virtual HRESULT InitializeGL (void) = 0; + virtual HRESULT PaintGL (void) = 0; + virtual HRESULT SetFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; + +protected: + virtual ~IDeckLinkGLScreenPreviewHelper_v7_6 () {}; // call Release method to drop reference count +}; + + +/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */ + +class IDeckLinkVideoConversion_v7_6 : public IUnknown +{ +public: + virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame_v7_6* srcFrame, /* in */ IDeckLinkVideoFrame_v7_6* dstFrame) = 0; + +protected: + virtual ~IDeckLinkVideoConversion_v7_6 () {}; // call Release method to drop reference count +}; + +/* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkConfiguration_v7_6 : public IUnknown +{ +public: + virtual HRESULT GetConfigurationValidator (/* out */ IDeckLinkConfiguration_v7_6 **configObject) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + + /* Video Output Configuration */ + + virtual HRESULT SetVideoOutputFormat (/* in */ BMDVideoConnection_v7_6 videoOutputConnection) = 0; + virtual HRESULT IsVideoOutputActive (/* in */ BMDVideoConnection_v7_6 videoOutputConnection, /* out */ bool *active) = 0; + + virtual HRESULT SetAnalogVideoOutputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; + virtual HRESULT GetAnalogVideoOutputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; + + virtual HRESULT EnableFieldFlickerRemovalWhenPaused (/* in */ bool enable) = 0; + virtual HRESULT IsEnabledFieldFlickerRemovalWhenPaused (/* out */ bool *enabled) = 0; + + virtual HRESULT Set444And3GBpsVideoOutput (/* in */ bool enable444VideoOutput, /* in */ bool enable3GbsOutput) = 0; + virtual HRESULT Get444And3GBpsVideoOutput (/* out */ bool *is444VideoOutputEnabled, /* out */ bool *threeGbsOutputEnabled) = 0; + + virtual HRESULT SetVideoOutputConversionMode (/* in */ BMDVideoOutputConversionMode conversionMode) = 0; + virtual HRESULT GetVideoOutputConversionMode (/* out */ BMDVideoOutputConversionMode *conversionMode) = 0; + + virtual HRESULT Set_HD1080p24_to_HD1080i5994_Conversion (/* in */ bool enable) = 0; + virtual HRESULT Get_HD1080p24_to_HD1080i5994_Conversion (/* out */ bool *enabled) = 0; + + /* Video Input Configuration */ + + virtual HRESULT SetVideoInputFormat (/* in */ BMDVideoConnection_v7_6 videoInputFormat) = 0; + virtual HRESULT GetVideoInputFormat (/* out */ BMDVideoConnection_v7_6 *videoInputFormat) = 0; + + virtual HRESULT SetAnalogVideoInputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; + virtual HRESULT GetAnalogVideoInputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; + + virtual HRESULT SetVideoInputConversionMode (/* in */ BMDVideoInputConversionMode conversionMode) = 0; + virtual HRESULT GetVideoInputConversionMode (/* out */ BMDVideoInputConversionMode *conversionMode) = 0; + + virtual HRESULT SetBlackVideoOutputDuringCapture (/* in */ bool blackOutInCapture) = 0; + virtual HRESULT GetBlackVideoOutputDuringCapture (/* out */ bool *blackOutInCapture) = 0; + + virtual HRESULT Set32PulldownSequenceInitialTimecodeFrame (/* in */ uint32_t aFrameTimecode) = 0; + virtual HRESULT Get32PulldownSequenceInitialTimecodeFrame (/* out */ uint32_t *aFrameTimecode) = 0; + + virtual HRESULT SetVancSourceLineMapping (/* in */ uint32_t activeLine1VANCsource, /* in */ uint32_t activeLine2VANCsource, /* in */ uint32_t activeLine3VANCsource) = 0; + virtual HRESULT GetVancSourceLineMapping (/* out */ uint32_t *activeLine1VANCsource, /* out */ uint32_t *activeLine2VANCsource, /* out */ uint32_t *activeLine3VANCsource) = 0; + + /* Audio Input Configuration */ + + virtual HRESULT SetAudioInputFormat (/* in */ BMDAudioConnection audioInputFormat) = 0; + virtual HRESULT GetAudioInputFormat (/* out */ BMDAudioConnection *audioInputFormat) = 0; +}; + + + +/* Functions */ + +extern "C" { + + IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void); + IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void); + IDeckLinkCocoaScreenPreviewCallback_v7_6* CreateCocoaScreenPreview_v7_6 (void* /* (NSView*) */ parentView); + IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void); + +}; + + +#endif // defined(__cplusplus) +#endif // __DeckLink_API_v7_6_h__ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_9.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_9.h new file mode 100644 index 0000000000..4ea8e58f24 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v7_9.h @@ -0,0 +1,104 @@ +/* -LICENSE-START- +** Copyright (c) 2010 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v7_9.h */ + +#ifndef __DeckLink_API_v7_9_h__ +#define __DeckLink_API_v7_9_h__ + +#include "DeckLinkAPI.h" + +// Interface ID Declarations + +#define IID_IDeckLinkDeckControl_v7_9 /* A4D81043-0619-42B7-8ED6-602D29041DF7 */ (REFIID){0xA4,0xD8,0x10,0x43,0x06,0x19,0x42,0xB7,0x8E,0xD6,0x60,0x2D,0x29,0x04,0x1D,0xF7} + + +#if defined(__cplusplus) + +// Forward Declarations + +class IDeckLinkDeckControl_v7_9; + + +/* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */ + +class IDeckLinkDeckControl_v7_9 : public IUnknown +{ +public: + virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Close (/* in */ bool standbyOn) = 0; + virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0; + virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0; + virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeString (/* out */ BMDstring *currentTimeCode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0; + virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0; + virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0; + virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0; + virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0; + virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0; + virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0; + virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Abort (void) = 0; + virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback *callback) = 0; + +protected: + virtual ~IDeckLinkDeckControl_v7_9 () {}; // call Release method to drop reference count +}; + + +#endif // defined(__cplusplus) +#endif // __DeckLink_API_v7_9_h__ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v8_0.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v8_0.h new file mode 100644 index 0000000000..0239ab6126 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v8_0.h @@ -0,0 +1,76 @@ +/* -LICENSE-START- +** Copyright (c) 2011 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v8_0_H +#define BMD_DECKLINKAPI_v8_0_H + +#include "DeckLinkAPI.h" + +// Interface ID Declarations + +#define IID_IDeckLink_v8_0 /* 62BFF75D-6569-4E55-8D4D-66AA03829ABC */ (REFIID){0x62,0xBF,0xF7,0x5D,0x65,0x69,0x4E,0x55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC} +#define IID_IDeckLinkIterator_v8_0 /* 74E936FC-CC28-4A67-81A0-1E94E52D4E69 */ (REFIID){0x74,0xE9,0x36,0xFC,0xCC,0x28,0x4A,0x67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69} + +#if defined (__cplusplus) + +/* Interface IDeckLink_v8_0 - represents a DeckLink device */ + +class IDeckLink_v8_0 : public IUnknown +{ +public: + virtual HRESULT GetModelName (/* out */ CFStringRef *modelName) = 0; +}; + +/* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */ + +class IDeckLinkIterator_v8_0 : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLink_v8_0 **deckLinkInstance) = 0; +}; + +extern "C" { + IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance_v8_0 (void); +}; + + +#endif // defined __cplusplus + +#endif /* defined(BMD_DECKLINKAPI_v8_0_H) */ diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v8_1.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v8_1.h new file mode 100644 index 0000000000..33c77f5575 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v8_1.h @@ -0,0 +1,124 @@ +/* -LICENSE-START- + ** Copyright (c) 2011 Blackmagic Design + ** + ** Permission is hereby granted, free of charge, to any person or organization + ** obtaining a copy of the software and accompanying documentation (the + ** "Software") to use, reproduce, display, distribute, sub-license, execute, + ** and transmit the Software, and to prepare derivative works of the Software, + ** and to permit third-parties to whom the Software is furnished to do so, in + ** accordance with: + ** + ** (1) if the Software is obtained from Blackmagic Design, the End User License + ** Agreement for the Software Development Kit (“EULA”) available at + ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + ** + ** (2) if the Software is obtained from any third party, such licensing terms + ** as notified by that third party, + ** + ** and all subject to the following: + ** + ** (3) the copyright notices in the Software and this entire statement, + ** including the above license grant, this restriction and the following + ** disclaimer, must be included in all copies of the Software, in whole or in + ** part, and all derivative works of the Software, unless such copies or + ** derivative works are solely in the form of machine-executable object code + ** generated by a source language processor. + ** + ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + ** DEALINGS IN THE SOFTWARE. + ** + ** A copy of the Software is available free of charge at + ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + ** + ** -LICENSE-END- + */ + +#ifndef BMD_DECKLINKAPI_v8_1_H +#define BMD_DECKLINKAPI_v8_1_H + +#include "DeckLinkAPI.h" + + +// Interface ID Declarations + +#define IID_IDeckLinkDeckControlStatusCallback_v8_1 /* E5F693C1-4283-4716-B18F-C1431521955B */ (REFIID){0xE5,0xF6,0x93,0xC1,0x42,0x83,0x47,0x16,0xB1,0x8F,0xC1,0x43,0x15,0x21,0x95,0x5B} +#define IID_IDeckLinkDeckControl_v8_1 /* 522A9E39-0F3C-4742-94EE-D80DE335DA1D */ (REFIID){0x52,0x2A,0x9E,0x39,0x0F,0x3C,0x47,0x42,0x94,0xEE,0xD8,0x0D,0xE3,0x35,0xDA,0x1D} + + +/* Enum BMDDeckControlVTRControlState_v8_1 - VTR Control state */ + +typedef uint32_t BMDDeckControlVTRControlState_v8_1; +enum _BMDDeckControlVTRControlState_v8_1 { + bmdDeckControlNotInVTRControlMode_v8_1 = 'nvcm', + bmdDeckControlVTRControlPlaying_v8_1 = 'vtrp', + bmdDeckControlVTRControlRecording_v8_1 = 'vtrr', + bmdDeckControlVTRControlStill_v8_1 = 'vtra', + bmdDeckControlVTRControlSeeking_v8_1 = 'vtrs', + bmdDeckControlVTRControlStopped_v8_1 = 'vtro' +}; + + +/* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */ + +class IDeckLinkDeckControlStatusCallback_v8_1 : public IUnknown +{ +public: + virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; + virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState_v8_1 newState, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0; + virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0; + +protected: + virtual ~IDeckLinkDeckControlStatusCallback_v8_1 () {}; // call Release method to drop reference count +}; + +/* Interface IDeckLinkDeckControl_v8_1 - Deck Control main interface */ + +class IDeckLinkDeckControl_v8_1 : public IUnknown +{ +public: + virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Close (/* in */ bool standbyOn) = 0; + virtual HRESULT GetCurrentState (/* out */ BMDDeckControlMode *mode, /* out */ BMDDeckControlVTRControlState_v8_1 *vtrControlState, /* out */ BMDDeckControlStatusFlags *flags) = 0; + virtual HRESULT SetStandby (/* in */ bool standbyOn) = 0; + virtual HRESULT SendCommand (/* in */ uint8_t *inBuffer, /* in */ uint32_t inBufferSize, /* out */ uint8_t *outBuffer, /* out */ uint32_t *outDataSize, /* in */ uint32_t outBufferSize, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Play (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Stop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT TogglePlayStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Eject (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GoToTimecode (/* in */ BMDTimecodeBCD timecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT FastForward (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Rewind (/* in */ bool viewTape, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepForward (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StepBack (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Jog (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Shuttle (/* in */ double rate, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeString (/* out */ CFStringRef *currentTimeCode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecode (/* out */ IDeckLinkTimecode **currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetTimecodeBCD (/* out */ BMDTimecodeBCD *currentTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetPreroll (/* in */ uint32_t prerollSeconds) = 0; + virtual HRESULT GetPreroll (/* out */ uint32_t *prerollSeconds) = 0; + virtual HRESULT SetExportOffset (/* in */ int32_t exportOffsetFields) = 0; + virtual HRESULT GetExportOffset (/* out */ int32_t *exportOffsetFields) = 0; + virtual HRESULT GetManualExportOffset (/* out */ int32_t *deckManualExportOffsetFields) = 0; + virtual HRESULT SetCaptureOffset (/* in */ int32_t captureOffsetFields) = 0; + virtual HRESULT GetCaptureOffset (/* out */ int32_t *captureOffsetFields) = 0; + virtual HRESULT StartExport (/* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* in */ BMDDeckControlExportModeOpsFlags exportModeOps, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT StartCapture (/* in */ bool useVITC, /* in */ BMDTimecodeBCD inTimecode, /* in */ BMDTimecodeBCD outTimecode, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT GetDeviceID (/* out */ uint16_t *deviceId, /* out */ BMDDeckControlError *error) = 0; + virtual HRESULT Abort (void) = 0; + virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback_v8_1 *callback) = 0; + +protected: + virtual ~IDeckLinkDeckControl_v8_1 () {}; // call Release method to drop reference count +}; + + +#endif // BMD_DECKLINKAPI_v8_1_H diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v9_2.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v9_2.h new file mode 100644 index 0000000000..e06210d9a1 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v9_2.h @@ -0,0 +1,96 @@ +/* -LICENSE-START- +** Copyright (c) 2012 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v9_2_H +#define BMD_DECKLINKAPI_v9_2_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" +#include "DeckLinkAPIVideoInput_v11_5_1.h" + + +// Interface ID Declarations + +#define IID_IDeckLinkInput_v9_2 /* 6D40EF78-28B9-4E21-990D-95BB7750A04F */ (REFIID){0x6D,0x40,0xEF,0x78,0x28,0xB9,0x4E,0x21,0x99,0x0D,0x95,0xBB,0x77,0x50,0xA0,0x4F} + + +#if defined(__cplusplus) + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkInput_v9_2 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Input */ + + virtual HRESULT EnableVideoInput (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags) = 0; + virtual HRESULT DisableVideoInput (void) = 0; + virtual HRESULT GetAvailableVideoFrameCount (/* out */ uint32_t *availableFrameCount) = 0; + + /* Audio Input */ + + virtual HRESULT EnableAudioInput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount) = 0; + virtual HRESULT DisableAudioInput (void) = 0; + virtual HRESULT GetAvailableAudioSampleFrameCount (/* out */ uint32_t *availableSampleFrameCount) = 0; + + /* Input Control */ + + virtual HRESULT StartStreams (void) = 0; + virtual HRESULT StopStreams (void) = 0; + virtual HRESULT PauseStreams (void) = 0; + virtual HRESULT FlushStreams (void) = 0; + virtual HRESULT SetCallback (/* in */ IDeckLinkInputCallback_v11_5_1 *theCallback) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkInput_v9_2 () {}; // call Release method to drop reference count +}; + + +#endif // defined(__cplusplus) +#endif // BMD_DECKLINKAPI_v9_2_H diff --git a/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v9_9.h b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v9_9.h new file mode 100644 index 0000000000..095a1fed06 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/mac/DeckLinkAPI_v9_9.h @@ -0,0 +1,115 @@ +/* -LICENSE-START- +** Copyright (c) 2013 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v9_9_H +#define BMD_DECKLINKAPI_v9_9_H + +#include "DeckLinkAPI.h" +#include "DeckLinkAPI_v10_11.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkOutput_v9_9 = /* A3EF0963-0862-44ED-92A9-EE89ABF431C7 */ {0xA3,0xEF,0x09,0x63,0x08,0x62,0x44,0xED,0x92,0xA9,0xEE,0x89,0xAB,0xF4,0x31,0xC7}; + + +#if defined(__cplusplus) + +// Forward Declarations +class IDeckLinkOutput_v9_9; + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +class IDeckLinkOutput_v9_9 : public IUnknown +{ +public: + virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport_v10_11 *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; + virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + /* Video Output */ + + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; + virtual HRESULT DisableVideoOutput (void) = 0; + + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; + virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; + virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; + virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; + + /* Audio Output */ + + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; + virtual HRESULT DisableAudioOutput (void) = 0; + + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT BeginAudioPreroll (void) = 0; + virtual HRESULT EndAudioPreroll (void) = 0; + virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; + + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; + virtual HRESULT FlushBufferedAudioSamples (void) = 0; + + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + /* Output Control */ + + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; + virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; + virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; + virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; + virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0; + + /* Hardware Timing */ + + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; + +protected: + virtual ~IDeckLinkOutput_v9_9 () {}; // call Release method to drop reference count +}; + +#endif // defined(__cplusplus) +#endif /* defined(BMD_DECKLINKAPI_v9_9_H) */ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/meson.build b/subprojects/gst-plugins-bad/sys/decklink2/meson.build new file mode 100644 index 0000000000..5cc329fffe --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/meson.build @@ -0,0 +1,96 @@ +decklink2_sources = [ + 'gstdecklink2combiner.cpp', + 'gstdecklink2demux.cpp', + 'gstdecklink2deviceprovider.cpp', + 'gstdecklink2input.cpp', + 'gstdecklink2object.cpp', + 'gstdecklink2output.cpp', + 'gstdecklink2sink.cpp', + 'gstdecklink2src.cpp', + 'gstdecklink2srcbin.cpp', + 'gstdecklink2utils.cpp', + 'plugin.cpp', +] + +decklink2_sdk = [] +decklink2_deps = [] +decklink2_extra_args = ['-DGST_USE_UNSTABLE_API'] +decklink2_ldflags = [] +decklink2_incl = [] +decklink2_option = get_option('decklink2') + +if decklink2_option.disabled() + subdir_done() +endif + +# Build SDK headers using midl compiler on Windows +if host_system == 'windows' + midl = find_program('midl', required: decklink2_option) + if not midl.found() + subdir_done() + endif + + if host_machine.cpu_family() == 'x86' + midl_env = 'win32' + elif host_machine.cpu_family() == 'x86_64' + midl_env = 'win64' + else + # ARM64 support? + if decklink2_option.enabled() + error(host_machine.cpu_family() + ' is not supported') + endif + subdir_done() + endif + + decklink2_sdk = custom_target('DeckLinkAPI.h', + output : ['DeckLinkAPI_i.c', 'DeckLinkAPI.h'], + input : 'win/DeckLinkAPI.idl', + command : [midl, '/h', 'DeckLinkAPI.h', + '/env', midl_env, + '/target', 'NT50', + '/notlb', + '/out', meson.current_build_dir(), + '@INPUT@'] + ) +else + libdl = cc.find_library('dl', required: decklink2_option) + have_pthread_h = cc.has_header('pthread.h', required: decklink2_option) + if not libdl.found() or not have_pthread_h + subdir_done() + endif + + decklink2_extra_args += cc.get_supported_arguments([ + '-Wno-missing-declarations', + ]) + + decklink2_deps += [libdl, dependency('threads')] + if host_system == 'linux' + decklink2_sdk += ['linux/DeckLinkAPIDispatch.cpp', + 'linux/DeckLinkAPIDispatch_v10_11.cpp'] + decklink2_incl = include_directories('linux') + elif host_system in ['darwin', 'ios'] + decklink2_sdk += ['mac/DeckLinkAPIDispatch.cpp', + 'mac/DeckLinkAPIDispatch_v10_11.cpp'] + decklink2_ldflags += ['-Wl,-framework,CoreFoundation'] + decklink2_incl = include_directories('mac') + else + if decklink2_option.enabled() + error('Host system "@0@" is not supported'.format(host_system)) + endif + subdir_done() + endif +endif + +decklink2 = library('gstdecklink2', + decklink2_sources + decklink2_sdk, + c_args : gst_plugins_bad_args + decklink2_extra_args, + cpp_args : gst_plugins_bad_args + decklink2_extra_args, + link_args : decklink2_ldflags + noseh_link_args, + include_directories : [configinc] + decklink2_incl, + dependencies : [gstvideo_dep, gstaudio_dep, gstbase_dep, gst_dep] + decklink2_deps, + override_options : ['cpp_std=c++14'], + install : true, + install_dir : plugins_install_dir, +) + +plugins += [decklink2] \ No newline at end of file diff --git a/subprojects/gst-plugins-bad/sys/decklink2/plugin.cpp b/subprojects/gst-plugins-bad/sys/decklink2/plugin.cpp new file mode 100644 index 0000000000..0503200192 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/plugin.cpp @@ -0,0 +1,74 @@ +/* + * GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * plugin-decklink2: + * + * Since: 1.24 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gstdecklink2combiner.h" +#include "gstdecklink2demux.h" +#include "gstdecklink2deviceprovider.h" +#include "gstdecklink2sink.h" +#include "gstdecklink2src.h" +#include "gstdecklink2srcbin.h" +#include "gstdecklink2utils.h" + +GST_DEBUG_CATEGORY (gst_decklink2_debug); + +static void +plugin_deinit (gpointer data) +{ + gst_decklink2_deinit (); +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (gst_decklink2_debug, "decklink2", 0, "decklink2"); + + gst_decklink2_init_once (); + + GST_ELEMENT_REGISTER (decklink2combiner, plugin); + GST_ELEMENT_REGISTER (decklink2demux, plugin); + GST_ELEMENT_REGISTER (decklink2sink, plugin); + GST_ELEMENT_REGISTER (decklink2src, plugin); + GST_ELEMENT_REGISTER (decklink2srcbin, plugin); + + GST_DEVICE_PROVIDER_REGISTER (decklink2deviceprovider, plugin); + + g_object_set_data_full (G_OBJECT (plugin), + "plugin-decklink2-shutdown", (gpointer) "shutdown-data", + (GDestroyNotify) plugin_deinit); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + decklink2, + "Blackmagic Decklink plugin", + plugin_init, VERSION, "LGPL", PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI.idl new file mode 100644 index 0000000000..4179aeff6e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI.idl @@ -0,0 +1,1376 @@ +/* -LICENSE-START- + ** Copyright (c) 2022 Blackmagic Design + ** + ** Permission is hereby granted, free of charge, to any person or organization + ** obtaining a copy of the software and accompanying documentation (the + ** "Software") to use, reproduce, display, distribute, sub-license, execute, + ** and transmit the Software, and to prepare derivative works of the Software, + ** and to permit third-parties to whom the Software is furnished to do so, in + ** accordance with: + ** + ** (1) if the Software is obtained from Blackmagic Design, the End User License + ** Agreement for the Software Development Kit ("EULA") available at + ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + ** + ** (2) if the Software is obtained from any third party, such licensing terms + ** as notified by that third party, + ** + ** and all subject to the following: + ** + ** (3) the copyright notices in the Software and this entire statement, + ** including the above license grant, this restriction and the following + ** disclaimer, must be included in all copies of the Software, in whole or in + ** part, and all derivative works of the Software, unless such copies or + ** derivative works are solely in the form of machine-executable object code + ** generated by a source language processor. + ** + ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + ** DEALINGS IN THE SOFTWARE. + ** + ** A copy of the Software is available free of charge at + ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + ** + ** -LICENSE-END- + */ + + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +/* DeckLink API */ + +import "unknwn.idl"; + +[uuid(D864517A-EDD5-466D-867D-C819F1C052BB), +version(1.0), helpstring("DeckLink API Library")] +library DeckLinkAPI +{ + +#include "DeckLinkAPITypes.idl" +#include "DeckLinkAPIModes.idl" +#include "DeckLinkAPIDiscovery.idl" +#include "DeckLinkAPIConfiguration.idl" +#include "DeckLinkAPIDeckControl.idl" +#include "DeckLinkAPIStreaming.idl" + +// Type Declarations + + +// Enumeration Mapping + +cpp_quote("typedef unsigned int BMDFrameFlags;") +cpp_quote("typedef unsigned int BMDVideoInputFlags;") +cpp_quote("typedef unsigned int BMDVideoInputFormatChangedEvents;") +cpp_quote("typedef unsigned int BMDDetectedVideoInputFormatFlags;") +cpp_quote("typedef unsigned int BMDDeckLinkCapturePassthroughMode;") +cpp_quote("typedef unsigned int BMDAnalogVideoFlags;") +cpp_quote("typedef unsigned int BMDDeviceBusyState;") +cpp_quote("#if 0") +typedef enum _BMDFrameFlags BMDFrameFlags; +typedef enum _BMDVideoInputFlags BMDVideoInputFlags; +typedef enum _BMDVideoInputFormatChangedEvents BMDVideoInputFormatChangedEvents; +typedef enum _BMDDetectedVideoInputFormatFlags BMDDetectedVideoInputFormatFlags; +typedef enum _BMDDeckLinkCapturePassthroughMode BMDDeckLinkCapturePassthroughMode; +typedef enum _BMDAnalogVideoFlags BMDAnalogVideoFlags; +typedef enum _BMDDeviceBusyState BMDDeviceBusyState; +cpp_quote("#endif") + +/* Enum BMDVideoOutputFlags - Flags to control the output of ancillary data along with video. */ + +typedef [v1_enum] enum _BMDVideoOutputFlags { + bmdVideoOutputFlagDefault = 0, + bmdVideoOutputVANC = 1 << 0, + bmdVideoOutputVITC = 1 << 1, + bmdVideoOutputRP188 = 1 << 2, + bmdVideoOutputDualStream3D = 1 << 4, + bmdVideoOutputSynchronizeToPlaybackGroup = 1 << 6 +} BMDVideoOutputFlags; + +/* Enum BMDSupportedVideoModeFlags - Flags to describe supported video modes */ + +typedef [v1_enum] enum _BMDSupportedVideoModeFlags { + bmdSupportedVideoModeDefault = 0, + bmdSupportedVideoModeKeying = 1 << 0, + bmdSupportedVideoModeDualStream3D = 1 << 1, + bmdSupportedVideoModeSDISingleLink = 1 << 2, + bmdSupportedVideoModeSDIDualLink = 1 << 3, + bmdSupportedVideoModeSDIQuadLink = 1 << 4, + bmdSupportedVideoModeInAnyProfile = 1 << 5 +} BMDSupportedVideoModeFlags; + +/* Enum BMDPacketType - Type of packet */ + +typedef [v1_enum] enum _BMDPacketType { + bmdPacketTypeStreamInterruptedMarker = /* 'sint' */ 0x73696E74, // A packet of this type marks the time when a video stream was interrupted, for example by a disconnected cable + bmdPacketTypeStreamData = /* 'sdat' */ 0x73646174 // Regular stream data +} BMDPacketType; + +/* Enum BMDFrameFlags - Frame flags */ + +[v1_enum] enum _BMDFrameFlags { + bmdFrameFlagDefault = 0, + bmdFrameFlagFlipVertical = 1 << 0, + bmdFrameContainsHDRMetadata = 1 << 1, + + /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */ + + bmdFrameCapturedAsPsF = 1 << 30, + bmdFrameHasNoInputSource = 1 << 31 +}; + +/* Enum BMDVideoInputFlags - Flags applicable to video input */ + +[v1_enum] enum _BMDVideoInputFlags { + bmdVideoInputFlagDefault = 0, + bmdVideoInputEnableFormatDetection = 1 << 0, + bmdVideoInputDualStream3D = 1 << 1, + bmdVideoInputSynchronizeToCaptureGroup = 1 << 2 +}; + +/* Enum BMDVideoInputFormatChangedEvents - Bitmask passed to the VideoInputFormatChanged notification to identify the properties of the input signal that have changed */ + +[v1_enum] enum _BMDVideoInputFormatChangedEvents { + bmdVideoInputDisplayModeChanged = 1 << 0, + bmdVideoInputFieldDominanceChanged = 1 << 1, + bmdVideoInputColorspaceChanged = 1 << 2 +}; + +/* Enum BMDDetectedVideoInputFormatFlags - Flags passed to the VideoInputFormatChanged notification to describe the detected video input signal */ + +[v1_enum] enum _BMDDetectedVideoInputFormatFlags { + bmdDetectedVideoInputYCbCr422 = 1 << 0, + bmdDetectedVideoInputRGB444 = 1 << 1, + bmdDetectedVideoInputDualStream3D = 1 << 2, + bmdDetectedVideoInput12BitDepth = 1 << 3, + bmdDetectedVideoInput10BitDepth = 1 << 4, + bmdDetectedVideoInput8BitDepth = 1 << 5 +}; + +/* Enum BMDDeckLinkCapturePassthroughMode - Enumerates whether the video output is electrically connected to the video input or if the clean switching mode is enabled */ + +[v1_enum] enum _BMDDeckLinkCapturePassthroughMode { + bmdDeckLinkCapturePassthroughModeDisabled = /* 'pdis' */ 0x70646973, + bmdDeckLinkCapturePassthroughModeDirect = /* 'pdir' */ 0x70646972, + bmdDeckLinkCapturePassthroughModeCleanSwitch = /* 'pcln' */ 0x70636C6E +}; + +/* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */ + +typedef [v1_enum] enum _BMDOutputFrameCompletionResult { + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed +} BMDOutputFrameCompletionResult; + +/* Enum BMDReferenceStatus - GenLock input status */ + +typedef [v1_enum] enum _BMDReferenceStatus { + bmdReferenceUnlocked = 0, + bmdReferenceNotSupportedByHardware = 1 << 0, + bmdReferenceLocked = 1 << 1 +} BMDReferenceStatus; + +/* Enum BMDAudioFormat - Audio Format */ + +typedef [v1_enum] enum _BMDAudioFormat { + bmdAudioFormatPCM = /* 'lpcm' */ 0x6C70636D // Linear signed PCM samples +} BMDAudioFormat; + +/* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */ + +typedef [v1_enum] enum _BMDAudioSampleRate { + bmdAudioSampleRate48kHz = 48000 +} BMDAudioSampleRate; + +/* Enum BMDAudioSampleType - Audio sample sizes supported for output/input */ + +typedef [v1_enum] enum _BMDAudioSampleType { + bmdAudioSampleType16bitInteger = 16, + bmdAudioSampleType32bitInteger = 32 +} BMDAudioSampleType; + +/* Enum BMDAudioOutputStreamType - Audio output stream type */ + +typedef [v1_enum] enum _BMDAudioOutputStreamType { + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped +} BMDAudioOutputStreamType; + +/* Enum BMDAncillaryPacketFormat - Ancillary packet format */ + +typedef [v1_enum] enum _BMDAncillaryPacketFormat { + bmdAncillaryPacketFormatUInt8 = /* 'ui08' */ 0x75693038, + bmdAncillaryPacketFormatUInt16 = /* 'ui16' */ 0x75693136, + bmdAncillaryPacketFormatYCbCr10 = /* 'v210' */ 0x76323130 +} BMDAncillaryPacketFormat; + +/* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ + +typedef [v1_enum] enum _BMDTimecodeFormat { + bmdTimecodeRP188VITC1 = /* 'rpv1' */ 0x72707631, // RP188 timecode where DBB1 equals VITC1 (line 9) + bmdTimecodeRP188VITC2 = /* 'rp12' */ 0x72703132, // RP188 timecode where DBB1 equals VITC2 (line 9 for progressive or line 571 for interlaced/PsF) + bmdTimecodeRP188LTC = /* 'rplt' */ 0x72706C74, // RP188 timecode where DBB1 equals LTC (line 10) + bmdTimecodeRP188HighFrameRate = /* 'rphr' */ 0x72706872, // RP188 timecode where DBB1 is an HFRTC (SMPTE ST 12-3), the only timecode allowing the frame value to go above 30 + bmdTimecodeRP188Any = /* 'rp18' */ 0x72703138, // Convenience for capture, returning the first valid timecode in {HFRTC (if supported), VITC1, VITC2, LTC } + bmdTimecodeVITC = /* 'vitc' */ 0x76697463, + bmdTimecodeVITCField2 = /* 'vit2' */ 0x76697432, + bmdTimecodeSerial = /* 'seri' */ 0x73657269 +} BMDTimecodeFormat; + +/* Enum BMDAnalogVideoFlags - Analog video display flags */ + +[v1_enum] enum _BMDAnalogVideoFlags { + bmdAnalogVideoFlagCompositeSetup75 = 1 << 0, + bmdAnalogVideoFlagComponentBetacamLevels = 1 << 1 +}; + +/* Enum BMDAudioOutputAnalogAESSwitch - Audio output Analog/AESEBU switch */ + +typedef [v1_enum] enum _BMDAudioOutputAnalogAESSwitch { + bmdAudioOutputSwitchAESEBU = /* 'aes ' */ 0x61657320, + bmdAudioOutputSwitchAnalog = /* 'anlg' */ 0x616E6C67 +} BMDAudioOutputAnalogAESSwitch; + +/* Enum BMDVideoOutputConversionMode - Video/audio conversion mode */ + +typedef [v1_enum] enum _BMDVideoOutputConversionMode { + bmdNoVideoOutputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoOutputLetterboxDownconversion = /* 'ltbx' */ 0x6C746278, + bmdVideoOutputAnamorphicDownconversion = /* 'amph' */ 0x616D7068, + bmdVideoOutputHD720toHD1080Conversion = /* '720c' */ 0x37323063, + bmdVideoOutputHardwareLetterboxDownconversion = /* 'HWlb' */ 0x48576C62, + bmdVideoOutputHardwareAnamorphicDownconversion = /* 'HWam' */ 0x4857616D, + bmdVideoOutputHardwareCenterCutDownconversion = /* 'HWcc' */ 0x48576363, + bmdVideoOutputHardware720p1080pCrossconversion = /* 'xcap' */ 0x78636170, + bmdVideoOutputHardwareAnamorphic720pUpconversion = /* 'ua7p' */ 0x75613770, + bmdVideoOutputHardwareAnamorphic1080iUpconversion = /* 'ua1i' */ 0x75613169, + bmdVideoOutputHardwareAnamorphic149To720pUpconversion = /* 'u47p' */ 0x75343770, + bmdVideoOutputHardwareAnamorphic149To1080iUpconversion = /* 'u41i' */ 0x75343169, + bmdVideoOutputHardwarePillarbox720pUpconversion = /* 'up7p' */ 0x75703770, + bmdVideoOutputHardwarePillarbox1080iUpconversion = /* 'up1i' */ 0x75703169 +} BMDVideoOutputConversionMode; + +/* Enum BMDVideoInputConversionMode - Video input conversion mode */ + +typedef [v1_enum] enum _BMDVideoInputConversionMode { + bmdNoVideoInputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoInputLetterboxDownconversionFromHD1080 = /* '10lb' */ 0x31306C62, + bmdVideoInputAnamorphicDownconversionFromHD1080 = /* '10am' */ 0x3130616D, + bmdVideoInputLetterboxDownconversionFromHD720 = /* '72lb' */ 0x37326C62, + bmdVideoInputAnamorphicDownconversionFromHD720 = /* '72am' */ 0x3732616D, + bmdVideoInputLetterboxUpconversion = /* 'lbup' */ 0x6C627570, + bmdVideoInputAnamorphicUpconversion = /* 'amup' */ 0x616D7570 +} BMDVideoInputConversionMode; + +/* Enum BMDVideo3DPackingFormat - Video 3D packing format */ + +typedef [v1_enum] enum _BMDVideo3DPackingFormat { + bmdVideo3DPackingSidebySideHalf = /* 'sbsh' */ 0x73627368, + bmdVideo3DPackingLinebyLine = /* 'lbyl' */ 0x6C62796C, + bmdVideo3DPackingTopAndBottom = /* 'tabo' */ 0x7461626F, + bmdVideo3DPackingFramePacking = /* 'frpk' */ 0x6672706B, + bmdVideo3DPackingLeftOnly = /* 'left' */ 0x6C656674, + bmdVideo3DPackingRightOnly = /* 'righ' */ 0x72696768 +} BMDVideo3DPackingFormat; + +/* Enum BMDIdleVideoOutputOperation - Video output operation when not playing video */ + +typedef [v1_enum] enum _BMDIdleVideoOutputOperation { + bmdIdleVideoOutputBlack = /* 'blac' */ 0x626C6163, + bmdIdleVideoOutputLastFrame = /* 'lafa' */ 0x6C616661 +} BMDIdleVideoOutputOperation; + +/* Enum BMDVideoEncoderFrameCodingMode - Video frame coding mode */ + +typedef [v1_enum] enum _BMDVideoEncoderFrameCodingMode { + bmdVideoEncoderFrameCodingModeInter = /* 'inte' */ 0x696E7465, + bmdVideoEncoderFrameCodingModeIntra = /* 'intr' */ 0x696E7472 +} BMDVideoEncoderFrameCodingMode; + +/* Enum BMDDNxHRLevel - DNxHR Levels */ + +typedef [v1_enum] enum _BMDDNxHRLevel { + bmdDNxHRLevelSQ = /* 'dnsq' */ 0x646E7371, + bmdDNxHRLevelLB = /* 'dnlb' */ 0x646E6C62, + bmdDNxHRLevelHQ = /* 'dnhq' */ 0x646E6871, + bmdDNxHRLevelHQX = /* 'dhqx' */ 0x64687178, + bmdDNxHRLevel444 = /* 'd444' */ 0x64343434 +} BMDDNxHRLevel; + +/* Enum BMDLinkConfiguration - Video link configuration */ + +typedef [v1_enum] enum _BMDLinkConfiguration { + bmdLinkConfigurationSingleLink = /* 'lcsl' */ 0x6C63736C, + bmdLinkConfigurationDualLink = /* 'lcdl' */ 0x6C63646C, + bmdLinkConfigurationQuadLink = /* 'lcql' */ 0x6C63716C +} BMDLinkConfiguration; + +/* Enum BMDDeviceInterface - Device interface type */ + +typedef [v1_enum] enum _BMDDeviceInterface { + bmdDeviceInterfacePCI = /* 'pci ' */ 0x70636920, + bmdDeviceInterfaceUSB = /* 'usb ' */ 0x75736220, + bmdDeviceInterfaceThunderbolt = /* 'thun' */ 0x7468756E +} BMDDeviceInterface; + +/* Enum BMDColorspace - Colorspace */ + +typedef [v1_enum] enum _BMDColorspace { + bmdColorspaceRec601 = /* 'r601' */ 0x72363031, + bmdColorspaceRec709 = /* 'r709' */ 0x72373039, + bmdColorspaceRec2020 = /* '2020' */ 0x32303230 +} BMDColorspace; + +/* Enum BMDDynamicRange - SDR or HDR */ + +typedef [v1_enum] enum _BMDDynamicRange { + bmdDynamicRangeSDR = 0, // Standard Dynamic Range in accordance with SMPTE ST 2036-1 + bmdDynamicRangeHDRStaticPQ = 1 << 29, // High Dynamic Range PQ in accordance with SMPTE ST 2084 + bmdDynamicRangeHDRStaticHLG = 1 << 30 // High Dynamic Range HLG in accordance with ITU-R BT.2100-0 +} BMDDynamicRange; + +/* Enum BMDDeckLinkHDMIInputEDIDID - DeckLink HDMI Input EDID ID */ + +typedef [v1_enum] enum _BMDDeckLinkHDMIInputEDIDID { + + /* Integers */ + + bmdDeckLinkHDMIInputEDIDDynamicRange = /* 'HIDy' */ 0x48494479 // Parameter is of type BMDDynamicRange. Default is (bmdDynamicRangeSDR|bmdDynamicRangeHDRStaticPQ) +} BMDDeckLinkHDMIInputEDIDID; + +/* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ + +typedef [v1_enum] enum _BMDDeckLinkFrameMetadataID { + + /* Colorspace Metadata - Integers */ + + bmdDeckLinkFrameMetadataColorspace = /* 'cspc' */ 0x63737063, // Colorspace of video frame (see BMDColorspace) + + /* HDR Metadata - Integers */ + + bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc = /* 'eotf' */ 0x656F7466, // EOTF in range 0-7 as per CEA 861.3 + + /* HDR Metadata - Floats */ + + bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX = /* 'hdrx' */ 0x68647278, // Red display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY = /* 'hdry' */ 0x68647279, // Red display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX = /* 'hdgx' */ 0x68646778, // Green display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenY = /* 'hdgy' */ 0x68646779, // Green display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueX = /* 'hdbx' */ 0x68646278, // Blue display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRDisplayPrimariesBlueY = /* 'hdby' */ 0x68646279, // Blue display primaries in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRWhitePointX = /* 'hdwx' */ 0x68647778, // White point in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRWhitePointY = /* 'hdwy' */ 0x68647779, // White point in range 0.0 - 1.0 + bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance = /* 'hdml' */ 0x68646D6C, // Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance = /* 'hmil' */ 0x686D696C, // Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel = /* 'mcll' */ 0x6D636C6C, // Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 +} BMDDeckLinkFrameMetadataID; + +/* Enum BMDProfileID - Identifies a profile */ + +typedef [v1_enum] enum _BMDProfileID { + bmdProfileOneSubDeviceFullDuplex = /* '1dfd' */ 0x31646664, + bmdProfileOneSubDeviceHalfDuplex = /* '1dhd' */ 0x31646864, + bmdProfileTwoSubDevicesFullDuplex = /* '2dfd' */ 0x32646664, + bmdProfileTwoSubDevicesHalfDuplex = /* '2dhd' */ 0x32646864, + bmdProfileFourSubDevicesHalfDuplex = /* '4dhd' */ 0x34646864 +} BMDProfileID; + +/* Enum BMDHDMITimecodePacking - Packing form of timecode on HDMI */ + +typedef [v1_enum] enum _BMDHDMITimecodePacking { + bmdHDMITimecodePackingIEEEOUI000085 = 0x00008500, + bmdHDMITimecodePackingIEEEOUI080046 = 0x08004601, + bmdHDMITimecodePackingIEEEOUI5CF9F0 = 0x5CF9F003 +} BMDHDMITimecodePacking; + +/* Enum BMDInternalKeyingAncillaryDataSource - Source for VANC and timecode data when performing internal keying */ + +typedef [v1_enum] enum _BMDInternalKeyingAncillaryDataSource { + bmdInternalKeyingUsesAncillaryDataFromInputSignal = /* 'ikai' */ 0x696B6169, + bmdInternalKeyingUsesAncillaryDataFromKeyFrame = /* 'ikak' */ 0x696B616B +} BMDInternalKeyingAncillaryDataSource; + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef [v1_enum] enum _BMDDeckLinkAttributeID { + + /* Flags */ + + BMDDeckLinkSupportsInternalKeying = /* 'keyi' */ 0x6B657969, + BMDDeckLinkSupportsExternalKeying = /* 'keye' */ 0x6B657965, + BMDDeckLinkSupportsInputFormatDetection = /* 'infd' */ 0x696E6664, + BMDDeckLinkHasReferenceInput = /* 'hrin' */ 0x6872696E, + BMDDeckLinkHasSerialPort = /* 'hspt' */ 0x68737074, + BMDDeckLinkHasAnalogVideoOutputGain = /* 'avog' */ 0x61766F67, + BMDDeckLinkCanOnlyAdjustOverallVideoOutputGain = /* 'ovog' */ 0x6F766F67, + BMDDeckLinkHasVideoInputAntiAliasingFilter = /* 'aafl' */ 0x6161666C, + BMDDeckLinkHasBypass = /* 'byps' */ 0x62797073, + BMDDeckLinkSupportsClockTimingAdjustment = /* 'ctad' */ 0x63746164, + BMDDeckLinkSupportsFullFrameReferenceInputTimingOffset = /* 'frin' */ 0x6672696E, + BMDDeckLinkSupportsSMPTELevelAOutput = /* 'lvla' */ 0x6C766C61, + BMDDeckLinkSupportsAutoSwitchingPPsFOnInput = /* 'apsf' */ 0x61707366, + BMDDeckLinkSupportsDualLinkSDI = /* 'sdls' */ 0x73646C73, + BMDDeckLinkSupportsQuadLinkSDI = /* 'sqls' */ 0x73716C73, + BMDDeckLinkSupportsIdleOutput = /* 'idou' */ 0x69646F75, + BMDDeckLinkVANCRequires10BitYUVVideoFrames = /* 'vioY' */ 0x76696F59, // Legacy product requires v210 active picture for IDeckLinkVideoFrameAncillaryPackets or 10-bit VANC + BMDDeckLinkHasLTCTimecodeInput = /* 'hltc' */ 0x686C7463, + BMDDeckLinkSupportsHDRMetadata = /* 'hdrm' */ 0x6864726D, + BMDDeckLinkSupportsColorspaceMetadata = /* 'cmet' */ 0x636D6574, + BMDDeckLinkSupportsHDMITimecode = /* 'htim' */ 0x6874696D, + BMDDeckLinkSupportsHighFrameRateTimecode = /* 'HFRT' */ 0x48465254, + BMDDeckLinkSupportsSynchronizeToCaptureGroup = /* 'stcg' */ 0x73746367, + BMDDeckLinkSupportsSynchronizeToPlaybackGroup = /* 'stpg' */ 0x73747067, + + /* Integers */ + + BMDDeckLinkMaximumAudioChannels = /* 'mach' */ 0x6D616368, + BMDDeckLinkMaximumAnalogAudioInputChannels = /* 'iach' */ 0x69616368, + BMDDeckLinkMaximumAnalogAudioOutputChannels = /* 'aach' */ 0x61616368, + BMDDeckLinkNumberOfSubDevices = /* 'nsbd' */ 0x6E736264, + BMDDeckLinkSubDeviceIndex = /* 'subi' */ 0x73756269, + BMDDeckLinkPersistentID = /* 'peid' */ 0x70656964, + BMDDeckLinkDeviceGroupID = /* 'dgid' */ 0x64676964, + BMDDeckLinkTopologicalID = /* 'toid' */ 0x746F6964, + BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkVideoIOSupport = /* 'vios' */ 0x76696F73, // Returns a BMDVideoIOSupport bit field + BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, // Returns a BMDDeckControlConnection bit field + BMDDeckLinkDeviceInterface = /* 'dbus' */ 0x64627573, // Returns a BMDDeviceInterface + BMDDeckLinkAudioInputRCAChannelCount = /* 'airc' */ 0x61697263, + BMDDeckLinkAudioInputXLRChannelCount = /* 'aixc' */ 0x61697863, + BMDDeckLinkAudioOutputRCAChannelCount = /* 'aorc' */ 0x616F7263, + BMDDeckLinkAudioOutputXLRChannelCount = /* 'aoxc' */ 0x616F7863, + BMDDeckLinkProfileID = /* 'prid' */ 0x70726964, // Returns a BMDProfileID + BMDDeckLinkDuplex = /* 'dupx' */ 0x64757078, + BMDDeckLinkMinimumPrerollFrames = /* 'mprf' */ 0x6D707266, + BMDDeckLinkSupportedDynamicRange = /* 'sudr' */ 0x73756472, + + /* Floats */ + + BMDDeckLinkVideoInputGainMinimum = /* 'vigm' */ 0x7669676D, + BMDDeckLinkVideoInputGainMaximum = /* 'vigx' */ 0x76696778, + BMDDeckLinkVideoOutputGainMinimum = /* 'vogm' */ 0x766F676D, + BMDDeckLinkVideoOutputGainMaximum = /* 'vogx' */ 0x766F6778, + BMDDeckLinkMicrophoneInputGainMinimum = /* 'migm' */ 0x6D69676D, + BMDDeckLinkMicrophoneInputGainMaximum = /* 'migx' */ 0x6D696778, + + /* Strings */ + + BMDDeckLinkSerialPortDeviceName = /* 'slpn' */ 0x736C706E, + BMDDeckLinkVendorName = /* 'vndr' */ 0x766E6472, + BMDDeckLinkDisplayName = /* 'dspn' */ 0x6473706E, + BMDDeckLinkModelName = /* 'mdln' */ 0x6D646C6E, + BMDDeckLinkDeviceHandle = /* 'devh' */ 0x64657668 +} BMDDeckLinkAttributeID; + +/* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */ + +typedef [v1_enum] enum _BMDDeckLinkAPIInformationID { + + /* Integer or String */ + + BMDDeckLinkAPIVersion = /* 'vers' */ 0x76657273 +} BMDDeckLinkAPIInformationID; + +/* Enum BMDDeckLinkStatusID - DeckLink Status ID */ + +typedef [v1_enum] enum _BMDDeckLinkStatusID { + + /* Integers */ + + bmdDeckLinkStatusDetectedVideoInputMode = /* 'dvim' */ 0x6476696D, + bmdDeckLinkStatusDetectedVideoInputFormatFlags = /* 'dvff' */ 0x64766666, + bmdDeckLinkStatusDetectedVideoInputFieldDominance = /* 'dvfd' */ 0x64766664, + bmdDeckLinkStatusDetectedVideoInputColorspace = /* 'dscl' */ 0x6473636C, + bmdDeckLinkStatusDetectedVideoInputDynamicRange = /* 'dsdr' */ 0x64736472, + bmdDeckLinkStatusDetectedSDILinkConfiguration = /* 'dslc' */ 0x64736C63, + bmdDeckLinkStatusCurrentVideoInputMode = /* 'cvim' */ 0x6376696D, + bmdDeckLinkStatusCurrentVideoInputPixelFormat = /* 'cvip' */ 0x63766970, + bmdDeckLinkStatusCurrentVideoInputFlags = /* 'cvif' */ 0x63766966, + bmdDeckLinkStatusCurrentVideoOutputMode = /* 'cvom' */ 0x63766F6D, + bmdDeckLinkStatusCurrentVideoOutputFlags = /* 'cvof' */ 0x63766F66, + bmdDeckLinkStatusPCIExpressLinkWidth = /* 'pwid' */ 0x70776964, + bmdDeckLinkStatusPCIExpressLinkSpeed = /* 'plnk' */ 0x706C6E6B, + bmdDeckLinkStatusLastVideoOutputPixelFormat = /* 'opix' */ 0x6F706978, + bmdDeckLinkStatusReferenceSignalMode = /* 'refm' */ 0x7265666D, + bmdDeckLinkStatusReferenceSignalFlags = /* 'reff' */ 0x72656666, + bmdDeckLinkStatusBusy = /* 'busy' */ 0x62757379, + bmdDeckLinkStatusInterchangeablePanelType = /* 'icpt' */ 0x69637074, + bmdDeckLinkStatusDeviceTemperature = /* 'dtmp' */ 0x64746D70, + + /* Flags */ + + bmdDeckLinkStatusVideoInputSignalLocked = /* 'visl' */ 0x7669736C, + bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C, + + /* Bytes */ + + bmdDeckLinkStatusReceivedEDID = /* 'edid' */ 0x65646964 +} BMDDeckLinkStatusID; + +/* Enum BMDDeckLinkVideoStatusFlags - */ + +typedef [v1_enum] enum _BMDDeckLinkVideoStatusFlags { + bmdDeckLinkVideoStatusPsF = 1 << 0, + bmdDeckLinkVideoStatusDualStream3D = 1 << 1 +} BMDDeckLinkVideoStatusFlags; + +/* Enum BMDDuplexMode - Duplex of the device */ + +typedef [v1_enum] enum _BMDDuplexMode { + bmdDuplexFull = /* 'dxfu' */ 0x64786675, + bmdDuplexHalf = /* 'dxha' */ 0x64786861, + bmdDuplexSimplex = /* 'dxsp' */ 0x64787370, + bmdDuplexInactive = /* 'dxin' */ 0x6478696E +} BMDDuplexMode; + +/* Enum BMDPanelType - The type of interchangeable panel */ + +typedef [v1_enum] enum _BMDPanelType { + bmdPanelNotDetected = /* 'npnl' */ 0x6E706E6C, + bmdPanelTeranexMiniSmartPanel = /* 'tmsm' */ 0x746D736D +} BMDPanelType; + +/* Enum BMDDeviceBusyState - Current device busy state */ + +[v1_enum] enum _BMDDeviceBusyState { + bmdDeviceCaptureBusy = 1 << 0, + bmdDevicePlaybackBusy = 1 << 1, + bmdDeviceSerialPortBusy = 1 << 2 +}; + +/* Enum BMDVideoIOSupport - Device video input/output support */ + +typedef [v1_enum] enum _BMDVideoIOSupport { + bmdDeviceSupportsCapture = 1 << 0, + bmdDeviceSupportsPlayback = 1 << 1 +} BMDVideoIOSupport; + +/* Enum BMD3DPreviewFormat - Linked Frame preview format */ + +typedef [v1_enum] enum _BMD3DPreviewFormat { + bmd3DPreviewFormatDefault = /* 'defa' */ 0x64656661, + bmd3DPreviewFormatLeftOnly = /* 'left' */ 0x6C656674, + bmd3DPreviewFormatRightOnly = /* 'righ' */ 0x72696768, + bmd3DPreviewFormatSideBySide = /* 'side' */ 0x73696465, + bmd3DPreviewFormatTopBottom = /* 'topb' */ 0x746F7062 +} BMD3DPreviewFormat; + +/* Enum BMDNotifications - Events that can be subscribed through IDeckLinkNotification */ + +typedef [v1_enum] enum _BMDNotifications { + bmdPreferencesChanged = /* 'pref' */ 0x70726566, + bmdStatusChanged = /* 'stat' */ 0x73746174 +} BMDNotifications; + +// Forward Declarations + +interface IDeckLinkVideoOutputCallback; +interface IDeckLinkInputCallback; +interface IDeckLinkEncoderInputCallback; +interface IDeckLinkMemoryAllocator; +interface IDeckLinkAudioOutputCallback; +interface IDeckLinkIterator; +interface IDeckLinkAPIInformation; +interface IDeckLinkOutput; +interface IDeckLinkInput; +interface IDeckLinkHDMIInputEDID; +interface IDeckLinkEncoderInput; +interface IDeckLinkVideoFrame; +interface IDeckLinkMutableVideoFrame; +interface IDeckLinkVideoFrame3DExtensions; +interface IDeckLinkVideoFrameMetadataExtensions; +interface IDeckLinkVideoInputFrame; +interface IDeckLinkAncillaryPacket; +interface IDeckLinkAncillaryPacketIterator; +interface IDeckLinkVideoFrameAncillaryPackets; +interface IDeckLinkVideoFrameAncillary; +interface IDeckLinkEncoderPacket; +interface IDeckLinkEncoderVideoPacket; +interface IDeckLinkEncoderAudioPacket; +interface IDeckLinkH265NALPacket; +interface IDeckLinkAudioInputPacket; +interface IDeckLinkScreenPreviewCallback; +interface IDeckLinkGLScreenPreviewHelper; +interface IDeckLinkDX9ScreenPreviewHelper; +interface IDeckLinkWPFDX9ScreenPreviewHelper; +interface IDeckLinkNotificationCallback; +interface IDeckLinkNotification; +interface IDeckLinkProfileAttributes; +interface IDeckLinkProfileIterator; +interface IDeckLinkProfile; +interface IDeckLinkProfileCallback; +interface IDeckLinkProfileManager; +interface IDeckLinkStatus; +interface IDeckLinkKeyer; +interface IDeckLinkVideoConversion; +interface IDeckLinkDeviceNotificationCallback; +interface IDeckLinkDiscovery; + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +[ + object, + uuid(20AA5225-1958-47CB-820B-80A8D521A6EE), + helpstring("Frame completion callback.") +] interface IDeckLinkVideoOutputCallback : IUnknown +{ + HRESULT ScheduledFrameCompleted ([in] IDeckLinkVideoFrame* completedFrame, [in] BMDOutputFrameCompletionResult result); + HRESULT ScheduledPlaybackHasStopped (void); +}; + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +[ + object, + uuid(C6FCE4C9-C4E4-4047-82FB-5D238232A902), + helpstring("Frame arrival callback.") +] interface IDeckLinkInputCallback : IUnknown +{ + HRESULT VideoInputFormatChanged ([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode* newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags); + HRESULT VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame* videoFrame, [in] IDeckLinkAudioInputPacket* audioPacket); +}; + +/* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */ + +[ + object, + uuid(ACF13E61-F4A0-4974-A6A7-59AFF6268B31), + helpstring("Frame arrival callback.") +] interface IDeckLinkEncoderInputCallback : IUnknown +{ + HRESULT VideoInputSignalChanged ([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode* newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags); + HRESULT VideoPacketArrived ([in] IDeckLinkEncoderVideoPacket* videoPacket); + HRESULT AudioPacketArrived ([in] IDeckLinkEncoderAudioPacket* audioPacket); +}; + +/* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */ + +[ + object, + uuid(B36EB6E7-9D29-4AA8-92EF-843B87A289E8), + local, + helpstring("Memory allocator for video frames.") +] interface IDeckLinkMemoryAllocator : IUnknown +{ + HRESULT AllocateBuffer ([in] unsigned int bufferSize, [out] void** allocatedBuffer); + HRESULT ReleaseBuffer ([in] void* buffer); + HRESULT Commit (void); + HRESULT Decommit (void); +}; + +/* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */ + +[ + object, + uuid(403C681B-7F46-4A12-B993-2BB127084EE6), + local, + helpstring("Optional callback to allow audio samples to be pulled as required.") +] interface IDeckLinkAudioOutputCallback : IUnknown +{ + HRESULT RenderAudioSamples ([in] BOOL preroll); +}; + +/* Interface IDeckLinkIterator - Enumerates installed DeckLink hardware */ + +[ + object, + uuid(50FB36CD-3063-4B73-BDBB-958087F2D8BA), + helpstring("Enumerates installed DeckLink hardware") +] interface IDeckLinkIterator : IUnknown +{ + HRESULT Next ([out] IDeckLink** deckLinkInstance); +}; + +/* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */ + +[ + object, + uuid(7BEA3C68-730D-4322-AF34-8A7152B532A4), + helpstring("DeckLinkAPI attribute interface") +] interface IDeckLinkAPIInformation : IUnknown +{ + HRESULT GetFlag ([in] BMDDeckLinkAPIInformationID cfgID, [out] BOOL* value); + HRESULT GetInt ([in] BMDDeckLinkAPIInformationID cfgID, [out] LONGLONG* value); + HRESULT GetFloat ([in] BMDDeckLinkAPIInformationID cfgID, [out] double* value); + HRESULT GetString ([in] BMDDeckLinkAPIInformationID cfgID, [out] BSTR* value); +}; + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(BE2D9020-461E-442F-84B7-E949CB953B9D), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput : IUnknown +{ + HRESULT DoesSupportVideoMode ([in] BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, [in] BMDDisplayMode requestedMode, [in] BMDPixelFormat requestedPixelFormat, [in] BMDVideoOutputConversionMode conversionMode, [in] BMDSupportedVideoModeFlags flags, [out] BMDDisplayMode* actualMode, [out] BOOL* supported); + HRESULT GetDisplayMode ([in] BMDDisplayMode displayMode, [out] IDeckLinkDisplayMode** resultDisplayMode); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + HRESULT SetScreenPreviewCallback ([in] IDeckLinkScreenPreviewCallback* previewCallback); + + /* Video Output */ + + HRESULT EnableVideoOutput ([in] BMDDisplayMode displayMode, [in] BMDVideoOutputFlags flags); + HRESULT DisableVideoOutput (void); + HRESULT SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + HRESULT CreateVideoFrame ([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame** outFrame); + HRESULT CreateAncillaryData ([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary** outBuffer); // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + HRESULT DisplayVideoFrameSync ([in] IDeckLinkVideoFrame* theFrame); + HRESULT ScheduleVideoFrame ([in] IDeckLinkVideoFrame* theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback* theCallback); + HRESULT GetBufferedVideoFrameCount ([out] unsigned int* bufferedFrameCount); + + /* Audio Output */ + + HRESULT EnableAudioOutput ([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount, [in] BMDAudioOutputStreamType streamType); + HRESULT DisableAudioOutput (void); + HRESULT WriteAudioSamplesSync ([in] void* buffer, [in] unsigned int sampleFrameCount, [out] unsigned int* sampleFramesWritten); + HRESULT BeginAudioPreroll (void); + HRESULT EndAudioPreroll (void); + HRESULT ScheduleAudioSamples ([in] void* buffer, [in] unsigned int sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned int* sampleFramesWritten); + HRESULT GetBufferedAudioSampleFrameCount ([out] unsigned int* bufferedSampleFrameCount); + HRESULT FlushBufferedAudioSamples (void); + HRESULT SetAudioCallback ([in] IDeckLinkAudioOutputCallback* theCallback); + + /* Output Control */ + + HRESULT StartScheduledPlayback ([in] BMDTimeValue playbackStartTime, [in] BMDTimeScale timeScale, [in] double playbackSpeed); + HRESULT StopScheduledPlayback ([in] BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue* actualStopTime, [in] BMDTimeScale timeScale); + HRESULT IsScheduledPlaybackRunning ([out] BOOL* active); + HRESULT GetScheduledStreamTime ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* streamTime, [out] double* playbackSpeed); + HRESULT GetReferenceStatus ([out] BMDReferenceStatus* referenceStatus); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* hardwareTime, [out] BMDTimeValue* timeInFrame, [out] BMDTimeValue* ticksPerFrame); + HRESULT GetFrameCompletionReferenceTimestamp ([in] IDeckLinkVideoFrame* theFrame, [in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* frameCompletionTimestamp); +}; + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(C21CDB6E-F414-46E4-A636-80A566E0ED37), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput : IUnknown +{ + HRESULT DoesSupportVideoMode ([in] BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, [in] BMDDisplayMode requestedMode, [in] BMDPixelFormat requestedPixelFormat, [in] BMDVideoInputConversionMode conversionMode, [in] BMDSupportedVideoModeFlags flags, [out] BMDDisplayMode* actualMode, [out] BOOL* supported); + HRESULT GetDisplayMode ([in] BMDDisplayMode displayMode, [out] IDeckLinkDisplayMode** resultDisplayMode); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + HRESULT SetScreenPreviewCallback ([in] IDeckLinkScreenPreviewCallback* previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput ([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput (void); + HRESULT GetAvailableVideoFrameCount ([out] unsigned int* availableFrameCount); + HRESULT SetVideoInputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + + /* Audio Input */ + + HRESULT EnableAudioInput ([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput (void); + HRESULT GetAvailableAudioSampleFrameCount ([out] unsigned int* availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams (void); + HRESULT StopStreams (void); + HRESULT PauseStreams (void); + HRESULT FlushStreams (void); + HRESULT SetCallback ([in] IDeckLinkInputCallback* theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* hardwareTime, [out] BMDTimeValue* timeInFrame, [out] BMDTimeValue* ticksPerFrame); +}; + +/* Interface IDeckLinkHDMIInputEDID - Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default */ + +[ + object, + uuid(ABBBACBC-45BC-4665-9D92-ACE6E5A97902), + helpstring("Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default") +] interface IDeckLinkHDMIInputEDID : IUnknown +{ + HRESULT SetInt ([in] BMDDeckLinkHDMIInputEDIDID cfgID, [in] LONGLONG value); + HRESULT GetInt ([in] BMDDeckLinkHDMIInputEDIDID cfgID, [out] LONGLONG* value); + HRESULT WriteToEDID (void); +}; + +/* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(F222551D-13DF-4FD8-B587-9D4F19EC12C9), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkEncoderInput : IUnknown +{ + HRESULT DoesSupportVideoMode ([in] BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, [in] BMDDisplayMode requestedMode, [in] BMDPixelFormat requestedCodec, [in] unsigned int requestedCodecProfile, [in] BMDSupportedVideoModeFlags flags, [out] BOOL* supported); + HRESULT GetDisplayMode ([in] BMDDisplayMode displayMode, [out] IDeckLinkDisplayMode** resultDisplayMode); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + + /* Video Input */ + + HRESULT EnableVideoInput ([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput (void); + HRESULT GetAvailablePacketsCount ([out] unsigned int* availablePacketsCount); + HRESULT SetMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + + /* Audio Input */ + + HRESULT EnableAudioInput ([in] BMDAudioFormat audioFormat, [in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput (void); + HRESULT GetAvailableAudioSampleFrameCount ([out] unsigned int* availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams (void); + HRESULT StopStreams (void); + HRESULT PauseStreams (void); + HRESULT FlushStreams (void); + HRESULT SetCallback ([in] IDeckLinkEncoderInputCallback* theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* hardwareTime, [out] BMDTimeValue* timeInFrame, [out] BMDTimeValue* ticksPerFrame); +}; + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +[ + object, + uuid(3F716FE0-F023-4111-BE5D-EF4414C05B17), + local, + helpstring("Interface to encapsulate a video frame; can be caller-implemented.") +] interface IDeckLinkVideoFrame : IUnknown +{ + long GetWidth (void); + long GetHeight (void); + long GetRowBytes (void); + BMDPixelFormat GetPixelFormat (void); + BMDFrameFlags GetFlags (void); + HRESULT GetBytes ([out] void** buffer); + HRESULT GetTimecode ([in] BMDTimecodeFormat format, [out] IDeckLinkTimecode** timecode); + HRESULT GetAncillaryData ([out] IDeckLinkVideoFrameAncillary** ancillary); // Use of IDeckLinkVideoFrameAncillaryPackets is preferred +}; + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +[ + object, + uuid(69E2639F-40DA-4E19-B6F2-20ACE815C390), + local, + helpstring("Created by IDeckLinkOutput::CreateVideoFrame.") +] interface IDeckLinkMutableVideoFrame : IDeckLinkVideoFrame +{ + HRESULT SetFlags ([in] BMDFrameFlags newFlags); + HRESULT SetTimecode ([in] BMDTimecodeFormat format, [in] IDeckLinkTimecode* timecode); + HRESULT SetTimecodeFromComponents ([in] BMDTimecodeFormat format, [in] unsigned char hours, [in] unsigned char minutes, [in] unsigned char seconds, [in] unsigned char frames, [in] BMDTimecodeFlags flags); + HRESULT SetAncillaryData ([in] IDeckLinkVideoFrameAncillary* ancillary); + HRESULT SetTimecodeUserBits ([in] BMDTimecodeFormat format, [in] BMDTimecodeUserBits userBits); +}; + +/* Interface IDeckLinkVideoFrame3DExtensions - Optional interface implemented on IDeckLinkVideoFrame to support 3D frames */ + +[ + object, + uuid(DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7), + local, + helpstring("Optional interface implemented on IDeckLinkVideoFrame to support 3D frames") +] interface IDeckLinkVideoFrame3DExtensions : IUnknown +{ + BMDVideo3DPackingFormat Get3DPackingFormat (void); + HRESULT GetFrameForRightEye ([out] IDeckLinkVideoFrame** rightEyeFrame); +}; + +/* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDR information */ + +[ + object, + uuid(E232A5B7-4DB4-44C9-9152-F47C12E5F051), + local, + helpstring("Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDR information") +] interface IDeckLinkVideoFrameMetadataExtensions : IUnknown +{ + HRESULT GetInt ([in] BMDDeckLinkFrameMetadataID metadataID, [out] LONGLONG* value); + HRESULT GetFloat ([in] BMDDeckLinkFrameMetadataID metadataID, [out] double* value); + HRESULT GetFlag ([in] BMDDeckLinkFrameMetadataID metadataID, [out] BOOL* value); + HRESULT GetString ([in] BMDDeckLinkFrameMetadataID metadataID, [out] BSTR* value); + HRESULT GetBytes ([in] BMDDeckLinkFrameMetadataID metadataID, [out] void* buffer /* optional */, [in, out] unsigned int* bufferSize); +}; + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +[ + object, + uuid(05CFE374-537C-4094-9A57-680525118F44), + local, + helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") +] interface IDeckLinkVideoInputFrame : IDeckLinkVideoFrame +{ + HRESULT GetStreamTime ([out] BMDTimeValue* frameTime, [out] BMDTimeValue* frameDuration, [in] BMDTimeScale timeScale); + HRESULT GetHardwareReferenceTimestamp ([in] BMDTimeScale timeScale, [out] BMDTimeValue* frameTime, [out] BMDTimeValue* frameDuration); +}; + +/* Interface IDeckLinkAncillaryPacket - On output, user needs to implement this interface */ + +[ + object, + uuid(CC5BBF7E-029C-4D3B-9158-6000EF5E3670), + helpstring("On output, user needs to implement this interface") +] interface IDeckLinkAncillaryPacket : IUnknown +{ + HRESULT GetBytes ([in] BMDAncillaryPacketFormat format /* For output, only one format need be offered */, [out] const void** data /* Optional */, [out] unsigned int* size /* Optional */); + unsigned char GetDID (void); + unsigned char GetSDID (void); + unsigned int GetLineNumber (void); // On output, zero is auto + unsigned char GetDataStreamIndex (void); // Usually zero. Can only be 1 if non-SD and the first data stream is completely full +}; + +/* Interface IDeckLinkAncillaryPacketIterator - Enumerates ancillary packets */ + +[ + object, + uuid(3FC8994B-88FB-4C17-968F-9AAB69D964A7), + helpstring("Enumerates ancillary packets") +] interface IDeckLinkAncillaryPacketIterator : IUnknown +{ + HRESULT Next ([out] IDeckLinkAncillaryPacket** packet); +}; + +/* Interface IDeckLinkVideoFrameAncillaryPackets - Obtained through QueryInterface on an IDeckLinkVideoFrame object. */ + +[ + object, + uuid(6C186C0F-459E-41D8-AEE2-4812D81AEE68), + local, + helpstring("Obtained through QueryInterface on an IDeckLinkVideoFrame object.") +] interface IDeckLinkVideoFrameAncillaryPackets : IUnknown +{ + HRESULT GetPacketIterator ([out] IDeckLinkAncillaryPacketIterator** iterator); + HRESULT GetFirstPacketByID ([in] unsigned char DID, [in] unsigned char SDID, [out] IDeckLinkAncillaryPacket** packet); + HRESULT AttachPacket ([in] IDeckLinkAncillaryPacket* packet); // Implement IDeckLinkAncillaryPacket to output your own + HRESULT DetachPacket ([in] IDeckLinkAncillaryPacket* packet); + HRESULT DetachAllPackets (void); +}; + +/* Interface IDeckLinkVideoFrameAncillary - Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface on an IDeckLinkVideoFrame object. */ + +[ + object, + uuid(732E723C-D1A4-4E29-9E8E-4A88797A0004), + local, + helpstring("Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface on an IDeckLinkVideoFrame object.") +] interface IDeckLinkVideoFrameAncillary : IUnknown +{ + HRESULT GetBufferForVerticalBlankingLine ([in] unsigned int lineNumber, [out] void** buffer); // Pixels/rowbytes is same as display mode, except for above HD where it's 1920 pixels for UHD modes and 2048 pixels for DCI modes + BMDPixelFormat GetPixelFormat (void); + BMDDisplayMode GetDisplayMode (void); +}; + +/* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */ + +[ + object, + uuid(B693F36C-316E-4AF1-B6C2-F389A4BCA620), + local, + helpstring("Interface to encapsulate an encoded packet.") +] interface IDeckLinkEncoderPacket : IUnknown +{ + HRESULT GetBytes ([out] void** buffer); + long GetSize (void); + HRESULT GetStreamTime ([out] BMDTimeValue* frameTime, [in] BMDTimeScale timeScale); + BMDPacketType GetPacketType (void); +}; + +/* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */ + +[ + object, + uuid(4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0), + local, + helpstring("Provided by the IDeckLinkEncoderInput video packet arrival callback.") +] interface IDeckLinkEncoderVideoPacket : IDeckLinkEncoderPacket +{ + BMDPixelFormat GetPixelFormat (void); + HRESULT GetHardwareReferenceTimestamp ([in] BMDTimeScale timeScale, [out] BMDTimeValue* frameTime, [out] BMDTimeValue* frameDuration); + HRESULT GetTimecode ([in] BMDTimecodeFormat format, [out] IDeckLinkTimecode** timecode); +}; + +/* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */ + +[ + object, + uuid(49E8EDC8-693B-4E14-8EF6-12C658F5A07A), + local, + helpstring("Provided by the IDeckLinkEncoderInput audio packet arrival callback.") +] interface IDeckLinkEncoderAudioPacket : IDeckLinkEncoderPacket +{ + BMDAudioFormat GetAudioFormat (void); +}; + +/* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface on an IDeckLinkEncoderVideoPacket object */ + +[ + object, + uuid(639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7), + local, + helpstring("Obtained through QueryInterface on an IDeckLinkEncoderVideoPacket object") +] interface IDeckLinkH265NALPacket : IDeckLinkEncoderVideoPacket +{ + HRESULT GetUnitType ([out] unsigned char* unitType); + HRESULT GetBytesNoPrefix ([out] void** buffer); + long GetSizeNoPrefix (void); +}; + +/* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */ + +[ + object, + uuid(E43D5870-2894-11DE-8C30-0800200C9A66), + local, + helpstring("Provided by the IDeckLinkInput callback.") +] interface IDeckLinkAudioInputPacket : IUnknown +{ + long GetSampleFrameCount (void); + HRESULT GetBytes ([out] void** buffer); + HRESULT GetPacketTime ([out] BMDTimeValue* packetTime, [in] BMDTimeScale timeScale); +}; + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +[ + object, + uuid(B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438), + local, + helpstring("Screen preview callback") +] interface IDeckLinkScreenPreviewCallback : IUnknown +{ + HRESULT DrawFrame ([in] IDeckLinkVideoFrame* theFrame); +}; + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance on platforms with native COM support or from CreateOpenGLScreenPreviewHelper/CreateOpenGL3ScreenPreviewHelper on other platforms. */ + +[ + object, + uuid(504E2209-CAC7-4C1A-9FB4-C5BB6274D22F), + local, + helpstring("Created with CoCreateInstance on platforms with native COM support or from CreateOpenGLScreenPreviewHelper/CreateOpenGL3ScreenPreviewHelper on other platforms.") +] interface IDeckLinkGLScreenPreviewHelper : IUnknown +{ + + /* Methods must be called with OpenGL context set */ + + HRESULT InitializeGL (void); + HRESULT PaintGL (void); + HRESULT SetFrame ([in] IDeckLinkVideoFrame* theFrame); + HRESULT Set3DPreviewFormat ([in] BMD3DPreviewFormat previewFormat); +}; + +/* Interface IDeckLinkDX9ScreenPreviewHelper - Created with CoCreateInstance. */ + +[ + object, + uuid(2094B522-D1A1-40C0-9AC7-1C012218EF02), + local, + helpstring("Created with CoCreateInstance.") +] interface IDeckLinkDX9ScreenPreviewHelper : IUnknown +{ + HRESULT Initialize ([in] void* device); + HRESULT Render ([in] RECT* rc); + HRESULT SetFrame ([in] IDeckLinkVideoFrame* theFrame); + HRESULT Set3DPreviewFormat ([in] BMD3DPreviewFormat previewFormat); +}; + +/* Interface IDeckLinkWPFDX9ScreenPreviewHelper - Created with CoCreateInstance(). */ + +[ + object, + uuid(AD8EC84A-7DDE-11E9-8F9E-2A86E4085A59), + local, + helpstring("Created with CoCreateInstance().") +] interface IDeckLinkWPFDX9ScreenPreviewHelper : IUnknown +{ + HRESULT Initialize (void); + HRESULT Render (void); + HRESULT SetSurfaceSize ([in] unsigned int width, [in] unsigned int height); + HRESULT SetFrame ([in] IDeckLinkVideoFrame* theFrame); + HRESULT Set3DPreviewFormat ([in] BMD3DPreviewFormat previewFormat); + HRESULT GetBackBuffer ([out] void** backBuffer); +}; + +/* Interface IDeckLinkNotificationCallback - DeckLink Notification Callback Interface */ + +[ + object, + uuid(b002a1ec-070d-4288-8289-bd5d36e5ff0d), + local, + helpstring("DeckLink Notification Callback Interface") +] interface IDeckLinkNotificationCallback : IUnknown +{ + HRESULT Notify ([in] BMDNotifications topic, [in] ULONGLONG param1, [in] ULONGLONG param2); +}; + +/* Interface IDeckLinkNotification - DeckLink Notification interface */ + +[ + object, + uuid(b85df4c8-bdf5-47c1-8064-28162ebdd4eb), + local, + helpstring("DeckLink Notification interface") +] interface IDeckLinkNotification : IUnknown +{ + HRESULT Subscribe ([in] BMDNotifications topic, [in] IDeckLinkNotificationCallback* theCallback); + HRESULT Unsubscribe ([in] BMDNotifications topic, [in] IDeckLinkNotificationCallback* theCallback); +}; + +/* Interface IDeckLinkProfileAttributes - Created by QueryInterface from an IDeckLinkProfile, or from IDeckLink. When queried from IDeckLink, interrogates the active profile */ + +[ + object, + uuid(17D4BF8E-4911-473A-80A0-731CF6FF345B), + local, + helpstring("Created by QueryInterface from an IDeckLinkProfile, or from IDeckLink. When queried from IDeckLink, interrogates the active profile") +] interface IDeckLinkProfileAttributes : IUnknown +{ + HRESULT GetFlag ([in] BMDDeckLinkAttributeID cfgID, [out] BOOL* value); + HRESULT GetInt ([in] BMDDeckLinkAttributeID cfgID, [out] LONGLONG* value); + HRESULT GetFloat ([in] BMDDeckLinkAttributeID cfgID, [out] double* value); + HRESULT GetString ([in] BMDDeckLinkAttributeID cfgID, [out] BSTR* value); +}; + +/* Interface IDeckLinkProfileIterator - Enumerates IDeckLinkProfile interfaces */ + +[ + object, + uuid(29E5A8C0-8BE4-46EB-93AC-31DAAB5B7BF2), + helpstring("Enumerates IDeckLinkProfile interfaces") +] interface IDeckLinkProfileIterator : IUnknown +{ + HRESULT Next ([out] IDeckLinkProfile** profile); +}; + +/* Interface IDeckLinkProfile - Represents the active profile when queried from IDeckLink */ + +[ + object, + uuid(16093466-674A-432B-9DA0-1AC2C5A8241C), + local, + helpstring("Represents the active profile when queried from IDeckLink") +] interface IDeckLinkProfile : IUnknown +{ + HRESULT GetDevice ([out] IDeckLink** device); // Device affected when this profile becomes active + HRESULT IsActive ([out] BOOL* isActive); + HRESULT SetActive (void); // Activating a profile will also change the profile on all devices enumerated by GetPeers. Activation is not complete until IDeckLinkProfileCallback::ProfileActivated is called + HRESULT GetPeers ([out] IDeckLinkProfileIterator** profileIterator); // Profiles of other devices activated with this profile +}; + +/* Interface IDeckLinkProfileCallback - Receive notifications about profiles related to this device */ + +[ + object, + uuid(A4F9341E-97AA-4E04-8935-15F809898CEA), + helpstring("Receive notifications about profiles related to this device") +] interface IDeckLinkProfileCallback : IUnknown +{ + HRESULT ProfileChanging ([in] IDeckLinkProfile* profileToBeActivated, [in] BOOL streamsWillBeForcedToStop); // Called before this device changes profile. User has an opportunity for teardown if streamsWillBeForcedToStop + HRESULT ProfileActivated ([in] IDeckLinkProfile* activatedProfile); // Called after this device has been activated with a new profile +}; + +/* Interface IDeckLinkProfileManager - Created by QueryInterface from IDeckLink when a device has multiple optional profiles */ + +[ + object, + uuid(30D41429-3998-4B6D-84F8-78C94A797C6E), + helpstring("Created by QueryInterface from IDeckLink when a device has multiple optional profiles") +] interface IDeckLinkProfileManager : IUnknown +{ + HRESULT GetProfiles ([out] IDeckLinkProfileIterator** profileIterator); // All available profiles for this device + HRESULT GetProfile ([in] BMDProfileID profileID, [out] IDeckLinkProfile** profile); + HRESULT SetCallback ([in] IDeckLinkProfileCallback* callback); +}; + +/* Interface IDeckLinkStatus - DeckLink Status interface */ + +[ + object, + uuid(5F558200-4028-49BC-BEAC-DB3FA4A96E46), + local, + helpstring("DeckLink Status interface") +] interface IDeckLinkStatus : IUnknown +{ + HRESULT GetFlag ([in] BMDDeckLinkStatusID statusID, [out] BOOL* value); + HRESULT GetInt ([in] BMDDeckLinkStatusID statusID, [out] LONGLONG* value); + HRESULT GetFloat ([in] BMDDeckLinkStatusID statusID, [out] double* value); + HRESULT GetString ([in] BMDDeckLinkStatusID statusID, [out] BSTR* value); + HRESULT GetBytes ([in] BMDDeckLinkStatusID statusID, [out] void* buffer, [in, out] unsigned int* bufferSize); +}; + +/* Interface IDeckLinkKeyer - DeckLink Keyer interface */ + +[ + object, + uuid(89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3), + local, + helpstring("DeckLink Keyer interface") +] interface IDeckLinkKeyer : IUnknown +{ + HRESULT Enable ([in] BOOL isExternal); + HRESULT SetLevel ([in] unsigned char level); + HRESULT RampUp ([in] unsigned int numberOfFrames); + HRESULT RampDown ([in] unsigned int numberOfFrames); + HRESULT Disable (void); +}; + +/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance. */ + +[ + object, + uuid(3BBCB8A2-DA2C-42D9-B5D8-88083644E99A), + local, + helpstring("Created with CoCreateInstance.") +] interface IDeckLinkVideoConversion : IUnknown +{ + HRESULT ConvertFrame ([in] IDeckLinkVideoFrame* srcFrame, [in] IDeckLinkVideoFrame* dstFrame); +}; + +/* Interface IDeckLinkDeviceNotificationCallback - DeckLink device arrival/removal notification callbacks */ + +[ + object, + uuid(4997053B-0ADF-4CC8-AC70-7A50C4BE728F), + helpstring("DeckLink device arrival/removal notification callbacks") +] interface IDeckLinkDeviceNotificationCallback : IUnknown +{ + HRESULT DeckLinkDeviceArrived ([in] IDeckLink* deckLinkDevice); + HRESULT DeckLinkDeviceRemoved ([in] IDeckLink* deckLinkDevice); +}; + +/* Interface IDeckLinkDiscovery - DeckLink device discovery */ + +[ + object, + uuid(CDBF631C-BC76-45FA-B44D-C55059BC6101), + helpstring("DeckLink device discovery") +] interface IDeckLinkDiscovery : IUnknown +{ + HRESULT InstallDeviceNotifications ([in] IDeckLinkDeviceNotificationCallback* deviceNotificationCallback); + HRESULT UninstallDeviceNotifications (void); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(BA6C6F44-6DA5-4DCE-94AA-EE2D1372A676), + helpstring("CDeckLinkIterator Class") +] coclass CDeckLinkIterator +{ + [default] interface IDeckLinkIterator; +}; + +[ + uuid(263CA19F-ED09-482E-9F9D-84005783A237), + helpstring("CDeckLinkAPIInformation Class") +] coclass CDeckLinkAPIInformation +{ + [default] interface IDeckLinkAPIInformation; +}; + +[ + uuid(F63E77C7-B655-4A4A-9AD0-3CA85D394343), + helpstring("CDeckLinkGLScreenPreviewHelper Class") +] coclass CDeckLinkGLScreenPreviewHelper +{ + [default] interface IDeckLinkGLScreenPreviewHelper; +}; + +[ + uuid(00696A71-EBC7-491F-AC02-18D3393F33F0), + helpstring("CDeckLinkGL3ScreenPreviewHelper Class. Requires OpenGL 3.2 support and provides improved performance and color handling") +] coclass CDeckLinkGL3ScreenPreviewHelper +{ + [default] interface IDeckLinkGLScreenPreviewHelper; +}; + +[ + uuid(CC010023-E01D-4525-9D59-80C8AB3DC7A0), + helpstring("CDeckLinkDX9ScreenPreviewHelper Class") +] coclass CDeckLinkDX9ScreenPreviewHelper +{ + [default] interface IDeckLinkDX9ScreenPreviewHelper; +}; + +[ + uuid(EF2A8478-7DDF-11E9-8F9E-2A86E4085A59), + helpstring("CDeckLinkWPFDX9ScreenPreviewHelper Class") +] coclass CDeckLinkWPFDX9ScreenPreviewHelper +{ + [default] interface IDeckLinkWPFDX9ScreenPreviewHelper; +}; + +[ + uuid(7DBBBB11-5B7B-467D-AEA4-CEA468FD368C), + helpstring("CDeckLinkVideoConversion Class") +] coclass CDeckLinkVideoConversion +{ + [default] interface IDeckLinkVideoConversion; +}; + +[ + uuid(22FBFC33-8D07-495C-A5BF-DAB5EA9B82DB), + helpstring("CDeckLinkDiscovery Class") +] coclass CDeckLinkDiscovery +{ + [default] interface IDeckLinkDiscovery; +}; + +[ + uuid(F891AD29-D0C2-46E9-A926-4E2D0DD8CFAD), + helpstring("CDeckLinkVideoFrameAncillaryPackets Class") +] coclass CDeckLinkVideoFrameAncillaryPackets +{ + [default] interface IDeckLinkVideoFrameAncillaryPackets; +}; + +// import deprecated interfaces + +#include "DeckLinkAPI_v11_5_1.idl" +#include "DeckLinkAPI_v10_11.idl" +#include "DeckLinkAPI_v10_9.idl" +#include "DeckLinkAPIStreaming_v10_8.idl" +#include "DeckLinkAPI_v10_4.idl" +#include "DeckLinkAPI_v10_2.idl" +#include "DeckLinkAPI_v11_5.idl" +#include "DeckLinkAPI_v11_4.idl" +#include "DeckLinkAPI_v10_8.idl" +#include "DeckLinkAPI_v10_6.idl" +#include "DeckLinkAPI_v10_5.idl" +#include "DeckLinkAPI_v9_9.idl" +#include "DeckLinkAPI_v9_2.idl" +#include "DeckLinkAPI_v8_1.idl" +#include "DeckLinkAPI_v8_0.idl" +#include "DeckLinkAPI_v7_9.idl" +#include "DeckLinkAPI_v7_6.idl" +#include "DeckLinkAPI_v7_3.idl" +#include "DeckLinkAPI_v7_1.idl" +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIConfiguration.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIConfiguration.idl new file mode 100644 index 0000000000..10ebc09cd6 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIConfiguration.idl @@ -0,0 +1,252 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +// Type Declarations + + +// Enumeration Mapping + +cpp_quote("#if 0") +cpp_quote("#endif") + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkConfigurationID { + + /* Serial port Flags */ + + bmdDeckLinkConfigSwapSerialRxTx = /* 'ssrt' */ 0x73737274, + + /* Video Input/Output Integers */ + + bmdDeckLinkConfigHDMI3DPackingFormat = /* '3dpf' */ 0x33647066, + bmdDeckLinkConfigBypass = /* 'byps' */ 0x62797073, + bmdDeckLinkConfigClockTimingAdjustment = /* 'ctad' */ 0x63746164, + + /* Audio Input/Output Flags */ + + bmdDeckLinkConfigAnalogAudioConsumerLevels = /* 'aacl' */ 0x6161636C, + bmdDeckLinkConfigSwapHDMICh3AndCh4OnInput = /* 'hi34' */ 0x68693334, + bmdDeckLinkConfigSwapHDMICh3AndCh4OnOutput = /* 'ho34' */ 0x686F3334, + + /* Video Output Flags */ + + bmdDeckLinkConfigFieldFlickerRemoval = /* 'fdfr' */ 0x66646672, + bmdDeckLinkConfigHD1080p24ToHD1080i5994Conversion = /* 'to59' */ 0x746F3539, + bmdDeckLinkConfig444SDIVideoOutput = /* '444o' */ 0x3434346F, + bmdDeckLinkConfigBlackVideoOutputDuringCapture = /* 'bvoc' */ 0x62766F63, + bmdDeckLinkConfigLowLatencyVideoOutput = /* 'llvo' */ 0x6C6C766F, + bmdDeckLinkConfigDownConversionOnAllAnalogOutput = /* 'caao' */ 0x6361616F, + bmdDeckLinkConfigSMPTELevelAOutput = /* 'smta' */ 0x736D7461, + bmdDeckLinkConfigRec2020Output = /* 'rec2' */ 0x72656332, // Ensure output is Rec.2020 colorspace + bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit = /* 'SDQS' */ 0x53445153, + bmdDeckLinkConfigOutput1080pAsPsF = /* 'pfpr' */ 0x70667072, + + /* Video Output Integers */ + + bmdDeckLinkConfigVideoOutputConnection = /* 'vocn' */ 0x766F636E, + bmdDeckLinkConfigVideoOutputConversionMode = /* 'vocm' */ 0x766F636D, + bmdDeckLinkConfigAnalogVideoOutputFlags = /* 'avof' */ 0x61766F66, + bmdDeckLinkConfigReferenceInputTimingOffset = /* 'glot' */ 0x676C6F74, + bmdDeckLinkConfigVideoOutputIdleOperation = /* 'voio' */ 0x766F696F, + bmdDeckLinkConfigDefaultVideoOutputMode = /* 'dvom' */ 0x64766F6D, + bmdDeckLinkConfigDefaultVideoOutputModeFlags = /* 'dvof' */ 0x64766F66, + bmdDeckLinkConfigSDIOutputLinkConfiguration = /* 'solc' */ 0x736F6C63, + bmdDeckLinkConfigHDMITimecodePacking = /* 'htpk' */ 0x6874706B, + bmdDeckLinkConfigPlaybackGroup = /* 'plgr' */ 0x706C6772, + + /* Video Output Floats */ + + bmdDeckLinkConfigVideoOutputComponentLumaGain = /* 'oclg' */ 0x6F636C67, + bmdDeckLinkConfigVideoOutputComponentChromaBlueGain = /* 'occb' */ 0x6F636362, + bmdDeckLinkConfigVideoOutputComponentChromaRedGain = /* 'occr' */ 0x6F636372, + bmdDeckLinkConfigVideoOutputCompositeLumaGain = /* 'oilg' */ 0x6F696C67, + bmdDeckLinkConfigVideoOutputCompositeChromaGain = /* 'oicg' */ 0x6F696367, + bmdDeckLinkConfigVideoOutputSVideoLumaGain = /* 'oslg' */ 0x6F736C67, + bmdDeckLinkConfigVideoOutputSVideoChromaGain = /* 'oscg' */ 0x6F736367, + + /* Video Input Flags */ + + bmdDeckLinkConfigVideoInputScanning = /* 'visc' */ 0x76697363, // Applicable to H264 Pro Recorder only + bmdDeckLinkConfigUseDedicatedLTCInput = /* 'dltc' */ 0x646C7463, // Use timecode from LTC input instead of SDI stream + bmdDeckLinkConfigSDIInput3DPayloadOverride = /* '3dds' */ 0x33646473, + bmdDeckLinkConfigCapture1080pAsPsF = /* 'cfpr' */ 0x63667072, + + /* Video Input Integers */ + + bmdDeckLinkConfigVideoInputConnection = /* 'vicn' */ 0x7669636E, + bmdDeckLinkConfigAnalogVideoInputFlags = /* 'avif' */ 0x61766966, + bmdDeckLinkConfigVideoInputConversionMode = /* 'vicm' */ 0x7669636D, + bmdDeckLinkConfig32PulldownSequenceInitialTimecodeFrame = /* 'pdif' */ 0x70646966, + bmdDeckLinkConfigVANCSourceLine1Mapping = /* 'vsl1' */ 0x76736C31, + bmdDeckLinkConfigVANCSourceLine2Mapping = /* 'vsl2' */ 0x76736C32, + bmdDeckLinkConfigVANCSourceLine3Mapping = /* 'vsl3' */ 0x76736C33, + bmdDeckLinkConfigCapturePassThroughMode = /* 'cptm' */ 0x6370746D, + bmdDeckLinkConfigCaptureGroup = /* 'cpgr' */ 0x63706772, + + /* Video Input Floats */ + + bmdDeckLinkConfigVideoInputComponentLumaGain = /* 'iclg' */ 0x69636C67, + bmdDeckLinkConfigVideoInputComponentChromaBlueGain = /* 'iccb' */ 0x69636362, + bmdDeckLinkConfigVideoInputComponentChromaRedGain = /* 'iccr' */ 0x69636372, + bmdDeckLinkConfigVideoInputCompositeLumaGain = /* 'iilg' */ 0x69696C67, + bmdDeckLinkConfigVideoInputCompositeChromaGain = /* 'iicg' */ 0x69696367, + bmdDeckLinkConfigVideoInputSVideoLumaGain = /* 'islg' */ 0x69736C67, + bmdDeckLinkConfigVideoInputSVideoChromaGain = /* 'iscg' */ 0x69736367, + + /* Keying Integers */ + + bmdDeckLinkConfigInternalKeyingAncillaryDataSource = /* 'ikas' */ 0x696B6173, + + /* Audio Input Flags */ + + bmdDeckLinkConfigMicrophonePhantomPower = /* 'mphp' */ 0x6D706870, + + /* Audio Input Integers */ + + bmdDeckLinkConfigAudioInputConnection = /* 'aicn' */ 0x6169636E, + + /* Audio Input Floats */ + + bmdDeckLinkConfigAnalogAudioInputScaleChannel1 = /* 'ais1' */ 0x61697331, + bmdDeckLinkConfigAnalogAudioInputScaleChannel2 = /* 'ais2' */ 0x61697332, + bmdDeckLinkConfigAnalogAudioInputScaleChannel3 = /* 'ais3' */ 0x61697333, + bmdDeckLinkConfigAnalogAudioInputScaleChannel4 = /* 'ais4' */ 0x61697334, + bmdDeckLinkConfigDigitalAudioInputScale = /* 'dais' */ 0x64616973, + bmdDeckLinkConfigMicrophoneInputGain = /* 'micg' */ 0x6D696367, + + /* Audio Output Integers */ + + bmdDeckLinkConfigAudioOutputAESAnalogSwitch = /* 'aoaa' */ 0x616F6161, + + /* Audio Output Floats */ + + bmdDeckLinkConfigAnalogAudioOutputScaleChannel1 = /* 'aos1' */ 0x616F7331, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel2 = /* 'aos2' */ 0x616F7332, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel3 = /* 'aos3' */ 0x616F7333, + bmdDeckLinkConfigAnalogAudioOutputScaleChannel4 = /* 'aos4' */ 0x616F7334, + bmdDeckLinkConfigDigitalAudioOutputScale = /* 'daos' */ 0x64616F73, + bmdDeckLinkConfigHeadphoneVolume = /* 'hvol' */ 0x68766F6C, + + /* Device Information Strings */ + + bmdDeckLinkConfigDeviceInformationLabel = /* 'dila' */ 0x64696C61, + bmdDeckLinkConfigDeviceInformationSerialNumber = /* 'disn' */ 0x6469736E, + bmdDeckLinkConfigDeviceInformationCompany = /* 'dico' */ 0x6469636F, + bmdDeckLinkConfigDeviceInformationPhone = /* 'diph' */ 0x64697068, + bmdDeckLinkConfigDeviceInformationEmail = /* 'diem' */ 0x6469656D, + bmdDeckLinkConfigDeviceInformationDate = /* 'dida' */ 0x64696461, + + /* Deck Control Integers */ + + bmdDeckLinkConfigDeckControlConnection = /* 'dcco' */ 0x6463636F +} BMDDeckLinkConfigurationID; + +/* Enum BMDDeckLinkEncoderConfigurationID - DeckLink Encoder Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkEncoderConfigurationID { + + /* Video Encoder Integers */ + + bmdDeckLinkEncoderConfigPreferredBitDepth = /* 'epbr' */ 0x65706272, + bmdDeckLinkEncoderConfigFrameCodingMode = /* 'efcm' */ 0x6566636D, + + /* HEVC/H.265 Encoder Integers */ + + bmdDeckLinkEncoderConfigH265TargetBitrate = /* 'htbr' */ 0x68746272, + + /* DNxHR/DNxHD Compression ID */ + + bmdDeckLinkEncoderConfigDNxHRCompressionID = /* 'dcid' */ 0x64636964, + + /* DNxHR/DNxHD Level */ + + bmdDeckLinkEncoderConfigDNxHRLevel = /* 'dlev' */ 0x646C6576, + + /* Encoded Sample Decriptions */ + + bmdDeckLinkEncoderConfigMPEG4SampleDescription = /* 'stsE' */ 0x73747345, // Full MPEG4 sample description (aka SampleEntry of an 'stsd' atom-box). Useful for MediaFoundation, QuickTime, MKV and more + bmdDeckLinkEncoderConfigMPEG4CodecSpecificDesc = /* 'esds' */ 0x65736473 // Sample description extensions only (atom stream, each with size and fourCC header). Useful for AVFoundation, VideoToolbox, MKV and more +} BMDDeckLinkEncoderConfigurationID; + +// Forward Declarations + +interface IDeckLinkConfiguration; +interface IDeckLinkEncoderConfiguration; + +/* Interface IDeckLinkConfiguration - DeckLink Configuration interface */ + +[ + object, + uuid(912F634B-2D4E-40A4-8AAB-8D80B73F1289), + local, + helpstring("DeckLink Configuration interface") +] interface IDeckLinkConfiguration : IUnknown +{ + HRESULT SetFlag ([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag ([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL* value); + HRESULT SetInt ([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt ([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG* value); + HRESULT SetFloat ([in] BMDDeckLinkConfigurationID cfgID, [in] double value); + HRESULT GetFloat ([in] BMDDeckLinkConfigurationID cfgID, [out] double* value); + HRESULT SetString ([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value); + HRESULT GetString ([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR* value); + HRESULT WriteConfigurationToPreferences (void); +}; + +/* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ + +[ + object, + uuid(138050E5-C60A-4552-BF3F-0F358049327E), + local, + helpstring("DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput") +] interface IDeckLinkEncoderConfiguration : IUnknown +{ + HRESULT SetFlag ([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag ([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BOOL* value); + HRESULT SetInt ([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt ([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] LONGLONG* value); + HRESULT SetFloat ([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] double value); + HRESULT GetFloat ([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] double* value); + HRESULT SetString ([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BSTR value); + HRESULT GetString ([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BSTR* value); + HRESULT GetBytes ([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] void* buffer /* optional */, [in, out] unsigned int* bufferSize); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIDeckControl.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIDeckControl.idl new file mode 100644 index 0000000000..70275040b5 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIDeckControl.idl @@ -0,0 +1,204 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +// Type Declarations + + +// Enumeration Mapping + +cpp_quote("typedef unsigned int BMDDeckControlStatusFlags;") +cpp_quote("typedef unsigned int BMDDeckControlExportModeOpsFlags;") +cpp_quote("#if 0") +typedef enum _BMDDeckControlStatusFlags BMDDeckControlStatusFlags; +typedef enum _BMDDeckControlExportModeOpsFlags BMDDeckControlExportModeOpsFlags; +cpp_quote("#endif") + +/* Enum BMDDeckControlMode - DeckControl mode */ + +typedef [v1_enum] enum _BMDDeckControlMode { + bmdDeckControlNotOpened = /* 'ntop' */ 0x6E746F70, + bmdDeckControlVTRControlMode = /* 'vtrc' */ 0x76747263, + bmdDeckControlExportMode = /* 'expm' */ 0x6578706D, + bmdDeckControlCaptureMode = /* 'capm' */ 0x6361706D +} BMDDeckControlMode; + +/* Enum BMDDeckControlEvent - DeckControl event */ + +typedef [v1_enum] enum _BMDDeckControlEvent { + bmdDeckControlAbortedEvent = /* 'abte' */ 0x61627465, // This event is triggered when a capture or edit-to-tape operation is aborted. + + /* Export-To-Tape events */ + + bmdDeckControlPrepareForExportEvent = /* 'pfee' */ 0x70666565, // This event is triggered a few frames before reaching the in-point. IDeckLinkInput::StartScheduledPlayback should be called at this point. + bmdDeckControlExportCompleteEvent = /* 'exce' */ 0x65786365, // This event is triggered a few frames after reaching the out-point. At this point, it is safe to stop playback. Upon reception of this event the deck's control mode is set back to bmdDeckControlVTRControlMode. + + /* Capture events */ + + bmdDeckControlPrepareForCaptureEvent = /* 'pfce' */ 0x70666365, // This event is triggered a few frames before reaching the in-point. The serial timecode attached to IDeckLinkVideoInputFrames is now valid. + bmdDeckControlCaptureCompleteEvent = /* 'ccev' */ 0x63636576 // This event is triggered a few frames after reaching the out-point. Upon reception of this event the deck's control mode is set back to bmdDeckControlVTRControlMode. +} BMDDeckControlEvent; + +/* Enum BMDDeckControlVTRControlState - VTR Control state */ + +typedef [v1_enum] enum _BMDDeckControlVTRControlState { + bmdDeckControlNotInVTRControlMode = /* 'nvcm' */ 0x6E76636D, + bmdDeckControlVTRControlPlaying = /* 'vtrp' */ 0x76747270, + bmdDeckControlVTRControlRecording = /* 'vtrr' */ 0x76747272, + bmdDeckControlVTRControlStill = /* 'vtra' */ 0x76747261, + bmdDeckControlVTRControlShuttleForward = /* 'vtsf' */ 0x76747366, + bmdDeckControlVTRControlShuttleReverse = /* 'vtsr' */ 0x76747372, + bmdDeckControlVTRControlJogForward = /* 'vtjf' */ 0x76746A66, + bmdDeckControlVTRControlJogReverse = /* 'vtjr' */ 0x76746A72, + bmdDeckControlVTRControlStopped = /* 'vtro' */ 0x7674726F +} BMDDeckControlVTRControlState; + +/* Enum BMDDeckControlStatusFlags - Deck Control status flags */ + +[v1_enum] enum _BMDDeckControlStatusFlags { + bmdDeckControlStatusDeckConnected = 1 << 0, + bmdDeckControlStatusRemoteMode = 1 << 1, + bmdDeckControlStatusRecordInhibited = 1 << 2, + bmdDeckControlStatusCassetteOut = 1 << 3 +}; + +/* Enum BMDDeckControlExportModeOpsFlags - Export mode flags */ + +[v1_enum] enum _BMDDeckControlExportModeOpsFlags { + bmdDeckControlExportModeInsertVideo = 1 << 0, + bmdDeckControlExportModeInsertAudio1 = 1 << 1, + bmdDeckControlExportModeInsertAudio2 = 1 << 2, + bmdDeckControlExportModeInsertAudio3 = 1 << 3, + bmdDeckControlExportModeInsertAudio4 = 1 << 4, + bmdDeckControlExportModeInsertAudio5 = 1 << 5, + bmdDeckControlExportModeInsertAudio6 = 1 << 6, + bmdDeckControlExportModeInsertAudio7 = 1 << 7, + bmdDeckControlExportModeInsertAudio8 = 1 << 8, + bmdDeckControlExportModeInsertAudio9 = 1 << 9, + bmdDeckControlExportModeInsertAudio10 = 1 << 10, + bmdDeckControlExportModeInsertAudio11 = 1 << 11, + bmdDeckControlExportModeInsertAudio12 = 1 << 12, + bmdDeckControlExportModeInsertTimeCode = 1 << 13, + bmdDeckControlExportModeInsertAssemble = 1 << 14, + bmdDeckControlExportModeInsertPreview = 1 << 15, + bmdDeckControlUseManualExport = 1 << 16 +}; + +/* Enum BMDDeckControlError - Deck Control error */ + +typedef [v1_enum] enum _BMDDeckControlError { + bmdDeckControlNoError = /* 'noer' */ 0x6E6F6572, + bmdDeckControlModeError = /* 'moer' */ 0x6D6F6572, + bmdDeckControlMissedInPointError = /* 'mier' */ 0x6D696572, + bmdDeckControlDeckTimeoutError = /* 'dter' */ 0x64746572, + bmdDeckControlCommandFailedError = /* 'cfer' */ 0x63666572, + bmdDeckControlDeviceAlreadyOpenedError = /* 'dalo' */ 0x64616C6F, + bmdDeckControlFailedToOpenDeviceError = /* 'fder' */ 0x66646572, + bmdDeckControlInLocalModeError = /* 'lmer' */ 0x6C6D6572, + bmdDeckControlEndOfTapeError = /* 'eter' */ 0x65746572, + bmdDeckControlUserAbortError = /* 'uaer' */ 0x75616572, + bmdDeckControlNoTapeInDeckError = /* 'nter' */ 0x6E746572, + bmdDeckControlNoVideoFromCardError = /* 'nvfc' */ 0x6E766663, + bmdDeckControlNoCommunicationError = /* 'ncom' */ 0x6E636F6D, + bmdDeckControlBufferTooSmallError = /* 'btsm' */ 0x6274736D, + bmdDeckControlBadChecksumError = /* 'chks' */ 0x63686B73, + bmdDeckControlUnknownError = /* 'uner' */ 0x756E6572 +} BMDDeckControlError; + +// Forward Declarations + +interface IDeckLinkDeckControlStatusCallback; +interface IDeckLinkDeckControl; + +/* Interface IDeckLinkDeckControlStatusCallback - Deck control state change callback. */ + +[ + object, + uuid(53436FFB-B434-4906-BADC-AE3060FFE8EF), + helpstring("Deck control state change callback.") +] interface IDeckLinkDeckControlStatusCallback : IUnknown +{ + HRESULT TimecodeUpdate ([in] BMDTimecodeBCD currentTimecode); + HRESULT VTRControlStateChanged ([in] BMDDeckControlVTRControlState newState, [in] BMDDeckControlError error); + HRESULT DeckControlEventReceived ([in] BMDDeckControlEvent event, [in] BMDDeckControlError error); + HRESULT DeckControlStatusChanged ([in] BMDDeckControlStatusFlags flags, [in] unsigned int mask); +}; + +/* Interface IDeckLinkDeckControl - Deck Control main interface */ + +[ + object, + uuid(8E1C3ACE-19C7-4E00-8B92-D80431D958BE), + helpstring("Deck Control main interface") +] interface IDeckLinkDeckControl : IUnknown +{ + HRESULT Open ([in] BMDTimeScale timeScale, [in] BMDTimeValue timeValue, [in] BOOL timecodeIsDropFrame, [out] BMDDeckControlError* error); + HRESULT Close ([in] BOOL standbyOn); + HRESULT GetCurrentState ([out] BMDDeckControlMode* mode, [out] BMDDeckControlVTRControlState* vtrControlState, [out] BMDDeckControlStatusFlags* flags); + HRESULT SetStandby ([in] BOOL standbyOn); + HRESULT SendCommand ([in] unsigned char* inBuffer, [in] unsigned int inBufferSize, [out] unsigned char* outBuffer, [out] unsigned int* outDataSize, [in] unsigned int outBufferSize, [out] BMDDeckControlError* error); + HRESULT Play ([out] BMDDeckControlError* error); + HRESULT Stop ([out] BMDDeckControlError* error); + HRESULT TogglePlayStop ([out] BMDDeckControlError* error); + HRESULT Eject ([out] BMDDeckControlError* error); + HRESULT GoToTimecode ([in] BMDTimecodeBCD timecode, [out] BMDDeckControlError* error); + HRESULT FastForward ([in] BOOL viewTape, [out] BMDDeckControlError* error); + HRESULT Rewind ([in] BOOL viewTape, [out] BMDDeckControlError* error); + HRESULT StepForward ([out] BMDDeckControlError* error); + HRESULT StepBack ([out] BMDDeckControlError* error); + HRESULT Jog ([in] double rate, [out] BMDDeckControlError* error); + HRESULT Shuttle ([in] double rate, [out] BMDDeckControlError* error); + HRESULT GetTimecodeString ([out] BSTR* currentTimeCode, [out] BMDDeckControlError* error); + HRESULT GetTimecode ([out] IDeckLinkTimecode** currentTimecode, [out] BMDDeckControlError* error); + HRESULT GetTimecodeBCD ([out] BMDTimecodeBCD* currentTimecode, [out] BMDDeckControlError* error); + HRESULT SetPreroll ([in] unsigned int prerollSeconds); + HRESULT GetPreroll ([out] unsigned int* prerollSeconds); + HRESULT SetExportOffset ([in] int exportOffsetFields); + HRESULT GetExportOffset ([out] int* exportOffsetFields); + HRESULT GetManualExportOffset ([out] int* deckManualExportOffsetFields); + HRESULT SetCaptureOffset ([in] int captureOffsetFields); + HRESULT GetCaptureOffset ([out] int* captureOffsetFields); + HRESULT StartExport ([in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [in] BMDDeckControlExportModeOpsFlags exportModeOps, [out] BMDDeckControlError* error); + HRESULT StartCapture ([in] BOOL useVITC, [in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [out] BMDDeckControlError* error); + HRESULT GetDeviceID ([out] unsigned short* deviceId, [out] BMDDeckControlError* error); + HRESULT Abort (void); + HRESULT CrashRecordStart ([out] BMDDeckControlError* error); + HRESULT CrashRecordStop ([out] BMDDeckControlError* error); + HRESULT SetCallback ([in] IDeckLinkDeckControlStatusCallback* callback); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIDiscovery.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIDiscovery.idl new file mode 100644 index 0000000000..4ba8ae1817 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIDiscovery.idl @@ -0,0 +1,63 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +// Type Declarations + + +// Enumeration Mapping + +cpp_quote("#if 0") +cpp_quote("#endif") + +// Forward Declarations + +interface IDeckLink; + +/* Interface IDeckLink - Represents a DeckLink device */ + +[ + object, + uuid(C418FBDD-0587-48ED-8FE5-640F0A14AF91), + helpstring("Represents a DeckLink device") +] interface IDeckLink : IUnknown +{ + HRESULT GetModelName ([out] BSTR* modelName); + HRESULT GetDisplayName ([out] BSTR* displayName); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIModes.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIModes.idl new file mode 100644 index 0000000000..46b0fa21ff --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIModes.idl @@ -0,0 +1,270 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +// Type Declarations + + +// Enumeration Mapping + +cpp_quote("typedef unsigned int BMDDisplayModeFlags;") +cpp_quote("#if 0") +typedef enum _BMDDisplayModeFlags BMDDisplayModeFlags; +cpp_quote("#endif") + +/* Enum BMDDisplayMode - BMDDisplayMode enumerates the video modes supported. */ + +typedef [v1_enum] enum _BMDDisplayMode { + + /* SD Modes */ + + bmdModeNTSC = /* 'ntsc' */ 0x6E747363, + bmdModeNTSC2398 = /* 'nt23' */ 0x6E743233, // 3:2 pulldown + bmdModePAL = /* 'pal ' */ 0x70616C20, + bmdModeNTSCp = /* 'ntsp' */ 0x6E747370, + bmdModePALp = /* 'palp' */ 0x70616C70, + + /* HD 1080 Modes */ + + bmdModeHD1080p2398 = /* '23ps' */ 0x32337073, + bmdModeHD1080p24 = /* '24ps' */ 0x32347073, + bmdModeHD1080p25 = /* 'Hp25' */ 0x48703235, + bmdModeHD1080p2997 = /* 'Hp29' */ 0x48703239, + bmdModeHD1080p30 = /* 'Hp30' */ 0x48703330, + bmdModeHD1080p4795 = /* 'Hp47' */ 0x48703437, + bmdModeHD1080p48 = /* 'Hp48' */ 0x48703438, + bmdModeHD1080p50 = /* 'Hp50' */ 0x48703530, + bmdModeHD1080p5994 = /* 'Hp59' */ 0x48703539, + bmdModeHD1080p6000 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080p9590 = /* 'Hp95' */ 0x48703935, + bmdModeHD1080p96 = /* 'Hp96' */ 0x48703936, + bmdModeHD1080p100 = /* 'Hp10' */ 0x48703130, + bmdModeHD1080p11988 = /* 'Hp11' */ 0x48703131, + bmdModeHD1080p120 = /* 'Hp12' */ 0x48703132, + bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, + bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, + bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. + + /* HD 720 Modes */ + + bmdModeHD720p50 = /* 'hp50' */ 0x68703530, + bmdModeHD720p5994 = /* 'hp59' */ 0x68703539, + bmdModeHD720p60 = /* 'hp60' */ 0x68703630, + + /* 2K Modes */ + + bmdMode2k2398 = /* '2k23' */ 0x326B3233, + bmdMode2k24 = /* '2k24' */ 0x326B3234, + bmdMode2k25 = /* '2k25' */ 0x326B3235, + + /* 2K DCI Modes */ + + bmdMode2kDCI2398 = /* '2d23' */ 0x32643233, + bmdMode2kDCI24 = /* '2d24' */ 0x32643234, + bmdMode2kDCI25 = /* '2d25' */ 0x32643235, + bmdMode2kDCI2997 = /* '2d29' */ 0x32643239, + bmdMode2kDCI30 = /* '2d30' */ 0x32643330, + bmdMode2kDCI4795 = /* '2d47' */ 0x32643437, + bmdMode2kDCI48 = /* '2d48' */ 0x32643438, + bmdMode2kDCI50 = /* '2d50' */ 0x32643530, + bmdMode2kDCI5994 = /* '2d59' */ 0x32643539, + bmdMode2kDCI60 = /* '2d60' */ 0x32643630, + bmdMode2kDCI9590 = /* '2d95' */ 0x32643935, + bmdMode2kDCI96 = /* '2d96' */ 0x32643936, + bmdMode2kDCI100 = /* '2d10' */ 0x32643130, + bmdMode2kDCI11988 = /* '2d11' */ 0x32643131, + bmdMode2kDCI120 = /* '2d12' */ 0x32643132, + + /* 4K UHD Modes */ + + bmdMode4K2160p2398 = /* '4k23' */ 0x346B3233, + bmdMode4K2160p24 = /* '4k24' */ 0x346B3234, + bmdMode4K2160p25 = /* '4k25' */ 0x346B3235, + bmdMode4K2160p2997 = /* '4k29' */ 0x346B3239, + bmdMode4K2160p30 = /* '4k30' */ 0x346B3330, + bmdMode4K2160p4795 = /* '4k47' */ 0x346B3437, + bmdMode4K2160p48 = /* '4k48' */ 0x346B3438, + bmdMode4K2160p50 = /* '4k50' */ 0x346B3530, + bmdMode4K2160p5994 = /* '4k59' */ 0x346B3539, + bmdMode4K2160p60 = /* '4k60' */ 0x346B3630, + bmdMode4K2160p9590 = /* '4k95' */ 0x346B3935, + bmdMode4K2160p96 = /* '4k96' */ 0x346B3936, + bmdMode4K2160p100 = /* '4k10' */ 0x346B3130, + bmdMode4K2160p11988 = /* '4k11' */ 0x346B3131, + bmdMode4K2160p120 = /* '4k12' */ 0x346B3132, + + /* 4K DCI Modes */ + + bmdMode4kDCI2398 = /* '4d23' */ 0x34643233, + bmdMode4kDCI24 = /* '4d24' */ 0x34643234, + bmdMode4kDCI25 = /* '4d25' */ 0x34643235, + bmdMode4kDCI2997 = /* '4d29' */ 0x34643239, + bmdMode4kDCI30 = /* '4d30' */ 0x34643330, + bmdMode4kDCI4795 = /* '4d47' */ 0x34643437, + bmdMode4kDCI48 = /* '4d48' */ 0x34643438, + bmdMode4kDCI50 = /* '4d50' */ 0x34643530, + bmdMode4kDCI5994 = /* '4d59' */ 0x34643539, + bmdMode4kDCI60 = /* '4d60' */ 0x34643630, + bmdMode4kDCI9590 = /* '4d95' */ 0x34643935, + bmdMode4kDCI96 = /* '4d96' */ 0x34643936, + bmdMode4kDCI100 = /* '4d10' */ 0x34643130, + bmdMode4kDCI11988 = /* '4d11' */ 0x34643131, + bmdMode4kDCI120 = /* '4d12' */ 0x34643132, + + /* 8K UHD Modes */ + + bmdMode8K4320p2398 = /* '8k23' */ 0x386B3233, + bmdMode8K4320p24 = /* '8k24' */ 0x386B3234, + bmdMode8K4320p25 = /* '8k25' */ 0x386B3235, + bmdMode8K4320p2997 = /* '8k29' */ 0x386B3239, + bmdMode8K4320p30 = /* '8k30' */ 0x386B3330, + bmdMode8K4320p4795 = /* '8k47' */ 0x386B3437, + bmdMode8K4320p48 = /* '8k48' */ 0x386B3438, + bmdMode8K4320p50 = /* '8k50' */ 0x386B3530, + bmdMode8K4320p5994 = /* '8k59' */ 0x386B3539, + bmdMode8K4320p60 = /* '8k60' */ 0x386B3630, + + /* 8K DCI Modes */ + + bmdMode8kDCI2398 = /* '8d23' */ 0x38643233, + bmdMode8kDCI24 = /* '8d24' */ 0x38643234, + bmdMode8kDCI25 = /* '8d25' */ 0x38643235, + bmdMode8kDCI2997 = /* '8d29' */ 0x38643239, + bmdMode8kDCI30 = /* '8d30' */ 0x38643330, + bmdMode8kDCI4795 = /* '8d47' */ 0x38643437, + bmdMode8kDCI48 = /* '8d48' */ 0x38643438, + bmdMode8kDCI50 = /* '8d50' */ 0x38643530, + bmdMode8kDCI5994 = /* '8d59' */ 0x38643539, + bmdMode8kDCI60 = /* '8d60' */ 0x38643630, + + /* PC Modes */ + + bmdMode640x480p60 = /* 'vga6' */ 0x76676136, + bmdMode800x600p60 = /* 'svg6' */ 0x73766736, + bmdMode1440x900p50 = /* 'wxg5' */ 0x77786735, + bmdMode1440x900p60 = /* 'wxg6' */ 0x77786736, + bmdMode1440x1080p50 = /* 'sxg5' */ 0x73786735, + bmdMode1440x1080p60 = /* 'sxg6' */ 0x73786736, + bmdMode1600x1200p50 = /* 'uxg5' */ 0x75786735, + bmdMode1600x1200p60 = /* 'uxg6' */ 0x75786736, + bmdMode1920x1200p50 = /* 'wux5' */ 0x77757835, + bmdMode1920x1200p60 = /* 'wux6' */ 0x77757836, + bmdMode1920x1440p50 = /* '1945' */ 0x31393435, + bmdMode1920x1440p60 = /* '1946' */ 0x31393436, + bmdMode2560x1440p50 = /* 'wqh5' */ 0x77716835, + bmdMode2560x1440p60 = /* 'wqh6' */ 0x77716836, + bmdMode2560x1600p50 = /* 'wqx5' */ 0x77717835, + bmdMode2560x1600p60 = /* 'wqx6' */ 0x77717836, + + /* Special Modes */ + + bmdModeUnknown = /* 'iunk' */ 0x69756E6B +} BMDDisplayMode; + +/* Enum BMDFieldDominance - BMDFieldDominance enumerates settings applicable to video fields. */ + +typedef [v1_enum] enum _BMDFieldDominance { + bmdUnknownFieldDominance = 0, + bmdLowerFieldFirst = /* 'lowr' */ 0x6C6F7772, + bmdUpperFieldFirst = /* 'uppr' */ 0x75707072, + bmdProgressiveFrame = /* 'prog' */ 0x70726F67, + bmdProgressiveSegmentedFrame = /* 'psf ' */ 0x70736620 +} BMDFieldDominance; + +/* Enum BMDPixelFormat - Video pixel formats supported for output/input */ + +typedef [v1_enum] enum _BMDPixelFormat { + bmdFormatUnspecified = 0, + bmdFormat8BitYUV = /* '2vuy' */ 0x32767579, + bmdFormat10BitYUV = /* 'v210' */ 0x76323130, + bmdFormat8BitARGB = 32, + bmdFormat8BitBGRA = /* 'BGRA' */ 0x42475241, + bmdFormat10BitRGB = /* 'r210' */ 0x72323130, // Big-endian RGB 10-bit per component with SMPTE video levels (64-960). Packed as 2:10:10:10 + bmdFormat12BitRGB = /* 'R12B' */ 0x52313242, // Big-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component + bmdFormat12BitRGBLE = /* 'R12L' */ 0x5231324C, // Little-endian RGB 12-bit per component with full range (0-4095). Packed as 12-bit per component + bmdFormat10BitRGBXLE = /* 'R10l' */ 0x5231306C, // Little-endian 10-bit RGB with SMPTE video levels (64-940) + bmdFormat10BitRGBX = /* 'R10b' */ 0x52313062, // Big-endian 10-bit RGB with SMPTE video levels (64-940) + bmdFormatH265 = /* 'hev1' */ 0x68657631, // High Efficiency Video Coding (HEVC/h.265) + + /* AVID DNxHR */ + + bmdFormatDNxHR = /* 'AVdh' */ 0x41566468 +} BMDPixelFormat; + +/* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */ + +[v1_enum] enum _BMDDisplayModeFlags { + bmdDisplayModeSupports3D = 1 << 0, + bmdDisplayModeColorspaceRec601 = 1 << 1, + bmdDisplayModeColorspaceRec709 = 1 << 2, + bmdDisplayModeColorspaceRec2020 = 1 << 3 +}; + +// Forward Declarations + +interface IDeckLinkDisplayModeIterator; +interface IDeckLinkDisplayMode; + +/* Interface IDeckLinkDisplayModeIterator - Enumerates over supported input/output display modes. */ + +[ + object, + uuid(9C88499F-F601-4021-B80B-032E4EB41C35), + helpstring("Enumerates over supported input/output display modes.") +] interface IDeckLinkDisplayModeIterator : IUnknown +{ + HRESULT Next ([out] IDeckLinkDisplayMode** deckLinkDisplayMode); +}; + +/* Interface IDeckLinkDisplayMode - Represents a display mode */ + +[ + object, + uuid(3EB2C1AB-0A3D-4523-A3AD-F40D7FB14E78), + helpstring("Represents a display mode") +] interface IDeckLinkDisplayMode : IUnknown +{ + HRESULT GetName ([out] BSTR* name); + BMDDisplayMode GetDisplayMode (void); + long GetWidth (void); + long GetHeight (void); + HRESULT GetFrameRate ([out] BMDTimeValue* frameDuration, [out] BMDTimeScale* timeScale); + BMDFieldDominance GetFieldDominance (void); + BMDDisplayModeFlags GetFlags (void); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIStreaming.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIStreaming.idl new file mode 100644 index 0000000000..066ce17750 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIStreaming.idl @@ -0,0 +1,362 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +// Type Declarations + + +// Enumeration Mapping + +cpp_quote("#if 0") +cpp_quote("#endif") + +/* Enum BMDStreamingDeviceMode - Device modes */ + +typedef [v1_enum] enum _BMDStreamingDeviceMode { + bmdStreamingDeviceIdle = /* 'idle' */ 0x69646C65, + bmdStreamingDeviceEncoding = /* 'enco' */ 0x656E636F, + bmdStreamingDeviceStopping = /* 'stop' */ 0x73746F70, + bmdStreamingDeviceUnknown = /* 'munk' */ 0x6D756E6B +} BMDStreamingDeviceMode; + +/* Enum BMDStreamingEncodingFrameRate - Encoded frame rates */ + +typedef [v1_enum] enum _BMDStreamingEncodingFrameRate { + + /* Interlaced rates */ + + bmdStreamingEncodedFrameRate50i = /* 'e50i' */ 0x65353069, + bmdStreamingEncodedFrameRate5994i = /* 'e59i' */ 0x65353969, + bmdStreamingEncodedFrameRate60i = /* 'e60i' */ 0x65363069, + + /* Progressive rates */ + + bmdStreamingEncodedFrameRate2398p = /* 'e23p' */ 0x65323370, + bmdStreamingEncodedFrameRate24p = /* 'e24p' */ 0x65323470, + bmdStreamingEncodedFrameRate25p = /* 'e25p' */ 0x65323570, + bmdStreamingEncodedFrameRate2997p = /* 'e29p' */ 0x65323970, + bmdStreamingEncodedFrameRate30p = /* 'e30p' */ 0x65333070, + bmdStreamingEncodedFrameRate50p = /* 'e50p' */ 0x65353070, + bmdStreamingEncodedFrameRate5994p = /* 'e59p' */ 0x65353970, + bmdStreamingEncodedFrameRate60p = /* 'e60p' */ 0x65363070 +} BMDStreamingEncodingFrameRate; + +/* Enum BMDStreamingEncodingSupport - Output encoding mode supported flag */ + +typedef [v1_enum] enum _BMDStreamingEncodingSupport { + bmdStreamingEncodingModeNotSupported = 0, + bmdStreamingEncodingModeSupported, + bmdStreamingEncodingModeSupportedWithChanges +} BMDStreamingEncodingSupport; + +/* Enum BMDStreamingVideoCodec - Video codecs */ + +typedef [v1_enum] enum _BMDStreamingVideoCodec { + bmdStreamingVideoCodecH264 = /* 'H264' */ 0x48323634 +} BMDStreamingVideoCodec; + +/* Enum BMDStreamingH264Profile - H264 encoding profile */ + +typedef [v1_enum] enum _BMDStreamingH264Profile { + bmdStreamingH264ProfileHigh = /* 'high' */ 0x68696768, + bmdStreamingH264ProfileMain = /* 'main' */ 0x6D61696E, + bmdStreamingH264ProfileBaseline = /* 'base' */ 0x62617365 +} BMDStreamingH264Profile; + +/* Enum BMDStreamingH264Level - H264 encoding level */ + +typedef [v1_enum] enum _BMDStreamingH264Level { + bmdStreamingH264Level12 = /* 'lv12' */ 0x6C763132, + bmdStreamingH264Level13 = /* 'lv13' */ 0x6C763133, + bmdStreamingH264Level2 = /* 'lv2 ' */ 0x6C763220, + bmdStreamingH264Level21 = /* 'lv21' */ 0x6C763231, + bmdStreamingH264Level22 = /* 'lv22' */ 0x6C763232, + bmdStreamingH264Level3 = /* 'lv3 ' */ 0x6C763320, + bmdStreamingH264Level31 = /* 'lv31' */ 0x6C763331, + bmdStreamingH264Level32 = /* 'lv32' */ 0x6C763332, + bmdStreamingH264Level4 = /* 'lv4 ' */ 0x6C763420, + bmdStreamingH264Level41 = /* 'lv41' */ 0x6C763431, + bmdStreamingH264Level42 = /* 'lv42' */ 0x6C763432 +} BMDStreamingH264Level; + +/* Enum BMDStreamingH264EntropyCoding - H264 entropy coding */ + +typedef [v1_enum] enum _BMDStreamingH264EntropyCoding { + bmdStreamingH264EntropyCodingCAVLC = /* 'EVLC' */ 0x45564C43, + bmdStreamingH264EntropyCodingCABAC = /* 'EBAC' */ 0x45424143 +} BMDStreamingH264EntropyCoding; + +/* Enum BMDStreamingAudioCodec - Audio codecs */ + +typedef [v1_enum] enum _BMDStreamingAudioCodec { + bmdStreamingAudioCodecAAC = /* 'AAC ' */ 0x41414320 +} BMDStreamingAudioCodec; + +/* Enum BMDStreamingEncodingModePropertyID - Encoding mode properties */ + +typedef [v1_enum] enum _BMDStreamingEncodingModePropertyID { + + /* Integers, Video Properties */ + + bmdStreamingEncodingPropertyVideoFrameRate = /* 'vfrt' */ 0x76667274, // Uses values of type BMDStreamingEncodingFrameRate + bmdStreamingEncodingPropertyVideoBitRateKbps = /* 'vbrt' */ 0x76627274, + + /* Integers, H264 Properties */ + + bmdStreamingEncodingPropertyH264Profile = /* 'hprf' */ 0x68707266, + bmdStreamingEncodingPropertyH264Level = /* 'hlvl' */ 0x686C766C, + bmdStreamingEncodingPropertyH264EntropyCoding = /* 'hent' */ 0x68656E74, + + /* Flags, H264 Properties */ + + bmdStreamingEncodingPropertyH264HasBFrames = /* 'hBfr' */ 0x68426672, + + /* Integers, Audio Properties */ + + bmdStreamingEncodingPropertyAudioCodec = /* 'acdc' */ 0x61636463, + bmdStreamingEncodingPropertyAudioSampleRate = /* 'asrt' */ 0x61737274, + bmdStreamingEncodingPropertyAudioChannelCount = /* 'achc' */ 0x61636863, + bmdStreamingEncodingPropertyAudioBitRateKbps = /* 'abrt' */ 0x61627274 +} BMDStreamingEncodingModePropertyID; + +// Forward Declarations + +interface IBMDStreamingDeviceNotificationCallback; +interface IBMDStreamingH264InputCallback; +interface IBMDStreamingDiscovery; +interface IBMDStreamingVideoEncodingMode; +interface IBMDStreamingMutableVideoEncodingMode; +interface IBMDStreamingVideoEncodingModePresetIterator; +interface IBMDStreamingDeviceInput; +interface IBMDStreamingH264NALPacket; +interface IBMDStreamingAudioPacket; +interface IBMDStreamingMPEG2TSPacket; +interface IBMDStreamingH264NALParser; + +/* Interface IBMDStreamingDeviceNotificationCallback - Device notification callbacks. */ + +[ + object, + uuid(F9531D64-3305-4B29-A387-7F74BB0D0E84), + helpstring("Device notification callbacks.") +] interface IBMDStreamingDeviceNotificationCallback : IUnknown +{ + HRESULT StreamingDeviceArrived ([in] IDeckLink* device); + HRESULT StreamingDeviceRemoved ([in] IDeckLink* device); + HRESULT StreamingDeviceModeChanged ([in] IDeckLink* device, [in] BMDStreamingDeviceMode mode); +}; + +/* Interface IBMDStreamingH264InputCallback - H264 input callbacks. */ + +[ + object, + uuid(823C475F-55AE-46F9-890C-537CC5CEDCCA), + helpstring("H264 input callbacks.") +] interface IBMDStreamingH264InputCallback : IUnknown +{ + HRESULT H264NALPacketArrived ([in] IBMDStreamingH264NALPacket* nalPacket); + HRESULT H264AudioPacketArrived ([in] IBMDStreamingAudioPacket* audioPacket); + HRESULT MPEG2TSPacketArrived ([in] IBMDStreamingMPEG2TSPacket* tsPacket); + HRESULT H264VideoInputConnectorScanningChanged (void); + HRESULT H264VideoInputConnectorChanged (void); + HRESULT H264VideoInputModeChanged (void); +}; + +/* Interface IBMDStreamingDiscovery - Installs device notifications */ + +[ + object, + uuid(2C837444-F989-4D87-901A-47C8A36D096D), + helpstring("Installs device notifications") +] interface IBMDStreamingDiscovery : IUnknown +{ + HRESULT InstallDeviceNotifications ([in] IBMDStreamingDeviceNotificationCallback* theCallback); + HRESULT UninstallDeviceNotifications (void); +}; + +/* Interface IBMDStreamingVideoEncodingMode - Represents an encoded video mode. */ + +[ + object, + uuid(1AB8035B-CD13-458D-B6DF-5E8F7C2141D9), + helpstring("Represents an encoded video mode.") +] interface IBMDStreamingVideoEncodingMode : IUnknown +{ + HRESULT GetName ([out] BSTR* name); + unsigned int GetPresetID (void); + unsigned int GetSourcePositionX (void); + unsigned int GetSourcePositionY (void); + unsigned int GetSourceWidth (void); + unsigned int GetSourceHeight (void); + unsigned int GetDestWidth (void); + unsigned int GetDestHeight (void); + HRESULT GetFlag ([in] BMDStreamingEncodingModePropertyID cfgID, [out] BOOL* value); + HRESULT GetInt ([in] BMDStreamingEncodingModePropertyID cfgID, [out] LONGLONG* value); + HRESULT GetFloat ([in] BMDStreamingEncodingModePropertyID cfgID, [out] double* value); + HRESULT GetString ([in] BMDStreamingEncodingModePropertyID cfgID, [out] BSTR* value); + HRESULT CreateMutableVideoEncodingMode ([out] IBMDStreamingMutableVideoEncodingMode** newEncodingMode); // Creates a mutable copy of the encoding mode +}; + +/* Interface IBMDStreamingMutableVideoEncodingMode - Represents a mutable encoded video mode. */ + +[ + object, + uuid(19BF7D90-1E0A-400D-B2C6-FFC4E78AD49D), + helpstring("Represents a mutable encoded video mode.") +] interface IBMDStreamingMutableVideoEncodingMode : IBMDStreamingVideoEncodingMode +{ + HRESULT SetSourceRect ([in] unsigned int posX, [in] unsigned int posY, [in] unsigned int width, [in] unsigned int height); + HRESULT SetDestSize ([in] unsigned int width, [in] unsigned int height); + HRESULT SetFlag ([in] BMDStreamingEncodingModePropertyID cfgID, [in] BOOL value); + HRESULT SetInt ([in] BMDStreamingEncodingModePropertyID cfgID, [in] LONGLONG value); + HRESULT SetFloat ([in] BMDStreamingEncodingModePropertyID cfgID, [in] double value); + HRESULT SetString ([in] BMDStreamingEncodingModePropertyID cfgID, [in] BSTR value); +}; + +/* Interface IBMDStreamingVideoEncodingModePresetIterator - Enumerates encoding mode presets */ + +[ + object, + uuid(7AC731A3-C950-4AD0-804A-8377AA51C6C4), + helpstring("Enumerates encoding mode presets") +] interface IBMDStreamingVideoEncodingModePresetIterator : IUnknown +{ + HRESULT Next ([out] IBMDStreamingVideoEncodingMode** videoEncodingMode); +}; + +/* Interface IBMDStreamingDeviceInput - Created by QueryInterface from IDeckLink */ + +[ + object, + uuid(24B6B6EC-1727-44BB-9818-34FF086ACF98), + helpstring("Created by QueryInterface from IDeckLink") +] interface IBMDStreamingDeviceInput : IUnknown +{ + + /* Input modes */ + + HRESULT DoesSupportVideoInputMode ([in] BMDDisplayMode inputMode, [out] BOOL* result); + HRESULT GetVideoInputModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + HRESULT SetVideoInputMode ([in] BMDDisplayMode inputMode); + HRESULT GetCurrentDetectedVideoInputMode ([out] BMDDisplayMode* detectedMode); + + /* Capture modes */ + + HRESULT GetVideoEncodingMode ([out] IBMDStreamingVideoEncodingMode** encodingMode); + HRESULT GetVideoEncodingModePresetIterator ([in] BMDDisplayMode inputMode, [out] IBMDStreamingVideoEncodingModePresetIterator** iterator); + HRESULT DoesSupportVideoEncodingMode ([in] BMDDisplayMode inputMode, [in] IBMDStreamingVideoEncodingMode* encodingMode, [out] BMDStreamingEncodingSupport* result, [out] IBMDStreamingVideoEncodingMode** changedEncodingMode); + HRESULT SetVideoEncodingMode ([in] IBMDStreamingVideoEncodingMode* encodingMode); + + /* Input control */ + + HRESULT StartCapture (void); + HRESULT StopCapture (void); + HRESULT SetCallback ([in] IUnknown* theCallback); +}; + +/* Interface IBMDStreamingH264NALPacket - Represent an H.264 NAL packet */ + +[ + object, + uuid(E260E955-14BE-4395-9775-9F02CC0A9D89), + helpstring("Represent an H.264 NAL packet") +] interface IBMDStreamingH264NALPacket : IUnknown +{ + long GetPayloadSize (void); + HRESULT GetBytes ([out] void** buffer); + HRESULT GetBytesWithSizePrefix ([out] void** buffer); // Contains a 32-bit unsigned big endian size prefix + HRESULT GetDisplayTime ([in] ULONGLONG requestedTimeScale, [out] ULONGLONG* displayTime); + HRESULT GetPacketIndex ([out] unsigned int* packetIndex); // Deprecated +}; + +/* Interface IBMDStreamingAudioPacket - Represents a chunk of audio data */ + +[ + object, + uuid(D9EB5902-1AD2-43F4-9E2C-3CFA50B5EE19), + helpstring("Represents a chunk of audio data") +] interface IBMDStreamingAudioPacket : IUnknown +{ + BMDStreamingAudioCodec GetCodec (void); + long GetPayloadSize (void); + HRESULT GetBytes ([out] void** buffer); + HRESULT GetPlayTime ([in] ULONGLONG requestedTimeScale, [out] ULONGLONG* playTime); + HRESULT GetPacketIndex ([out] unsigned int* packetIndex); // Deprecated +}; + +/* Interface IBMDStreamingMPEG2TSPacket - Represent an MPEG2 Transport Stream packet */ + +[ + object, + uuid(91810D1C-4FB3-4AAA-AE56-FA301D3DFA4C), + helpstring("Represent an MPEG2 Transport Stream packet") +] interface IBMDStreamingMPEG2TSPacket : IUnknown +{ + long GetPayloadSize (void); + HRESULT GetBytes ([out] void** buffer); +}; + +/* Interface IBMDStreamingH264NALParser - For basic NAL parsing */ + +[ + object, + uuid(5867F18C-5BFA-4CCC-B2A7-9DFD140417D2), + helpstring("For basic NAL parsing") +] interface IBMDStreamingH264NALParser : IUnknown +{ + HRESULT IsNALSequenceParameterSet ([in] IBMDStreamingH264NALPacket* nal); + HRESULT IsNALPictureParameterSet ([in] IBMDStreamingH264NALPacket* nal); + HRESULT GetProfileAndLevelFromSPS ([in] IBMDStreamingH264NALPacket* nal, [out] unsigned int* profileIdc, [out] unsigned int* profileCompatability, [out] unsigned int* levelIdc); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(23A4EDF5-A0E5-432C-94EF-3BABB5F81C82), + helpstring("CBMDStreamingDiscovery Class") +] coclass CBMDStreamingDiscovery +{ + [default] interface IBMDStreamingDiscovery; +}; + +[ + uuid(7753EFBD-951C-407C-97A5-23C737B73B52), + helpstring("CBMDStreamingH264NALParser Class") +] coclass CBMDStreamingH264NALParser +{ + [default] interface IBMDStreamingH264NALParser; +}; + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIStreaming_v10_8.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIStreaming_v10_8.idl new file mode 100644 index 0000000000..1a63027081 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIStreaming_v10_8.idl @@ -0,0 +1,53 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + + + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(0CAA31F6-8A26-40B0-86A4-BF58DCCA710C), + helpstring("CBMDStreamingDiscovery Class") +] coclass CBMDStreamingDiscovery_v10_8 +{ + [default] interface IBMDStreamingDiscovery; +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPITypes.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPITypes.idl new file mode 100644 index 0000000000..d0a05313b7 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPITypes.idl @@ -0,0 +1,114 @@ +/* -LICENSE-START- +** Copyright (c) 2022 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_CONST + #if defined(_MSC_VER) + #define BMD_CONST __declspec(selectany) static const + #else + #define BMD_CONST static const + #endif +#endif + +// Type Declarations + +typedef LONGLONG BMDTimeValue; +typedef LONGLONG BMDTimeScale; +typedef unsigned int BMDTimecodeBCD; +typedef unsigned int BMDTimecodeUserBits; + +// Enumeration Mapping + +cpp_quote("typedef unsigned int BMDTimecodeFlags;") +cpp_quote("#if 0") +typedef enum _BMDTimecodeFlags BMDTimecodeFlags; +cpp_quote("#endif") + +/* Enum BMDTimecodeFlags - Timecode flags */ + +[v1_enum] enum _BMDTimecodeFlags { + bmdTimecodeFlagDefault = 0, + bmdTimecodeIsDropFrame = 1 << 0, + bmdTimecodeFieldMark = 1 << 1, + bmdTimecodeColorFrame = 1 << 2, + bmdTimecodeEmbedRecordingTrigger = 1 << 3, // On SDI recording trigger utilises a user-bit. + bmdTimecodeRecordingTriggered = 1 << 4 +}; + +/* Enum BMDVideoConnection - Video connection types */ + +typedef [v1_enum] enum _BMDVideoConnection { + bmdVideoConnectionUnspecified = 0, + bmdVideoConnectionSDI = 1 << 0, + bmdVideoConnectionHDMI = 1 << 1, + bmdVideoConnectionOpticalSDI = 1 << 2, + bmdVideoConnectionComponent = 1 << 3, + bmdVideoConnectionComposite = 1 << 4, + bmdVideoConnectionSVideo = 1 << 5 +} BMDVideoConnection; + +/* Enum BMDAudioConnection - Audio connection types */ + +typedef [v1_enum] enum _BMDAudioConnection { + bmdAudioConnectionEmbedded = 1 << 0, + bmdAudioConnectionAESEBU = 1 << 1, + bmdAudioConnectionAnalog = 1 << 2, + bmdAudioConnectionAnalogXLR = 1 << 3, + bmdAudioConnectionAnalogRCA = 1 << 4, + bmdAudioConnectionMicrophone = 1 << 5, + bmdAudioConnectionHeadphones = 1 << 6 +} BMDAudioConnection; + +/* Enum BMDDeckControlConnection - Deck control connections */ + +typedef [v1_enum] enum _BMDDeckControlConnection { + bmdDeckControlConnectionRS422Remote1 = 1 << 0, + bmdDeckControlConnectionRS422Remote2 = 1 << 1 +} BMDDeckControlConnection; + +// Forward Declarations + +interface IDeckLinkTimecode; + +/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ + +[ + object, + uuid(BC6CFBD3-8317-4325-AC1C-1216391E9340), + helpstring("Used for video frame timecode representation.") +] interface IDeckLinkTimecode : IUnknown +{ + BMDTimecodeBCD GetBCD (void); + HRESULT GetComponents ([out] unsigned char* hours, [out] unsigned char* minutes, [out] unsigned char* seconds, [out] unsigned char* frames); + HRESULT GetString ([out] BSTR* timecode); + BMDTimecodeFlags GetFlags (void); + HRESULT GetTimecodeUserBits ([out] BMDTimecodeUserBits* userBits); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIVersion.h b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIVersion.h new file mode 100644 index 0000000000..679ef92584 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPIVersion.h @@ -0,0 +1,50 @@ +/* -LICENSE-START- + * ** Copyright (c) 2014 Blackmagic Design + * ** + * ** Permission is hereby granted, free of charge, to any person or organization + * ** obtaining a copy of the software and accompanying documentation (the + * ** "Software") to use, reproduce, display, distribute, sub-license, execute, + * ** and transmit the Software, and to prepare derivative works of the Software, + * ** and to permit third-parties to whom the Software is furnished to do so, in + * ** accordance with: + * ** + * ** (1) if the Software is obtained from Blackmagic Design, the End User License + * ** Agreement for the Software Development Kit (“EULA”) available at + * ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or + * ** + * ** (2) if the Software is obtained from any third party, such licensing terms + * ** as notified by that third party, + * ** + * ** and all subject to the following: + * ** + * ** (3) the copyright notices in the Software and this entire statement, + * ** including the above license grant, this restriction and the following + * ** disclaimer, must be included in all copies of the Software, in whole or in + * ** part, and all derivative works of the Software, unless such copies or + * ** derivative works are solely in the form of machine-executable object code + * ** generated by a source language processor. + * ** + * ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * ** DEALINGS IN THE SOFTWARE. + * ** + * ** A copy of the Software is available free of charge at + * ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. + * ** + * ** -LICENSE-END- + * */ + +/* DeckLinkAPIVersion.h */ + +#ifndef __DeckLink_API_Version_h__ +#define __DeckLink_API_Version_h__ + +#define BLACKMAGIC_DECKLINK_API_VERSION 0x0c040200 +#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "12.4.2" + +#endif // __DeckLink_API_Version_h__ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_11.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_11.idl new file mode 100644 index 0000000000..8b3317ab1d --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_11.idl @@ -0,0 +1,302 @@ +/* -LICENSE-START- +** Copyright (c) 2018 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_11.idl */ + +// Enumeration Mapping + +/* Enum BMDDisplayModeSupport_v10_11 - Output mode supported flags */ + +typedef [v1_enum] enum _BMDDisplayModeSupport_v10_11 { + bmdDisplayModeNotSupported_v10_11 = 0, + bmdDisplayModeSupported_v10_11, + bmdDisplayModeSupportedWithConversion_v10_11 +} BMDDisplayModeSupport_v10_11; + +/* Enum BMDDuplexMode - Duplex for configurable ports */ + +typedef [v1_enum] enum _BMDDuplexMode_v10_11 { + bmdDuplexModeFull_v10_11 = /* 'fdup' */ 0x66647570, + bmdDuplexModeHalf_v10_11 = /* 'hdup' */ 0x68647570 +} BMDDuplexMode_v10_11; + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkConfigurationID_v10_11 { + + /* Video Input/Output Integers */ + + bmdDeckLinkConfigDuplexMode_v10_11 = /* 'dupx' */ 0x64757078, + +} BMDDeckLinkConfigurationID_v10_11; + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef [v1_enum] enum _BMDDeckLinkAttributeID_v10_11 { + + /* Flags */ + + BMDDeckLinkSupportsDuplexModeConfiguration_v10_11 = /* 'dupx' */ 0x64757078, + BMDDeckLinkSupportsHDKeying_v10_11 = /* 'keyh' */ 0x6B657968, + + /* Integers */ + + BMDDeckLinkPairedDevicePersistentID_v10_11 = /* 'ppid' */ 0x70706964, + BMDDeckLinkSupportsFullDuplex_v10_11 = /* 'fdup' */ 0x66647570, + +} BMDDeckLinkAttributeID_v10_11; + +typedef [v1_enum] enum _BMDDeckLinkStatusID_v10_11 { + bmdDeckLinkStatusDuplexMode_v10_11 = /* 'dupx' */ 0x64757078, +} BMDDeckLinkStatusID_v10_11; + +/* Enum BMDDuplexStatus - Duplex status of the device */ + +typedef [v1_enum] enum _BMDDuplexStatus_v10_11 { + bmdDuplexFullDuplex_v10_11 = /* 'fdup' */ 0x66647570, + bmdDuplexHalfDuplex_v10_11 = /* 'hdup' */ 0x68647570, + bmdDuplexSimplex_v10_11 = /* 'splx' */ 0x73706C78, + bmdDuplexInactive_v10_11 = /* 'inac' */ 0x696E6163 +} BMDDuplexStatus_v10_11; + +// Forward Declarations + +interface IDeckLinkConfiguration_v10_11; +interface IDeckLinkAttributes_v10_11; +interface IDeckLinkNotification_v10_11; + +/* Interface IDeckLinkConfiguration_v10_11 - DeckLink Configuration interface */ + +[ + object, + uuid(EF90380B-4AE5-4346-9077-E288E149F129), + local, + helpstring("DeckLink Configuration interface") +] interface IDeckLinkConfiguration_v10_11 : IUnknown +{ + HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value); + HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value); + HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value); + HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value); + HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value); + HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value); + HRESULT WriteConfigurationToPreferences(void); +}; + +/* Interface IDeckLinkAttributes_v10_11 - DeckLink Attribute interface */ + +[ + object, + uuid(ABC11843-D966-44CB-96E2-A1CB5D3135C4), + local, + helpstring("DeckLink Attribute interface") +] interface IDeckLinkAttributes_v10_11 : IUnknown +{ + HRESULT GetFlag([in] BMDDeckLinkAttributeID cfgID, [out] BOOL *value); + HRESULT GetInt([in] BMDDeckLinkAttributeID cfgID, [out] LONGLONG *value); + HRESULT GetFloat([in] BMDDeckLinkAttributeID cfgID, [out] double *value); + HRESULT GetString([in] BMDDeckLinkAttributeID cfgID, [out] BSTR *value); +}; + +/* Interface IDeckLinkOutput_v10_11 - DeckLink output interface. */ + +[ + object, + uuid(CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput_v10_11 : IUnknown +{ + HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoOutputFlags flags, [out] BMDDisplayModeSupport_v10_11 *result, [out] IDeckLinkDisplayMode **resultDisplayMode); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback); + + /* Video Output */ + + HRESULT EnableVideoOutput([in] BMDDisplayMode displayMode, [in] BMDVideoOutputFlags flags); + HRESULT DisableVideoOutput(void); + + HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); + HRESULT CreateVideoFrame([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame); + HRESULT CreateAncillaryData([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer); + + HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame); + HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback); + HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount); + + /* Audio Output */ + + HRESULT EnableAudioOutput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount, [in] BMDAudioOutputStreamType streamType); + HRESULT DisableAudioOutput(void); + + HRESULT WriteAudioSamplesSync([in] void *buffer, [in] unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten); + + HRESULT BeginAudioPreroll(void); + HRESULT EndAudioPreroll(void); + HRESULT ScheduleAudioSamples([in] void *buffer, [in] unsigned int sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten); + + HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount); + HRESULT FlushBufferedAudioSamples(void); + + HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback); + + /* Output Control */ + + HRESULT StartScheduledPlayback([in] BMDTimeValue playbackStartTime, [in] BMDTimeScale timeScale, [in] double playbackSpeed); + HRESULT StopScheduledPlayback([in] BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, [in] BMDTimeScale timeScale); + HRESULT IsScheduledPlaybackRunning([out] BOOL *active); + HRESULT GetScheduledStreamTime([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed); + HRESULT GetReferenceStatus([out] BMDReferenceStatus *referenceStatus); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); + HRESULT GetFrameCompletionReferenceTimestamp([in] IDeckLinkVideoFrame *theFrame, [in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *frameCompletionTimestamp); +}; + +/* Interface IDeckLinkInput_v10_11 - DeckLink input interface. */ + +[ + object, + uuid(AF22762B-DFAC-4846-AA79-FA8883560995), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput_v10_11 : IUnknown +{ + HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags, [out] BMDDisplayModeSupport_v10_11 *result, [out] IDeckLinkDisplayMode **resultDisplayMode); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput(void); + HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount); + HRESULT SetVideoInputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); + + /* Audio Input */ + + HRESULT EnableAudioInput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput(void); + HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams(void); + HRESULT StopStreams(void); + HRESULT PauseStreams(void); + HRESULT FlushStreams(void); + HRESULT SetCallback([in] IDeckLinkInputCallback_v11_5_1 *theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + +/* Interface IDeckLinkEncoderInput_v10_11 - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(270587DA-6B7D-42E7-A1F0-6D853F581185), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkEncoderInput_v10_11 : IUnknown +{ + HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags, [out] BMDDisplayModeSupport_v10_11 *result, [out] IDeckLinkDisplayMode **resultDisplayMode); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator); + + /* Video Input */ + + HRESULT EnableVideoInput([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput(void); + HRESULT GetAvailablePacketsCount([out] unsigned int *availablePacketsCount); + HRESULT SetMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); + + /* Audio Input */ + + HRESULT EnableAudioInput([in] BMDAudioFormat audioFormat, [in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput(void); + HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams(void); + HRESULT StopStreams(void); + HRESULT PauseStreams(void); + HRESULT FlushStreams(void); + HRESULT SetCallback([in] IDeckLinkEncoderInputCallback *theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + +/* Interface IDeckLinkNotification_v10_11 - DeckLink Notification interface */ + +[ + object, + uuid(0A1FB207-E215-441B-9B19-6FA1575946C5), + local, + helpstring("DeckLink Notification interface") +] interface IDeckLinkNotification_v10_11 : IUnknown +{ + HRESULT Subscribe([in] BMDNotifications topic, [in] IDeckLinkNotificationCallback *theCallback); + HRESULT Unsubscribe([in] BMDNotifications topic, [in] IDeckLinkNotificationCallback *theCallback); +}; + +importlib("stdole2.tlb"); + +[ + uuid(87D2693F-8D4A-45C7-B43F-10ACBA25E68F), + helpstring("CDeckLinkIterator_v10_11 Class") +] coclass CDeckLinkIterator_v10_11 +{ + [default] interface IDeckLinkIterator; +}; + +[ + uuid(652615D4-26CD-4514-B161-2FD5072ED008), + helpstring("CDeckLinkDiscovery_v10_11 Class") +] coclass CDeckLinkDiscovery_v10_11 +{ + [default] interface IDeckLinkDiscovery; +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_2.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_2.idl new file mode 100644 index 0000000000..e31ff599d3 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_2.idl @@ -0,0 +1,86 @@ +/* -LICENSE-START- +** Copyright (c) 2014 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_2.idl */ + +// Enumeration Mapping + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkConfigurationID_v10_2 { + + /* Video output flags */ + + bmdDeckLinkConfig3GBpsVideoOutput_v10_2 = /* '3gbs' */ 0x33676273 + +} BMDDeckLinkConfigurationID_v10_2; + +/* Enum BMDAudioConnection_v10_2 - Audio connection types */ + +typedef [v1_enum] enum _BMDAudioConnection_v10_2 { + bmdAudioConnectionEmbedded_v10_2 = /* 'embd' */ 0x656D6264, + bmdAudioConnectionAESEBU_v10_2 = /* 'aes ' */ 0x61657320, + bmdAudioConnectionAnalog_v10_2 = /* 'anlg' */ 0x616E6C67, + bmdAudioConnectionAnalogXLR_v10_2 = /* 'axlr' */ 0x61786C72, + bmdAudioConnectionAnalogRCA_v10_2 = /* 'arca' */ 0x61726361 +} BMDAudioConnection_v10_2; + +// Forward Declarations + +interface IDeckLinkConfiguration_v10_2; + +/* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */ + +[ + object, + uuid(C679A35B-610C-4D09-B748-1D0478100FC0), + local, + helpstring("DeckLink Configuration interface") +] interface IDeckLinkConfiguration_v10_2 : IUnknown +{ + HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value); + HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value); + HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value); + HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value); + HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value); + HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value); + HRESULT WriteConfigurationToPreferences(void); +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_4.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_4.idl new file mode 100644 index 0000000000..e5e47942ac --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_4.idl @@ -0,0 +1,74 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_4.idl */ + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkConfigurationID_v10_4 { + + /* Video output flags */ + + bmdDeckLinkConfigSingleLinkVideoOutput_v10_4 = /* 'sglo' */ 0x73676C6F, + +} BMDDeckLinkConfigurationID_v10_4; + +// Forward Declarations + +interface IDeckLinkConfiguration_v10_4; + +/* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */ + +[ + object, + uuid(1E69FCF6-4203-4936-8076-2A9F4CFD50CB), + local, + helpstring("DeckLink Configuration interface") +] interface IDeckLinkConfiguration_v10_4 : IUnknown +{ + HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value); + HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value); + HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value); + HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value); + HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value); + HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value); + HRESULT WriteConfigurationToPreferences(void); +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_5.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_5.idl new file mode 100644 index 0000000000..f18274494e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_5.idl @@ -0,0 +1,74 @@ +/* -LICENSE-START- +** Copyright (c) 2015 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_5.idl */ + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkAttributeID_v10_5 { + + /* Integers */ + + BMDDeckLinkDeviceBusyState_v10_5 = /* 'dbst' */ 0x64627374, + +} BMDDeckLinkAttributeID_v10_5; + +// Forward Declarations + +interface IDeckLinkEncoderConfiguration_v10_5; + +/* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ + +[ + object, + uuid(67455668-0848-45DF-8D8E-350A77C9A028), + local, + helpstring("DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput") +] interface IDeckLinkEncoderConfiguration_v10_5 : IUnknown +{ + HRESULT SetFlag([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BOOL *value); + HRESULT SetInt([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] LONGLONG *value); + HRESULT SetFloat([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] double value); + HRESULT GetFloat([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] double *value); + HRESULT SetString([in] BMDDeckLinkEncoderConfigurationID cfgID, [in] BSTR value); + HRESULT GetString([in] BMDDeckLinkEncoderConfigurationID cfgID, [out] BSTR *value); + HRESULT GetDecoderConfigurationInfo([out] void *buffer, [in] long bufferSize, [out] long *returnedSize); +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_6.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_6.idl new file mode 100644 index 0000000000..4993772094 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_6.idl @@ -0,0 +1,54 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_6.idl */ + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef [v1_enum] enum _BMDDeckLinkAttributeID_v10_6 { + + /* Flags */ + + BMDDeckLinkSupportsDesktopDisplay_v10_6 = /* 'extd' */ 0x65787464, + +} BMDDeckLinkAttributeID_v10_6; + +typedef [v1_enum] enum _BMDIdleVideoOutputOperation_v10_6 { + bmdIdleVideoOutputDesktop_v10_6 = /* 'desk' */ 0x6465736B +} BMDIdleVideoOutputOperation_v10_6; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_8.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_8.idl new file mode 100644 index 0000000000..d115625e9e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_8.idl @@ -0,0 +1,59 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_8.idl */ + + +importlib("stdole2.tlb"); + +[ + uuid(1F2E109A-8F4F-49E4-9203-135595CB6FA5), + helpstring("CDeckLinkIterator_v10_8 Class") +] coclass CDeckLinkIterator_v10_8 +{ + [default] interface IDeckLinkIterator; +}; + +[ + uuid(1073A05C-D885-47E9-B3C6-129B3F9F648B), + helpstring("CDeckLinkDiscovery_v10_8 Class") +] coclass CDeckLinkDiscovery_v10_8 +{ + [default] interface IDeckLinkDiscovery; +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_9.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_9.idl new file mode 100644 index 0000000000..db75747ee3 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v10_9.idl @@ -0,0 +1,74 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_9.idl */ + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkConfigurationID_v10_9 { + + /* Video output flags */ + + bmdDeckLinkConfig1080pNotPsF_v10_9 = /* 'fpro' */ 0x6670726F, + +} BMDDeckLinkConfigurationID_v10_9; + +// Forward Declarations + +interface IDeckLinkConfiguration_v10_9; + +/* Interface IDeckLinkConfiguration_v10_9 - DeckLink Configuration interface */ + +[ + object, + uuid(CB71734A-FE37-4E8D-8E13-802133A1C3F2), + local, + helpstring("DeckLink Configuration interface") +] interface IDeckLinkConfiguration_v10_9 : IUnknown +{ + HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value); + HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value); + HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value); + HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value); + HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value); + HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value); + HRESULT WriteConfigurationToPreferences(void); +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_4.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_4.idl new file mode 100644 index 0000000000..a72bfad8df --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_4.idl @@ -0,0 +1,133 @@ +/* -LICENSE-START- +** Copyright (c) 2019 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v11_4.idl */ + +// Enumeration Mapping + +/* Interface IDeckLinkOutput_v11_4 - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(065A0F6C-C508-4D0D-B919-F5EB0EBFC96B), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput_v11_4 : IUnknown +{ + HRESULT DoesSupportVideoMode ([in] BMDVideoConnection connection /* If a value of 0 is specified, the caller does not care about the connection */, [in] BMDDisplayMode requestedMode, [in] BMDPixelFormat requestedPixelFormat, [in] BMDSupportedVideoModeFlags flags, [out] BMDDisplayMode* actualMode, [out] BOOL* supported); + HRESULT GetDisplayMode ([in] BMDDisplayMode displayMode, [out] IDeckLinkDisplayMode** resultDisplayMode); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + HRESULT SetScreenPreviewCallback ([in] IDeckLinkScreenPreviewCallback* previewCallback); + + /* Video Output */ + + HRESULT EnableVideoOutput ([in] BMDDisplayMode displayMode, [in] BMDVideoOutputFlags flags); + HRESULT DisableVideoOutput (void); + HRESULT SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + HRESULT CreateVideoFrame ([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame** outFrame); + HRESULT CreateAncillaryData ([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary** outBuffer); // Use of IDeckLinkVideoFrameAncillaryPackets is preferred + HRESULT DisplayVideoFrameSync ([in] IDeckLinkVideoFrame* theFrame); + HRESULT ScheduleVideoFrame ([in] IDeckLinkVideoFrame* theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback* theCallback); + HRESULT GetBufferedVideoFrameCount ([out] unsigned int* bufferedFrameCount); + + /* Audio Output */ + + HRESULT EnableAudioOutput ([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount, [in] BMDAudioOutputStreamType streamType); + HRESULT DisableAudioOutput (void); + HRESULT WriteAudioSamplesSync ([in] void* buffer, [in] unsigned int sampleFrameCount, [out] unsigned int* sampleFramesWritten); + HRESULT BeginAudioPreroll (void); + HRESULT EndAudioPreroll (void); + HRESULT ScheduleAudioSamples ([in] void* buffer, [in] unsigned int sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned int* sampleFramesWritten); + HRESULT GetBufferedAudioSampleFrameCount ([out] unsigned int* bufferedSampleFrameCount); + HRESULT FlushBufferedAudioSamples (void); + HRESULT SetAudioCallback ([in] IDeckLinkAudioOutputCallback* theCallback); + + /* Output Control */ + + HRESULT StartScheduledPlayback ([in] BMDTimeValue playbackStartTime, [in] BMDTimeScale timeScale, [in] double playbackSpeed); + HRESULT StopScheduledPlayback ([in] BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue* actualStopTime, [in] BMDTimeScale timeScale); + HRESULT IsScheduledPlaybackRunning ([out] BOOL* active); + HRESULT GetScheduledStreamTime ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* streamTime, [out] double* playbackSpeed); + HRESULT GetReferenceStatus ([out] BMDReferenceStatus* referenceStatus); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* hardwareTime, [out] BMDTimeValue* timeInFrame, [out] BMDTimeValue* ticksPerFrame); + HRESULT GetFrameCompletionReferenceTimestamp ([in] IDeckLinkVideoFrame* theFrame, [in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* frameCompletionTimestamp); +}; + +/* Interface IDeckLinkInput_v11_4 - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(2A88CF76-F494-4216-A7EF-DC74EEB83882), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput_v11_4 : IUnknown +{ + HRESULT DoesSupportVideoMode ([in] BMDVideoConnection connection /* If a value of 0 is specified, the caller does not care about the connection */, [in] BMDDisplayMode requestedMode, [in] BMDPixelFormat requestedPixelFormat, [in] BMDSupportedVideoModeFlags flags, [out] BOOL* supported); + HRESULT GetDisplayMode ([in] BMDDisplayMode displayMode, [out] IDeckLinkDisplayMode** resultDisplayMode); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + HRESULT SetScreenPreviewCallback ([in] IDeckLinkScreenPreviewCallback* previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput ([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput (void); + HRESULT GetAvailableVideoFrameCount ([out] unsigned int* availableFrameCount); + HRESULT SetVideoInputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + + /* Audio Input */ + + HRESULT EnableAudioInput ([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput (void); + HRESULT GetAvailableAudioSampleFrameCount ([out] unsigned int* availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams (void); + HRESULT StopStreams (void); + HRESULT PauseStreams (void); + HRESULT FlushStreams (void); + HRESULT SetCallback ([in] IDeckLinkInputCallback_v11_5_1* theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* hardwareTime, [out] BMDTimeValue* timeInFrame, [out] BMDTimeValue* ticksPerFrame); +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_5.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_5.idl new file mode 100644 index 0000000000..050bb6744e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_5.idl @@ -0,0 +1,112 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v11_5.idl */ + +typedef [v1_enum] enum _BMDDeckLinkFrameMetadataID_v11_5 { + bmdDeckLinkFrameMetadataCintelFilmType_v11_5 = /* 'cfty' */ 0x63667479, // Current film type + bmdDeckLinkFrameMetadataCintelFilmGauge_v11_5 = /* 'cfga' */ 0x63666761, // Current film gauge + bmdDeckLinkFrameMetadataCintelKeykodeLow_v11_5 = /* 'ckkl' */ 0x636B6B6C, // Raw keykode value - low 64 bits + bmdDeckLinkFrameMetadataCintelKeykodeHigh_v11_5 = /* 'ckkh' */ 0x636B6B68, // Raw keykode value - high 64 bits + bmdDeckLinkFrameMetadataCintelTile1Size_v11_5 = /* 'ct1s' */ 0x63743173, // Size in bytes of compressed raw tile 1 + bmdDeckLinkFrameMetadataCintelTile2Size_v11_5 = /* 'ct2s' */ 0x63743273, // Size in bytes of compressed raw tile 2 + bmdDeckLinkFrameMetadataCintelTile3Size_v11_5 = /* 'ct3s' */ 0x63743373, // Size in bytes of compressed raw tile 3 + bmdDeckLinkFrameMetadataCintelTile4Size_v11_5 = /* 'ct4s' */ 0x63743473, // Size in bytes of compressed raw tile 4 + bmdDeckLinkFrameMetadataCintelImageWidth_v11_5 = /* 'IWPx' */ 0x49575078, // Width in pixels of image + bmdDeckLinkFrameMetadataCintelImageHeight_v11_5 = /* 'IHPx' */ 0x49485078, // Height in pixels of image + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInRed_v11_5 = /* 'mrir' */ 0x6D726972, // Red in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInRed_v11_5 = /* 'mgir' */ 0x6D676972, // Green in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInRed_v11_5 = /* 'mbir' */ 0x6D626972, // Blue in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInGreen_v11_5 = /* 'mrig' */ 0x6D726967, // Red in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInGreen_v11_5 = /* 'mgig' */ 0x6D676967, // Green in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInGreen_v11_5 = /* 'mbig' */ 0x6D626967, // Blue in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInBlue_v11_5 = /* 'mrib' */ 0x6D726962, // Red in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInBlue_v11_5 = /* 'mgib' */ 0x6D676962, // Green in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInBlue_v11_5 = /* 'mbib' */ 0x6D626962, // Blue in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInRed_v11_5 = /* 'mlrr' */ 0x6D6C7272, // Red in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInRed_v11_5 = /* 'mlgr' */ 0x6D6C6772, // Green in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInRed_v11_5 = /* 'mlbr' */ 0x6D6C6272, // Blue in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInGreen_v11_5 = /* 'mlrg' */ 0x6D6C7267, // Red in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInGreen_v11_5 = /* 'mlgg' */ 0x6D6C6767, // Green in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInGreen_v11_5 = /* 'mlbg' */ 0x6D6C6267, // Blue in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInBlue_v11_5 = /* 'mlrb' */ 0x6D6C7262, // Red in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInBlue_v11_5 = /* 'mlgb' */ 0x6D6C6762, // Green in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInBlue_v11_5 = /* 'mlbb' */ 0x6D6C6262, // Blue in blue log masking parameter + bmdDeckLinkFrameMetadataCintelFilmFrameRate_v11_5 = /* 'cffr' */ 0x63666672, // Film frame rate + bmdDeckLinkFrameMetadataCintelOffsetToApplyHorizontal_v11_5 = /* 'otah' */ 0x6F746168, // Horizontal offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelOffsetToApplyVertical_v11_5 = /* 'otav' */ 0x6F746176, // Vertical offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelGainRed_v11_5 = /* 'LfRd' */ 0x4C665264, // Red gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainGreen_v11_5 = /* 'LfGr' */ 0x4C664772, // Green gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainBlue_v11_5 = /* 'LfBl' */ 0x4C66426C, // Blue gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelLiftRed_v11_5 = /* 'GnRd' */ 0x476E5264, // Red lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftGreen_v11_5 = /* 'GnGr' */ 0x476E4772, // Green lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftBlue_v11_5 = /* 'GnBl' */ 0x476E426C, // Blue lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelHDRGainRed_v11_5 = /* 'HGRd' */ 0x48475264, // Red gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintelHDRGainGreen_v11_5 = /* 'HGGr' */ 0x48474772, // Green gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintelHDRGainBlue_v11_5 = /* 'HGBl' */ 0x4847426C, // Blue gain parameter to apply to linear data for HDR Combination + bmdDeckLinkFrameMetadataCintel16mmCropRequired_v11_5 = /* 'c16c' */ 0x63313663, // The image should be cropped to 16mm size + bmdDeckLinkFrameMetadataCintelInversionRequired_v11_5 = /* 'cinv' */ 0x63696E76, // The image should be colour inverted + bmdDeckLinkFrameMetadataCintelFlipRequired_v11_5 = /* 'cflr' */ 0x63666C72, // The image should be flipped horizontally + bmdDeckLinkFrameMetadataCintelFocusAssistEnabled_v11_5 = /* 'cfae' */ 0x63666165, // Focus Assist is currently enabled + bmdDeckLinkFrameMetadataCintelKeykodeIsInterpolated_v11_5 = /* 'kkii' */ 0x6B6B6969 // The keykode for this frame is interpolated from nearby keykodes +} BMDDeckLinkFrameMetadataID_v11_5; + +// Forward Declarations + +interface IDeckLinkVideoFrameMetadataExtensions_v11_5; + +/* Interface IDeckLinkVideoFrameMetadataExtensions_v11_5 - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */ + +[ + object, + uuid(D5973DC9-6432-46D0-8F0B-2496F8A1238F), + local, + helpstring("Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information") +] interface IDeckLinkVideoFrameMetadataExtensions_v11_5 : IUnknown +{ + HRESULT GetInt([in] BMDDeckLinkFrameMetadataID_v11_5 metadataID, [out] LONGLONG *value); + HRESULT GetFloat([in] BMDDeckLinkFrameMetadataID_v11_5 metadataID, [out] double *value); + HRESULT GetFlag([in] BMDDeckLinkFrameMetadataID_v11_5 metadataID, [out] BOOL* value); + HRESULT GetString([in] BMDDeckLinkFrameMetadataID_v11_5 metadataID, [out] BSTR *value); +}; + +/* Coclasses */ + +importlib("stdole2.tlb"); diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_5_1.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_5_1.idl new file mode 100644 index 0000000000..b9f3bd6a51 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v11_5_1.idl @@ -0,0 +1,104 @@ +/* -LICENSE-START- +** Copyright (c) 2020 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v11_5_1.idl */ + +// Enumeration Mapping + +/* Enum BMDDeckLinkStatusID - DeckLink Status ID */ + +typedef [v1_enum] enum _BMDDeckLinkStatusID_v11_5_1 { + + /* Video output flags */ + + bmdDeckLinkStatusDetectedVideoInputFlags_v11_5_1 = /* 'dvif' */ 0x64766966, + +} BMDDeckLinkStatusID_v11_5_1; + +/* Interface IDeckLinkInputCallback_v11_5_1 - Frame arrival callback. */ + +[ + object, + uuid(DD04E5EC-7415-42AB-AE4A-E80C4DFC044A), + helpstring("Frame arrival callback.") +] interface IDeckLinkInputCallback_v11_5_1 : IUnknown +{ + HRESULT VideoInputFormatChanged ([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode* newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags); + HRESULT VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame* videoFrame, [in] IDeckLinkAudioInputPacket* audioPacket); +}; + +/* Interface IDeckLinkInput_v11_5_1 - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(9434C6E4-B15D-4B1C-979E-661E3DDCB4B9), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput_v11_5_1 : IUnknown +{ + HRESULT DoesSupportVideoMode ([in] BMDVideoConnection connection /* If a value of bmdVideoConnectionUnspecified is specified, the caller does not care about the connection */, [in] BMDDisplayMode requestedMode, [in] BMDPixelFormat requestedPixelFormat, [in] BMDVideoInputConversionMode conversionMode, [in] BMDSupportedVideoModeFlags flags, [out] BMDDisplayMode* actualMode, [out] BOOL* supported); + HRESULT GetDisplayMode ([in] BMDDisplayMode displayMode, [out] IDeckLinkDisplayMode** resultDisplayMode); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator** iterator); + HRESULT SetScreenPreviewCallback ([in] IDeckLinkScreenPreviewCallback* previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput ([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput (void); + HRESULT GetAvailableVideoFrameCount ([out] unsigned int* availableFrameCount); + HRESULT SetVideoInputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + + /* Audio Input */ + + HRESULT EnableAudioInput ([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput (void); + HRESULT GetAvailableAudioSampleFrameCount ([out] unsigned int* availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams (void); + HRESULT StopStreams (void); + HRESULT PauseStreams (void); + HRESULT FlushStreams (void); + HRESULT SetCallback ([in] IDeckLinkInputCallback_v11_5_1* theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock ([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue* hardwareTime, [out] BMDTimeValue* timeInFrame, [out] BMDTimeValue* ticksPerFrame); +}; + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_1.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_1.idl new file mode 100644 index 0000000000..24707bf169 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_1.idl @@ -0,0 +1,173 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v7_1.idl */ + + interface IDeckLinkDisplayModeIterator_v7_1; + interface IDeckLinkDisplayMode_v7_1; + interface IDeckLinkVideoFrame_v7_1; + interface IDeckLinkVideoInputFrame_v7_1; + interface IDeckLinkAudioInputPacket_v7_1; + + [object, uuid(B28131B6-59AC-4857-B5AC-CD75D5883E2F), + helpstring("IDeckLinkDisplayModeIterator_v7_1 enumerates over supported input/output display modes.")] + interface IDeckLinkDisplayModeIterator_v7_1 : IUnknown + { + HRESULT Next ([out] IDeckLinkDisplayMode_v7_1** deckLinkDisplayMode); + }; + + + [object, uuid(AF0CD6D5-8376-435E-8433-54F9DD530AC3), + helpstring("IDeckLinkDisplayMode_v7_1 represents a display mode")] + interface IDeckLinkDisplayMode_v7_1 : IUnknown + { + HRESULT GetName ([out] BSTR* name); + BMDDisplayMode GetDisplayMode (); + long GetWidth (); + long GetHeight (); + HRESULT GetFrameRate ([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale); + }; + + [object, uuid(EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9), + helpstring("IDeckLinkVideoOutputCallback. Frame completion callback.")] + interface IDeckLinkVideoOutputCallback_v7_1 : IUnknown + { + HRESULT ScheduledFrameCompleted ([in] IDeckLinkVideoFrame_v7_1* completedFrame, [in] BMDOutputFrameCompletionResult result); + }; + + [object, uuid(7F94F328-5ED4-4E9F-9729-76A86BDC99CC), + helpstring("IDeckLinkInputCallback_v7_1. Frame arrival callback.")] + interface IDeckLinkInputCallback_v7_1 : IUnknown + { + HRESULT VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame_v7_1* videoFrame, [in] IDeckLinkAudioInputPacket_v7_1* audioPacket); + }; + + + [object, uuid(AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5), local, + helpstring("IDeckLinkOutput_v7_1. Created by QueryInterface from IDeckLink.")] + interface IDeckLinkOutput_v7_1 : IUnknown + { + HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport_v10_11 *result); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator); + + // Video output + HRESULT EnableVideoOutput (BMDDisplayMode displayMode); + HRESULT DisableVideoOutput (); + + HRESULT SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + HRESULT CreateVideoFrame (int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame); + HRESULT CreateVideoFrameFromBuffer (void* buffer, int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame); + + HRESULT DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame); + HRESULT ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback_v7_1* theCallback); + + // Audio output + HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount); + HRESULT DisableAudioOutput (); + + HRESULT WriteAudioSamplesSync (void* buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten); + + HRESULT BeginAudioPreroll (); + HRESULT EndAudioPreroll (); + HRESULT ScheduleAudioSamples (void* buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten); + + HRESULT GetBufferedAudioSampleFrameCount ( [out] unsigned int *bufferedSampleCount); + HRESULT FlushBufferedAudioSamples (); + + HRESULT SetAudioCallback ( [in] IDeckLinkAudioOutputCallback* theCallback); + + // Output control + HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed); + HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale); + HRESULT GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan); + }; + + [object, uuid(2B54EDEF-5B32-429F-BA11-BB990596EACD), + helpstring("IDeckLinkInput_v7_1. Created by QueryInterface from IDeckLink.")] + interface IDeckLinkInput_v7_1 : IUnknown + { + HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport_v10_11 *result); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator); + + // Video input + HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags); + HRESULT DisableVideoInput (); + + // Audio input + HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount); + HRESULT DisableAudioInput (); + HRESULT ReadAudioSamples (void* buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesRead, [out] BMDTimeValue *audioPacketTime, BMDTimeScale timeScale); + HRESULT GetBufferedAudioSampleFrameCount ( [out] unsigned int *bufferedSampleCount); + + // Input control + HRESULT StartStreams (); + HRESULT StopStreams (); + HRESULT PauseStreams (); + HRESULT SetCallback ([in] IDeckLinkInputCallback_v7_1* theCallback); + }; + + [object, uuid(333F3A10-8C2D-43CF-B79D-46560FEEA1CE), local, + helpstring("IDeckLinkVideoFrame_v7_1. Created by IDeckLinkVideoOutput::CreateVideoFrame.")] + interface IDeckLinkVideoFrame_v7_1 : IUnknown + { + long GetWidth (); + long GetHeight (); + long GetRowBytes (); + BMDPixelFormat GetPixelFormat (); + BMDFrameFlags GetFlags (); + HRESULT GetBytes (void* *buffer); + }; + + [object, uuid(C8B41D95-8848-40EE-9B37-6E3417FB114B), local, + helpstring("IDeckLinkVideoInputFrame_v7_1. Provided by the IDeckLinkVideoInput frame arrival callback.")] + interface IDeckLinkVideoInputFrame_v7_1 : IDeckLinkVideoFrame_v7_1 + { + HRESULT GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale); + }; + + [object, uuid(C86DE4F6-A29F-42E3-AB3A-1363E29F0788), local, + helpstring("IDeckLinkAudioInputPacket_v7_1. Provided by the IDeckLinkInput callback.")] + interface IDeckLinkAudioInputPacket_v7_1 : IUnknown + { + long GetSampleCount (); + HRESULT GetBytes (void* *buffer); + HRESULT GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale); + }; + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_3.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_3.idl new file mode 100644 index 0000000000..3cbb0455eb --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_3.idl @@ -0,0 +1,170 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* Forward Declarations */ + +interface IDeckLinkInputCallback_v7_3; +interface IDeckLinkOutput_v7_3; +interface IDeckLinkInput_v7_3; +interface IDeckLinkVideoInputFrame_v7_3; + +/* End Forward Declarations */ + + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +[ + object, + uuid(FD6F311D-4D00-444B-9ED4-1F25B5730AD0), + helpstring("Frame arrival callback.") +] interface IDeckLinkInputCallback_v7_3 : IUnknown +{ + HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode_v7_6 *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags); + HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame_v7_3 *videoFrame, [in] IDeckLinkAudioInputPacket *audioPacket); +}; + +/* End Interface IDeckLinkInputCallback */ + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(271C65E3-C323-4344-A30F-D908BCB20AA3), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput_v7_3 : IUnknown +{ + HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport_v10_11 *result); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback); + + /* Video Output */ + + HRESULT EnableVideoOutput(BMDDisplayMode displayMode, BMDVideoOutputFlags flags); + HRESULT DisableVideoOutput(void); + + HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); + HRESULT CreateVideoFrame(int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame_v7_6 **outFrame); + HRESULT CreateAncillaryData(BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer); + + HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame_v7_6 *theFrame); + HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback); + HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount); + + /* Audio Output */ + + HRESULT EnableAudioOutput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount, BMDAudioOutputStreamType streamType); + HRESULT DisableAudioOutput(void); + + HRESULT WriteAudioSamplesSync([in] void *buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten); + + HRESULT BeginAudioPreroll(void); + HRESULT EndAudioPreroll(void); + HRESULT ScheduleAudioSamples([in] void *buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten); + + HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount); + HRESULT FlushBufferedAudioSamples(void); + + HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback); + + /* Output Control */ + + HRESULT StartScheduledPlayback(BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed); + HRESULT StopScheduledPlayback(BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, BMDTimeScale timeScale); + HRESULT IsScheduledPlaybackRunning([out] BOOL *active); + HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *elapsedTimeSinceSchedulerBegan); +}; + +/* End Interface IDeckLinkOutput */ + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(4973F012-9925-458C-871C-18774CDBBECB), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput_v7_3 : IUnknown +{ + HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport_v10_11 *result); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags); + HRESULT DisableVideoInput(void); + HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount); + + /* Audio Input */ + + HRESULT EnableAudioInput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount); + HRESULT DisableAudioInput(void); + HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams(void); + HRESULT StopStreams(void); + HRESULT PauseStreams(void); + HRESULT FlushStreams(void); + HRESULT SetCallback([in] IDeckLinkInputCallback_v7_3 *theCallback); +}; + +/* End Interface IDeckLinkInput */ + + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +[ + object, + uuid(CF317790-2894-11DE-8C30-0800200C9A66), + local, + helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") +] interface IDeckLinkVideoInputFrame_v7_3 : IDeckLinkVideoFrame_v7_6 +{ + HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale); +}; + +/* End Interface IDeckLinkVideoInputFrame */ + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_6.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_6.idl new file mode 100644 index 0000000000..ddf5a74b77 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_6.idl @@ -0,0 +1,409 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* Enum BMDVideoConnection - Video connection types */ + +typedef [v1_enum] enum _BMDVideoConnection_v7_6 { + bmdVideoConnectionSDI_v7_6 = /* 'sdi ' */ 0x73646920, + bmdVideoConnectionHDMI_v7_6 = /* 'hdmi' */ 0x68646D69, + bmdVideoConnectionOpticalSDI_v7_6 = /* 'opti' */ 0x6F707469, + bmdVideoConnectionComponent_v7_6 = /* 'cpnt' */ 0x63706E74, + bmdVideoConnectionComposite_v7_6 = /* 'cmst' */ 0x636D7374, + bmdVideoConnectionSVideo_v7_6 = /* 'svid' */ 0x73766964 +} BMDVideoConnection_v7_6; + + + +/* Forward Declarations */ + +interface IDeckLinkDisplayModeIterator_v7_6; +interface IDeckLinkDisplayMode_v7_6; +interface IDeckLinkOutput_v7_6; +interface IDeckLinkInput_v7_6; +interface IDeckLinkTimecode_v7_6; +interface IDeckLinkVideoFrame_v7_6; +interface IDeckLinkMutableVideoFrame_v7_6; +interface IDeckLinkVideoInputFrame_v7_6; +interface IDeckLinkScreenPreviewCallback_v7_6; +interface IDeckLinkGLScreenPreviewHelper_v7_6; +interface IDeckLinkVideoConversion_v7_6; +interface IDeckLinkConfiguration_v7_6; + + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +[ + object, + uuid(E763A626-4A3C-49D1-BF13-E7AD3692AE52), + helpstring("Frame completion callback.") +] interface IDeckLinkVideoOutputCallback_v7_6 : IUnknown +{ + HRESULT ScheduledFrameCompleted([in] IDeckLinkVideoFrame_v7_6 *completedFrame, [in] BMDOutputFrameCompletionResult result); + HRESULT ScheduledPlaybackHasStopped(void); +}; + + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +[ + object, + uuid(31D28EE7-88B6-4CB1-897A-CDBF79A26414), + helpstring("Frame arrival callback.") +] interface IDeckLinkInputCallback_v7_6 : IUnknown +{ + HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode_v7_6 *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags); + HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame_v7_6* videoFrame, [in] IDeckLinkAudioInputPacket* audioPacket); +}; + + +/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ + +[ + object, + uuid(455D741F-1779-4800-86F5-0B5D13D79751), + helpstring("enumerates over supported input/output display modes.") +] interface IDeckLinkDisplayModeIterator_v7_6 : IUnknown +{ + HRESULT Next([out] IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode); +}; + + +/* Interface IDeckLinkDisplayMode - represents a display mode */ + +[ + object, + uuid(87451E84-2B7E-439E-A629-4393EA4A8550), + helpstring("represents a display mode") +] interface IDeckLinkDisplayMode_v7_6 : IUnknown +{ + HRESULT GetName([out] BSTR *name); + BMDDisplayMode GetDisplayMode(void); + long GetWidth(void); + long GetHeight(void); + HRESULT GetFrameRate([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale); + BMDFieldDominance GetFieldDominance(void); +}; + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(29228142-EB8C-4141-A621-F74026450955), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput_v7_6 : IUnknown +{ + HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport_v10_11 *result); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback_v7_6 *previewCallback); + + /* Video Output */ + + HRESULT EnableVideoOutput(BMDDisplayMode displayMode, BMDVideoOutputFlags flags); + HRESULT DisableVideoOutput(void); + + HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); + HRESULT CreateVideoFrame(int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame_v7_6 **outFrame); + HRESULT CreateAncillaryData(BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer); + + HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame_v7_6 *theFrame); + HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback_v7_6 *theCallback); + HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount); + + /* Audio Output */ + + HRESULT EnableAudioOutput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount, BMDAudioOutputStreamType streamType); + HRESULT DisableAudioOutput(void); + + HRESULT WriteAudioSamplesSync([in] void *buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten); + + HRESULT BeginAudioPreroll(void); + HRESULT EndAudioPreroll(void); + HRESULT ScheduleAudioSamples([in] void *buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten); + + HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount); + HRESULT FlushBufferedAudioSamples(void); + + HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback); + + /* Output Control */ + + HRESULT StartScheduledPlayback(BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed); + HRESULT StopScheduledPlayback(BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, BMDTimeScale timeScale); + HRESULT IsScheduledPlaybackRunning([out] BOOL *active); + HRESULT GetScheduledStreamTime(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(300C135A-9F43-48E2-9906-6D7911D93CF1), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput_v7_6 : IUnknown +{ + HRESULT DoesSupportVideoMode(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport_v10_11 *result); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator_v7_6 **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback_v7_6 *previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput(BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags); + HRESULT DisableVideoInput(void); + HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount); + + /* Audio Input */ + + HRESULT EnableAudioInput(BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount); + HRESULT DisableAudioInput(void); + HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams(void); + HRESULT StopStreams(void); + HRESULT PauseStreams(void); + HRESULT FlushStreams(void); + HRESULT SetCallback([in] IDeckLinkInputCallback_v7_6 *theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + + +/* Interface IDeckLinkTimecode_v7_6 - Used for video frame timecode representation. */ + +[ + object, + uuid(EFB9BCA6-A521-44F7-BD69-2332F24D9EE6), + helpstring("Used for video frame timecode representation.") +] interface IDeckLinkTimecode_v7_6 : IUnknown +{ + BMDTimecodeBCD GetBCD(void); + HRESULT GetComponents([out] unsigned char *hours, [out] unsigned char *minutes, [out] unsigned char *seconds, [out] unsigned char *frames); + HRESULT GetString([out] BSTR *timecode); + BMDTimecodeFlags GetFlags(void); +}; + + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +[ + object, + uuid(A8D8238E-6B18-4196-99E1-5AF717B83D32), + local, + helpstring("Interface to encapsulate a video frame; can be caller-implemented.") +] interface IDeckLinkVideoFrame_v7_6 : IUnknown +{ + long GetWidth(void); + long GetHeight(void); + long GetRowBytes(void); + BMDPixelFormat GetPixelFormat(void); + BMDFrameFlags GetFlags(void); + HRESULT GetBytes([out] void **buffer); + + HRESULT GetTimecode(BMDTimecodeFormat format, [out] IDeckLinkTimecode_v7_6 **timecode); + HRESULT GetAncillaryData([out] IDeckLinkVideoFrameAncillary **ancillary); +}; + + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +[ + object, + uuid(46FCEE00-B4E6-43D0-91C0-023A7FCEB34F), + local, + helpstring("Created by IDeckLinkOutput::CreateVideoFrame.") +] interface IDeckLinkMutableVideoFrame_v7_6 : IDeckLinkVideoFrame_v7_6 +{ + HRESULT SetFlags(BMDFrameFlags newFlags); + + HRESULT SetTimecode(BMDTimecodeFormat format, [in] IDeckLinkTimecode_v7_6 *timecode); + HRESULT SetTimecodeFromComponents(BMDTimecodeFormat format, unsigned char hours, unsigned char minutes, unsigned char seconds, unsigned char frames, BMDTimecodeFlags flags); + HRESULT SetAncillaryData([in] IDeckLinkVideoFrameAncillary *ancillary); +}; + + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +[ + object, + uuid(9A74FA41-AE9F-47AC-8CF4-01F42DD59965), + local, + helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") +] interface IDeckLinkVideoInputFrame_v7_6 : IDeckLinkVideoFrame_v7_6 +{ + HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale); + HRESULT GetHardwareReferenceTimestamp(BMDTimeScale timeScale, [out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration); +}; + + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +[ + object, + uuid(373F499D-4B4D-4518-AD22-6354E5A5825E), + local, + helpstring("Screen preview callback") +] interface IDeckLinkScreenPreviewCallback_v7_6 : IUnknown +{ + HRESULT DrawFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame); +}; + + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ + +[ + object, + uuid(BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA), + local, + helpstring("Created with CoCreateInstance().") +] interface IDeckLinkGLScreenPreviewHelper_v7_6 : IUnknown +{ + + /* Methods must be called with OpenGL context set */ + + HRESULT InitializeGL(void); + HRESULT PaintGL(void); + HRESULT SetFrame([in] IDeckLinkVideoFrame_v7_6 *theFrame); +}; + + +/* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */ + +[ + object, + uuid(3EB504C9-F97D-40FE-A158-D407D48CB53B), + local, + helpstring("Created with CoCreateInstance().") +] interface IDeckLinkVideoConversion_v7_6 : IUnknown +{ + HRESULT ConvertFrame([in] IDeckLinkVideoFrame_v7_6* srcFrame, [in] IDeckLinkVideoFrame_v7_6* dstFrame); +}; + +/* Interface IDeckLinkConfiguration_v7_6 - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(B8EAD569-B764-47F0-A73F-AE40DF6CBF10), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkConfiguration_v7_6 : IUnknown +{ + HRESULT GetConfigurationValidator([out] IDeckLinkConfiguration_v7_6 **configObject); + HRESULT WriteConfigurationToPreferences(void); + + /* Video Output Configuration */ + + HRESULT SetVideoOutputFormat([in] BMDVideoConnection_v7_6 videoOutputConnection); + HRESULT IsVideoOutputActive([in] BMDVideoConnection_v7_6 videoOutputConnection, [out] BOOL *active); + + HRESULT SetAnalogVideoOutputFlags([in] BMDAnalogVideoFlags analogVideoFlags); + HRESULT GetAnalogVideoOutputFlags([out] BMDAnalogVideoFlags *analogVideoFlags); + + HRESULT EnableFieldFlickerRemovalWhenPaused([in] BOOL enable); + HRESULT IsEnabledFieldFlickerRemovalWhenPaused([out] BOOL *enabled); + + HRESULT Set444And3GBpsVideoOutput([in] BOOL enable444VideoOutput, [in] BOOL enable3GbsOutput); + HRESULT Get444And3GBpsVideoOutput([out] BOOL *is444VideoOutputEnabled, [out] BOOL *threeGbsOutputEnabled); + + HRESULT SetVideoOutputConversionMode([in] BMDVideoOutputConversionMode conversionMode); + HRESULT GetVideoOutputConversionMode([out] BMDVideoOutputConversionMode *conversionMode); + + HRESULT Set_HD1080p24_to_HD1080i5994_Conversion([in] BOOL enable); + HRESULT Get_HD1080p24_to_HD1080i5994_Conversion([out] BOOL *enabled); + + /* Video Input Configuration */ + + HRESULT SetVideoInputFormat([in] BMDVideoConnection_v7_6 videoInputFormat); + HRESULT GetVideoInputFormat([out] BMDVideoConnection_v7_6 *videoInputFormat); + + HRESULT SetAnalogVideoInputFlags([in] BMDAnalogVideoFlags analogVideoFlags); + HRESULT GetAnalogVideoInputFlags([out] BMDAnalogVideoFlags *analogVideoFlags); + + HRESULT SetVideoInputConversionMode([in] BMDVideoInputConversionMode conversionMode); + HRESULT GetVideoInputConversionMode([out] BMDVideoInputConversionMode *conversionMode); + + HRESULT SetBlackVideoOutputDuringCapture([in] BOOL blackOutInCapture); + HRESULT GetBlackVideoOutputDuringCapture([out] BOOL *blackOutInCapture); + + HRESULT Set32PulldownSequenceInitialTimecodeFrame([in] unsigned int aFrameTimecode); + HRESULT Get32PulldownSequenceInitialTimecodeFrame([out] unsigned int *aFrameTimecode); + + HRESULT SetVancSourceLineMapping([in] unsigned int activeLine1VANCsource, [in] unsigned int activeLine2VANCsource, [in] unsigned int activeLine3VANCsource); + HRESULT GetVancSourceLineMapping([out] unsigned int *activeLine1VANCsource, [out] unsigned int *activeLine2VANCsource, [out] unsigned int *activeLine3VANCsource); + + /* Audio Input Configuration */ + + HRESULT SetAudioInputFormat([in] BMDAudioConnection_v10_2 audioInputFormat); + HRESULT GetAudioInputFormat([out] BMDAudioConnection_v10_2 *audioInputFormat); +}; + + + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(D398CEE7-4434-4CA3-9BA6-5AE34556B905), + helpstring("CDeckLinkGLScreenPreviewHelper Class (DeckLink API v7.6)") +] coclass CDeckLinkGLScreenPreviewHelper_v7_6 +{ + [default] interface IDeckLinkGLScreenPreviewHelper_v7_6; +}; + +[ + uuid(FFA84F77-73BE-4FB7-B03E-B5E44B9F759B), + helpstring("CDeckLinkVideoConversion Class (DeckLink API v7.6)") +] coclass CDeckLinkVideoConversion_v7_6 +{ + [default] interface IDeckLinkVideoConversion_v7_6; +}; + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_9.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_9.idl new file mode 100644 index 0000000000..97ecb1c3da --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v7_9.idl @@ -0,0 +1,82 @@ +/* -LICENSE-START- +** Copyright (c) 2010 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v7_9.idl */ + +/* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */ + +[ + object, + uuid(A4D81043-0619-42B7-8ED6-602D29041DF7), + helpstring("Deck Control main interface") +] interface IDeckLinkDeckControl_v7_9 : IUnknown +{ + HRESULT Open([in] BMDTimeScale timeScale, [in] BMDTimeValue timeValue, [in] BOOL timecodeIsDropFrame, [out] BMDDeckControlError *error); + HRESULT Close([in] BOOL standbyOn); + HRESULT GetCurrentState([out] BMDDeckControlMode *mode, [out] BMDDeckControlVTRControlState *vtrControlState, [out] BMDDeckControlStatusFlags *flags); + HRESULT SetStandby([in] BOOL standbyOn); + HRESULT Play([out] BMDDeckControlError *error); + HRESULT Stop([out] BMDDeckControlError *error); + HRESULT TogglePlayStop([out] BMDDeckControlError *error); + HRESULT Eject([out] BMDDeckControlError *error); + HRESULT GoToTimecode([in] BMDTimecodeBCD timecode, [out] BMDDeckControlError *error); + HRESULT FastForward([in] BOOL viewTape, [out] BMDDeckControlError *error); + HRESULT Rewind([in] BOOL viewTape, [out] BMDDeckControlError *error); + HRESULT StepForward([out] BMDDeckControlError *error); + HRESULT StepBack([out] BMDDeckControlError *error); + HRESULT Jog([in] double rate, [out] BMDDeckControlError *error); + HRESULT Shuttle([in] double rate, [out] BMDDeckControlError *error); + HRESULT GetTimecodeString([out] BSTR *currentTimeCode, [out] BMDDeckControlError *error); + HRESULT GetTimecode([out] IDeckLinkTimecode **currentTimecode, [out] BMDDeckControlError *error); + HRESULT GetTimecodeBCD([out] BMDTimecodeBCD *currentTimecode, [out] BMDDeckControlError *error); + HRESULT SetPreroll([in] unsigned int prerollSeconds); + HRESULT GetPreroll([out] unsigned int *prerollSeconds); + HRESULT SetExportOffset([in] int exportOffsetFields); + HRESULT GetExportOffset([out] int *exportOffsetFields); + HRESULT GetManualExportOffset([out] int *deckManualExportOffsetFields); + HRESULT SetCaptureOffset([in] int captureOffsetFields); + HRESULT GetCaptureOffset([out] int *captureOffsetFields); + HRESULT StartExport([in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [in] BMDDeckControlExportModeOpsFlags exportModeOps, [out] BMDDeckControlError *error); + HRESULT StartCapture([in] BOOL useVITC, [in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [out] BMDDeckControlError *error); + HRESULT GetDeviceID([out] unsigned short *deviceId, [out] BMDDeckControlError *error); + HRESULT Abort(void); + HRESULT CrashRecordStart([out] BMDDeckControlError *error); + HRESULT CrashRecordStop([out] BMDDeckControlError *error); + HRESULT SetCallback([in] IDeckLinkDeckControlStatusCallback *callback); +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v8_0.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v8_0.idl new file mode 100644 index 0000000000..50d7e80ee9 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v8_0.idl @@ -0,0 +1,75 @@ +/* -LICENSE-START- +** Copyright (c) 2011 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v8_0.idl */ + +/* Interface IDeckLink_v8_0 - represents a DeckLink device */ + +[ + object, + uuid(62BFF75D-6569-4E55-8D4D-66AA03829ABC), + helpstring("represents a DeckLink device") +] interface IDeckLink_v8_0 : IUnknown +{ + HRESULT GetModelName([out] BSTR *modelName); +}; + +/* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */ + +[ + object, + uuid(74E936FC-CC28-4A67-81A0-1E94E52D4E69), + helpstring("enumerates installed DeckLink hardware") +] interface IDeckLinkIterator_v8_0 : IUnknown +{ + HRESULT Next([out] IDeckLink_v8_0 **deckLinkInstance); +}; + + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(D9EDA3B3-2887-41FA-B724-017CF1EB1D37), + helpstring("CDeckLinkIterator Class (DeckLink API v8.0)") +] coclass CDeckLinkIterator_v8_0 +{ + [default] interface IDeckLinkIterator_v8_0; +}; diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v8_1.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v8_1.idl new file mode 100644 index 0000000000..8c1f9ce41c --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v8_1.idl @@ -0,0 +1,114 @@ +/* -LICENSE-START- +** Copyright (c) 2011 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ +/* DeckLinkAPI_v8_1.idl */ + +/* Enum BMDDeckControlVTRControlState_v8_1 - VTR Control state */ + +typedef [v1_enum] enum _BMDDeckControlVTRControlState_v8_1 { + bmdDeckControlNotInVTRControlMode_v8_1 = /* 'nvcm' */ 0x6E76636D, + bmdDeckControlVTRControlPlaying_v8_1 = /* 'vtrp' */ 0x76747270, + bmdDeckControlVTRControlRecording_v8_1 = /* 'vtrr' */ 0x76747272, + bmdDeckControlVTRControlStill_v8_1 = /* 'vtra' */ 0x76747261, + bmdDeckControlVTRControlSeeking_v8_1 = /* 'vtrs' */ 0x76747273, + bmdDeckControlVTRControlStopped_v8_1 = /* 'vtro' */ 0x7674726F +} BMDDeckControlVTRControlState_v8_1; + + +interface IDeckLinkDeckControlStatusCallback; +interface IDeckLinkDeckControl; + +/* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */ + +[ + object, + uuid(E5F693C1-4283-4716-B18F-C1431521955B), + helpstring("Deck control state change callback.") +] interface IDeckLinkDeckControlStatusCallback_v8_1 : IUnknown +{ + HRESULT TimecodeUpdate([in] BMDTimecodeBCD currentTimecode); + HRESULT VTRControlStateChanged([in] BMDDeckControlVTRControlState_v8_1 newState, [in] BMDDeckControlError error); + HRESULT DeckControlEventReceived([in] BMDDeckControlEvent event, [in] BMDDeckControlError error); + HRESULT DeckControlStatusChanged([in] BMDDeckControlStatusFlags flags, [in] unsigned int mask); +}; + +/* Interface IDeckLinkDeckControl - Deck Control main interface */ + +[ + object, + uuid(522A9E39-0F3C-4742-94EE-D80DE335DA1D), + helpstring("Deck Control main interface") +] interface IDeckLinkDeckControl_v8_1 : IUnknown +{ + HRESULT Open([in] BMDTimeScale timeScale, [in] BMDTimeValue timeValue, [in] BOOL timecodeIsDropFrame, [out] BMDDeckControlError *error); + HRESULT Close([in] BOOL standbyOn); + HRESULT GetCurrentState([out] BMDDeckControlMode *mode, [out] BMDDeckControlVTRControlState_v8_1 *vtrControlState, [out] BMDDeckControlStatusFlags *flags); + HRESULT SetStandby([in] BOOL standbyOn); + HRESULT SendCommand([in] unsigned char *inBuffer, [in] unsigned int inBufferSize, [out] unsigned char *outBuffer, [out] unsigned int *outDataSize, [in] unsigned int outBufferSize, [out] BMDDeckControlError *error); + HRESULT Play([out] BMDDeckControlError *error); + HRESULT Stop([out] BMDDeckControlError *error); + HRESULT TogglePlayStop([out] BMDDeckControlError *error); + HRESULT Eject([out] BMDDeckControlError *error); + HRESULT GoToTimecode([in] BMDTimecodeBCD timecode, [out] BMDDeckControlError *error); + HRESULT FastForward([in] BOOL viewTape, [out] BMDDeckControlError *error); + HRESULT Rewind([in] BOOL viewTape, [out] BMDDeckControlError *error); + HRESULT StepForward([out] BMDDeckControlError *error); + HRESULT StepBack([out] BMDDeckControlError *error); + HRESULT Jog([in] double rate, [out] BMDDeckControlError *error); + HRESULT Shuttle([in] double rate, [out] BMDDeckControlError *error); + HRESULT GetTimecodeString([out] BSTR *currentTimeCode, [out] BMDDeckControlError *error); + HRESULT GetTimecode([out] IDeckLinkTimecode **currentTimecode, [out] BMDDeckControlError *error); + HRESULT GetTimecodeBCD([out] BMDTimecodeBCD *currentTimecode, [out] BMDDeckControlError *error); + HRESULT SetPreroll([in] unsigned int prerollSeconds); + HRESULT GetPreroll([out] unsigned int *prerollSeconds); + HRESULT SetExportOffset([in] int exportOffsetFields); + HRESULT GetExportOffset([out] int *exportOffsetFields); + HRESULT GetManualExportOffset([out] int *deckManualExportOffsetFields); + HRESULT SetCaptureOffset([in] int captureOffsetFields); + HRESULT GetCaptureOffset([out] int *captureOffsetFields); + HRESULT StartExport([in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [in] BMDDeckControlExportModeOpsFlags exportModeOps, [out] BMDDeckControlError *error); + HRESULT StartCapture([in] BOOL useVITC, [in] BMDTimecodeBCD inTimecode, [in] BMDTimecodeBCD outTimecode, [out] BMDDeckControlError *error); + HRESULT GetDeviceID([out] unsigned short *deviceId, [out] BMDDeckControlError *error); + HRESULT Abort(void); + HRESULT CrashRecordStart([out] BMDDeckControlError *error); + HRESULT CrashRecordStop([out] BMDDeckControlError *error); + HRESULT SetCallback([in] IDeckLinkDeckControlStatusCallback_v8_1 *callback); +}; + + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v9_2.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v9_2.idl new file mode 100644 index 0000000000..23060d9ef7 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v9_2.idl @@ -0,0 +1,81 @@ +/* -LICENSE-START- +** Copyright (c) 2012 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v9_2.idl */ + + +/* Interface IDeckLinkInput_v9_2 - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(6D40EF78-28B9-4E21-990D-95BB7750A04F), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput_v9_2 : IUnknown +{ + HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags, [out] BMDDisplayModeSupport_v10_11 *result, [out] IDeckLinkDisplayMode **resultDisplayMode); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback); + + /* Video Input */ + + HRESULT EnableVideoInput([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoInputFlags flags); + HRESULT DisableVideoInput(void); + HRESULT GetAvailableVideoFrameCount([out] unsigned int *availableFrameCount); + + /* Audio Input */ + + HRESULT EnableAudioInput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount); + HRESULT DisableAudioInput(void); + HRESULT GetAvailableAudioSampleFrameCount([out] unsigned int *availableSampleFrameCount); + + /* Input Control */ + + HRESULT StartStreams(void); + HRESULT StopStreams(void); + HRESULT PauseStreams(void); + HRESULT FlushStreams(void); + HRESULT SetCallback([in] IDeckLinkInputCallback_v11_5_1 *theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + diff --git a/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v9_9.idl b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v9_9.idl new file mode 100644 index 0000000000..b6c7ca089e --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/decklink2/win/DeckLinkAPI_v9_9.idl @@ -0,0 +1,100 @@ +/* -LICENSE-START- +** Copyright (c) 2012 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation (the +** "Software") to use, reproduce, display, distribute, sub-license, execute, +** and transmit the Software, and to prepare derivative works of the Software, +** and to permit third-parties to whom the Software is furnished to do so, in +** accordance with: +** +** (1) if the Software is obtained from Blackmagic Design, the End User License +** Agreement for the Software Development Kit (“EULA”) available at +** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or +** +** (2) if the Software is obtained from any third party, such licensing terms +** as notified by that third party, +** +** and all subject to the following: +** +** (3) the copyright notices in the Software and this entire statement, +** including the above license grant, this restriction and the following +** disclaimer, must be included in all copies of the Software, in whole or in +** part, and all derivative works of the Software, unless such copies or +** derivative works are solely in the form of machine-executable object code +** generated by a source language processor. +** +** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** +** A copy of the Software is available free of charge at +** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA. +** +** -LICENSE-END- +*/ + +/* DeckLinkAPI_v9_9.idl */ + + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(A3EF0963-0862-44ED-92A9-EE89ABF431C7), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput_v9_9 : IUnknown +{ + HRESULT DoesSupportVideoMode([in] BMDDisplayMode displayMode, [in] BMDPixelFormat pixelFormat, [in] BMDVideoOutputFlags flags, [out] BMDDisplayModeSupport_v10_11 *result, [out] IDeckLinkDisplayMode **resultDisplayMode); + HRESULT GetDisplayModeIterator([out] IDeckLinkDisplayModeIterator **iterator); + + HRESULT SetScreenPreviewCallback([in] IDeckLinkScreenPreviewCallback *previewCallback); + + /* Video Output */ + + HRESULT EnableVideoOutput([in] BMDDisplayMode displayMode, [in] BMDVideoOutputFlags flags); + HRESULT DisableVideoOutput(void); + + HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); + HRESULT CreateVideoFrame([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame); + HRESULT CreateAncillaryData([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer); + + HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame); + HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback([in] IDeckLinkVideoOutputCallback *theCallback); + HRESULT GetBufferedVideoFrameCount([out] unsigned int *bufferedFrameCount); + + /* Audio Output */ + + HRESULT EnableAudioOutput([in] BMDAudioSampleRate sampleRate, [in] BMDAudioSampleType sampleType, [in] unsigned int channelCount, [in] BMDAudioOutputStreamType streamType); + HRESULT DisableAudioOutput(void); + + HRESULT WriteAudioSamplesSync([in] void *buffer, [in] unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten); + + HRESULT BeginAudioPreroll(void); + HRESULT EndAudioPreroll(void); + HRESULT ScheduleAudioSamples([in] void *buffer, [in] unsigned int sampleFrameCount, [in] BMDTimeValue streamTime, [in] BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten); + + HRESULT GetBufferedAudioSampleFrameCount([out] unsigned int *bufferedSampleFrameCount); + HRESULT FlushBufferedAudioSamples(void); + + HRESULT SetAudioCallback([in] IDeckLinkAudioOutputCallback *theCallback); + + /* Output Control */ + + HRESULT StartScheduledPlayback([in] BMDTimeValue playbackStartTime, [in] BMDTimeScale timeScale, [in] double playbackSpeed); + HRESULT StopScheduledPlayback([in] BMDTimeValue stopPlaybackAtTime, [out] BMDTimeValue *actualStopTime, [in] BMDTimeScale timeScale); + HRESULT IsScheduledPlaybackRunning([out] BOOL *active); + HRESULT GetScheduledStreamTime([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed); + HRESULT GetReferenceStatus([out] BMDReferenceStatus *referenceStatus); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + diff --git a/subprojects/gst-plugins-bad/sys/ipcpipeline/gstipcpipelinesrc.c b/subprojects/gst-plugins-bad/sys/ipcpipeline/gstipcpipelinesrc.c index b5267286cc..2f40ca2e10 100644 --- a/subprojects/gst-plugins-bad/sys/ipcpipeline/gstipcpipelinesrc.c +++ b/subprojects/gst-plugins-bad/sys/ipcpipeline/gstipcpipelinesrc.c @@ -362,7 +362,7 @@ gst_ipc_pipeline_src_start_loop (GstIpcPipelineSrc * src) g_mutex_unlock (&src->comm.mutex); gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_ipc_pipeline_src_loop, - src, NULL); + gst_object_ref (src), gst_object_unref); } static void diff --git a/subprojects/gst-plugins-bad/sys/meson.build b/subprojects/gst-plugins-bad/sys/meson.build index 57370ace62..65f8d0bc5d 100644 --- a/subprojects/gst-plugins-bad/sys/meson.build +++ b/subprojects/gst-plugins-bad/sys/meson.build @@ -8,6 +8,7 @@ subdir('d3d11') subdir('d3d12') subdir('d3dvideosink') subdir('decklink') +subdir('decklink2') subdir('directsound') subdir('directshow') subdir('dvb') diff --git a/subprojects/gst-plugins-bad/sys/uvcgadget/gstuvcsink.c b/subprojects/gst-plugins-bad/sys/uvcgadget/gstuvcsink.c index da11e3f5e6..aba1799db3 100644 --- a/subprojects/gst-plugins-bad/sys/uvcgadget/gstuvcsink.c +++ b/subprojects/gst-plugins-bad/sys/uvcgadget/gstuvcsink.c @@ -865,7 +865,8 @@ gst_uvc_sink_watch (GstUvcSink * self) } if (!gst_pad_start_task (GST_PAD (self->sinkpad), - (GstTaskFunction) gst_uvc_sink_task, self, NULL)) { + (GstTaskFunction) gst_uvc_sink_task, gst_object_ref (self), + gst_object_unref)) { GST_ELEMENT_ERROR (self, CORE, THREAD, ("Could not start pad task"), ("Could not start pad task")); return FALSE; diff --git a/subprojects/gst-plugins-bad/tests/examples/meson.build b/subprojects/gst-plugins-bad/tests/examples/meson.build index 04bdccccb3..22dbc5b3fa 100644 --- a/subprojects/gst-plugins-bad/tests/examples/meson.build +++ b/subprojects/gst-plugins-bad/tests/examples/meson.build @@ -18,6 +18,7 @@ subdir('nvcodec') subdir('opencv', if_found: opencv_dep) subdir('qsv') subdir('qt6d3d11') +subdir('streamselector') subdir('uvch264') subdir('va') subdir('vulkan') diff --git a/subprojects/gst-plugins-bad/tests/examples/streamselector/meson.build b/subprojects/gst-plugins-bad/tests/examples/streamselector/meson.build new file mode 100644 index 0000000000..ff9ef7c93a --- /dev/null +++ b/subprojects/gst-plugins-bad/tests/examples/streamselector/meson.build @@ -0,0 +1,6 @@ +executable('streamselector', + ['streamselector.c'], + include_directories : [configinc], + dependencies: [gst_dep], + c_args : gst_plugins_bad_args, + install: false) diff --git a/subprojects/gst-plugins-bad/tests/examples/streamselector/streamselector.c b/subprojects/gst-plugins-bad/tests/examples/streamselector/streamselector.c new file mode 100644 index 0000000000..ebff8ffaa1 --- /dev/null +++ b/subprojects/gst-plugins-bad/tests/examples/streamselector/streamselector.c @@ -0,0 +1,125 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +static GMainLoop *loop = NULL; + +typedef struct +{ + GstElement *selector; + guint active_pad_num; +} SwitchData; + +static gboolean +bus_msg (GstBus * bus, GstMessage * message, gpointer data) +{ + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_ERROR:{ + GError *err; + gchar *debug; + + gst_message_parse_error (message, &err, &debug); + gst_println ("Error: %s", err->message); + g_error_free (err); + g_free (debug); + + g_main_loop_quit (loop); + break; + } + case GST_MESSAGE_EOS: + g_main_loop_quit (loop); + break; + default: + break; + } + + return TRUE; +} + +static gboolean +timer_cb (SwitchData * data) +{ + GstPad *to_active; + + if (data->active_pad_num == 0) { + to_active = gst_element_get_static_pad (data->selector, "sink_1"); + data->active_pad_num = 1; + } else { + to_active = gst_element_get_static_pad (data->selector, "sink_0"); + data->active_pad_num = 0; + } + + gst_println ("Switching to pad %d", data->active_pad_num); + + g_object_set (to_active, "active", TRUE, NULL); + + return G_SOURCE_CONTINUE; +} + +int +main (int argc, char *argv[]) +{ + GstElement *pipeline; + GstBus *bus; + SwitchData data; + + gst_init (&argc, &argv); + + loop = g_main_loop_new (NULL, FALSE); + + pipeline = gst_parse_launch ("streamselector name=selector ! videoconvert ! " + "videoscale ! autovideosink videotestsrc ! " + "video/x-raw,format=RGBA,width=640,height=480,framerate=30/1 ! queue ! " + "selector. videotestsrc pattern=ball ! " + "video/x-raw,format=NV12,width=320,height=240 ! queue ! " + "selector.", NULL); + + if (!pipeline) { + gst_printerrln ("Couldn't create pipeline"); + return 1; + } + + data.selector = gst_bin_get_by_name (GST_BIN (pipeline), "selector"); + data.active_pad_num = 0; + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_msg, NULL); + gst_object_unref (bus); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + g_timeout_add_seconds (3, (GSourceFunc) timer_cb, &data); + + g_main_loop_run (loop); + + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (data.selector); + gst_object_unref (pipeline); + + g_main_loop_unref (loop); + + gst_deinit (); + + return 0; +} diff --git a/subprojects/gst-plugins-base/ext/ogg/gstoggdemux.c b/subprojects/gst-plugins-base/ext/ogg/gstoggdemux.c index d6c549f84d..69d0c86d37 100644 --- a/subprojects/gst-plugins-base/ext/ogg/gstoggdemux.c +++ b/subprojects/gst-plugins-base/ext/ogg/gstoggdemux.c @@ -3723,7 +3723,7 @@ gst_ogg_demux_perform_seek_pull (GstOggDemux * ogg, GstEvent * event) /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (ogg->sinkpad, (GstTaskFunction) gst_ogg_demux_loop, - ogg->sinkpad, NULL); + gst_object_ref (ogg->sinkpad), gst_object_unref); } /* streaming can continue now */ @@ -4063,7 +4063,7 @@ gst_ogg_demux_setup_seek_pull (GstOggDemux * ogg, GstEvent * event) gst_event_replace (&ogg->seek_event, event); gst_pad_start_task (ogg->sinkpad, (GstTaskFunction) gst_ogg_demux_loop, - ogg->sinkpad, NULL); + gst_object_ref (ogg->sinkpad), gst_object_unref); GST_PAD_STREAM_UNLOCK (ogg->sinkpad); return TRUE; @@ -5236,7 +5236,7 @@ gst_ogg_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, ogg->pullmode = TRUE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ogg_demux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-base/gst-libs/gst/tag/gsttagdemux.c b/subprojects/gst-plugins-base/gst-libs/gst/tag/gsttagdemux.c index 16bf0015b6..95cca3380b 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/tag/gsttagdemux.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/tag/gsttagdemux.c @@ -938,7 +938,8 @@ gst_tag_demux_seek_pull (GstTagDemux * tagdemux, GstEvent * event) /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (tagdemux->priv->sinkpad, - (GstTaskFunction) gst_tag_demux_element_loop, tagdemux, NULL); + (GstTaskFunction) gst_tag_demux_element_loop, gst_object_ref (tagdemux), + gst_object_unref); /* streaming can continue now */ GST_PAD_STREAM_UNLOCK (tagdemux->priv->sinkpad); @@ -1603,7 +1604,8 @@ gst_tag_demux_sink_activate (GstPad * sinkpad, GstObject * parent) /* only start our task if we ourselves decide to start in pull mode */ return gst_pad_start_task (sinkpad, - (GstTaskFunction) gst_tag_demux_element_loop, demux, NULL); + (GstTaskFunction) gst_tag_demux_element_loop, gst_object_ref (demux), + gst_object_unref); activate_push: { diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoaggregator.c b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoaggregator.c index 2d8a17dbd2..8f97f52897 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoaggregator.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoaggregator.c @@ -1392,29 +1392,6 @@ gst_video_aggregator_default_negotiated_src_caps (GstAggregator * agg, return ret; } -static gboolean -gst_video_aggregator_get_sinkpads_interlace_mode (GstVideoAggregator * vagg, - GstVideoAggregatorPad * skip_pad, GstVideoInterlaceMode * mode) -{ - GList *walk; - - GST_OBJECT_LOCK (vagg); - for (walk = GST_ELEMENT (vagg)->sinkpads; walk; walk = g_list_next (walk)) { - GstVideoAggregatorPad *vaggpad = walk->data; - - if (skip_pad && vaggpad == skip_pad) - continue; - if (vaggpad->info.finfo - && GST_VIDEO_INFO_FORMAT (&vaggpad->info) != GST_VIDEO_FORMAT_UNKNOWN) { - *mode = GST_VIDEO_INFO_INTERLACE_MODE (&vaggpad->info); - GST_OBJECT_UNLOCK (vagg); - return TRUE; - } - } - GST_OBJECT_UNLOCK (vagg); - return FALSE; -} - static gboolean gst_video_aggregator_pad_sink_setcaps (GstPad * pad, GstObject * parent, GstCaps * caps) @@ -1435,30 +1412,6 @@ gst_video_aggregator_pad_sink_setcaps (GstPad * pad, GstObject * parent, } GST_VIDEO_AGGREGATOR_LOCK (vagg); - { - GstVideoInterlaceMode pads_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; - gboolean has_mode = FALSE; - - /* get the current output setting or fallback to other pads settings */ - if (GST_VIDEO_INFO_FORMAT (&vagg->info) != GST_VIDEO_FORMAT_UNKNOWN) { - pads_mode = GST_VIDEO_INFO_INTERLACE_MODE (&vagg->info); - has_mode = TRUE; - } else { - has_mode = - gst_video_aggregator_get_sinkpads_interlace_mode (vagg, vaggpad, - &pads_mode); - } - - if (has_mode) { - if (pads_mode != GST_VIDEO_INFO_INTERLACE_MODE (&info)) { - GST_ERROR_OBJECT (pad, - "got input caps %" GST_PTR_FORMAT ", but current caps are %" - GST_PTR_FORMAT, caps, vagg->priv->current_caps); - GST_VIDEO_AGGREGATOR_UNLOCK (vagg); - return FALSE; - } - } - } if (!vaggpad->info.finfo || GST_VIDEO_INFO_FORMAT (&vaggpad->info) == GST_VIDEO_FORMAT_UNKNOWN) { @@ -1484,116 +1437,6 @@ gst_video_aggregator_pad_sink_setcaps (GstPad * pad, GstObject * parent, return ret; } -static gboolean -gst_video_aggregator_caps_has_alpha (GstCaps * caps) -{ - guint size = gst_caps_get_size (caps); - guint i; - - for (i = 0; i < size; i++) { - GstStructure *s = gst_caps_get_structure (caps, i); - const GValue *formats = gst_structure_get_value (s, "format"); - - if (formats) { - const GstVideoFormatInfo *info; - - if (GST_VALUE_HOLDS_LIST (formats)) { - guint list_size = gst_value_list_get_size (formats); - guint index; - - for (index = 0; index < list_size; index++) { - const GValue *list_item = gst_value_list_get_value (formats, index); - info = - gst_video_format_get_info (gst_video_format_from_string - (g_value_get_string (list_item))); - if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info)) - return TRUE; - } - - } else if (G_VALUE_HOLDS_STRING (formats)) { - info = - gst_video_format_get_info (gst_video_format_from_string - (g_value_get_string (formats))); - if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info)) - return TRUE; - - } else { - g_assert_not_reached (); - GST_WARNING ("Unexpected type for video 'format' field: %s", - G_VALUE_TYPE_NAME (formats)); - } - - } else { - return TRUE; - } - } - return FALSE; -} - -static GstCaps * -_get_non_alpha_caps (GstCaps * caps) -{ - GstCaps *result; - guint i, size; - - size = gst_caps_get_size (caps); - result = gst_caps_new_empty (); - for (i = 0; i < size; i++) { - GstStructure *s = gst_caps_get_structure (caps, i); - const GValue *formats = gst_structure_get_value (s, "format"); - GValue new_formats = { 0, }; - gboolean has_format = FALSE; - - /* FIXME what to do if formats are missing? */ - if (formats) { - const GstVideoFormatInfo *info; - - if (GST_VALUE_HOLDS_LIST (formats)) { - guint list_size = gst_value_list_get_size (formats); - guint index; - - g_value_init (&new_formats, GST_TYPE_LIST); - - for (index = 0; index < list_size; index++) { - const GValue *list_item = gst_value_list_get_value (formats, index); - - info = - gst_video_format_get_info (gst_video_format_from_string - (g_value_get_string (list_item))); - if (!GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info)) { - has_format = TRUE; - gst_value_list_append_value (&new_formats, list_item); - } - } - - } else if (G_VALUE_HOLDS_STRING (formats)) { - info = - gst_video_format_get_info (gst_video_format_from_string - (g_value_get_string (formats))); - if (!GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info)) { - has_format = TRUE; - gst_value_init_and_copy (&new_formats, formats); - } - - } else { - g_assert_not_reached (); - GST_WARNING ("Unexpected type for video 'format' field: %s", - G_VALUE_TYPE_NAME (formats)); - } - - if (has_format) { - s = gst_structure_copy (s); - gst_structure_take_value_static_str (s, "format", &new_formats); - gst_caps_append_structure_full (result, s, - gst_caps_features_copy (gst_caps_get_features (caps, i))); - } - - } - } - - return result; -} - static GstCaps * gst_video_aggregator_pad_sink_getcaps (GstPad * pad, GstVideoAggregator * vagg, GstCaps * filter) @@ -1605,9 +1448,6 @@ gst_video_aggregator_pad_sink_getcaps (GstPad * pad, GstVideoAggregator * vagg, gint i, n; GstAggregator *agg = GST_AGGREGATOR (vagg); GstPad *srcpad = GST_PAD (agg->srcpad); - gboolean has_alpha; - GstVideoInterlaceMode interlace_mode; - gboolean has_interlace_mode; template_caps = gst_pad_get_pad_template_caps (srcpad); @@ -1615,11 +1455,6 @@ gst_video_aggregator_pad_sink_getcaps (GstPad * pad, GstVideoAggregator * vagg, srccaps = gst_pad_peer_query_caps (srcpad, template_caps); srccaps = gst_caps_make_writable (srccaps); - has_alpha = gst_video_aggregator_caps_has_alpha (srccaps); - - has_interlace_mode = - gst_video_aggregator_get_sinkpads_interlace_mode (vagg, NULL, - &interlace_mode); n = gst_caps_get_size (srccaps); for (i = 0; i < n; i++) { @@ -1634,9 +1469,7 @@ gst_video_aggregator_pad_sink_getcaps (GstPad * pad, GstVideoAggregator * vagg, "pixel-aspect-ratio", NULL); } - if (has_interlace_mode) - gst_structure_set_static_str (s, "interlace-mode", G_TYPE_STRING, - gst_video_interlace_mode_to_string (interlace_mode), NULL); + gst_structure_remove_fields (s, "interlace-mode", NULL); } if (filter) { @@ -1647,11 +1480,6 @@ gst_video_aggregator_pad_sink_getcaps (GstPad * pad, GstVideoAggregator * vagg, } sink_template_caps = gst_pad_get_pad_template_caps (pad); - if (!has_alpha) { - GstCaps *tmp = _get_non_alpha_caps (sink_template_caps); - gst_caps_unref (sink_template_caps); - sink_template_caps = tmp; - } { GstCaps *intersect = gst_caps_intersect (returned_caps, sink_template_caps); @@ -2979,6 +2807,8 @@ gst_video_aggregator_pad_sink_acceptcaps (GstPad * pad, gst_structure_remove_fields (s, "colorimetry", "chroma-site", "format", "pixel-aspect-ratio", NULL); } + + gst_structure_remove_fields (s, "interlace-mode", NULL); } ret = gst_caps_can_intersect (caps, accepted_caps); diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideodecoder.c b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideodecoder.c index c657b6b723..c379bcc4d4 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideodecoder.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideodecoder.c @@ -3282,27 +3282,23 @@ gst_video_decoder_prepare_finish_frame (GstVideoDecoder * } if (frame->pts == GST_CLOCK_TIME_NONE) { - /* Last ditch timestamp guess: Just add the duration to the previous - * frame. If it's the first frame, just use the segment start. */ - if (frame->duration != GST_CLOCK_TIME_NONE) { + if (frame->dts != GST_CLOCK_TIME_NONE) { + frame->pts = frame->dts; + GST_LOG_OBJECT (decoder, + "Setting DTS as PTS %" GST_TIME_FORMAT " for frame...", + GST_TIME_ARGS (frame->pts)); + } else if (frame->duration != GST_CLOCK_TIME_NONE) { + /* Last ditch timestamp guess: Just add the duration to the previous + * frame. If it's the first frame, just use the segment start. */ if (GST_CLOCK_TIME_IS_VALID (priv->last_timestamp_out)) frame->pts = priv->last_timestamp_out + frame->duration; - else if (frame->dts != GST_CLOCK_TIME_NONE) { - frame->pts = frame->dts; - GST_LOG_OBJECT (decoder, - "Setting DTS as PTS %" GST_TIME_FORMAT " for frame...", - GST_TIME_ARGS (frame->pts)); - } else if (decoder->output_segment.rate > 0.0) + else if (decoder->output_segment.rate > 0.0) frame->pts = decoder->output_segment.start; + GST_INFO_OBJECT (decoder, "Guessing PTS=%" GST_TIME_FORMAT " for frame... DTS=%" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts)); - } else if (sync && frame->dts != GST_CLOCK_TIME_NONE) { - frame->pts = frame->dts; - GST_LOG_OBJECT (decoder, - "Setting DTS as PTS %" GST_TIME_FORMAT " for frame...", - GST_TIME_ARGS (frame->pts)); } } diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c index 931966353f..dd2bc28fa9 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c @@ -1734,3 +1734,88 @@ gst_buffer_add_video_time_code_meta_full (GstBuffer * buffer, guint fps_n, return meta; } + +GType +gst_video_audio_meta_api_get_type (void) +{ + static volatile GType type; + + if (g_once_init_enter (&type)) { + static const gchar *tags[] = { NULL }; + GType _type = gst_meta_api_type_register ("GstVideoAudioMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + + +static gboolean +gst_video_audio_meta_transform (GstBuffer * dest, GstMeta * meta, + GstBuffer * buffer, GQuark type, gpointer data) +{ + GstVideoAudioMeta *dmeta, *smeta; + + if (GST_META_TRANSFORM_IS_COPY (type)) { + smeta = (GstVideoAudioMeta *) meta; + + GST_DEBUG ("copy video audio metadata"); + dmeta = gst_buffer_add_video_audio_meta (dest, smeta->buffer); + if (!dmeta) + return FALSE; + } else { + /* return FALSE, if transform type is not supported */ + return FALSE; + } + return TRUE; +} + +static gboolean +gst_video_audio_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer) +{ + GstVideoAudioMeta *emeta = (GstVideoAudioMeta *) meta; + + emeta->buffer = NULL; + + return TRUE; +} + +static void +gst_video_audio_meta_free (GstMeta * meta, GstBuffer * buffer) +{ + GstVideoAudioMeta *emeta = (GstVideoAudioMeta *) meta; + + gst_buffer_replace (&emeta->buffer, NULL); +} + +const GstMetaInfo * +gst_video_audio_meta_get_info (void) +{ + static const GstMetaInfo *meta_info = NULL; + + if (g_once_init_enter ((GstMetaInfo **) & meta_info)) { + const GstMetaInfo *mi = gst_meta_register (GST_VIDEO_AUDIO_META_API_TYPE, + "GstVideoAudioMeta", + sizeof (GstVideoAudioMeta), + gst_video_audio_meta_init, + gst_video_audio_meta_free, + gst_video_audio_meta_transform); + g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) mi); + } + return meta_info; +} + +GstVideoAudioMeta * +gst_buffer_add_video_audio_meta (GstBuffer * buffer, GstBuffer * audio_buffer) +{ + GstVideoAudioMeta *meta; + + g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (audio_buffer != NULL, NULL); + + meta = (GstVideoAudioMeta *) gst_buffer_add_meta (buffer, + GST_VIDEO_AUDIO_META_INFO, NULL); + + meta->buffer = gst_buffer_ref (audio_buffer); + + return meta; +} diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.h b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.h index a87dfd30ec..5f989c40e1 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.h @@ -495,6 +495,26 @@ gst_buffer_add_video_time_code_meta_full (GstBuffer guint frames, guint field_count); +typedef struct { + GstMeta meta; + + GstBuffer *buffer; +} GstVideoAudioMeta; + +GST_VIDEO_API +GType gst_video_audio_meta_api_get_type (void); +#define GST_VIDEO_AUDIO_META_API_TYPE (gst_video_audio_meta_api_get_type()) + +GST_VIDEO_API +const GstMetaInfo *gst_video_audio_meta_get_info (void); +#define GST_VIDEO_AUDIO_META_INFO (gst_video_audio_meta_get_info()) + +#define gst_buffer_get_video_audio_meta(b) \ + ((GstVideoAudioMeta*)gst_buffer_get_meta((b),GST_VIDEO_AUDIO_META_API_TYPE)) + +GST_VIDEO_API +GstVideoAudioMeta *gst_buffer_add_video_audio_meta (GstBuffer * buffer, GstBuffer * audio_buffer); + G_END_DECLS #endif /* __GST_VIDEO_META_H__ */ diff --git a/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.c b/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.c index 713ca52a9f..b64ff8437c 100644 --- a/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.c +++ b/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.c @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2018 Sebastian Dröge + * Copyright (C) 2022 Seungha Yang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,7 +22,9 @@ * SECTION:element-overlaycomposition * * The overlaycomposition element renders an overlay using an application - * provided draw function. + * provided draw function and/or blends already attached + * `GstVideoOverlayComposition` meta with incoming buffer if downstream does not + * support the `GstVideoOverlayComposition` meta. * * ## Example code * @@ -39,11 +42,25 @@ GST_DEBUG_CATEGORY_STATIC (gst_overlay_composition_debug); #define GST_CAT_DEFAULT gst_overlay_composition_debug -#define OVERLAY_COMPOSITION_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_OVERLAY_COMPOSITION_BLEND_FORMATS) - -#define ALL_CAPS OVERLAY_COMPOSITION_CAPS ";" \ +#define TEMPLATE_CAPS \ + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," \ + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, \ + GST_VIDEO_FORMATS_ALL) "; " \ + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " \ GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ANY) +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (TEMPLATE_CAPS) + ); + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (TEMPLATE_CAPS) + ); + enum { SIGNAL_CAPS_CHANGED, @@ -53,70 +70,59 @@ enum static guint overlay_composition_signals[LAST_SIGNAL]; -static GstStaticCaps overlay_composition_caps = -GST_STATIC_CAPS (OVERLAY_COMPOSITION_CAPS); - -static gboolean -can_blend_caps (GstCaps * incaps) +typedef enum { - gboolean ret; - GstCaps *caps; - - caps = gst_static_caps_get (&overlay_composition_caps); - ret = gst_caps_is_subset (incaps, caps); - gst_caps_unref (caps); + OVERLAY_MODE_UNKNOWN, + OVERLAY_MODE_ADD_META, + OVERLAY_MODE_BLEND, + OVERLAY_MODE_NOT_SUPPORTED, +} OverlayMode; - return ret; -} +struct _GstOverlayComposition +{ + GstBaseTransform parent; + + GstSample *sample; + GstVideoInfo info; + guint window_width; + guint window_height; + gboolean system_memory; + gboolean downstream_supports_meta; + gboolean allocation_supports_meta; + gboolean caps_changed; + OverlayMode overlay_mode; +}; -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (ALL_CAPS) - ); +#define gst_overlay_composition_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstOverlayComposition, gst_overlay_composition, + GST_TYPE_BASE_TRANSFORM, + GST_DEBUG_CATEGORY_INIT (gst_overlay_composition_debug, + "overlaycomposition", 0, "Overlay Composition")); -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (ALL_CAPS) - ); - -#define parent_class gst_overlay_composition_parent_class -G_DEFINE_TYPE (GstOverlayComposition, gst_overlay_composition, - GST_TYPE_ELEMENT); GST_ELEMENT_REGISTER_DEFINE (overlaycomposition, "overlaycomposition", GST_RANK_NONE, GST_TYPE_OVERLAY_COMPOSITION); -static GstFlowReturn gst_overlay_composition_sink_chain (GstPad * pad, - GstObject * parent, GstBuffer * buffer); -static gboolean gst_overlay_composition_sink_event (GstPad * pad, - GstObject * parent, GstEvent * event); -static gboolean gst_overlay_composition_sink_query (GstPad * pad, - GstObject * parent, GstQuery * query); -static gboolean gst_overlay_composition_src_query (GstPad * pad, - GstObject * parent, GstQuery * query); - -static GstStateChangeReturn gst_overlay_composition_change_state (GstElement * - element, GstStateChange transition); +static gboolean gst_overlay_composition_start (GstBaseTransform * trans); +static gboolean gst_overlay_composition_stop (GstBaseTransform * trans); +static gboolean +gst_overlay_composition_propose_allocation (GstBaseTransform * trans, + GstQuery * decide_query, GstQuery * query); +static GstCaps *gst_overlay_composition_transform_caps (GstBaseTransform * + trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter); +static GstCaps *gst_overlay_composition_fixate_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * othercaps); +static gboolean gst_overlay_composition_set_caps (GstBaseTransform * trans, + GstCaps * incaps, GstCaps * outcaps); +static GstFlowReturn gst_overlay_composition_transform (GstBaseTransform * + trans, GstBuffer * inbuf, GstBuffer * outbuf); +static GstFlowReturn gst_overlay_composition_generate_output (GstBaseTransform * + trans, GstBuffer ** outbuf); static void gst_overlay_composition_class_init (GstOverlayCompositionClass * klass) { - GstElementClass *gstelement_class = (GstElementClass *) klass; - - GST_DEBUG_CATEGORY_INIT (gst_overlay_composition_debug, "overlaycomposition", - 0, "Overlay Composition"); - - gst_element_class_set_static_metadata (gstelement_class, - "Overlay Composition", "Filter/Editor/Video", - "Overlay Composition", "Sebastian Dröge "); - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&src_template)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sink_template)); - - gstelement_class->change_state = gst_overlay_composition_change_state; + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstBaseTransformClass *transform_class = GST_BASE_TRANSFORM_CLASS (klass); /** * GstOverlayComposition::draw: @@ -149,563 +155,307 @@ gst_overlay_composition_class_init (GstOverlayCompositionClass * klass) g_signal_new ("caps-changed", G_TYPE_FROM_CLASS (klass), 0, 0, NULL, NULL, NULL, G_TYPE_NONE, 3, GST_TYPE_CAPS, G_TYPE_UINT, G_TYPE_UINT); + + gst_element_class_set_static_metadata (element_class, + "Overlay Composition", "Filter/Editor/Video", + "Overlay Composition", "Sebastian Dröge "); + + gst_element_class_add_static_pad_template (element_class, &src_template); + gst_element_class_add_static_pad_template (element_class, &sink_template); + + transform_class->passthrough_on_same_caps = FALSE; + + transform_class->start = GST_DEBUG_FUNCPTR (gst_overlay_composition_start); + transform_class->stop = GST_DEBUG_FUNCPTR (gst_overlay_composition_stop); + transform_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_overlay_composition_propose_allocation); + transform_class->transform_caps = + GST_DEBUG_FUNCPTR (gst_overlay_composition_transform_caps); + transform_class->fixate_caps = + GST_DEBUG_FUNCPTR (gst_overlay_composition_fixate_caps); + transform_class->set_caps = + GST_DEBUG_FUNCPTR (gst_overlay_composition_set_caps); + transform_class->transform = + GST_DEBUG_FUNCPTR (gst_overlay_composition_transform); + transform_class->generate_output = + GST_DEBUG_FUNCPTR (gst_overlay_composition_generate_output); } static void gst_overlay_composition_init (GstOverlayComposition * self) { - self->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink"); - gst_pad_set_chain_function (self->sinkpad, - GST_DEBUG_FUNCPTR (gst_overlay_composition_sink_chain)); - gst_pad_set_event_function (self->sinkpad, - GST_DEBUG_FUNCPTR (gst_overlay_composition_sink_event)); - gst_pad_set_query_function (self->sinkpad, - GST_DEBUG_FUNCPTR (gst_overlay_composition_sink_query)); - GST_PAD_SET_PROXY_ALLOCATION (self->sinkpad); - gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); - - self->srcpad = gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_set_query_function (self->srcpad, - GST_DEBUG_FUNCPTR (gst_overlay_composition_src_query)); - gst_element_add_pad (GST_ELEMENT (self), self->srcpad); } -static GstStateChangeReturn -gst_overlay_composition_change_state (GstElement * element, - GstStateChange transition) +static gboolean +gst_overlay_composition_start (GstBaseTransform * trans) { - GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (element); - GstStateChangeReturn state_ret; + GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (trans); - switch (transition) { - default: - break; - } + self->sample = gst_sample_new (NULL, NULL, NULL, NULL); - state_ret = - GST_ELEMENT_CLASS (gst_overlay_composition_parent_class)->change_state - (element, transition); - if (state_ret == GST_STATE_CHANGE_FAILURE) - return state_ret; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - memset (&self->info, 0, sizeof (self->info)); - self->window_width = self->window_height = 0; - self->attach_compo_to_buffer = FALSE; - if (self->sample) { - gst_sample_unref (self->sample); - self->sample = NULL; - } - gst_caps_replace (&self->caps, NULL); - gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); - break; - default: - break; - } - - return state_ret; + return TRUE; } -/* Based on gstbasetextoverlay.c */ static gboolean -gst_overlay_composition_negotiate (GstOverlayComposition * self, GstCaps * caps) +gst_overlay_composition_stop (GstBaseTransform * trans) { - gboolean upstream_has_meta = FALSE; - gboolean caps_has_meta = FALSE; - gboolean alloc_has_meta = FALSE; - gboolean attach = FALSE; - gboolean ret = TRUE; - guint width, height; - GstCapsFeatures *f; - GstCaps *overlay_caps; - GstQuery *query; - guint alloc_index; - - GST_DEBUG_OBJECT (self, "performing negotiation"); - - /* Clear any pending reconfigure to avoid negotiating twice */ - gst_pad_check_reconfigure (self->srcpad); - - self->window_width = self->window_height = 0; - - if (!caps) - caps = gst_pad_get_current_caps (self->sinkpad); - else - gst_caps_ref (caps); - - if (!caps || gst_caps_is_empty (caps)) - goto no_format; - - /* Check if upstream caps have meta */ - if ((f = gst_caps_get_features (caps, 0))) { - upstream_has_meta = gst_caps_features_contains (f, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); - } - - /* Initialize dimensions */ - width = self->info.width; - height = self->info.height; - - if (upstream_has_meta) { - overlay_caps = gst_caps_ref (caps); - } else { - GstCaps *peercaps; - - /* BaseTransform requires caps for the allocation query to work */ - overlay_caps = gst_caps_copy (caps); - f = gst_caps_get_features (overlay_caps, 0); - gst_caps_features_add (f, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); - - /* Then check if downstream accept overlay composition in caps */ - /* FIXME: We should probably check if downstream *prefers* the - * overlay meta, and only enforce usage of it if we can't handle - * the format ourselves and thus would have to drop the overlays. - * Otherwise we should prefer what downstream wants here. - */ - peercaps = gst_pad_peer_query_caps (self->srcpad, overlay_caps); - caps_has_meta = !gst_caps_is_empty (peercaps); - gst_caps_unref (peercaps); - - GST_DEBUG_OBJECT (self, "caps have overlay meta %d", caps_has_meta); - } - - if (upstream_has_meta || caps_has_meta) { - /* Send caps immediately, it's needed by GstBaseTransform to get a reply - * from allocation query */ - ret = gst_pad_set_caps (self->srcpad, overlay_caps); - - /* First check if the allocation meta has compositon */ - query = gst_query_new_allocation (overlay_caps, FALSE); - - if (!gst_pad_peer_query (self->srcpad, query)) { - /* no problem, we use the query defaults */ - GST_DEBUG_OBJECT (self, "ALLOCATION query failed"); - - /* In case we were flushing, mark reconfigure and fail this method, - * will make it retry */ - if (GST_PAD_IS_FLUSHING (self->srcpad)) - ret = FALSE; - } - - alloc_has_meta = gst_query_find_allocation_meta (query, - GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, &alloc_index); - - GST_DEBUG_OBJECT (self, "sink alloc has overlay meta %d", alloc_has_meta); - - if (alloc_has_meta) { - const GstStructure *params; - - gst_query_parse_nth_allocation_meta (query, alloc_index, ¶ms); - if (params) { - if (gst_structure_get (params, "width", G_TYPE_UINT, &width, - "height", G_TYPE_UINT, &height, NULL)) { - GST_DEBUG_OBJECT (self, "received window size: %dx%d", width, height); - g_assert (width != 0 && height != 0); - } - } - } - - gst_query_unref (query); - } - - /* Update render size if needed */ - self->window_width = width; - self->window_height = height; - - /* For backward compatibility, we will prefer blitting if downstream - * allocation does not support the meta. In other case we will prefer - * attaching, and will fail the negotiation in the unlikely case we are - * force to blit, but format isn't supported. */ - - if (upstream_has_meta) { - attach = TRUE; - } else if (caps_has_meta) { - if (alloc_has_meta) { - attach = TRUE; - } else { - /* Don't attach unless we cannot handle the format */ - attach = !can_blend_caps (caps); - } - } else { - ret = can_blend_caps (caps); - } - - /* If we attach, then pick the overlay caps */ - if (attach) { - GST_DEBUG_OBJECT (self, "Using caps %" GST_PTR_FORMAT, overlay_caps); - /* Caps where already sent */ - } else if (ret) { - GST_DEBUG_OBJECT (self, "Using caps %" GST_PTR_FORMAT, caps); - ret = gst_pad_set_caps (self->srcpad, caps); - } - - self->attach_compo_to_buffer = attach; + GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (trans); - if (!ret) { - GST_DEBUG_OBJECT (self, "negotiation failed, schedule reconfigure"); - gst_pad_mark_reconfigure (self->srcpad); - } + g_clear_pointer (&self->sample, gst_sample_unref); - g_signal_emit (self, overlay_composition_signals[SIGNAL_CAPS_CHANGED], 0, - caps, self->window_width, self->window_height, NULL); - - gst_caps_unref (overlay_caps); - gst_caps_unref (caps); - - return ret; - -no_format: - { - if (caps) - gst_caps_unref (caps); - gst_pad_mark_reconfigure (self->srcpad); - return FALSE; - } + return TRUE; } static gboolean -gst_overlay_composition_sink_event (GstPad * pad, GstObject * parent, - GstEvent * event) +gst_overlay_composition_propose_allocation (GstBaseTransform * trans, + GstQuery * decide_query, GstQuery * query) { - GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (parent); - gboolean ret = FALSE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEGMENT: - gst_event_copy_segment (event, &self->segment); - ret = gst_pad_event_default (pad, parent, event); - break; - case GST_EVENT_CAPS:{ - GstCaps *caps; - - gst_event_parse_caps (event, &caps); - if (!gst_video_info_from_caps (&self->info, caps)) { - gst_event_unref (event); - ret = FALSE; - break; - } - - if (!gst_overlay_composition_negotiate (self, caps)) { - gst_event_unref (event); - ret = FALSE; - break; - } - - gst_caps_replace (&self->caps, caps); - - ret = TRUE; - gst_event_unref (event); - - break; - } - case GST_EVENT_FLUSH_STOP: - gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); - ret = gst_pad_event_default (pad, parent, event); - break; - default: - ret = gst_pad_event_default (pad, parent, event); - break; + if (!GST_BASE_TRANSFORM_CLASS (parent_class)->propose_allocation (trans, + decide_query, query)) { + return FALSE; } - return ret; + /* Passthrough */ + if (!decide_query) + return TRUE; + + return gst_pad_peer_query (trans->srcpad, query); } -/* Based on gstbasetextoverlay.c */ -/** - * add_feature_and_intersect: - * - * Creates a new #GstCaps containing the (given caps + - * given caps feature) + (given caps intersected by the - * given filter). - * - * Returns: the new #GstCaps - */ static GstCaps * -add_feature_and_intersect (GstCaps * caps, - const gchar * feature, GstCaps * filter) +add_overlay_feature (GstCaps * caps) { - int i, caps_size; - GstCaps *new_caps; - - new_caps = gst_caps_copy (caps); + GstCaps *new_caps = gst_caps_new_empty (); + guint caps_size = gst_caps_get_size (caps); + guint i; - caps_size = gst_caps_get_size (new_caps); for (i = 0; i < caps_size; i++) { - GstCapsFeatures *features = gst_caps_get_features (new_caps, i); + GstStructure *s = gst_caps_get_structure (caps, i); + GstCapsFeatures *f = + gst_caps_features_copy (gst_caps_get_features (caps, i)); + GstCaps *c = gst_caps_new_full (gst_structure_copy (s), NULL); - if (!gst_caps_features_is_any (features)) { - gst_caps_features_add (features, feature); + if (!gst_caps_features_is_any (f) && + !gst_caps_features_contains (f, + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION)) { + gst_caps_features_add (f, + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); } - } - gst_caps_append (new_caps, gst_caps_intersect_full (caps, - filter, GST_CAPS_INTERSECT_FIRST)); + gst_caps_set_features (c, 0, f); + gst_caps_append (new_caps, c); + } return new_caps; } -/* Based on gstbasetextoverlay.c */ -/* intersect_by_feature: - * - * Creates a new #GstCaps based on the following filtering rule. - * - * For each individual caps contained in given caps, if the - * caps uses the given caps feature, keep a version of the caps - * with the feature and an another one without. Otherwise, intersect - * the caps with the given filter. - * - * Returns: the new #GstCaps - */ static GstCaps * -intersect_by_feature (GstCaps * caps, const gchar * feature, GstCaps * filter) +remove_overlay_feature (GstCaps * caps) { - int i, caps_size; - GstCaps *new_caps; - - new_caps = gst_caps_new_empty (); + GstCaps *new_caps = gst_caps_new_empty (); + guint caps_size = gst_caps_get_size (caps); + guint i; - caps_size = gst_caps_get_size (caps); for (i = 0; i < caps_size; i++) { - GstStructure *caps_structure = gst_caps_get_structure (caps, i); - GstCapsFeatures *caps_features = + GstStructure *s = gst_caps_get_structure (caps, i); + GstCapsFeatures *f = gst_caps_features_copy (gst_caps_get_features (caps, i)); - GstCaps *filtered_caps; - GstCaps *simple_caps = - gst_caps_new_full (gst_structure_copy (caps_structure), NULL); - gst_caps_set_features (simple_caps, 0, caps_features); + GstCaps *c = gst_caps_new_full (gst_structure_copy (s), NULL); - if (gst_caps_features_contains (caps_features, feature)) { - gst_caps_append (new_caps, gst_caps_copy (simple_caps)); - - gst_caps_features_remove (caps_features, feature); - filtered_caps = gst_caps_ref (simple_caps); - } else { - filtered_caps = gst_caps_intersect_full (simple_caps, filter, - GST_CAPS_INTERSECT_FIRST); - } - - gst_caps_unref (simple_caps); - gst_caps_append (new_caps, filtered_caps); + gst_caps_features_remove (f, + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); + gst_caps_set_features (c, 0, f); + gst_caps_append (new_caps, c); } return new_caps; } -/* Based on gstbasetextoverlay.c */ static GstCaps * -gst_overlay_composition_sink_query_caps (GstOverlayComposition * self, - GstCaps * filter) +gst_overlay_composition_transform_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * filter) { - GstCaps *peer_caps = NULL, *caps = NULL, *overlay_filter = NULL; - - if (filter) { - /* filter caps + composition feature + filter caps - * filtered by the software caps. */ - GstCaps *sw_caps = gst_static_caps_get (&overlay_composition_caps); - overlay_filter = add_feature_and_intersect (filter, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps); - gst_caps_unref (sw_caps); - - GST_DEBUG_OBJECT (self->sinkpad, "overlay filter %" GST_PTR_FORMAT, - overlay_filter); - } - - peer_caps = gst_pad_peer_query_caps (self->srcpad, overlay_filter); + GstCaps *result, *tmp; - if (overlay_filter) - gst_caps_unref (overlay_filter); + GST_LOG_OBJECT (trans, + "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, + (direction == GST_PAD_SINK) ? "sink" : "src"); - if (peer_caps) { - - GST_DEBUG_OBJECT (self->sinkpad, "peer caps %" GST_PTR_FORMAT, peer_caps); - - if (gst_caps_is_any (peer_caps)) { - /* if peer returns ANY caps, return filtered src pad template caps */ - GstCaps *tcaps = gst_pad_get_pad_template_caps (self->srcpad); - caps = gst_caps_copy (tcaps); - gst_caps_unref (tcaps); - } else { + tmp = gst_caps_merge (add_overlay_feature (caps), gst_caps_ref (caps)); + tmp = gst_caps_merge (tmp, remove_overlay_feature (caps)); - /* duplicate caps which contains the composition into one version with - * the meta and one without. Filter the other caps by the software caps */ - GstCaps *sw_caps = gst_static_caps_get (&overlay_composition_caps); - caps = intersect_by_feature (peer_caps, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps); - gst_caps_unref (sw_caps); - } - - gst_caps_unref (peer_caps); + if (filter) { + GST_LOG_OBJECT (trans, "Filter caps %" GST_PTR_FORMAT, filter); + result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); } else { - /* no peer, our padtemplate is enough then */ - caps = gst_pad_get_pad_template_caps (self->sinkpad); - } - - if (filter) { - GstCaps *intersection = gst_caps_intersect_full (filter, caps, - GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (caps); - caps = intersection; + result = tmp; } - GST_DEBUG_OBJECT (self->sinkpad, "returning %" GST_PTR_FORMAT, caps); + GST_LOG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, result); - return caps; + return result; } -/* Based on gstbasetextoverlay.c */ static GstCaps * -gst_overlay_composition_src_query_caps (GstOverlayComposition * self, - GstCaps * filter) +gst_overlay_composition_fixate_caps (GstBaseTransform * trans, + GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) { - GstCaps *peer_caps = NULL, *caps = NULL, *overlay_filter = NULL; + GstCaps *overlay_caps = NULL; + guint i; + guint caps_size = gst_caps_get_size (othercaps); - if (filter) { - /* duplicate filter caps which contains the composition into one version - * with the meta and one without. Filter the other caps by the software - * caps */ - GstCaps *sw_caps = gst_static_caps_get (&overlay_composition_caps); - overlay_filter = - intersect_by_feature (filter, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps); - gst_caps_unref (sw_caps); + /* Prefer overlaycomposition caps */ + for (i = 0; i < caps_size; i++) { + GstCapsFeatures *f = gst_caps_get_features (othercaps, i); + + if (f && !gst_caps_features_is_any (f) && + gst_caps_features_contains (f, + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION)) { + GstStructure *s = gst_caps_get_structure (othercaps, i); + overlay_caps = gst_caps_new_full (gst_structure_copy (s), NULL); + gst_caps_set_features_simple (overlay_caps, gst_caps_features_copy (f)); + break; + } } - peer_caps = gst_pad_peer_query_caps (self->sinkpad, overlay_filter); - - if (overlay_filter) - gst_caps_unref (overlay_filter); - - if (peer_caps) { + if (overlay_caps) { + gst_caps_unref (othercaps); + return gst_caps_fixate (overlay_caps); + } - GST_DEBUG_OBJECT (self->srcpad, "peer caps %" GST_PTR_FORMAT, peer_caps); + return gst_caps_fixate (othercaps); +} - if (gst_caps_is_any (peer_caps)) { +static gboolean +gst_overlay_composition_set_caps (GstBaseTransform * trans, GstCaps * incaps, + GstCaps * outcaps) +{ + GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (trans); + GstCapsFeatures *features; - /* if peer returns ANY caps, return filtered sink pad template caps */ - GstCaps *tcaps = gst_pad_get_pad_template_caps (self->sinkpad); - caps = gst_caps_copy (tcaps); - gst_caps_unref (tcaps); + GST_DEBUG_OBJECT (self, "Set incaps %" GST_PTR_FORMAT ", outcaps %" + GST_PTR_FORMAT, incaps, outcaps); - } else { + self->system_memory = FALSE; + self->downstream_supports_meta = FALSE; - /* return upstream caps + composition feature + upstream caps - * filtered by the software caps. */ - GstCaps *sw_caps = gst_static_caps_get (&overlay_composition_caps); - caps = add_feature_and_intersect (peer_caps, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, sw_caps); - gst_caps_unref (sw_caps); - } + if (!gst_video_info_from_caps (&self->info, incaps)) { + GST_ERROR_OBJECT (self, "Invalid incaps %" GST_PTR_FORMAT, incaps); + return FALSE; + } - gst_caps_unref (peer_caps); + features = gst_caps_get_features (incaps, 0); + if (features && gst_caps_features_contains (features, + GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY)) { + self->system_memory = TRUE; + } - } else { - /* no peer, our padtemplate is enough then */ - caps = gst_pad_get_pad_template_caps (self->srcpad); + features = gst_caps_get_features (outcaps, 0); + if (features && gst_caps_features_contains (features, + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION)) { + self->downstream_supports_meta = TRUE; } - if (filter) { - GstCaps *intersection; + gst_sample_set_caps (self->sample, incaps); + self->caps_changed = TRUE; + self->overlay_mode = OVERLAY_MODE_UNKNOWN; - intersection = - gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (caps); - caps = intersection; - } - GST_DEBUG_OBJECT (self->srcpad, "returning %" GST_PTR_FORMAT, caps); + /* will be updated per decide-allocation */ + self->window_width = GST_VIDEO_INFO_WIDTH (&self->info); + self->window_height = GST_VIDEO_INFO_HEIGHT (&self->info); - return caps; + return TRUE; } -static gboolean -gst_overlay_composition_sink_query (GstPad * pad, GstObject * parent, - GstQuery * query) +/* Dummy implementation to make basetransform happy. + * generate_output() method will do the actual transform */ +static GstFlowReturn +gst_overlay_composition_transform (GstBaseTransform * trans, + GstBuffer * inbuf, GstBuffer * outbuf) { - GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (parent); - gboolean ret = FALSE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CAPS:{ - GstCaps *filter, *caps; - - gst_query_parse_caps (query, &filter); - caps = gst_overlay_composition_sink_query_caps (self, filter); - gst_query_set_caps_result (query, caps); - gst_caps_unref (caps); - ret = TRUE; - break; - } - default: - ret = gst_pad_query_default (pad, parent, query); - break; - } - - return ret; + return GST_FLOW_OK; } -static gboolean -gst_overlay_composition_src_query (GstPad * pad, GstObject * parent, - GstQuery * query) +static const gchar * +overlay_mode_name (OverlayMode mode) { - GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (parent); - gboolean ret = FALSE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CAPS:{ - GstCaps *filter, *caps; - - gst_query_parse_caps (query, &filter); - caps = gst_overlay_composition_src_query_caps (self, filter); - gst_query_set_caps_result (query, caps); - gst_caps_unref (caps); - ret = TRUE; - break; - } - default: - ret = gst_pad_query_default (pad, parent, query); - break; + switch (mode) { + case OVERLAY_MODE_UNKNOWN: + return "unknown"; + case OVERLAY_MODE_ADD_META: + return "add-meta"; + case OVERLAY_MODE_BLEND: + return "blend"; + case OVERLAY_MODE_NOT_SUPPORTED: + return "not-supported"; } - return ret; + return "undefined"; } static GstFlowReturn -gst_overlay_composition_sink_chain (GstPad * pad, GstObject * parent, - GstBuffer * buffer) +gst_overlay_composition_generate_output (GstBaseTransform * trans, + GstBuffer ** outbuf) { - GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (parent); - GstVideoOverlayComposition *compo = NULL; - - if (gst_pad_check_reconfigure (self->srcpad)) { - if (!gst_overlay_composition_negotiate (self, NULL)) { - gst_pad_mark_reconfigure (self->srcpad); - gst_buffer_unref (buffer); - GST_OBJECT_LOCK (self->srcpad); - if (GST_PAD_IS_FLUSHING (self->srcpad)) { - GST_OBJECT_UNLOCK (self->srcpad); - return GST_FLOW_FLUSHING; + GstOverlayComposition *self = GST_OVERLAY_COMPOSITION (trans); + GstBuffer *inbuf; + GstVideoOverlayComposition *comp = NULL; + GstVideoOverlayCompositionMeta *meta; + guint i, num_rect; + GstFlowReturn ret = GST_FLOW_OK; + + inbuf = trans->queued_buf; + trans->queued_buf = NULL; + + if (!inbuf) + return GST_FLOW_OK; + + if (self->overlay_mode == OVERLAY_MODE_UNKNOWN) { + GST_DEBUG_OBJECT (self, "Deciding overlay mode, downstream-meta: %d, " + "allocation-meta: %d, system-memory: %d", + self->downstream_supports_meta, self->allocation_supports_meta, + self->system_memory); + + if (self->downstream_supports_meta) { + if (self->allocation_supports_meta || !self->system_memory) { + self->overlay_mode = OVERLAY_MODE_ADD_META; + } else { + self->overlay_mode = OVERLAY_MODE_BLEND; + } + } else { + if (self->system_memory) { + self->overlay_mode = OVERLAY_MODE_BLEND; + } else { + /* downstream does not support meta and also not system memory. + * Nothing we can do */ + GST_ELEMENT_WARNING (self, STREAM, NOT_IMPLEMENTED, (NULL), + ("Neither overlay nor blending is possible")); + self->overlay_mode = OVERLAY_MODE_NOT_SUPPORTED; } - GST_OBJECT_UNLOCK (self->srcpad); - return GST_FLOW_NOT_NEGOTIATED; } + + GST_INFO_OBJECT (self, "Selected overlay mode: %s", + overlay_mode_name (self->overlay_mode)); } - if (!self->sample) { - self->sample = gst_sample_new (buffer, self->caps, &self->segment, NULL); - } else { - self->sample = gst_sample_make_writable (self->sample); - gst_sample_set_buffer (self->sample, buffer); - gst_sample_set_caps (self->sample, self->caps); - gst_sample_set_segment (self->sample, &self->segment); + if (self->overlay_mode == OVERLAY_MODE_NOT_SUPPORTED) + goto out; + + if (self->caps_changed) { + g_signal_emit (self, overlay_composition_signals[SIGNAL_CAPS_CHANGED], 0, + gst_sample_get_caps (self->sample), self->window_width, + self->window_height, NULL); + self->caps_changed = FALSE; } + self->sample = gst_sample_make_writable (self->sample); + gst_sample_set_buffer (self->sample, inbuf); + gst_sample_set_segment (self->sample, &trans->segment); + g_signal_emit (self, overlay_composition_signals[SIGNAL_DRAW], 0, - self->sample, &compo); + self->sample, &comp); /* Don't store the buffer in the sample any longer, otherwise it will not * be writable below as we have one reference in the sample and one in @@ -714,45 +464,76 @@ gst_overlay_composition_sink_chain (GstPad * pad, GstObject * parent, * If the sample is not writable itself then the application kept an * reference itself. */ - if (gst_sample_is_writable (self->sample)) { + if (gst_sample_is_writable (self->sample)) gst_sample_set_buffer (self->sample, NULL); - } - if (!compo) { - GST_DEBUG_OBJECT (self->sinkpad, - "Application did not provide an overlay composition"); - return gst_pad_push (self->srcpad, buffer); + meta = gst_buffer_get_video_overlay_composition_meta (inbuf); + if (!comp && !meta) { + /* Nothing to do, just forward this buffer */ + goto out; } - buffer = gst_buffer_make_writable (buffer); + if (self->overlay_mode == OVERLAY_MODE_ADD_META) { + if (!comp) { + GST_DEBUG_OBJECT (self, + "Application did not provide an overlay composition"); + goto out; + } - if (self->attach_compo_to_buffer) { - GST_DEBUG_OBJECT (self->sinkpad, "Attaching as meta"); + inbuf = gst_buffer_make_writable (inbuf); + if (!meta) { + GST_DEBUG_OBJECT (self, "Attaching as meta"); - gst_buffer_add_video_overlay_composition_meta (buffer, compo); - gst_video_overlay_composition_unref (compo); - } else { + gst_buffer_add_video_overlay_composition_meta (inbuf, comp); + } else { + GST_DEBUG_OBJECT (self, "Appending to upstream overlay composition"); + + meta = gst_buffer_get_video_overlay_composition_meta (inbuf); + meta->overlay = + gst_video_overlay_composition_make_writable (meta->overlay); + + num_rect = gst_video_overlay_composition_n_rectangles (comp); + for (i = 0; i < num_rect; i++) { + GstVideoOverlayRectangle *rect = + gst_video_overlay_composition_get_rectangle (comp, i); + gst_video_overlay_composition_add_rectangle (meta->overlay, rect); + } + } + } else if (self->overlay_mode == OVERLAY_MODE_BLEND) { GstVideoFrame frame; - if (!gst_video_frame_map (&frame, &self->info, buffer, GST_MAP_READWRITE)) { - gst_video_overlay_composition_unref (compo); - goto map_failed; + inbuf = gst_buffer_make_writable (inbuf); + if (!gst_video_frame_map (&frame, &self->info, inbuf, + GST_MAP_READWRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)) { + GST_ERROR_OBJECT (self, "Failed to map buffer"); + ret = GST_FLOW_ERROR; + goto out; } - gst_video_overlay_composition_blend (compo, &frame); + i = 0; + while ((meta = gst_buffer_get_video_overlay_composition_meta (inbuf))) { + GST_LOG_OBJECT (self, "Blending upstream overlay meta %d", i); + gst_video_overlay_composition_blend (meta->overlay, &frame); + gst_buffer_remove_video_overlay_composition_meta (inbuf, meta); + i++; + } + + if (comp) { + GST_LOG_OBJECT (self, "Blending application overlay"); + gst_video_overlay_composition_blend (comp, &frame); + } gst_video_frame_unmap (&frame); - gst_video_overlay_composition_unref (compo); + } else { + g_assert_not_reached (); } - return gst_pad_push (self->srcpad, buffer); +out: + if (comp) + gst_video_overlay_composition_unref (comp); -map_failed: - { - GST_ERROR_OBJECT (self->sinkpad, "Failed to map buffer"); - gst_buffer_unref (buffer); - return GST_FLOW_ERROR; - } + *outbuf = inbuf; + return ret; } static gboolean diff --git a/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.h b/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.h index cc92f98ded..d53c0e9381 100644 --- a/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.h +++ b/subprojects/gst-plugins-base/gst/overlaycomposition/gstoverlaycomposition.h @@ -17,34 +17,20 @@ * Boston, MA 02110-1301, USA. */ +#pragma once + #include #include - -#ifndef __GST_OVERLAY_COMPOSITION_H__ -#define __GST_OVERLAY_COMPOSITION_H__ +#include G_BEGIN_DECLS #define GST_TYPE_OVERLAY_COMPOSITION (gst_overlay_composition_get_type()) G_DECLARE_FINAL_TYPE (GstOverlayComposition, gst_overlay_composition, - GST, OVERLAY_COMPOSITION, GstElement) - -struct _GstOverlayComposition { - GstElement parent; - - GstPad *sinkpad, *srcpad; - - /* state */ - GstSample *sample; - GstSegment segment; - GstCaps *caps; - GstVideoInfo info; - guint window_width, window_height; - gboolean attach_compo_to_buffer; -}; + GST, OVERLAY_COMPOSITION, GstBaseTransform) GST_ELEMENT_REGISTER_DECLARE (overlaycomposition); G_END_DECLS -#endif /* __GST_OVERLAY_COMPOSITION_H__ */ + diff --git a/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c b/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c index 7286570d13..0b822ea3ba 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c @@ -321,6 +321,10 @@ struct _GstDecodebin3Class gint (*select_stream) (GstDecodebin3 * dbin, GstStreamCollection * collection, GstStream * stream); + + /* signal fired to sort the factories */ + GValueArray *(*decoder_factory_sort) (GstDecodebin3 * dbin, + GstCaps * caps, GValueArray * factories); }; /* Input of decodebin, controls input pad and parsebin */ @@ -453,6 +457,7 @@ enum { SIGNAL_SELECT_STREAM, SIGNAL_ABOUT_TO_FINISH, + SIGNAL_DECODER_FACTORY_SORT, LAST_SIGNAL }; static guint gst_decodebin3_signals[LAST_SIGNAL] = { 0 }; @@ -569,6 +574,13 @@ gst_decodebin3_select_stream (GstDecodebin3 * dbin, return -1; } +static GValueArray * +gst_decodebin3_decoder_factory_sort (GstDecodebin3 * dbin, + GstCaps * caps, GValueArray * factories) +{ + return NULL; +} + static GstPad *gst_decodebin3_request_new_pad (GstElement * element, GstPadTemplate * temp, const gchar * name, const GstCaps * caps); static void gst_decodebin3_release_pad (GstElement * element, GstPad * pad); @@ -638,6 +650,21 @@ _gst_int_accumulator (GSignalInvocationHint * ihint, return FALSE; } +static gboolean +_gst_array_hasvalue_accumulator (GSignalInvocationHint * ihint, + GValue * return_accu, const GValue * handler_return, gpointer dummy) +{ + gpointer array; + + array = g_value_get_boxed (handler_return); + g_value_set_boxed (return_accu, array); + + if (array != NULL) + return FALSE; + + return TRUE; +} + static void gst_decodebin3_class_init (GstDecodebin3Class * klass) { @@ -687,6 +714,37 @@ gst_decodebin3_class_init (GstDecodebin3Class * klass) g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE); + /** + * GstDecodeBin3::decoder-factory-sort: + * @decodebin: a #GstDecodebin3 + * @caps: a #GstCaps. + * @factories: A #GValueArray of possible #GstElementFactory to use. + * + * Once decodebin3 has found the possible decoder #GstElementFactory objects + * to try for @caps, this signal is emitted. The purpose of the signal is for + * the application to perform additional sorting or filtering on the decoder + * factory array. + * + * The callee should copy and modify @factories or return %NULL if the + * order should not change. + * + * > Invocation of signal handlers stops after one signal handler has + * > returned something else than %NULL. Signal handlers are invoked in + * > the order they were connected in. + * > Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * > signal, they will never be invoked! + * + * Returns: A new sorted array of decoder #GstElementFactory objects. + * + * Since: 1.28 + */ + gst_decodebin3_signals[SIGNAL_DECODER_FACTORY_SORT] = + g_signal_new ("decoder-factory-sort", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstDecodebin3Class, decoder_factory_sort), + _gst_array_hasvalue_accumulator, NULL, + NULL, G_TYPE_VALUE_ARRAY, 2, GST_TYPE_CAPS, + G_TYPE_VALUE_ARRAY | G_SIGNAL_TYPE_STATIC_SCOPE); element_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_decodebin3_request_new_pad); @@ -717,6 +775,7 @@ gst_decodebin3_class_init (GstDecodebin3Class * klass) bin_klass->handle_message = gst_decodebin3_handle_message; klass->select_stream = gst_decodebin3_select_stream; + klass->decoder_factory_sort = gst_decodebin3_decoder_factory_sort; } static void @@ -3713,17 +3772,31 @@ gst_decodebin_input_link_to_slot (DecodebinInputStream * input_stream) slot->input = input_stream; } -static GList * +static GValueArray * create_decoder_factory_list (GstDecodebin3 * dbin, GstCaps * caps) { - GList *res; + GList *list, *tmp; + GValueArray *result; g_mutex_lock (&dbin->factories_lock); gst_decode_bin_update_factories_list (dbin); - res = gst_element_factory_list_filter (dbin->decoder_factories, + list = gst_element_factory_list_filter (dbin->decoder_factories, caps, GST_PAD_SINK, TRUE); g_mutex_unlock (&dbin->factories_lock); - return res; + + result = g_value_array_new (g_list_length (list)); + for (tmp = list; tmp; tmp = tmp->next) { + GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data); + GValue val = G_VALUE_INIT; + + g_value_init (&val, G_TYPE_OBJECT); + g_value_set_object (&val, factory); + g_value_array_append (result, &val); + g_value_unset (&val); + } + gst_plugin_feature_list_free (list); + + return result; } static GstPadProbeReturn @@ -3848,7 +3921,9 @@ db_output_stream_setup_decoder (DecodebinOutputStream * output, gboolean ret = TRUE; GstDecodebin3 *dbin = output->dbin; MultiQueueSlot *slot = output->slot; - GList *factories, *next_factory; + GValueArray *factories = NULL; + GValueArray *result = NULL; + guint i; GST_DEBUG_OBJECT (dbin, "output %s:%s caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME (output->src_pad), new_caps); @@ -3859,20 +3934,28 @@ db_output_stream_setup_decoder (DecodebinOutputStream * output, goto done; } - factories = next_factory = create_decoder_factory_list (dbin, new_caps); - if (!next_factory) { + factories = create_decoder_factory_list (dbin, new_caps); + g_signal_emit (dbin, gst_decodebin3_signals[SIGNAL_DECODER_FACTORY_SORT], 0, + new_caps, factories, &result); + if (result) { + g_value_array_free (factories); + factories = result; + } + + if (factories->n_values == 0) { GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT, new_caps); g_assert (output->decoder == NULL); ret = FALSE; goto missing_decoder; } - while (next_factory) { + for (i = 0; i < factories->n_values; i++) { CandidateDecoder *candidate = NULL; + GstElementFactory *factory = + g_value_get_object (g_value_array_get_nth (factories, i)); /* If we don't have a decoder yet, instantiate one */ - output->decoder = gst_element_factory_create ( - (GstElementFactory *) next_factory->data, NULL); + output->decoder = gst_element_factory_create (factory, NULL); GST_DEBUG ("Trying decoder %" GST_PTR_FORMAT, output->decoder); if (output->decoder == NULL) @@ -3928,16 +4011,14 @@ db_output_stream_setup_decoder (DecodebinOutputStream * output, if (candidate) remove_candidate_decoder (dbin, candidate); - if (!next_factory->next) { + if (i + 1 == factories->n_values) { ret = FALSE; if (output->decoder == NULL) goto missing_decoder; goto cleanup; } - next_factory = next_factory->next; } } - gst_plugin_feature_list_free (factories); done: if (output->type & GST_STREAM_TYPE_VIDEO && slot->drop_probe_id == 0) { @@ -3956,6 +4037,8 @@ db_output_stream_setup_decoder (DecodebinOutputStream * output, if (output->decoder) gst_element_sync_state_with_parent (output->decoder); + g_clear_pointer (&factories, g_value_array_free); + return ret; missing_decoder: @@ -3989,6 +4072,9 @@ db_output_stream_setup_decoder (DecodebinOutputStream * output, gst_bin_remove ((GstBin *) dbin, output->decoder); output->decoder = NULL; } + + g_clear_pointer (&factories, g_value_array_free); + return ret; } } diff --git a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c index 9ca023f773..8c64e9cda4 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c @@ -251,6 +251,7 @@ struct _GstURIDecodeBin3 gulong db_pad_removed_id; gulong db_select_stream_id; gulong db_about_to_finish_id; + gulong db_decoder_factory_sort_id; /* 1 if shutting down */ gint shutdown; @@ -269,12 +270,23 @@ gst_uridecodebin3_select_stream (GstURIDecodeBin3 * dbin, return -1; } +static GValueArray * +gst_uridecodebin3_decoder_factory_sort (GstURIDecodeBin3 * dbin, + GstCaps * caps, GValueArray * factories) +{ + return NULL; +} + struct _GstURIDecodeBin3Class { GstBinClass parent_class; gint (*select_stream) (GstURIDecodeBin3 * dbin, GstStreamCollection * collection, GstStream * stream); + + /* signal fired to sort the factories */ + GValueArray *(*decoder_factory_sort) (GstURIDecodeBin3 * dbin, + GstCaps * caps, GValueArray * factories); }; GST_DEBUG_CATEGORY_STATIC (gst_uri_decode_bin3_debug); @@ -286,6 +298,7 @@ enum SIGNAL_SELECT_STREAM, SIGNAL_SOURCE_SETUP, SIGNAL_ABOUT_TO_FINISH, + SIGNAL_DECODER_FACTORY_SORT, LAST_SIGNAL }; @@ -405,6 +418,20 @@ _gst_int_accumulator (GSignalInvocationHint * ihint, return FALSE; } +static gboolean +_gst_array_hasvalue_accumulator (GSignalInvocationHint * ihint, + GValue * return_accu, const GValue * handler_return, gpointer dummy) +{ + gpointer array; + + array = g_value_get_boxed (handler_return); + g_value_set_boxed (return_accu, array); + + if (array != NULL) + return FALSE; + + return TRUE; +} static void gst_uri_decode_bin3_class_init (GstURIDecodeBin3Class * klass) @@ -573,6 +600,37 @@ gst_uri_decode_bin3_class_init (GstURIDecodeBin3Class * klass) g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE); + /** + * GstURIDecodeBin3::decoder-factory-sort: + * @decodebin: a #GstURIDecodebin3 + * @caps: a #GstCaps. + * @factories: A #GValueArray of possible #GstElementFactory to use. + * + * Once decodebin3 has found the possible decoder #GstElementFactory objects + * to try for @caps, this signal is emitted. The purpose of the signal is for + * the application to perform additional sorting or filtering on the decoder + * factory array. + * + * The callee should copy and modify @factories or return %NULL if the + * order should not change. + * + * > Invocation of signal handlers stops after one signal handler has + * > returned something else than %NULL. Signal handlers are invoked in + * > the order they were connected in. + * > Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * > signal, they will never be invoked! + * + * Returns: A new sorted array of decoder #GstElementFactory objects. + * + * Since: 1.28 + */ + gst_uri_decode_bin3_signals[SIGNAL_DECODER_FACTORY_SORT] = + g_signal_new ("decoder-factory-sort", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstURIDecodeBin3Class, decoder_factory_sort), + _gst_array_hasvalue_accumulator, NULL, + NULL, G_TYPE_VALUE_ARRAY, 2, GST_TYPE_CAPS, + G_TYPE_VALUE_ARRAY | G_SIGNAL_TYPE_STATIC_SCOPE); gst_element_class_add_static_pad_template (gstelement_class, &video_src_template); @@ -593,6 +651,7 @@ gst_uri_decode_bin3_class_init (GstURIDecodeBin3Class * klass) gstbin_class->handle_message = gst_uri_decode_bin3_handle_message; klass->select_stream = gst_uridecodebin3_select_stream; + klass->decoder_factory_sort = gst_uridecodebin3_decoder_factory_sort; } static void @@ -885,6 +944,21 @@ db_about_to_finish_cb (GstElement * decodebin, GstURIDecodeBin3 * uridecodebin) emit_and_handle_about_to_finish (uridecodebin, uridecodebin->output_item); } +static GValueArray * +db_decoder_factory_sort_cb (GstElement * decodebin, + GstCaps * caps, GValueArray * factories, GstURIDecodeBin3 * uridecodebin) +{ + GValueArray *result; + + g_signal_emit (uridecodebin, + gst_uri_decode_bin3_signals[SIGNAL_DECODER_FACTORY_SORT], 0, caps, + factories, &result); + + GST_DEBUG_OBJECT (uridecodebin, "decoder-factory-sort returned %p", result); + + return result; +} + static void gst_uri_decode_bin3_init (GstURIDecodeBin3 * dec) { @@ -915,6 +989,9 @@ gst_uri_decode_bin3_init (GstURIDecodeBin3 * dec) dec->db_about_to_finish_id = g_signal_connect (dec->decodebin, "about-to-finish", G_CALLBACK (db_about_to_finish_cb), dec); + dec->db_decoder_factory_sort_id = + g_signal_connect (dec->decodebin, "decoder-factory-sort", + G_CALLBACK (db_decoder_factory_sort_cb), dec); GST_OBJECT_FLAG_SET (dec, GST_ELEMENT_FLAG_SOURCE); gst_bin_set_suppressed_flags (GST_BIN (dec), diff --git a/subprojects/gst-plugins-good/ext/dv/gstdvdemux.c b/subprojects/gst-plugins-good/ext/dv/gstdvdemux.c index 10c2dbaf40..5320cc011b 100644 --- a/subprojects/gst-plugins-good/ext/dv/gstdvdemux.c +++ b/subprojects/gst-plugins-good/ext/dv/gstdvdemux.c @@ -1155,7 +1155,7 @@ gst_dvdemux_handle_pull_seek (GstDVDemux * demux, GstPad * pad, /* and restart the task in case it got paused explicitly or by * the FLUSH_START event we pushed out. */ gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_dvdemux_loop, - demux->sinkpad, NULL); + gst_object_ref (demux->sinkpad), gst_object_unref); /* and release the lock again so we can continue streaming */ GST_PAD_STREAM_UNLOCK (demux->sinkpad); @@ -1940,7 +1940,8 @@ gst_dvdemux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, if (active) { demux->seek_handler = gst_dvdemux_handle_pull_seek; res = gst_pad_start_task (sinkpad, - (GstTaskFunction) gst_dvdemux_loop, sinkpad, NULL); + (GstTaskFunction) gst_dvdemux_loop, gst_object_ref (sinkpad), + gst_object_unref); } else { demux->seek_handler = NULL; res = gst_pad_stop_task (sinkpad); diff --git a/subprojects/gst-plugins-good/gst/avi/gstavidemux.c b/subprojects/gst-plugins-good/gst/avi/gstavidemux.c index 03adaa0df8..96788aa6c9 100644 --- a/subprojects/gst-plugins-good/gst/avi/gstavidemux.c +++ b/subprojects/gst-plugins-good/gst/avi/gstavidemux.c @@ -4697,7 +4697,7 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event) if (!avi->streaming) { gst_pad_start_task (avi->sinkpad, (GstTaskFunction) gst_avi_demux_loop, - avi->sinkpad, NULL); + gst_object_ref (avi->sinkpad), gst_object_unref); } /* reset the last flow and mark discont, seek is always DISCONT */ for (i = 0; i < avi->num_streams; i++) { @@ -5976,7 +5976,7 @@ gst_avi_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, if (active) { avi->streaming = FALSE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_avi_demux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-good/gst/debugutils/rndbuffersize.c b/subprojects/gst-plugins-good/gst/debugutils/rndbuffersize.c index 1fee416fbb..a85d6ce9f6 100644 --- a/subprojects/gst-plugins-good/gst/debugutils/rndbuffersize.c +++ b/subprojects/gst-plugins-good/gst/debugutils/rndbuffersize.c @@ -276,7 +276,7 @@ gst_rnd_buffer_size_activate_mode (GstPad * pad, GstObject * parent, GST_INFO_OBJECT (self, "starting pull"); res = gst_pad_start_task (pad, (GstTaskFunction) gst_rnd_buffer_size_loop, - self, NULL); + gst_object_ref (self), gst_object_unref); self->need_newsegment = TRUE; } else { GST_INFO_OBJECT (self, "stopping pull"); @@ -341,7 +341,7 @@ gst_rnd_buffer_size_src_event (GstPad * pad, GstObject * parent, self->need_newsegment = TRUE; gst_pad_start_task (self->sinkpad, (GstTaskFunction) gst_rnd_buffer_size_loop, - self, NULL); + gst_object_ref (self), gst_object_unref); GST_PAD_STREAM_UNLOCK (self->sinkpad); return TRUE; diff --git a/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c b/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c index 960ea51087..9dce51af3c 100644 --- a/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c +++ b/subprojects/gst-plugins-good/gst/flv/gstflvdemux.c @@ -4144,7 +4144,8 @@ gst_flv_demux_handle_seek_pull (GstFlvDemux * demux, GstEvent * event, gst_pad_pause_task (demux->sinkpad); } else { gst_pad_start_task (demux->sinkpad, - (GstTaskFunction) gst_flv_demux_loop, demux->sinkpad, NULL); + (GstTaskFunction) gst_flv_demux_loop, gst_object_ref (demux->sinkpad), + gst_object_unref); } GST_PAD_STREAM_UNLOCK (demux->sinkpad); @@ -4211,7 +4212,7 @@ gst_flv_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, demux->random_access = TRUE; demux->segment_seqnum = gst_util_seqnum_next (); res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flv_demux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { demux->random_access = FALSE; res = gst_pad_stop_task (sinkpad); diff --git a/subprojects/gst-plugins-good/gst/imagefreeze/gstimagefreeze.c b/subprojects/gst-plugins-good/gst/imagefreeze/gstimagefreeze.c index 98232dface..fc3b1779db 100644 --- a/subprojects/gst-plugins-good/gst/imagefreeze/gstimagefreeze.c +++ b/subprojects/gst-plugins-good/gst/imagefreeze/gstimagefreeze.c @@ -865,7 +865,8 @@ gst_image_freeze_src_event (GstPad * pad, GstObject * parent, GstEvent * event) if (self->buffer != NULL) gst_pad_start_task (self->srcpad, - (GstTaskFunction) gst_image_freeze_src_loop, self->srcpad, NULL); + (GstTaskFunction) gst_image_freeze_src_loop, + gst_object_ref (self->srcpad), gst_object_unref); g_mutex_unlock (&self->lock); } @@ -985,7 +986,7 @@ gst_image_freeze_sink_chain (GstPad * pad, GstObject * parent, gst_buffer_unref (buffer); gst_pad_start_task (self->srcpad, (GstTaskFunction) gst_image_freeze_src_loop, - self->srcpad, NULL); + gst_object_ref (self->srcpad), gst_object_unref); flow_ret = self->allow_replace ? GST_FLOW_OK : GST_FLOW_EOS; g_mutex_unlock (&self->lock); return flow_ret; diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c index b3b38ae99c..d3b2dfee82 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c @@ -1676,7 +1676,7 @@ gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event) /* restart streaming, NEWSEGMENT will be sent from the streaming thread. */ gst_pad_start_task (qtdemux->sinkpad, (GstTaskFunction) gst_qtdemux_loop, - qtdemux->sinkpad, NULL); + gst_object_ref (qtdemux->sinkpad), gst_object_unref); GST_PAD_STREAM_UNLOCK (qtdemux->sinkpad); @@ -9046,7 +9046,7 @@ qtdemux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, if (active) { demux->pullbased = TRUE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_qtdemux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-good/gst/matroska/matroska-demux.c b/subprojects/gst-plugins-good/gst/matroska/matroska-demux.c index ab11e17a02..421152754a 100644 --- a/subprojects/gst-plugins-good/gst/matroska/matroska-demux.c +++ b/subprojects/gst-plugins-good/gst/matroska/matroska-demux.c @@ -3337,7 +3337,8 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux, /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (demux->common.sinkpad, - (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL); + (GstTaskFunction) gst_matroska_demux_loop, + gst_object_ref (demux->common.sinkpad), gst_object_unref); /* streaming can continue now */ if (pad_locked) { @@ -7120,7 +7121,7 @@ gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, if (active) { /* if we have a scheduler we can start the task */ gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-good/gst/multifile/gstsplitmuxsrc.c b/subprojects/gst-plugins-good/gst/multifile/gstsplitmuxsrc.c index 55e662942b..f628fbd589 100644 --- a/subprojects/gst-plugins-good/gst/multifile/gstsplitmuxsrc.c +++ b/subprojects/gst-plugins-good/gst/multifile/gstsplitmuxsrc.c @@ -1110,7 +1110,8 @@ gst_splitmux_src_activate_part (GstSplitMuxSrc * splitmux, guint part, splitpad->clear_next_discont = FALSE; gst_pad_start_task (GST_PAD (splitpad), - (GstTaskFunction) gst_splitmux_pad_loop, splitpad, NULL); + (GstTaskFunction) gst_splitmux_pad_loop, gst_object_ref (splitpad), + gst_object_unref); } SPLITMUX_SRC_PADS_RUNLOCK (splitmux); @@ -1799,7 +1800,8 @@ splitmux_src_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) SPLITMUX_SRC_PADS_RLOCK (splitmux); /* Restart the task on this pad */ gst_pad_start_task (GST_PAD (pad), - (GstTaskFunction) gst_splitmux_pad_loop, pad, NULL); + (GstTaskFunction) gst_splitmux_pad_loop, gst_object_ref (pad), + gst_object_unref); SPLITMUX_SRC_PADS_RUNLOCK (splitmux); break; } diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c index b353db6212..23c5724154 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpjitterbuffer.c @@ -1930,7 +1930,8 @@ gst_rtp_jitter_buffer_src_activate_mode (GstPad * pad, GstObject * parent, /* start pushing out buffers */ GST_DEBUG_OBJECT (jitterbuffer, "Starting task on srcpad"); result = gst_pad_start_task (jitterbuffer->priv->srcpad, - (GstTaskFunction) gst_rtp_jitter_buffer_loop, jitterbuffer, NULL); + (GstTaskFunction) gst_rtp_jitter_buffer_loop, + gst_object_ref (jitterbuffer), gst_object_unref); } else { /* make sure all data processing stops ASAP */ gst_rtp_jitter_buffer_flush_start (jitterbuffer); diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtprtxsend.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtprtxsend.c index cb1afe3b08..67b9cbcdb2 100644 --- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtprtxsend.c +++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtprtxsend.c @@ -232,7 +232,8 @@ gst_rtp_rtx_send_set_task_state (GstRtpRtxSend * rtx, RtxTaskState task_state) GST_DEBUG_OBJECT (rtx, "Starting RTX task"); gst_rtp_rtx_send_set_flushing (rtx, FALSE); ret = gst_pad_start_task (rtx->srcpad, - (GstTaskFunction) gst_rtp_rtx_send_src_loop, rtx, NULL); + (GstTaskFunction) gst_rtp_rtx_send_src_loop, gst_object_ref (rtx), + gst_object_unref); } break; } diff --git a/subprojects/gst-plugins-good/gst/wavparse/gstwavparse.c b/subprojects/gst-plugins-good/gst/wavparse/gstwavparse.c index 7410b773d1..b8df1ac25e 100644 --- a/subprojects/gst-plugins-good/gst/wavparse/gstwavparse.c +++ b/subprojects/gst-plugins-good/gst/wavparse/gstwavparse.c @@ -626,7 +626,7 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event) /* and start the streaming task again */ if (!wav->streaming) { gst_pad_start_task (wav->sinkpad, (GstTaskFunction) gst_wavparse_loop, - wav->sinkpad, NULL); + gst_object_ref (wav->sinkpad), gst_object_unref); } GST_PAD_STREAM_UNLOCK (wav->sinkpad); @@ -3087,7 +3087,7 @@ gst_wavparse_sink_activate_mode (GstPad * sinkpad, GstObject * parent, if (active) { /* if we have a scheduler we can start the task */ res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_wavparse_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c b/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c index e300d9b22b..ba9effdede 100644 --- a/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c +++ b/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c @@ -1065,7 +1065,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder, self->output_flow = GST_FLOW_FLUSHING; self->draining = FALSE; if (!gst_pad_start_task (decoder->srcpad, - (GstTaskFunction) gst_v4l2_video_dec_loop, self, NULL)) + (GstTaskFunction) gst_v4l2_video_dec_loop, gst_object_ref (self), + gst_object_unref)) goto start_task_failed; } diff --git a/subprojects/gst-plugins-rs.wrap b/subprojects/gst-plugins-rs.wrap index f41d56b701..ab64934e57 100644 --- a/subprojects/gst-plugins-rs.wrap +++ b/subprojects/gst-plugins-rs.wrap @@ -1,5 +1,4 @@ [wrap-git] directory=gst-plugins-rs -url=https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git -push-url=git@gitlab.freedesktop.org:gstreamer/gst-plugins-rs.git -revision=main +url=https://github.com/trms/gst-plugins-rs.git +revision=cbl-2026-01-15 diff --git a/subprojects/gst-plugins-ugly/ext/sidplay/gstsiddec.cc b/subprojects/gst-plugins-ugly/ext/sidplay/gstsiddec.cc index 1a7c91ea9c..139674e282 100644 --- a/subprojects/gst-plugins-ugly/ext/sidplay/gstsiddec.cc +++ b/subprojects/gst-plugins-ugly/ext/sidplay/gstsiddec.cc @@ -488,7 +488,8 @@ start_play_tune (GstSidDec * siddec) siddec->group_id = G_MAXUINT; res = gst_pad_start_task (siddec->srcpad, - (GstTaskFunction) play_loop, siddec->srcpad, NULL); + (GstTaskFunction) play_loop, gst_object_ref (siddec->srcpad), + gst_object_unref); return res; /* ERRORS */ diff --git a/subprojects/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c b/subprojects/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c index 9450744e15..16d119c61f 100644 --- a/subprojects/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c +++ b/subprojects/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c @@ -383,7 +383,7 @@ gst_asf_demux_activate_mode (GstPad * sinkpad, GstObject * parent, demux->streaming = FALSE; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_asf_demux_loop, - demux, NULL); + gst_object_ref (demux), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } @@ -840,7 +840,7 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event) skip: /* restart our task since it might have been stopped when we did the flush */ gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_asf_demux_loop, - demux, NULL); + gst_object_ref (demux), gst_object_unref); /* streaming can continue now */ GST_PAD_STREAM_UNLOCK (demux->sinkpad); diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rademux.c b/subprojects/gst-plugins-ugly/gst/realmedia/rademux.c index 01b12f4ceb..bd60880081 100644 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rademux.c +++ b/subprojects/gst-plugins-ugly/gst/realmedia/rademux.c @@ -226,7 +226,8 @@ gst_real_audio_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, demux->seekable = TRUE; res = gst_pad_start_task (sinkpad, - (GstTaskFunction) gst_real_audio_demux_loop, demux, NULL); + (GstTaskFunction) gst_real_audio_demux_loop, gst_object_ref (demux), + gst_object_unref); } else { demux->seekable = FALSE; res = gst_pad_stop_task (sinkpad); @@ -841,7 +842,8 @@ gst_real_audio_demux_handle_seek (GstRealAudioDemux * demux, GstEvent * event) demux->segment_running = TRUE; /* restart our task since it might have been stopped when we did the flush */ gst_pad_start_task (demux->sinkpad, - (GstTaskFunction) gst_real_audio_demux_loop, demux, NULL); + (GstTaskFunction) gst_real_audio_demux_loop, gst_object_ref (demux), + gst_object_unref); /* streaming can continue now */ GST_PAD_STREAM_UNLOCK (demux->sinkpad); diff --git a/subprojects/gst-plugins-ugly/gst/realmedia/rmdemux.c b/subprojects/gst-plugins-ugly/gst/realmedia/rmdemux.c index 8501363f83..d5a4d71ee8 100644 --- a/subprojects/gst-plugins-ugly/gst/realmedia/rmdemux.c +++ b/subprojects/gst-plugins-ugly/gst/realmedia/rmdemux.c @@ -630,7 +630,7 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, GstEvent * event) /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (rmdemux->sinkpad, (GstTaskFunction) gst_rmdemux_loop, - rmdemux->sinkpad, NULL); + gst_object_ref (rmdemux->sinkpad), gst_object_unref); } done: @@ -869,7 +869,7 @@ gst_rmdemux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, demux->data_offset = G_MAXUINT; res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_rmdemux_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); } else { res = gst_pad_stop_task (sinkpad); } diff --git a/subprojects/gstreamer/docs/plugins/gst_plugins_cache.json b/subprojects/gstreamer/docs/plugins/gst_plugins_cache.json index 4c102dc041..d74c667831 100644 --- a/subprojects/gstreamer/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gstreamer/docs/plugins/gst_plugins_cache.json @@ -1029,6 +1029,20 @@ } }, "properties": { + "buffer-size": { + "blurb": "Size of the buffer passed to setvbuf(). If a non-zero value is set, it will be rounded down to the nearest multiple of 2.", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "2147483647", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "guint", + "writable": true + }, "location": { "blurb": "Location of the file to read", "conditionally-available": false, diff --git a/subprojects/gstreamer/gst/gstinfo.c b/subprojects/gstreamer/gst/gstinfo.c index 43c09da52e..a17edb4525 100644 --- a/subprojects/gstreamer/gst/gstinfo.c +++ b/subprojects/gstreamer/gst/gstinfo.c @@ -146,6 +146,100 @@ static char *gst_info_printf_pointer_extension_func (const char *format, #define GST_ENABLE_FORMAT_NONLITERAL_WARNING #endif +#undef GST_TIME_ARGS +#undef GST_STIME_ARGS +#undef GST_TIME_FORMAT +#undef GST_STIME_FORMAT + +static inline int +_u32_to_dec (char *p, guint32 v) +{ + if (v == 0) { + *p = '0'; + return 1; + } + char tmp[10]; /* UINT32_MAX = 4294967295, 10 digits */ + int n = 0; + while (v) { + tmp[n++] = '0' + (v % 10); + v /= 10; + } + for (int i = 0; i < n; ++i) + p[i] = tmp[n - 1 - i]; + return n; +} + +/* Internal: writes "[H...]H:MM:SS.nnnnnnnnn" at p, returns the end pointer. + Caller guarantees ns < GST_SECOND. */ +static inline char * +_gst_write_hms_ns (char *p, guint64 sec, guint ns) +{ + guint h = (guint) (sec / 3600); /* fits in 32 bits: + max ≈ 5.12e6 (unsigned) + max ≈ 2.56e6 (signed) */ + guint r = (guint) (sec - (guint64) h * 3600); + guint m = r / 60; + guint s = r - m * 60; + + p += _u32_to_dec (p, h); + *p++ = ':'; + *p++ = '0' + (m / 10); + *p++ = '0' + (m % 10); + *p++ = ':'; + *p++ = '0' + (s / 10); + *p++ = '0' + (s % 10); + *p++ = '.'; + for (int i = 8; i >= 0; --i) { + p[i] = '0' + (ns % 10); + ns /= 10; + } + return p + 9; +} + +static inline const char * +_gst_t_str (GstClockTime t, char *buf) +{ + if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (t))) { + memcpy (buf, "99:99:99.999999999", 19); /* incl. NUL */ + return buf; + } + guint64 sec = t / GST_SECOND; + guint ns = (guint) (t - sec * GST_SECOND); + *_gst_write_hms_ns (buf, sec, ns) = '\0'; + return buf; +} + +static inline const char * +_gst_st_str (GstClockTimeDiff t, char *buf) +{ + if (G_UNLIKELY (!GST_CLOCK_STIME_IS_VALID (t))) { + memcpy (buf, "+99:99:99.999999999", 20); /* incl. NUL */ + return buf; + } + char *p = buf; + guint64 abs_t; + if (t < 0) { + *p++ = '-'; + /* Unsigned negation is defined modulo 2^64 and yields the correct + magnitude even at t == G_MININT64, where -(gint64)t would be UB. + For valid inputs (t != G_MININT64) the magnitude fits in gint64 + anyway; this idiom just avoids a special case. */ + abs_t = -(guint64) t; + } else { + *p++ = '+'; + abs_t = (guint64) t; + } + guint64 sec = abs_t / GST_SECOND; + guint ns = (guint) (abs_t - sec * GST_SECOND); + *_gst_write_hms_ns (p, sec, ns) = '\0'; + return buf; +} + +#define GST_TIME_FORMAT "s" +#define GST_TIME_ARGS(t) _gst_t_str((t), (char[32]){0}) + +#define GST_STIME_FORMAT "s" +#define GST_STIME_ARGS(t) _gst_st_str((t), (char[32]){0}) #ifdef G_OS_WIN32 # define WIN32_LEAN_AND_MEAN /* prevents from including too many things */ @@ -345,6 +439,10 @@ struct _GstDebugMessage /* heap-allocated write area for short names */ gchar tmp_id[32]; + + /* Inline buffer @message is formatted into; vasnprintf falls back to malloc + * only if the result doesn't fit. */ + gchar inline_buf[1024]; }; struct _GstLogContext @@ -444,6 +542,13 @@ _priv_gst_debug_file_name (const gchar * env) return name; } +#ifdef G_OS_WIN32 +/* HANDLE for the configured log file. This needs to be in static storage + * because the address allows us to check when gst_debug_log_default() is + * called with a custom FILE* pointer by the user. */ +static HANDLE _gst_debug_log_handle = INVALID_HANDLE_VALUE; +#endif + /* Initialize the debugging system */ void _priv_gst_debug_init (void) @@ -458,13 +563,37 @@ _priv_gst_debug_init (void) log_file = stdout; } else { gchar *name = _priv_gst_debug_file_name (env); +#ifdef G_OS_WIN32 + wchar_t *wname = g_utf8_to_utf16 (name, -1, NULL, NULL, NULL); + if (wname) { + /* FILE_APPEND_DATA makes the kernel append each call's buffer + * atomically, so multiple threads logging in parallel never + * interleave lines and there is no userspace lock to contend on + * FILE_SHARE_READ allows other processes to read the file. + */ + _gst_debug_log_handle = CreateFileW (wname, FILE_APPEND_DATA, + FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, + NULL); + g_free (wname); + } + if (_gst_debug_log_handle == INVALID_HANDLE_VALUE) { + g_printerr ("Could not open log file '%s' for writing: %u\n", env, + (guint) GetLastError ()); + log_file = stderr; + } else { + /* Sentinel: _gst_debug_fprintf detects this by pointer-equality and + * writes via the HANDLE instead of through the CRT FILE* layer. */ + log_file = (FILE *) & _gst_debug_log_handle; + } +#else log_file = g_fopen (name, "w"); - g_free (name); if (log_file == NULL) { g_printerr ("Could not open log file '%s' for writing: %s\n", env, g_strerror (errno)); log_file = stderr; } +#endif + g_free (name); } } else { log_file = stderr; @@ -828,7 +957,8 @@ gst_debug_log_full_valist (GstDebugCategory * category, GstLogContext * ctx, } g_rw_lock_reader_unlock (&__log_func_mutex); - g_free (message.message); + if (message.message != message.inline_buf) + g_free (message.message); if (message.free_object_id) g_free (message.object_id); va_end (message.arguments); @@ -1001,8 +1131,8 @@ gst_debug_message_get (GstDebugMessage * message) if (message->message == NULL) { int len; - len = __gst_vasprintf (&message->message, message->format, - message->arguments); + len = __gst_vasprintf_buf (&message->message, message->inline_buf, + sizeof (message->inline_buf), message->format, message->arguments); if (len < 0) message->message = NULL; @@ -1760,11 +1890,13 @@ static void _gst_debug_fprintf (FILE * file, const gchar * format, ...) { va_list args; + gchar inline_buf[1024]; gchar *str = NULL; gint length; va_start (args, format); - length = gst_info_vasprintf (&str, format, args); + length = __gst_vasprintf_buf (&str, inline_buf, sizeof (inline_buf), + format, args); va_end (args); if (length == 0 || !str) @@ -1779,16 +1911,18 @@ _gst_debug_fprintf (FILE * file, const gchar * format, ...) g_printerr ("%s", str); } else if (file == stdout) { g_print ("%s", str); + } else if (file == (FILE *) & _gst_debug_log_handle) { + /* By default, we can bypass the CRT's buffering by using WriteFile */ + DWORD written; + WriteFile (_gst_debug_log_handle, str, (DWORD) length, &written, NULL); } else { - /* We are writing to file. Text editors/viewers should be able to - * decode valid UTF-8 string regardless of codepage setting */ + /* Cater for a custom FILE* user_data in gst_debug_add_log_function */ fwrite (str, 1, length, file); - - /* FIXME: fflush here might be redundant if setvbuf works as expected */ fflush (file); } - g_free (str); + if (str != inline_buf) + g_free (str); } #endif @@ -3295,6 +3429,10 @@ _priv_gst_debug_cleanup (void) } g_rw_lock_writer_unlock (&__log_func_mutex); +#ifdef G_OS_WIN32 + CloseHandle (_gst_debug_log_handle); +#endif + #ifdef HAVE_UNWIND # ifdef HAVE_DW if (_global_dwfl) { diff --git a/subprojects/gstreamer/gst/gstpad.c b/subprojects/gstreamer/gst/gstpad.c index 3b28c08e51..9a28dee23d 100644 --- a/subprojects/gstreamer/gst/gstpad.c +++ b/subprojects/gstreamer/gst/gstpad.c @@ -4539,6 +4539,12 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data) PROBE_HANDLE (pad, type, data, probe_stopped, probe_handled); + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) + goto flushing; + + if (G_UNLIKELY (GST_PAD_IS_EOS (pad))) + goto eos; + ACQUIRE_PARENT (pad, parent, no_parent); GST_OBJECT_UNLOCK (pad); diff --git a/subprojects/gstreamer/gst/printf/README b/subprojects/gstreamer/gst/printf/README index c8eac3815f..b6fec6cb4c 100644 --- a/subprojects/gstreamer/gst/printf/README +++ b/subprojects/gstreamer/gst/printf/README @@ -46,9 +46,11 @@ GStreamer modifications This was imported from GLib's gnulib subdirectory. g-gnulib.h and _g_gnulib namespace has been changed to gst-printf.h and -__gst_printf namespace for GStreamer. Also #define HAVE_SNPRINTF 0 has -been changed to #undef HAVE_SNPRINTF, and HAVE_ALLOCA has been replaced -by an #if defined(alloca) || defined(GLIB_HAVE_ALLOCA_H) +__gst_printf namespace for GStreamer. HAVE_SNPRINTF is defined in +gst-printf.h (snprintf is universally available on supported platforms); +%n is never appended to the reconstructed format string passed to snprintf +so glibc's _FORTIFY_SOURCE=2 check is satisfied. HAVE_ALLOCA has been +replaced by an #if defined(alloca) || defined(GLIB_HAVE_ALLOCA_H) printf-extension.[ch] were added to provide support for custom pointer arguments (e.g. caps, events, etc.) diff --git a/subprojects/gstreamer/gst/printf/gst-printf.h b/subprojects/gstreamer/gst/printf/gst-printf.h index db5972afed..e2de1ee6c5 100644 --- a/subprojects/gstreamer/gst/printf/gst-printf.h +++ b/subprojects/gstreamer/gst/printf/gst-printf.h @@ -36,11 +36,10 @@ #define realloc g_realloc #define free g_free -/* Don't use snprintf(); we have to use sprintf instead and do our own - * length calculations, because glibc doesn't allow passing %n in a format - * string if the string is in writable memory (if glibc has been compiled - * with _FORTIFY_SOURCE=2 which seems to be the case on some distros/systems) */ -#undef HAVE_SNPRINTF +/* All platforms we support have C99 snprintf. We never append %n to the + * reconstructed format string (see vasnprintf.c), so _FORTIFY_SOURCE=2 is + * fine. */ +#define HAVE_SNPRINTF 1 /* based on glib's config.h.win32.in */ #ifdef G_OS_WIN32 diff --git a/subprojects/gstreamer/gst/printf/printf.c b/subprojects/gstreamer/gst/printf/printf.c index d2bb373351..8a863b65ed 100644 --- a/subprojects/gstreamer/gst/printf/printf.c +++ b/subprojects/gstreamer/gst/printf/printf.c @@ -157,3 +157,19 @@ __gst_vasprintf (char **result, char const *format, va_list args) return length; } + +/* Format into fixed_buf if the result fits, otherwise into a freshly malloc'd + * buffer. The caller must check whether *result == fixed_buf to know whether + * to free it. */ +int +__gst_vasprintf_buf (char **result, char *fixed_buf, size_t fixed_buf_size, + char const *format, va_list args) +{ + size_t length = fixed_buf_size; + + *result = vasnprintf (fixed_buf, &length, format, args); + if (*result == NULL) + return -1; + + return length; +} diff --git a/subprojects/gstreamer/gst/printf/printf.h b/subprojects/gstreamer/gst/printf/printf.h index 18e3cf97ef..3f514f2d60 100644 --- a/subprojects/gstreamer/gst/printf/printf.h +++ b/subprojects/gstreamer/gst/printf/printf.h @@ -60,5 +60,11 @@ int __gst_vasprintf (char **result, char const *format, va_list args); +int __gst_vasprintf_buf (char **result, + char *fixed_buf, + size_t fixed_buf_size, + char const *format, + va_list args); + #endif /* __GNULIB_PRINTF_H__ */ diff --git a/subprojects/gstreamer/gst/printf/vasnprintf.c b/subprojects/gstreamer/gst/printf/vasnprintf.c index 4cbb295b1d..37de2c3dbc 100644 --- a/subprojects/gstreamer/gst/printf/vasnprintf.c +++ b/subprojects/gstreamer/gst/printf/vasnprintf.c @@ -692,13 +692,7 @@ vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) break; } *p = dp->conversion; -#ifdef HAVE_SNPRINTF - p[1] = '%'; - p[2] = 'n'; - p[3] = '\0'; -#else p[1] = '\0'; -#endif /* Construct the arguments for calling snprintf or sprintf. */ prefix_count = 0; diff --git a/subprojects/gstreamer/libs/gst/base/gstaggregator.c b/subprojects/gstreamer/libs/gst/base/gstaggregator.c index 01f1e79503..a182c2fb5d 100644 --- a/subprojects/gstreamer/libs/gst/base/gstaggregator.c +++ b/subprojects/gstreamer/libs/gst/base/gstaggregator.c @@ -1683,7 +1683,8 @@ gst_aggregator_start_srcpad_task (GstAggregator * self) self->priv->running = TRUE; gst_pad_start_task (GST_PAD (self->srcpad), - (GstTaskFunction) gst_aggregator_aggregate_func, self, NULL); + (GstTaskFunction) gst_aggregator_aggregate_func, gst_object_ref (self), + gst_object_unref); } static GstFlowReturn @@ -1697,6 +1698,7 @@ gst_aggregator_flush (GstAggregator * self) GST_OBJECT_LOCK (self); priv->send_segment = TRUE; priv->flushing = FALSE; + priv->first_buffer = TRUE; GST_OBJECT_UNLOCK (self); if (klass->flush) ret = klass->flush (self); @@ -4314,3 +4316,20 @@ gst_aggregator_set_force_live (GstAggregator * self, gboolean force_live) { self->priv->force_live = force_live; } + +/** + * gst_aggregator_ensure_mandatory_events: + * @self: The #GstAggregator + * + * This method will push mandatory events such as stream-start, caps, + * and segment if needed. + * + * Since: 1.24 + */ +void +gst_aggregator_ensure_mandatory_events (GstAggregator * self) +{ + g_return_if_fail (GST_IS_AGGREGATOR (self)); + + gst_aggregator_push_mandatory_events (self, FALSE); +} diff --git a/subprojects/gstreamer/libs/gst/base/gstaggregator.h b/subprojects/gstreamer/libs/gst/base/gstaggregator.h index 4d330e6f44..4203d5c5d0 100644 --- a/subprojects/gstreamer/libs/gst/base/gstaggregator.h +++ b/subprojects/gstreamer/libs/gst/base/gstaggregator.h @@ -524,6 +524,9 @@ GST_BASE_API void gst_aggregator_set_force_live (GstAggregator *self, gboolean force_live); +GST_BASE_API +void gst_aggregator_ensure_mandatory_events (GstAggregator * self); + /** * GstAggregatorStartTimeSelection: * @GST_AGGREGATOR_START_TIME_SELECTION_ZERO: Start at running time 0. diff --git a/subprojects/gstreamer/libs/gst/base/gstbaseparse.c b/subprojects/gstreamer/libs/gst/base/gstbaseparse.c index a278c169f1..621de253bc 100644 --- a/subprojects/gstreamer/libs/gst/base/gstbaseparse.c +++ b/subprojects/gstreamer/libs/gst/base/gstbaseparse.c @@ -3828,7 +3828,7 @@ gst_base_parse_sink_activate (GstPad * sinkpad, GstObject * parent) parse->priv->upstream_format = GST_FORMAT_BYTES; return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop, - sinkpad, NULL); + gst_object_ref (sinkpad), gst_object_unref); /* fallback */ baseparse_push: { @@ -4883,7 +4883,8 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event) /* Start streaming thread if paused */ gst_pad_start_task (parse->sinkpad, - (GstTaskFunction) gst_base_parse_loop, parse->sinkpad, NULL); + (GstTaskFunction) gst_base_parse_loop, gst_object_ref (parse->sinkpad), + gst_object_unref); GST_PAD_STREAM_UNLOCK (parse->sinkpad); diff --git a/subprojects/gstreamer/libs/gst/base/gstbasesink.c b/subprojects/gstreamer/libs/gst/base/gstbasesink.c index ba4b816251..0a92bdd786 100644 --- a/subprojects/gstreamer/libs/gst/base/gstbasesink.c +++ b/subprojects/gstreamer/libs/gst/base/gstbasesink.c @@ -4713,7 +4713,8 @@ gst_base_sink_default_activate_pull (GstBaseSink * basesink, gboolean active) if (active) { /* start task */ result = gst_pad_start_task (basesink->sinkpad, - (GstTaskFunction) gst_base_sink_loop, basesink->sinkpad, NULL); + (GstTaskFunction) gst_base_sink_loop, + gst_object_ref (basesink->sinkpad), gst_object_unref); } else { /* step 2, make sure streaming finishes */ result = gst_pad_stop_task (basesink->sinkpad); diff --git a/subprojects/gstreamer/libs/gst/base/gstbasesrc.c b/subprojects/gstreamer/libs/gst/base/gstbasesrc.c index c1dd9cff3b..1833e616ca 100644 --- a/subprojects/gstreamer/libs/gst/base/gstbasesrc.c +++ b/subprojects/gstreamer/libs/gst/base/gstbasesrc.c @@ -1855,7 +1855,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock) /* and restart the task in case it got paused explicitly or by * the FLUSH_START event we pushed out. */ tres = gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop, - src->srcpad, NULL); + gst_object_ref (src->srcpad), gst_object_unref); if (res && !tres) res = FALSE; @@ -1921,7 +1921,7 @@ gst_base_src_send_event (GstElement * element, GstEvent * event) if (start) gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop, - src->srcpad, NULL); + gst_object_ref (src->srcpad), gst_object_unref); GST_LIVE_UNLOCK (src); GST_PAD_STREAM_UNLOCK (src->srcpad); @@ -1970,7 +1970,7 @@ gst_base_src_send_event (GstElement * element, GstEvent * event) GST_DEBUG_OBJECT (src, "EOS marked, start task for asynchronous handling"); gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop, - src->srcpad, NULL); + gst_object_ref (src->srcpad), gst_object_unref); GST_PAD_STREAM_UNLOCK (src->srcpad); } else { @@ -3947,7 +3947,7 @@ gst_base_src_set_playing (GstBaseSrc * basesrc, gboolean live_play) GST_OBJECT_UNLOCK (basesrc->srcpad); if (start) gst_pad_start_task (basesrc->srcpad, (GstTaskFunction) gst_base_src_loop, - basesrc->srcpad, NULL); + gst_object_ref (basesrc->srcpad), gst_object_unref); GST_DEBUG_OBJECT (basesrc, "signal"); GST_LIVE_SIGNAL (basesrc); } diff --git a/subprojects/gstreamer/plugins/elements/gstdownloadbuffer.c b/subprojects/gstreamer/plugins/elements/gstdownloadbuffer.c index b25aadf2f8..bb5a9eae23 100644 --- a/subprojects/gstreamer/plugins/elements/gstdownloadbuffer.c +++ b/subprojects/gstreamer/plugins/elements/gstdownloadbuffer.c @@ -1056,7 +1056,8 @@ gst_download_buffer_handle_sink_event (GstPad * pad, GstObject * parent, /* reset rate counters */ reset_rate_timer (dlbuf); gst_pad_start_task (dlbuf->srcpad, - (GstTaskFunction) gst_download_buffer_loop, dlbuf->srcpad, NULL); + (GstTaskFunction) gst_download_buffer_loop, + gst_object_ref (dlbuf->srcpad), gst_object_unref); GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf); } else { GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf); @@ -1421,7 +1422,7 @@ gst_download_buffer_handle_src_event (GstPad * pad, GstObject * parent, dlbuf->sinkresult = GST_FLOW_OK; if (GST_PAD_MODE (pad) == GST_PAD_MODE_PUSH) { gst_pad_start_task (pad, (GstTaskFunction) gst_download_buffer_loop, - pad, NULL); + gst_object_ref (pad), gst_object_unref); } } GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf); @@ -1735,7 +1736,7 @@ gst_download_buffer_src_activate_push (GstPad * pad, GstObject * parent, dlbuf->upstream_size = -1; result = gst_pad_start_task (pad, (GstTaskFunction) gst_download_buffer_loop, - pad, NULL); + gst_object_ref (pad), gst_object_unref); GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf); } else { /* unblock loop function */ diff --git a/subprojects/gstreamer/plugins/elements/gstfilesrc.c b/subprojects/gstreamer/plugins/elements/gstfilesrc.c index 7c5712ae56..192088126f 100644 --- a/subprojects/gstreamer/plugins/elements/gstfilesrc.c +++ b/subprojects/gstreamer/plugins/elements/gstfilesrc.c @@ -38,7 +38,6 @@ #endif #include -#include #include "gstfilesrc.h" #include "gstcoreelementselements.h" @@ -52,6 +51,10 @@ * variants, so explicitly define it that way. */ #undef lseek #define lseek _lseeki64 +#ifndef HAVE_FSEEKO +/* fseeko is not defined in Windows SDK's stdio.h */ +#define fseeko _fseeki64 +#endif #undef off_t #define off_t guint64 /* Prevent stat.h from defining the stat* functions as @@ -113,11 +116,13 @@ enum }; #define DEFAULT_BLOCKSIZE 4*1024 +#define DEFAULT_BUFFER_SIZE 20*1024*1024 enum { PROP_0, - PROP_LOCATION + PROP_LOCATION, + PROP_BUFFER_SIZE, }; static void gst_file_src_finalize (GObject * object); @@ -166,6 +171,24 @@ gst_file_src_class_init (GstFileSrcClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); + /** + * GstFileSrc:buffer-size: + * + * Size of the buffer passed to setvbuf POSIX function. Depending on system, + * or read pattern (e.g., sequencial or randon-access), larger buffer size can + * improve throughput or reduce file access overhead. + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE, + g_param_spec_uint ("buffer-size", "Buffer Size", + "Size of the buffer passed to setvbuf(). If a non-zero value is set, " + "it will be rounded down to the nearest multiple of 2.", + /* NOTE: allowed max size on Windows is INT_MAX */ + 0, G_MAXINT32, DEFAULT_BUFFER_SIZE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY)); + gobject_class->finalize = gst_file_src_finalize; gst_element_class_set_static_metadata (gstelement_class, @@ -190,11 +213,7 @@ gst_file_src_class_init (GstFileSrcClass * klass) static void gst_file_src_init (GstFileSrc * src) { - src->filename = NULL; - src->fd = 0; - src->uri = NULL; - - src->is_regular = FALSE; + src->buffer_size = DEFAULT_BUFFER_SIZE; gst_base_src_set_blocksize (GST_BASE_SRC (src), DEFAULT_BLOCKSIZE); } @@ -206,6 +225,7 @@ gst_file_src_finalize (GObject * object) src = GST_FILE_SRC (object); + g_free (src->buffer); g_free (src->filename); g_free (src->uri); @@ -273,6 +293,11 @@ gst_file_src_set_property (GObject * object, guint prop_id, case PROP_LOCATION: gst_file_src_set_location (src, g_value_get_string (value), NULL); break; + case PROP_BUFFER_SIZE: + src->buffer_size = g_value_get_uint (value); + if (src->buffer_size > 0) + src->buffer_size = GST_ROUND_DOWN_2 (src->buffer_size); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -293,6 +318,9 @@ gst_file_src_get_property (GObject * object, guint prop_id, GValue * value, case PROP_LOCATION: g_value_set_string (value, src->filename); break; + case PROP_BUFFER_SIZE: + g_value_set_uint (value, src->buffer_size); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -315,7 +343,7 @@ gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, { GstFileSrc *src; guint to_read, bytes_read; - int ret; + gsize ret; GstMapInfo info; guint8 *data; @@ -324,8 +352,8 @@ gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, if (G_UNLIKELY (offset != -1 && src->read_position != offset)) { off_t res; - res = lseek (src->fd, offset, SEEK_SET); - if (G_UNLIKELY (res == (off_t) - 1 || res != offset)) + res = fseeko (src->fp, offset, SEEK_SET); + if (G_UNLIKELY (res != 0)) goto seek_failed; src->read_position = offset; @@ -341,7 +369,7 @@ gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x", to_read, offset + bytes_read); errno = 0; - ret = read (src->fd, data + bytes_read, to_read); + ret = fread (data + bytes_read, 1, to_read, src->fp); if (G_UNLIKELY (ret < 0)) { if (errno == EAGAIN || errno == EINTR) continue; @@ -416,21 +444,27 @@ gst_file_src_win32_iph (wchar_t const *exp, wchar_t const *func, } static HANDLE -gst_file_src_win32_get_osfhandle (int fd) +gst_file_src_win32_get_osfhandle (FILE * fp) { HANDLE handle; + int fd; _invalid_parameter_handler old_iph = _set_thread_local_invalid_parameter_handler (gst_file_src_win32_iph); - handle = (HANDLE) _get_osfhandle (fd); + fd = _fileno (fp); + if (fd == -1) { + handle = INVALID_HANDLE_VALUE; + } else { + handle = (HANDLE) _get_osfhandle (fd); + } _set_thread_local_invalid_parameter_handler (old_iph); return handle; } #else /* HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER */ static HANDLE -gst_file_src_win32_get_osfhandle (int fd) +gst_file_src_win32_get_osfhandle (FILE * fp) { - return (HANDLE) _get_osfhandle (fd); + return (HANDLE) _get_osfhandle (_fileno (fp)); } #endif /* HAVE__SET_THREAD_LOCAL_INVALID_PARAMETER_HANDLER */ #endif /* G_OS_WIN32 */ @@ -447,38 +481,39 @@ gst_file_src_get_size (GstBaseSrc * basesrc, guint64 * size) * succeed, and wrongly say our length is zero. */ return FALSE; } + + if (!src->fp) + return FALSE; + #ifdef G_OS_WIN32 { - HANDLE h = gst_file_src_win32_get_osfhandle (src->fd); + HANDLE h = gst_file_src_win32_get_osfhandle (src->fp); LARGE_INTEGER file_size; if (h == INVALID_HANDLE_VALUE) - goto could_not_stat; + return FALSE; - if (!GetFileSizeEx (h, &file_size)) { - goto could_not_stat; - } + if (!GetFileSizeEx (h, &file_size)) + return FALSE; *size = file_size.QuadPart; } #else { struct_stat stat_results; + int fd = fileno (src->fp); + + if (fd == -1) + return FALSE; - if (fstat (src->fd, &stat_results) < 0) - goto could_not_stat; + if (fstat (fileno (src->fp), &stat_results) < 0) + return FALSE; *size = stat_results.st_size; } #endif return TRUE; - - /* ERROR */ -could_not_stat: - { - return FALSE; - } } /* open the file, necessary to go to READY state */ @@ -486,10 +521,6 @@ static gboolean gst_file_src_start (GstBaseSrc * basesrc) { GstFileSrc *src = GST_FILE_SRC (basesrc); - int flags = O_RDONLY | O_BINARY; -#if defined (__BIONIC__) - flags |= O_LARGEFILE; -#endif if (src->filename == NULL || src->filename[0] == '\0') goto no_filename; @@ -497,14 +528,14 @@ gst_file_src_start (GstBaseSrc * basesrc) GST_INFO_OBJECT (src, "opening file %s", src->filename); /* open the file */ - src->fd = g_open (src->filename, flags, 0); + src->fp = fopen (src->filename, "rb"); - if (src->fd < 0) + if (!src->fp) goto open_failed; #ifdef G_OS_WIN32 { - HANDLE h = gst_file_src_win32_get_osfhandle (src->fd); + HANDLE h = gst_file_src_win32_get_osfhandle (src->fp); FILE_STANDARD_INFO file_info; if (h == INVALID_HANDLE_VALUE) @@ -525,7 +556,7 @@ gst_file_src_start (GstBaseSrc * basesrc) struct_stat stat_results; /* check if it is a regular file, otherwise bail out */ - if (fstat (src->fd, &stat_results) < 0) + if (fstat (fileno (src->fp), &stat_results) < 0) goto no_stat; if (S_ISDIR (stat_results.st_mode)) @@ -544,14 +575,14 @@ gst_file_src_start (GstBaseSrc * basesrc) /* We need to check if the underlying file is seekable. */ { - off_t res = lseek (src->fd, 0, SEEK_END); + off_t res = fseeko (src->fp, 0, SEEK_END); if (res == (off_t) - 1) { GST_LOG_OBJECT (src, "disabling seeking, lseek failed: %s", g_strerror (errno)); src->seekable = FALSE; } else { - res = lseek (src->fd, 0, SEEK_SET); + res = fseeko (src->fp, 0, SEEK_SET); if (res == (off_t) - 1) { /* We really don't like not being able to go back to 0 */ @@ -569,6 +600,14 @@ gst_file_src_start (GstBaseSrc * basesrc) gst_base_src_set_dynamic_size (basesrc, src->seekable); + if (src->buffer_size) { + src->buffer = g_malloc (src->buffer_size); + if (setvbuf (src->fp, (char *) src->buffer, _IOFBF, src->buffer_size) != 0) { + GST_WARNING_OBJECT (src, "setvbuf() failed"); + g_clear_pointer (&src->buffer, g_free); + } + } + return TRUE; /* ERROR */ @@ -621,7 +660,7 @@ gst_file_src_start (GstBaseSrc * basesrc) goto error_close; } error_close: - close (src->fd); + g_clear_pointer (&src->fp, fclose); error_exit: return FALSE; } @@ -632,11 +671,9 @@ gst_file_src_stop (GstBaseSrc * basesrc) { GstFileSrc *src = GST_FILE_SRC (basesrc); - /* close the file */ - g_close (src->fd, NULL); + g_clear_pointer (&src->fp, fclose); + g_clear_pointer (&src->buffer, g_free); - /* zero out a lot of our state */ - src->fd = 0; src->is_regular = FALSE; return TRUE; diff --git a/subprojects/gstreamer/plugins/elements/gstfilesrc.h b/subprojects/gstreamer/plugins/elements/gstfilesrc.h index e73cfc3d5e..99702623a3 100644 --- a/subprojects/gstreamer/plugins/elements/gstfilesrc.h +++ b/subprojects/gstreamer/plugins/elements/gstfilesrc.h @@ -28,6 +28,7 @@ #include #include +#include G_BEGIN_DECLS @@ -57,12 +58,14 @@ struct _GstFileSrc { /*< private >*/ gchar *filename; /* filename */ gchar *uri; /* caching the URI */ - gint fd; /* open file descriptor */ - guint64 read_position; /* position of fd */ + FILE *fp; + guint64 read_position; /* position of file stream */ gboolean seekable; /* whether the file is seekable */ gboolean is_regular; /* whether it's a (symlink to a) regular file */ + gsize buffer_size; + guint8 *buffer; }; struct _GstFileSrcClass { diff --git a/subprojects/gstreamer/plugins/elements/gstmultiqueue.c b/subprojects/gstreamer/plugins/elements/gstmultiqueue.c index 7fb1c5f79c..a2f6272e24 100644 --- a/subprojects/gstreamer/plugins/elements/gstmultiqueue.c +++ b/subprojects/gstreamer/plugins/elements/gstmultiqueue.c @@ -1338,7 +1338,8 @@ gst_single_queue_start (GstMultiQueue * mq, GstSingleQueue * sq) if (srcpad) { res = gst_pad_start_task (srcpad, - (GstTaskFunction) gst_multi_queue_loop, srcpad, NULL); + (GstTaskFunction) gst_multi_queue_loop, gst_object_ref (srcpad), + gst_object_unref); gst_object_unref (srcpad); } diff --git a/subprojects/gstreamer/plugins/elements/gstqueue.c b/subprojects/gstreamer/plugins/elements/gstqueue.c index 4a1ac40bba..8ce17a8220 100644 --- a/subprojects/gstreamer/plugins/elements/gstqueue.c +++ b/subprojects/gstreamer/plugins/elements/gstqueue.c @@ -1045,7 +1045,7 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) queue->unexpected = FALSE; if (gst_pad_is_active (queue->srcpad)) { gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue_loop, - queue->srcpad, NULL); + gst_object_ref (queue->srcpad), gst_object_unref); } else { GST_INFO_OBJECT (queue->srcpad, "not re-starting task on srcpad, " "pad not active any longer"); @@ -1099,7 +1099,8 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) queue->eos = FALSE; queue->unexpected = FALSE; gst_pad_start_task (queue->srcpad, - (GstTaskFunction) gst_queue_loop, queue->srcpad, NULL); + (GstTaskFunction) gst_queue_loop, + gst_object_ref (queue->srcpad), gst_object_unref); } else { queue->eos = FALSE; queue->unexpected = FALSE; @@ -1681,7 +1682,8 @@ gst_queue_handle_src_event (GstPad * pad, GstObject * parent, GstEvent * event) /* when we got not linked, assume downstream is linked again now and we * can try to start pushing again */ queue->srcresult = GST_FLOW_OK; - gst_pad_start_task (pad, (GstTaskFunction) gst_queue_loop, pad, NULL); + gst_pad_start_task (pad, (GstTaskFunction) gst_queue_loop, + gst_object_ref (pad), gst_object_unref); } GST_QUEUE_MUTEX_UNLOCK (queue); @@ -1840,8 +1842,8 @@ gst_queue_src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, queue->eos = FALSE; queue->unexpected = FALSE; result = - gst_pad_start_task (pad, (GstTaskFunction) gst_queue_loop, pad, - NULL); + gst_pad_start_task (pad, (GstTaskFunction) gst_queue_loop, + gst_object_ref (pad), gst_object_unref); GST_QUEUE_MUTEX_UNLOCK (queue); } else { /* step 1, unblock loop function */ diff --git a/subprojects/gstreamer/plugins/elements/gstqueue2.c b/subprojects/gstreamer/plugins/elements/gstqueue2.c index 1fa62f9240..b22759b038 100644 --- a/subprojects/gstreamer/plugins/elements/gstqueue2.c +++ b/subprojects/gstreamer/plugins/elements/gstqueue2.c @@ -2639,7 +2639,7 @@ gst_queue2_handle_sink_event (GstPad * pad, GstObject * parent, /* reset rate counters */ reset_rate_timer (queue); gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue2_loop, - queue->srcpad, NULL); + gst_object_ref (queue->srcpad), gst_object_unref); GST_QUEUE2_MUTEX_UNLOCK (queue); } else { GST_QUEUE2_MUTEX_LOCK (queue); @@ -2720,7 +2720,8 @@ gst_queue2_handle_sink_event (GstPad * pad, GstObject * parent, /* reset rate counters */ reset_rate_timer (queue); gst_pad_start_task (queue->srcpad, - (GstTaskFunction) gst_queue2_loop, queue->srcpad, NULL); + (GstTaskFunction) gst_queue2_loop, + gst_object_ref (queue->srcpad), gst_object_unref); } else { queue->is_eos = FALSE; queue->unexpected = FALSE; @@ -3318,8 +3319,8 @@ gst_queue2_handle_src_event (GstPad * pad, GstObject * parent, GstEvent * event) queue->srcresult = GST_FLOW_OK; queue->sinkresult = GST_FLOW_OK; if (GST_PAD_MODE (pad) == GST_PAD_MODE_PUSH) { - gst_pad_start_task (pad, (GstTaskFunction) gst_queue2_loop, pad, - NULL); + gst_pad_start_task (pad, (GstTaskFunction) gst_queue2_loop, + gst_object_ref (pad), gst_object_unref); } } @@ -3703,7 +3704,8 @@ gst_queue2_src_activate_push (GstPad * pad, GstObject * parent, gboolean active) queue->is_eos = FALSE; queue->unexpected = FALSE; result = - gst_pad_start_task (pad, (GstTaskFunction) gst_queue2_loop, pad, NULL); + gst_pad_start_task (pad, (GstTaskFunction) gst_queue2_loop, + gst_object_ref (pad), gst_object_unref); GST_QUEUE2_MUTEX_UNLOCK (queue); } else { /* unblock loop function */ diff --git a/subprojects/gstreamer/plugins/elements/gsttypefindelement.c b/subprojects/gstreamer/plugins/elements/gsttypefindelement.c index ea1bf044b6..907dfec1f5 100644 --- a/subprojects/gstreamer/plugins/elements/gsttypefindelement.c +++ b/subprojects/gstreamer/plugins/elements/gsttypefindelement.c @@ -535,7 +535,8 @@ gst_type_find_element_seek (GstTypeFindElement * typefind, GstEvent * event) /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (typefind->sink, - (GstTaskFunction) gst_type_find_element_loop, typefind->sink, NULL); + (GstTaskFunction) gst_type_find_element_loop, + gst_object_ref (typefind->sink), gst_object_unref); /* streaming can continue now */ GST_PAD_STREAM_UNLOCK (typefind->sink); @@ -1334,7 +1335,7 @@ gst_type_find_element_activate_sink (GstPad * pad, GstObject * parent) /* only start our task if we ourselves decide to start in pull mode */ return gst_pad_start_task (pad, (GstTaskFunction) gst_type_find_element_loop, - pad, NULL); + gst_object_ref (pad), gst_object_unref); typefind_push: { diff --git a/subprojects/gstreamer/tests/check/gst/gstelement.c b/subprojects/gstreamer/tests/check/gst/gstelement.c index 851f186a66..201a1fdbe1 100644 --- a/subprojects/gstreamer/tests/check/gst/gstelement.c +++ b/subprojects/gstreamer/tests/check/gst/gstelement.c @@ -101,7 +101,8 @@ test_add_pad_while_paused_pad_activatemode (GstPad * pad, GstObject * parent, *(gboolean *) pad->activatemodedata = active; fail_unless (mode == GST_PAD_MODE_PUSH); if (active) - gst_pad_start_task (pad, test_add_pad_while_paused_dummy_task, pad, NULL); + gst_pad_start_task (pad, test_add_pad_while_paused_dummy_task, + gst_object_ref (pad), gst_object_unref); else gst_pad_stop_task (pad); return TRUE;