diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c index 04d15538b1..599f543cfa 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c +++ b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c @@ -433,6 +433,7 @@ struct _CCBuffer /* properties */ GstClockTime max_buffer_time; gboolean output_padding; + gboolean output_ccp_padding; }; G_DEFINE_TYPE (CCBuffer, cc_buffer, G_TYPE_OBJECT); @@ -452,6 +453,7 @@ cc_buffer_init (CCBuffer * buf) buf->max_buffer_time = DEFAULT_MAX_BUFFER_TIME; buf->output_padding = TRUE; + buf->output_ccp_padding = FALSE; } static void @@ -838,8 +840,32 @@ cc_buffer_take_separated (CCBuffer * buf, "small to hold output (%u)", *cc_data_len, write_ccp_size); *cc_data_len = 0; } else if (cc_data) { + guint ccp_padding = 0; memcpy (cc_data, buf->cc_data->data, write_ccp_size); - *cc_data_len = write_ccp_size; + if (buf->output_ccp_padding + && (write_ccp_size < 3 * fps_entry->max_ccp_count)) { + guint i; + + ccp_padding = 3 * fps_entry->max_ccp_count - write_ccp_size; + GST_TRACE_OBJECT (buf, "need %u ccp padding bytes (%u - %u)", + ccp_padding, fps_entry->max_ccp_count, write_ccp_size); + for (i = 0; i < ccp_padding; i += 3) { + cc_data[i + write_ccp_size] = 0xfa; + cc_data[i + 1 + write_ccp_size] = 0x00; + cc_data[i + 2 + write_ccp_size] = 0x00; + } + } + *cc_data_len = write_ccp_size + ccp_padding; + } else if (buf->output_padding) { + guint i; + guint padding = 3 * fps_entry->max_ccp_count; + for (i = 0; i < padding; i += 3) { + cc_data[i + write_ccp_size] = 0xfa; + cc_data[i + 1 + write_ccp_size] = 0x00; + cc_data[i + 2 + write_ccp_size] = 0x00; + } + GST_TRACE_OBJECT (buf, "outputting only %u padding bytes", padding); + *cc_data_len = padding; } else { *cc_data_len = 0; } @@ -874,6 +900,7 @@ cc_buffer_take_cc_data (CCBuffer * buf, guint cea608_output_count = write_cea608_1_size + write_cea608_2_size + field1_padding + field2_padding; + guint ccp_padding = 0; wrote_first = !buf->last_cea608_written_was_field1; while (cea608_1_i + cea608_2_i < cea608_output_count) { @@ -925,7 +952,22 @@ cc_buffer_take_cc_data (CCBuffer * buf, if (write_ccp_size > 0) memcpy (&cc_data[out_i], buf->cc_data->data, write_ccp_size); - *cc_data_len = out_i + write_ccp_size; + if (buf->output_ccp_padding + && (write_ccp_size < 3 * fps_entry->max_ccp_count)) { + guint i; + + ccp_padding = 3 * fps_entry->max_ccp_count - write_ccp_size; + GST_TRACE_OBJECT (buf, "need %u ccp padding bytes (%u - %u)", ccp_padding, + fps_entry->max_ccp_count, write_ccp_size); + for (i = 0; i < ccp_padding; i += 3) { + cc_data[i + out_i + write_ccp_size] = 0xfa; + cc_data[i + 1 + out_i + write_ccp_size] = 0x00; + cc_data[i + 2 + out_i + write_ccp_size] = 0x00; + } + } + *cc_data_len = out_i + write_ccp_size + ccp_padding; + GST_TRACE_OBJECT (buf, "cc_data_len is %u (%u + %u + %u)", *cc_data_len, + out_i, write_ccp_size, ccp_padding); } g_array_remove_range (buf->cea608_1, 0, write_cea608_1_size); @@ -1010,7 +1052,9 @@ cc_buffer_set_max_buffer_time (CCBuffer * buf, GstClockTime max_time) } void -cc_buffer_set_output_padding (CCBuffer * buf, gboolean output_padding) +cc_buffer_set_output_padding (CCBuffer * buf, gboolean output_padding, + gboolean output_ccp_padding) { buf->output_padding = output_padding; + buf->output_ccp_padding = output_ccp_padding; } diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h index 4c745822f1..611969e8de 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h +++ b/subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h @@ -130,7 +130,8 @@ void cc_buffer_set_max_buffer_time (CCBuffer * buf, GstClockTime max_time); G_GNUC_INTERNAL void cc_buffer_set_output_padding (CCBuffer * buf, - gboolean output_padding); + gboolean output_padding, + gboolean output_ccp_padding); G_END_DECLS diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c b/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c index 743cc65c0d..402fa6df38 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c +++ b/subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c @@ -1099,7 +1099,8 @@ gst_cc_combiner_change_state (GstElement * element, GstStateChange transition) self->max_scheduled = self->prop_max_scheduled; self->output_padding = self->prop_output_padding; cc_buffer_set_max_buffer_time (self->cc_buffer, GST_CLOCK_TIME_NONE); - cc_buffer_set_output_padding (self->cc_buffer, self->prop_output_padding); + cc_buffer_set_output_padding (self->cc_buffer, self->prop_output_padding, + self->prop_output_padding); break; default: break; diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/gstccconverter.c b/subprojects/gst-plugins-bad/ext/closedcaption/gstccconverter.c index 98784c887c..ffbf11d8b9 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/gstccconverter.c +++ b/subprojects/gst-plugins-bad/ext/closedcaption/gstccconverter.c @@ -1881,4 +1881,5 @@ gst_cc_converter_init (GstCCConverter * self) self->in_field = 0; self->out_field = 0; self->cc_buffer = cc_buffer_new (); + cc_buffer_set_output_padding (self->cc_buffer, TRUE, FALSE); } diff --git a/subprojects/gst-plugins-bad/ext/closedcaption/gstcea608mux.c b/subprojects/gst-plugins-bad/ext/closedcaption/gstcea608mux.c index d897b482ac..0249f4f301 100644 --- a/subprojects/gst-plugins-bad/ext/closedcaption/gstcea608mux.c +++ b/subprojects/gst-plugins-bad/ext/closedcaption/gstcea608mux.c @@ -436,7 +436,7 @@ gst_cea608_mux_init (GstCea608Mux * self) { self->cc_buffer = cc_buffer_new (); cc_buffer_set_max_buffer_time (self->cc_buffer, GST_CLOCK_TIME_NONE); - cc_buffer_set_output_padding (self->cc_buffer, TRUE); + cc_buffer_set_output_padding (self->cc_buffer, TRUE, FALSE); self->cdp_fps_entry = &null_fps_entry; self->start_time = GST_CLOCK_TIME_NONE; } diff --git a/subprojects/gst-plugins-bad/tests/check/elements/cccombiner.c b/subprojects/gst-plugins-bad/tests/check/elements/cccombiner.c index 74894722ad..fa56cb7fed 100644 --- a/subprojects/gst-plugins-bad/tests/check/elements/cccombiner.c +++ b/subprojects/gst-plugins-bad/tests/check/elements/cccombiner.c @@ -107,7 +107,13 @@ GST_START_TEST (captions_and_eos) GstBuffer *second_video_buf, *second_caption_buf; const guint8 cc_data[3] = { 0xfc, 0x20, 0x20 }; - h = gst_harness_new_with_padnames ("cccombiner", "sink", "src"); + GstElement *element = gst_element_factory_make ("cccombiner", NULL); + g_assert (element != NULL); + /* these must be set before it changes the state */ + g_object_set (element, "schedule", FALSE, "output-padding", FALSE, NULL); + + h = gst_harness_new_with_element (element, "sink", "src"); + gst_object_unref (element); h2 = gst_harness_new_with_element (h->element, NULL, NULL); caption_pad = gst_element_request_pad_simple (h->element, "caption"); gst_harness_add_element_sink_pad (h2, caption_pad);