mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
cccombiner: expose output-padding property
When schedule=true and output-padding=false, cccombiner will not inject padding in the output closed caption meta stream. The property has no effect when schedule=false. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1621>
This commit is contained in:
parent
db5a4b490d
commit
f10e2eb88f
3 changed files with 59 additions and 7 deletions
|
@ -4952,6 +4952,18 @@
|
||||||
"type": "guint",
|
"type": "guint",
|
||||||
"writable": true
|
"writable": true
|
||||||
},
|
},
|
||||||
|
"output-padding": {
|
||||||
|
"blurb": "Whether to output padding packets when schedule=true",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "true",
|
||||||
|
"mutable": "ready",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gboolean",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"blurb": "Schedule caption buffers so that exactly one is output per video frame",
|
"blurb": "Schedule caption buffers so that exactly one is output per video frame",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
|
|
@ -60,11 +60,13 @@ enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_SCHEDULE,
|
PROP_SCHEDULE,
|
||||||
|
PROP_OUTPUT_PADDING,
|
||||||
PROP_MAX_SCHEDULED,
|
PROP_MAX_SCHEDULED,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_MAX_SCHEDULED 30
|
#define DEFAULT_MAX_SCHEDULED 30
|
||||||
#define DEFAULT_SCHEDULE TRUE
|
#define DEFAULT_SCHEDULE TRUE
|
||||||
|
#define DEFAULT_OUTPUT_PADDING TRUE
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -689,7 +691,7 @@ dequeue_caption_one_field (GstCCCombiner * self, const GstVideoTimeCode * tc,
|
||||||
caption_data.buffer = scheduled->buffer;
|
caption_data.buffer = scheduled->buffer;
|
||||||
caption_data.caption_type = self->caption_type;
|
caption_data.caption_type = self->caption_type;
|
||||||
g_array_append_val (self->current_frame_captions, caption_data);
|
g_array_append_val (self->current_frame_captions, caption_data);
|
||||||
} else if (!drain) {
|
} else if (!drain && self->output_padding) {
|
||||||
caption_data.caption_type = self->caption_type;
|
caption_data.caption_type = self->caption_type;
|
||||||
caption_data.buffer = make_padding (self, tc, field);
|
caption_data.buffer = make_padding (self, tc, field);
|
||||||
g_array_append_val (self->current_frame_captions, caption_data);
|
g_array_append_val (self->current_frame_captions, caption_data);
|
||||||
|
@ -701,7 +703,7 @@ dequeue_caption_both_fields (GstCCCombiner * self, const GstVideoTimeCode * tc,
|
||||||
gboolean drain)
|
gboolean drain)
|
||||||
{
|
{
|
||||||
CaptionQueueItem *field0_scheduled, *field1_scheduled;
|
CaptionQueueItem *field0_scheduled, *field1_scheduled;
|
||||||
GstBuffer *field0_buffer, *field1_buffer;
|
GstBuffer *field0_buffer = NULL, *field1_buffer = NULL;
|
||||||
CaptionData caption_data;
|
CaptionData caption_data;
|
||||||
|
|
||||||
field0_scheduled = gst_queue_array_pop_head_struct (self->scheduled[0]);
|
field0_scheduled = gst_queue_array_pop_head_struct (self->scheduled[0]);
|
||||||
|
@ -713,20 +715,31 @@ dequeue_caption_both_fields (GstCCCombiner * self, const GstVideoTimeCode * tc,
|
||||||
|
|
||||||
if (field0_scheduled) {
|
if (field0_scheduled) {
|
||||||
field0_buffer = field0_scheduled->buffer;
|
field0_buffer = field0_scheduled->buffer;
|
||||||
} else {
|
} else if (self->output_padding) {
|
||||||
field0_buffer = make_padding (self, tc, 0);
|
field0_buffer = make_padding (self, tc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field1_scheduled) {
|
if (field1_scheduled) {
|
||||||
field1_buffer = field1_scheduled->buffer;
|
field1_buffer = field1_scheduled->buffer;
|
||||||
} else {
|
} else if (self->output_padding) {
|
||||||
field1_buffer = make_padding (self, tc, 1);
|
field1_buffer = make_padding (self, tc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
caption_data.caption_type = self->caption_type;
|
if (field0_buffer || field1_buffer) {
|
||||||
caption_data.buffer = gst_buffer_append (field0_buffer, field1_buffer);
|
if (field0_buffer && field1_buffer) {
|
||||||
|
caption_data.buffer = gst_buffer_append (field0_buffer, field1_buffer);
|
||||||
|
} else if (field0_buffer) {
|
||||||
|
caption_data.buffer = field0_buffer;
|
||||||
|
} else if (field1_buffer) {
|
||||||
|
caption_data.buffer = field1_buffer;
|
||||||
|
} else {
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
g_array_append_val (self->current_frame_captions, caption_data);
|
caption_data.caption_type = self->caption_type;
|
||||||
|
|
||||||
|
g_array_append_val (self->current_frame_captions, caption_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -1419,6 +1432,7 @@ gst_cc_combiner_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
self->schedule = self->prop_schedule;
|
self->schedule = self->prop_schedule;
|
||||||
self->max_scheduled = self->prop_max_scheduled;
|
self->max_scheduled = self->prop_max_scheduled;
|
||||||
|
self->output_padding = self->prop_output_padding;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1440,6 +1454,9 @@ gst_cc_combiner_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_MAX_SCHEDULED:
|
case PROP_MAX_SCHEDULED:
|
||||||
self->prop_max_scheduled = g_value_get_uint (value);
|
self->prop_max_scheduled = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_OUTPUT_PADDING:
|
||||||
|
self->prop_output_padding = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1459,6 +1476,9 @@ gst_cc_combiner_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_MAX_SCHEDULED:
|
case PROP_MAX_SCHEDULED:
|
||||||
g_value_set_uint (value, self->prop_max_scheduled);
|
g_value_set_uint (value, self->prop_max_scheduled);
|
||||||
break;
|
break;
|
||||||
|
case PROP_OUTPUT_PADDING:
|
||||||
|
g_value_set_boolean (value, self->prop_output_padding);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1536,6 +1556,23 @@ gst_cc_combiner_class_init (GstCCCombinerClass * klass)
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
GST_PARAM_MUTABLE_READY));
|
GST_PARAM_MUTABLE_READY));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstCCCombiner:output-padding:
|
||||||
|
*
|
||||||
|
* When #GstCCCombiner:schedule is %TRUE, this property controls
|
||||||
|
* whether the output closed caption meta stream will be padded.
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
||||||
|
PROP_OUTPUT_PADDING, g_param_spec_boolean ("output-padding",
|
||||||
|
"Output padding",
|
||||||
|
"Whether to output padding packets when schedule=true",
|
||||||
|
DEFAULT_OUTPUT_PADDING,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
GST_PARAM_MUTABLE_READY));
|
||||||
|
|
||||||
|
|
||||||
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
||||||
&sinktemplate, GST_TYPE_AGGREGATOR_PAD);
|
&sinktemplate, GST_TYPE_AGGREGATOR_PAD);
|
||||||
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
||||||
|
@ -1585,6 +1622,7 @@ gst_cc_combiner_init (GstCCCombiner * self)
|
||||||
|
|
||||||
self->prop_schedule = DEFAULT_SCHEDULE;
|
self->prop_schedule = DEFAULT_SCHEDULE;
|
||||||
self->prop_max_scheduled = DEFAULT_MAX_SCHEDULED;
|
self->prop_max_scheduled = DEFAULT_MAX_SCHEDULED;
|
||||||
|
self->prop_output_padding = DEFAULT_OUTPUT_PADDING;
|
||||||
self->scheduled[0] =
|
self->scheduled[0] =
|
||||||
gst_queue_array_new_for_struct (sizeof (CaptionQueueItem), 0);
|
gst_queue_array_new_for_struct (sizeof (CaptionQueueItem), 0);
|
||||||
self->scheduled[1] =
|
self->scheduled[1] =
|
||||||
|
|
|
@ -65,9 +65,11 @@ struct _GstCCCombiner
|
||||||
|
|
||||||
gboolean prop_schedule;
|
gboolean prop_schedule;
|
||||||
guint prop_max_scheduled;
|
guint prop_max_scheduled;
|
||||||
|
gboolean prop_output_padding;
|
||||||
|
|
||||||
gboolean schedule;
|
gboolean schedule;
|
||||||
guint max_scheduled;
|
guint max_scheduled;
|
||||||
|
gboolean output_padding;
|
||||||
/* One queue per field */
|
/* One queue per field */
|
||||||
GstQueueArray *scheduled[2];
|
GstQueueArray *scheduled[2];
|
||||||
guint16 cdp_hdr_sequence_cntr;
|
guint16 cdp_hdr_sequence_cntr;
|
||||||
|
|
Loading…
Reference in a new issue