ccutils: Add padding also for ccp data

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5423>
This commit is contained in:
Vivia Nikolaidou 2023-10-02 15:34:42 +03:00 committed by GStreamer Marge Bot
parent 1fc2bd8032
commit dd00dab5e9
6 changed files with 60 additions and 7 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);