From 7abece4416d6cd8ad9ac7ec426be53b5204a3b2e Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Mon, 27 Jan 2025 18:55:26 +0100 Subject: [PATCH] cccombiner: Restore QoS messaging Reimplement the QoS message generation that was lost together with the caption frame counting. Part-of: --- .../ext/closedcaption/ccutils.c | 32 +++++++++----- .../ext/closedcaption/ccutils.h | 10 ++++- .../ext/closedcaption/gstcccombiner.c | 42 +++++++++++++------ 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c index ac573b80f3..728c0fa162 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c +++ b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c @@ -589,12 +589,13 @@ calculate_n_cea708_doubles_from_time_ceil (GstClockTime ns) return GST_ROUND_UP_2 (ret); } -static void +static CCBufferPushReturn push_internal (CCBuffer * buf, const guint8 * cea608_1, guint cea608_1_len, const guint8 * cea608_2, guint cea608_2_len, const guint8 * cc_data, guint cc_data_len) { guint max_cea608_bytes; + gboolean pushed = FALSE, overflow = FALSE; GST_DEBUG_OBJECT (buf, "pushing cea608-1: %u cea608-2: %u ccp: %u", cea608_1_len, cea608_2_len, cc_data_len); @@ -607,8 +608,10 @@ push_internal (CCBuffer * buf, const guint8 * cea608_1, "previous data, max %u, attempted to hold %u", max_cea608_bytes, cea608_1_len + buf->cea608_1->len); g_array_set_size (buf->cea608_1, 0); + overflow = TRUE; } g_array_append_vals (buf->cea608_1, cea608_1, cea608_1_len); + pushed = TRUE; } if (cea608_2_len > 0) { if (cea608_2_len + buf->cea608_2->len > max_cea608_bytes) { @@ -616,8 +619,10 @@ push_internal (CCBuffer * buf, const guint8 * cea608_1, "previous data, max %u, attempted to hold %u", max_cea608_bytes, cea608_2_len + buf->cea608_2->len); g_array_set_size (buf->cea608_2, 0); + overflow = TRUE; } g_array_append_vals (buf->cea608_2, cea608_2, cea608_2_len); + pushed = TRUE; } if (cc_data_len > 0) { guint max_cea708_bytes = @@ -627,12 +632,21 @@ push_internal (CCBuffer * buf, const guint8 * cea608_1, "previous data, max %u, attempted to hold %u", max_cea708_bytes, cc_data_len + buf->cc_data->len); g_array_set_size (buf->cc_data, 0); + overflow = TRUE; } g_array_append_vals (buf->cc_data, cc_data, cc_data_len); + pushed = TRUE; } + + if (overflow) + return CC_BUFFER_PUSH_OVERFLOW; + else if (pushed) + return CC_BUFFER_PUSH_OK; + else + return CC_BUFFER_PUSH_NO_DATA; } -gboolean +CCBufferPushReturn cc_buffer_push_separated (CCBuffer * buf, const guint8 * cea608_1, guint cea608_1_len, const guint8 * cea608_2, guint cea608_2_len, const guint8 * cc_data, guint cc_data_len) @@ -681,13 +695,11 @@ cc_buffer_push_separated (CCBuffer * buf, const guint8 * cea608_1, cc_data_len = 0; } - push_internal (buf, cea608_1_copy, cea608_1_len, cea608_2_copy, + return push_internal (buf, cea608_1_copy, cea608_1_len, cea608_2_copy, cea608_2_len, cc_data_copy, cc_data_len); - - return cea608_1_len > 0 || cea608_2_len > 0 || cc_data_len > 0; } -gboolean +CCBufferPushReturn cc_buffer_push_cc_data (CCBuffer * buf, const guint8 * cc_data, guint cc_data_len) { @@ -709,13 +721,11 @@ cc_buffer_push_cc_data (CCBuffer * buf, const guint8 * cc_data, if (ccp_offset < 0) { GST_WARNING_OBJECT (buf, "Failed to extract cea608 from cc_data"); - return FALSE; + return CC_BUFFER_PUSH_NO_DATA; } - push_internal (buf, cea608_1, cea608_1_len, cea608_2, - cea608_2_len, &cc_data_copy[ccp_offset], cc_data_len - ccp_offset); - - return cea608_1_len > 0 || cea608_2_len > 0 || cc_data_len - ccp_offset > 0; + return push_internal (buf, cea608_1, cea608_1_len, cea608_2, cea608_2_len, + &cc_data_copy[ccp_offset], cc_data_len - ccp_offset); } void diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h index 89ffdf4f97..fbbe20f663 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h +++ b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h @@ -100,6 +100,12 @@ typedef enum { #define GST_TYPE_CC_BUFFER_CEA608_PADDING_STRATEGY (gst_cc_buffer_cea608_padding_strategy_get_type()) GType gst_cc_buffer_cea608_padding_strategy_get_type (void); +typedef enum { + CC_BUFFER_PUSH_OK, + CC_BUFFER_PUSH_NO_DATA, + CC_BUFFER_PUSH_OVERFLOW, +} CCBufferPushReturn; + G_DECLARE_FINAL_TYPE (CCBuffer, cc_buffer, GST, CC_BUFFER, GObject); G_GNUC_INTERNAL @@ -110,7 +116,7 @@ void cc_buffer_get_stored_size (CCBuffer * buf, guint * cea608_2_len, guint * cc_data_len); G_GNUC_INTERNAL -gboolean cc_buffer_push_separated (CCBuffer * buf, +CCBufferPushReturn cc_buffer_push_separated (CCBuffer * buf, const guint8 * cea608_1, guint cea608_1_len, const guint8 * cea608_2, @@ -118,7 +124,7 @@ gboolean cc_buffer_push_separated (CCBuffer * buf, const guint8 * cc_data, guint cc_data_len); G_GNUC_INTERNAL -gboolean cc_buffer_push_cc_data (CCBuffer * buf, +CCBufferPushReturn cc_buffer_push_cc_data (CCBuffer * buf, const guint8 * cc_data, guint cc_data_len); G_GNUC_INTERNAL diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c b/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c index 61d168f355..b1416f49d5 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c +++ b/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c @@ -246,7 +246,7 @@ out: gst_buffer_set_size (buffer, s334_len); } -static void +static CCBufferPushReturn schedule_cdp (GstCCCombiner * self, const GstVideoTimeCode * tc, const guint8 * data, guint len, GstClockTime pts, GstClockTime duration) { @@ -254,10 +254,10 @@ schedule_cdp (GstCCCombiner * self, const GstVideoTimeCode * tc, guint cc_data_len; cc_data_len = extract_cdp (self, data, len, cc_data); - cc_buffer_push_cc_data (self->cc_buffer, cc_data, cc_data_len); + return cc_buffer_push_cc_data (self->cc_buffer, cc_data, cc_data_len); } -static void +static CCBufferPushReturn schedule_cea608_s334_1a (GstCCCombiner * self, guint8 * data, guint len, GstClockTime pts, GstClockTime duration) { @@ -287,21 +287,22 @@ schedule_cea608_s334_1a (GstCCCombiner * self, guint8 * data, guint len, } } - cc_buffer_push_separated (self->cc_buffer, field0_data, field0_len, + return cc_buffer_push_separated (self->cc_buffer, field0_data, field0_len, field1_data, field1_len, NULL, 0); } -static void +static CCBufferPushReturn schedule_cea708_raw (GstCCCombiner * self, guint8 * data, guint len, GstClockTime pts, GstClockTime duration) { - cc_buffer_push_cc_data (self->cc_buffer, data, len); + return cc_buffer_push_cc_data (self->cc_buffer, data, len); } -static void +static CCBufferPushReturn schedule_cea608_raw (GstCCCombiner * self, guint8 * data, guint len) { - cc_buffer_push_separated (self->cc_buffer, data, len, NULL, 0, NULL, 0); + return cc_buffer_push_separated (self->cc_buffer, data, len, + NULL, 0, NULL, 0); } static void @@ -310,6 +311,7 @@ schedule_caption (GstCCCombiner * self, GstAggregatorPad * caption_pad, { GstMapInfo map; GstClockTime pts, duration, running_time; + CCBufferPushReturn push_ret = CC_BUFFER_PUSH_NO_DATA; pts = GST_BUFFER_PTS (caption_buf); duration = GST_BUFFER_DURATION (caption_buf); @@ -323,22 +325,38 @@ schedule_caption (GstCCCombiner * self, GstAggregatorPad * caption_pad, switch (self->caption_type) { case GST_VIDEO_CAPTION_TYPE_CEA708_CDP: - schedule_cdp (self, tc, map.data, map.size, pts, duration); + push_ret = schedule_cdp (self, tc, map.data, map.size, pts, duration); break; case GST_VIDEO_CAPTION_TYPE_CEA708_RAW: - schedule_cea708_raw (self, map.data, map.size, pts, duration); + push_ret = schedule_cea708_raw (self, map.data, map.size, pts, duration); break; case GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A: - schedule_cea608_s334_1a (self, map.data, map.size, pts, duration); + push_ret = + schedule_cea608_s334_1a (self, map.data, map.size, pts, duration); break; case GST_VIDEO_CAPTION_TYPE_CEA608_RAW: - schedule_cea608_raw (self, map.data, map.size); + push_ret = schedule_cea608_raw (self, map.data, map.size); break; default: break; } gst_buffer_unmap (caption_buf, &map); + + if (push_ret == CC_BUFFER_PUSH_OVERFLOW) { + GstClockTime stream_time; + + GST_WARNING_OBJECT (self, "CC buffer overflowed with %" GST_PTR_FORMAT, + caption_buf); + + stream_time = + gst_segment_to_stream_time (&caption_pad->segment, GST_FORMAT_TIME, + pts); + + gst_element_post_message (GST_ELEMENT_CAST (self), + gst_message_new_qos (GST_OBJECT_CAST (self), FALSE, + running_time, stream_time, pts, duration)); + } } static void