mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 13:11:06 +00:00
basetsmux: Support for caps changes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/981>
This commit is contained in:
parent
a8ebf72627
commit
95eb8672a6
1 changed files with 79 additions and 17 deletions
|
@ -370,9 +370,9 @@ release_buffer_cb (guint8 * data, void *user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
gst_base_ts_mux_create_or_update_stream (GstBaseTsMux * mux,
|
||||||
|
GstBaseTsMuxPad * ts_pad, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCaps *caps;
|
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
guint st = TSMUX_ST_RESERVED;
|
guint st = TSMUX_ST_RESERVED;
|
||||||
const gchar *mt;
|
const gchar *mt;
|
||||||
|
@ -386,15 +386,9 @@ gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
||||||
const gchar *stream_format = NULL;
|
const gchar *stream_format = NULL;
|
||||||
const char *interlace_mode = NULL;
|
const char *interlace_mode = NULL;
|
||||||
|
|
||||||
caps = gst_pad_get_current_caps (GST_PAD (ts_pad));
|
|
||||||
if (caps == NULL) {
|
|
||||||
GST_DEBUG_OBJECT (ts_pad, "Sink pad caps were not set before pushing");
|
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ts_pad,
|
GST_DEBUG_OBJECT (ts_pad,
|
||||||
"Creating stream with PID 0x%04x for caps %" GST_PTR_FORMAT,
|
"%s stream with PID 0x%04x for caps %" GST_PTR_FORMAT,
|
||||||
ts_pad->pid, caps);
|
ts_pad->stream ? "Recreating" : "Creating", ts_pad->pid, caps);
|
||||||
|
|
||||||
s = gst_caps_get_structure (caps, 0);
|
s = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
|
@ -403,6 +397,9 @@ gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
codec_data = gst_value_get_buffer (value);
|
codec_data = gst_value_get_buffer (value);
|
||||||
|
|
||||||
|
g_clear_pointer (&ts_pad->codec_data, gst_buffer_unref);
|
||||||
|
ts_pad->prepare_func = NULL;
|
||||||
|
|
||||||
stream_format = gst_structure_get_string (s, "stream-format");
|
stream_format = gst_structure_get_string (s, "stream-format");
|
||||||
|
|
||||||
if (strcmp (mt, "video/x-dirac") == 0) {
|
if (strcmp (mt, "video/x-dirac") == 0) {
|
||||||
|
@ -470,6 +467,10 @@ gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
||||||
GST_ERROR_OBJECT (mux, "Need codec_data for raw MPEG-4 AAC");
|
GST_ERROR_OBJECT (mux, "Need codec_data for raw MPEG-4 AAC");
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
}
|
}
|
||||||
|
} else if (codec_data) {
|
||||||
|
ts_pad->codec_data = gst_buffer_ref (codec_data);
|
||||||
|
} else {
|
||||||
|
ts_pad->codec_data = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -675,10 +676,19 @@ gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_pad->stream =
|
if (ts_pad->stream && st != ts_pad->stream->stream_type) {
|
||||||
tsmux_create_stream (mux->tsmux, st, ts_pad->pid, ts_pad->language);
|
GST_ELEMENT_ERROR (mux, STREAM, MUX,
|
||||||
if (ts_pad->stream == NULL)
|
("Stream type change from %02x to %02x not supported",
|
||||||
|
ts_pad->stream->stream_type, st), NULL);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ts_pad->stream == NULL) {
|
||||||
|
ts_pad->stream =
|
||||||
|
tsmux_create_stream (mux->tsmux, st, ts_pad->pid, ts_pad->language);
|
||||||
|
if (ts_pad->stream == NULL)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
interlace_mode = gst_structure_get_string (s, "interlace-mode");
|
interlace_mode = gst_structure_get_string (s, "interlace-mode");
|
||||||
gst_structure_get_int (s, "rate", &ts_pad->stream->audio_sampling);
|
gst_structure_get_int (s, "rate", &ts_pad->stream->audio_sampling);
|
||||||
|
@ -707,18 +717,14 @@ gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
||||||
ts_pad->stream->opus_channel_config_code = opus_channel_config_code;
|
ts_pad->stream->opus_channel_config_code = opus_channel_config_code;
|
||||||
|
|
||||||
tsmux_stream_set_buffer_release_func (ts_pad->stream, release_buffer_cb);
|
tsmux_stream_set_buffer_release_func (ts_pad->stream, release_buffer_cb);
|
||||||
tsmux_program_add_stream (ts_pad->prog, ts_pad->stream);
|
|
||||||
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
not_negotiated:
|
not_negotiated:
|
||||||
gst_caps_unref (caps);
|
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
gst_caps_unref (caps);
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,6 +736,27 @@ is_valid_pmt_pid (guint16 pmt_pid)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_base_ts_mux_create_stream (GstBaseTsMux * mux, GstBaseTsMuxPad * ts_pad)
|
||||||
|
{
|
||||||
|
GstCaps *caps = gst_pad_get_current_caps (GST_PAD (ts_pad));
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
if (caps == NULL) {
|
||||||
|
GST_DEBUG_OBJECT (ts_pad, "Sink pad caps were not set before pushing");
|
||||||
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gst_base_ts_mux_create_or_update_stream (mux, ts_pad, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
if (ret == GST_FLOW_OK) {
|
||||||
|
tsmux_program_add_stream (ts_pad->prog, ts_pad->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_base_ts_mux_create_pad_stream (GstBaseTsMux * mux, GstPad * pad)
|
gst_base_ts_mux_create_pad_stream (GstBaseTsMux * mux, GstPad * pad)
|
||||||
{
|
{
|
||||||
|
@ -1863,6 +1890,41 @@ gst_base_ts_mux_sink_event (GstAggregator * agg, GstAggregatorPad * agg_pad,
|
||||||
gboolean forward = TRUE;
|
gboolean forward = TRUE;
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
GList *cur;
|
||||||
|
|
||||||
|
if (ts_pad->stream == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
forward = FALSE;
|
||||||
|
|
||||||
|
gst_event_parse_caps (event, &caps);
|
||||||
|
if (!caps || !gst_caps_is_fixed (caps))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = gst_base_ts_mux_create_or_update_stream (mux, ts_pad, caps);
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
mux->tsmux->pat_changed = TRUE;
|
||||||
|
mux->tsmux->si_changed = TRUE;
|
||||||
|
tsmux_resend_pat (mux->tsmux);
|
||||||
|
tsmux_resend_si (mux->tsmux);
|
||||||
|
|
||||||
|
/* output PMT for each program */
|
||||||
|
for (cur = mux->tsmux->programs; cur; cur = cur->next) {
|
||||||
|
TsMuxProgram *program = (TsMuxProgram *) cur->data;
|
||||||
|
|
||||||
|
program->pmt_changed = TRUE;
|
||||||
|
tsmux_resend_pmt (program);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
||||||
{
|
{
|
||||||
GstClockTime timestamp, stream_time, running_time;
|
GstClockTime timestamp, stream_time, running_time;
|
||||||
|
|
Loading…
Reference in a new issue