Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
bbd1f0a
gstpad: check EOS / FLUSHING again after running probes in chain
MathieuDuponchelle Nov 24, 2020
8e18d12
ccextractor: Add force-expose-caption-pad property
seungha-yang Aug 11, 2021
3d39421
filesrc: Port to FILE struct
seungha-yang Dec 29, 2021
aa8a9f0
filesrc: Add buffer-size property
seungha-yang Dec 29, 2021
b6144b3
Set default filesrc buffer-size to 10MB
raytiley May 2, 2022
58d076f
Increase default filesrc buffer to 20MB
raytiley May 26, 2022
6e40557
WIP: Video audio meta
MathieuDuponchelle Mar 25, 2021
3c389c5
mpegvideoparse: Update pixel-aspect-ratio if resolution is updated
seungha-yang Aug 27, 2022
d4bd8c8
videodecoder: Always prefer DTS as PTS if PTS is unknown
seungha-yang Aug 30, 2022
ecb6a54
ccconverter: Don't assert on error
seungha-yang Mar 29, 2023
5e18221
decklink2: Import SDK v12.4.2 files
seungha-yang Dec 31, 2022
74ed484
decklink2: Remove fprintf from SDK
seungha-yang Mar 22, 2023
9197120
decklink2: Add new Blackmagic DeckLink plugin
seungha-yang Dec 30, 2022
1b1d71c
aggregator: Add gst_aggregator_ensure_mandatory_events() method
seungha-yang Jun 1, 2023
0f045f2
streamselector: Add new input stream selector element
seungha-yang Jun 1, 2023
1694633
decklink2srcbin: Configure small queue between src and demux
seungha-yang Jun 6, 2023
d7a51b3
decklink2sink: Fill audio silence when video is duplicated
seungha-yang Jun 6, 2023
6c259c3
streamselector: Always drop old buffers from inactive pad
seungha-yang Jun 5, 2023
05d5a56
decklink2src: Add "skip-first-time" property
seungha-yang Jun 13, 2023
6ef23f3
decklink2src: Add "restart" signal action
seungha-yang Jun 13, 2023
8cec0fd
decklink2sink: Add auto-restart property
seungha-yang Jun 20, 2023
af4fa2c
decklink2sink: Add restart signal action
seungha-yang Jun 20, 2023
1cbd184
decklink2: Update for CFStringRef to std::string converision
seungha-yang Jun 15, 2023
05a01ad
decklink2src: Use GstQueueArray instead of std::queue
seungha-yang Jun 15, 2023
79db6be
decklink2sink: Loop ScheduleAudioSamples() until all data is written
seungha-yang Jun 21, 2023
cc2c399
decklink2src: Add "desync-threshold" and "no-signal-threshold" proper…
seungha-yang Jun 21, 2023
ce0f0b6
decklink2src: Remove no-signal-threshold property
seungha-yang Jun 26, 2023
abca8b3
decklink2src: Update for signal state logging
seungha-yang Jun 27, 2023
071f2da
decklink2sink: Don't hold lock while stopping
seungha-yang Jun 30, 2023
3192d38
Flush device streams when we don't get enough audio samples from the …
raytiley Jul 10, 2023
4dd5695
decklink2: Fix output audio prepend and add more logs
seungha-yang Jul 11, 2023
b05bdb5
decklink2sink: Restart only when frames are dropped
seungha-yang Jul 14, 2023
b1af882
decklink2output: Duplicate more frames on underrun
seungha-yang Jul 14, 2023
2b07406
decklink2output: Calculate audio sample timestamp
seungha-yang Jul 27, 2023
4fa910c
decklink2sink: Add output-stats property
seungha-yang Jul 28, 2023
990fa9f
Set audio output mode to bmdAudioSampleRate48kHz
raytiley Jul 29, 2023
995d024
decklink2sink: Add buffered audio and video time to ouptput-stats
seungha-yang Jul 28, 2023
f977add
ceiling latency for awscombiner
raytiley Aug 1, 2023
37844a8
decklink2combiner: Don't aggregate multiple audio buffers
seungha-yang Aug 1, 2023
6eac5b8
decklink2output: Update audio drop logic
seungha-yang Aug 1, 2023
343bce8
streamselector: Don't try to drop buffer of the current active pad
seungha-yang Aug 5, 2023
9e67e0a
streamselector: Fix busy waiting
seungha-yang Aug 5, 2023
367476f
streamselectorbin: Add sync-only-inactive property
seungha-yang Sep 14, 2023
6867627
decklink2src: Validate frame resolution and formats
seungha-yang Nov 3, 2023
ea270f6
decklink2sink: Add desync-threshold property
seungha-yang Dec 4, 2023
9a458d3
decklink2src: Fix mutex usage
seungha-yang Dec 7, 2023
747070a
decklink2src: Release mutex while stopping
seungha-yang Dec 7, 2023
a86ae14
decklink2: Validate video buffer size
seungha-yang Dec 14, 2023
a7608be
decklink2src: Implement soft restart
seungha-yang Dec 14, 2023
a35ddff
decklink2: Fix caps to mode conversion
seungha-yang Apr 3, 2024
7f1628e
filesrc: Don't abort on _get_osfhandle()
seungha-yang May 17, 2024
d563ed0
fix cherry-pick
raytiley May 17, 2024
3640625
filesrc: Fix build
seungha-yang May 20, 2024
480c2b2
[TEST] - Test default max decode threads at 2
raytiley Jun 11, 2024
79d3371
Revert "[TEST] - Test default max decode threads at 2"
raytiley Jun 18, 2024
c587100
timecodestamper: Add running-time source mode
seungha-yang Aug 7, 2024
b6c5a29
Fix rebase
raytiley Dec 1, 2024
d0257f7
line21dec: Handle the case where there is only one line of CC
bilboed Nov 4, 2024
d4e8ea5
Add warning about if there is audio with no video from decklink2src
raytiley Dec 6, 2024
1379310
decklink2src: Respect requested video-format
seungha-yang Jan 8, 2025
7ccfc73
decklink2src: Avoid unnecessary restart on format change callback
seungha-yang Feb 10, 2025
7665232
decklink2output: Fix out of bounds read
seungha-yang Feb 20, 2025
540bd1d
avviddec: Drop frame on resolution mismatch
seungha-yang Aug 7, 2025
140ee00
decodebin3: Add decoder-factory-sort signal
seungha-yang Sep 10, 2025
5c50528
videoaggregator: Remove input interlace-mode and alpha restrictions
seungha-yang Nov 4, 2025
ba10f82
videoaggregator: Actually accept differnt interlace-mode
seungha-yang Nov 6, 2025
df9b9cf
overlaycomposition: Add support for blending upstream composition
seungha-yang Jan 6, 2026
4d06e11
overlaycomposition: Implement fixate_caps()
seungha-yang Aug 8, 2023
7a0d486
overlaycomposition: Fix transform caps
seungha-yang Jul 1, 2024
c05edd0
Use Cablecast plugins
raytiley Jan 19, 2026
22a1921
aggregator: select new start time after flush stop
MathieuDuponchelle Mar 3, 2026
2dc2a2c
decklink2: Use correct IID in video frame QueryInterface()
sdroege May 6, 2026
9aa5586
decklink2: Fix wrong IIDs in QueryInterface and Clone refcount bug
raytiley May 28, 2026
e7d38e0
gstinfo: Use stack allocation for <=1KB messages
nirbheek May 9, 2026
ed62611
gstinfo: Don't ever use %n to know how much was written
nirbheek May 9, 2026
25270e5
gstinfo: Use stack allocated memory when printing on Win32
nirbheek May 11, 2026
c0830c5
gstinfo: Use a more optimized version of GST_TIME_ARGS
nirbheek May 9, 2026
cb1a983
gstinfo: Don't use fwrite() on Windows for debug logging
nirbheek May 11, 2026
ff7157c
stop streams instead of pause during restart
raytiley May 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .indent_cpp_list
Original file line number Diff line number Diff line change
Expand Up @@ -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$)
Expand Down
3 changes: 2 additions & 1 deletion subprojects/gst-libav/ext/libav/gstavviddec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
1,258 changes: 1,258 additions & 0 deletions subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json

Large diffs are not rendered by default.

18 changes: 12 additions & 6 deletions subprojects/gst-plugins-bad/gst/closedcaption/gstccconverter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
112 changes: 91 additions & 21 deletions subprojects/gst-plugins-bad/gst/closedcaption/gstccextractor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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");

Expand All @@ -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;
Expand All @@ -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 */
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct _GstCCExtractor
GstFlowCombiner *combiner;

gboolean remove_caption_meta;
gboolean force_expose_caption_pad;
};

struct _GstCCExtractorClass
Expand Down
16 changes: 10 additions & 6 deletions subprojects/gst-plugins-bad/gst/closedcaption/gstline21dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions subprojects/gst-plugins-bad/gst/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading