mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 17:51:16 +00:00
mpegtsmux: add stream-number property on GstBaseTsMuxPad
This new property allows setting of PES stream number for AAC audio and AVC video streams. The stream number is subject to the following constraints: 1. it must be between 0 and 15 for video 2. it must be between 0 and 31 for audio Currently the PES stream number is hard-coded to zero for these stream types. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4822>
This commit is contained in:
parent
4c92d4096e
commit
a72ca72a27
8 changed files with 123 additions and 18 deletions
|
@ -214420,7 +214420,22 @@
|
||||||
"GObject"
|
"GObject"
|
||||||
],
|
],
|
||||||
"kind": "object",
|
"kind": "object",
|
||||||
"properties": {},
|
"properties": {
|
||||||
|
"stream-number": {
|
||||||
|
"blurb": "stream number",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "0",
|
||||||
|
"max": "31",
|
||||||
|
"min": "0",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gint",
|
||||||
|
"writable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"signals": {}
|
"signals": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -292,9 +292,9 @@ gst_atsc_mux_stream_get_es_descrs (TsMuxStream * stream,
|
||||||
|
|
||||||
static TsMuxStream *
|
static TsMuxStream *
|
||||||
gst_atsc_mux_create_new_stream (guint16 new_pid,
|
gst_atsc_mux_create_new_stream (guint16 new_pid,
|
||||||
TsMuxStreamType stream_type, GstBaseTsMux * mpegtsmux)
|
TsMuxStreamType stream_type, guint stream_number, GstBaseTsMux * mpegtsmux)
|
||||||
{
|
{
|
||||||
TsMuxStream *ret = tsmux_stream_new (new_pid, stream_type);
|
TsMuxStream *ret = tsmux_stream_new (new_pid, stream_type, stream_number);
|
||||||
|
|
||||||
if (stream_type == ATSCMUX_ST_PS_AUDIO_EAC3) {
|
if (stream_type == ATSCMUX_ST_PS_AUDIO_EAC3) {
|
||||||
ret->id = 0xBD;
|
ret->id = 0xBD;
|
||||||
|
|
|
@ -93,6 +93,15 @@ GST_DEBUG_CATEGORY (gst_base_ts_mux_debug);
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstBaseTsMuxPad, gst_base_ts_mux_pad, GST_TYPE_AGGREGATOR_PAD);
|
G_DEFINE_TYPE (GstBaseTsMuxPad, gst_base_ts_mux_pad, GST_TYPE_AGGREGATOR_PAD);
|
||||||
|
|
||||||
|
#define DEFAULT_PAD_STREAM_NUMBER 0
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PAD_PROP_0,
|
||||||
|
PAD_PROP_STREAM_NUMBER,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Internals */
|
/* Internals */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -163,6 +172,38 @@ gst_base_ts_mux_pad_dispose (GObject * obj)
|
||||||
G_OBJECT_CLASS (gst_base_ts_mux_pad_parent_class)->dispose (obj);
|
G_OBJECT_CLASS (gst_base_ts_mux_pad_parent_class)->dispose (obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_base_ts_mux_pad_set_property (GObject * object, guint prop_id,
|
||||||
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstBaseTsMuxPad *ts_pad = GST_BASE_TS_MUX_PAD (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PAD_PROP_STREAM_NUMBER:
|
||||||
|
ts_pad->stream_number = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_base_ts_mux_pad_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstBaseTsMuxPad *ts_pad = GST_BASE_TS_MUX_PAD (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PAD_PROP_STREAM_NUMBER:
|
||||||
|
g_value_set_int (value, ts_pad->stream_number);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_base_ts_mux_pad_class_init (GstBaseTsMuxPadClass * klass)
|
gst_base_ts_mux_pad_class_init (GstBaseTsMuxPadClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -170,9 +211,30 @@ gst_base_ts_mux_pad_class_init (GstBaseTsMuxPadClass * klass)
|
||||||
GstAggregatorPadClass *gstaggpad_class = GST_AGGREGATOR_PAD_CLASS (klass);
|
GstAggregatorPadClass *gstaggpad_class = GST_AGGREGATOR_PAD_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->dispose = gst_base_ts_mux_pad_dispose;
|
gobject_class->dispose = gst_base_ts_mux_pad_dispose;
|
||||||
|
gobject_class->set_property = gst_base_ts_mux_pad_set_property;
|
||||||
|
gobject_class->get_property = gst_base_ts_mux_pad_get_property;
|
||||||
|
|
||||||
gstaggpad_class->flush = gst_base_ts_mux_pad_flush;
|
gstaggpad_class->flush = gst_base_ts_mux_pad_flush;
|
||||||
|
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_BASE_TS_MUX, 0);
|
gst_type_mark_as_plugin_api (GST_TYPE_BASE_TS_MUX, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstBaseTsMuxPad:stream-number:
|
||||||
|
*
|
||||||
|
* Set stream number for AVC video stream
|
||||||
|
* or AAC audio streams.
|
||||||
|
*
|
||||||
|
* video stream number is stored in 4 bits
|
||||||
|
* audio stream number is stored in 5 bits.
|
||||||
|
* See Table 2-22 of ITU-T H222.0 for details on AAC and AVC stream numbers
|
||||||
|
*
|
||||||
|
* Since: 1.24
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PAD_PROP_STREAM_NUMBER,
|
||||||
|
g_param_spec_int ("stream-number", "stream number",
|
||||||
|
"stream number", 0x0, 0x1F, DEFAULT_PAD_STREAM_NUMBER,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -728,9 +790,12 @@ gst_base_ts_mux_create_or_update_stream (GstBaseTsMux * mux,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts_pad->stream == NULL) {
|
if (ts_pad->stream == NULL) {
|
||||||
|
gint stream_number = DEFAULT_PAD_STREAM_NUMBER;
|
||||||
|
|
||||||
|
g_object_get (ts_pad, "stream-number", &stream_number, NULL);
|
||||||
ts_pad->stream =
|
ts_pad->stream =
|
||||||
tsmux_create_stream (mux->tsmux, st, ts_pad->pid, ts_pad->language,
|
tsmux_create_stream (mux->tsmux, st, stream_number, ts_pad->pid,
|
||||||
ts_pad->bitrate, ts_pad->max_bitrate);
|
ts_pad->language, ts_pad->bitrate, ts_pad->max_bitrate);
|
||||||
if (ts_pad->stream == NULL)
|
if (ts_pad->stream == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,7 @@ struct _GstBaseTsMuxPad
|
||||||
gchar *language;
|
gchar *language;
|
||||||
gint bitrate;
|
gint bitrate;
|
||||||
gint max_bitrate;
|
gint max_bitrate;
|
||||||
|
gint stream_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstBaseTsMuxPadClass
|
struct _GstBaseTsMuxPadClass
|
||||||
|
|
|
@ -703,9 +703,10 @@ tsmux_get_new_pid (TsMux * mux)
|
||||||
* tsmux_create_stream:
|
* tsmux_create_stream:
|
||||||
* @mux: a #TsMux
|
* @mux: a #TsMux
|
||||||
* @stream_type: the stream type
|
* @stream_type: the stream type
|
||||||
|
* @stream_number: stream number
|
||||||
* @pid: the PID of the new stream.
|
* @pid: the PID of the new stream.
|
||||||
*
|
*
|
||||||
* Create a new stream of @stream_type in the muxer session @mux.
|
* Create a new stream of @stream_type with @stream_number in the muxer session @mux.
|
||||||
*
|
*
|
||||||
* When @pid is set to #TSMUX_PID_AUTO, a new free PID will automatically
|
* When @pid is set to #TSMUX_PID_AUTO, a new free PID will automatically
|
||||||
* be allocated for the new stream.
|
* be allocated for the new stream.
|
||||||
|
@ -713,8 +714,8 @@ tsmux_get_new_pid (TsMux * mux)
|
||||||
* Returns: a new #TsMuxStream.
|
* Returns: a new #TsMuxStream.
|
||||||
*/
|
*/
|
||||||
TsMuxStream *
|
TsMuxStream *
|
||||||
tsmux_create_stream (TsMux * mux, guint stream_type, guint16 pid,
|
tsmux_create_stream (TsMux * mux, guint stream_type, guint stream_number,
|
||||||
gchar * language, guint bitrate, guint max_bitrate)
|
guint16 pid, gchar * language, guint bitrate, guint max_bitrate)
|
||||||
{
|
{
|
||||||
TsMuxStream *stream;
|
TsMuxStream *stream;
|
||||||
guint16 new_pid;
|
guint16 new_pid;
|
||||||
|
@ -732,7 +733,9 @@ tsmux_create_stream (TsMux * mux, guint stream_type, guint16 pid,
|
||||||
if (tsmux_find_stream (mux, new_pid))
|
if (tsmux_find_stream (mux, new_pid))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
stream = mux->new_stream_func (new_pid, stream_type, mux->new_stream_data);
|
stream =
|
||||||
|
mux->new_stream_func (new_pid, stream_type, stream_number,
|
||||||
|
mux->new_stream_data);
|
||||||
|
|
||||||
mux->streams = g_list_prepend (mux->streams, stream);
|
mux->streams = g_list_prepend (mux->streams, stream);
|
||||||
mux->nb_streams++;
|
mux->nb_streams++;
|
||||||
|
|
|
@ -84,7 +84,7 @@ typedef struct TsMux TsMux;
|
||||||
|
|
||||||
typedef gboolean (*TsMuxWriteFunc) (GstBuffer * buf, void *user_data, gint64 new_pcr);
|
typedef gboolean (*TsMuxWriteFunc) (GstBuffer * buf, void *user_data, gint64 new_pcr);
|
||||||
typedef void (*TsMuxAllocFunc) (GstBuffer ** buf, void *user_data);
|
typedef void (*TsMuxAllocFunc) (GstBuffer ** buf, void *user_data);
|
||||||
typedef TsMuxStream * (*TsMuxNewStreamFunc) (guint16 new_pid, guint stream_type, void *user_data);
|
typedef TsMuxStream * (*TsMuxNewStreamFunc) (guint16 new_pid, guint stream_type, guint stream_number, void *user_data);
|
||||||
|
|
||||||
struct TsMuxSection {
|
struct TsMuxSection {
|
||||||
TsMuxPacketInfo pi;
|
TsMuxPacketInfo pi;
|
||||||
|
@ -223,7 +223,7 @@ gboolean tsmux_add_mpegts_si_section (TsMux * mux, GstMpegtsSection *
|
||||||
gboolean tsmux_send_section (TsMux *mux, GstMpegtsSection *section);
|
gboolean tsmux_send_section (TsMux *mux, GstMpegtsSection *section);
|
||||||
|
|
||||||
/* stream management */
|
/* stream management */
|
||||||
TsMuxStream * tsmux_create_stream (TsMux *mux, guint stream_type, guint16 pid, gchar *language, guint bitrate, guint max_bitrate);
|
TsMuxStream * tsmux_create_stream (TsMux *mux, guint stream_type, guint stream_number, guint16 pid, gchar *language, guint bitrate, guint max_bitrate);
|
||||||
TsMuxStream * tsmux_find_stream (TsMux *mux, guint16 pid);
|
TsMuxStream * tsmux_find_stream (TsMux *mux, guint16 pid);
|
||||||
gboolean tsmux_remove_stream (TsMux *mux, guint16 pid, TsMuxProgram *program);
|
gboolean tsmux_remove_stream (TsMux *mux, guint16 pid, TsMuxProgram *program);
|
||||||
|
|
||||||
|
|
|
@ -100,15 +100,18 @@ struct TsMuxStreamBuffer
|
||||||
* tsmux_stream_new:
|
* tsmux_stream_new:
|
||||||
* @pid: a PID
|
* @pid: a PID
|
||||||
* @stream_type: the stream type
|
* @stream_type: the stream type
|
||||||
|
* @stream_number: stream number
|
||||||
*
|
*
|
||||||
* Create a new stream with PID of @pid and @stream_type.
|
* Create a new stream with PID of @pid and @stream_type,
|
||||||
|
* with stream number @stream_number.
|
||||||
*
|
*
|
||||||
* Returns: a new #TsMuxStream.
|
* Returns: a new #TsMuxStream.
|
||||||
*/
|
*/
|
||||||
TsMuxStream *
|
TsMuxStream *
|
||||||
tsmux_stream_new (guint16 pid, guint stream_type)
|
tsmux_stream_new (guint16 pid, guint stream_type, guint stream_number)
|
||||||
{
|
{
|
||||||
TsMuxStream *stream = g_new0 (TsMuxStream, 1);
|
TsMuxStream *stream = g_new0 (TsMuxStream, 1);
|
||||||
|
gboolean supports_user_specified_stream_number = FALSE;
|
||||||
|
|
||||||
stream->state = TSMUX_STREAM_STATE_HEADER;
|
stream->state = TSMUX_STREAM_STATE_HEADER;
|
||||||
stream->pi.pid = pid;
|
stream->pi.pid = pid;
|
||||||
|
@ -125,10 +128,16 @@ tsmux_stream_new (guint16 pid, guint stream_type)
|
||||||
case TSMUX_ST_VIDEO_MPEG4:
|
case TSMUX_ST_VIDEO_MPEG4:
|
||||||
case TSMUX_ST_VIDEO_H264:
|
case TSMUX_ST_VIDEO_H264:
|
||||||
case TSMUX_ST_VIDEO_HEVC:
|
case TSMUX_ST_VIDEO_HEVC:
|
||||||
/* FIXME: Assign sequential IDs? */
|
if (stream_number > 0xF) {
|
||||||
stream->id = 0xE0;
|
GST_WARNING
|
||||||
|
("video stream number %d is greater than 0xF. Setting to 0.",
|
||||||
|
stream_number);
|
||||||
|
stream_number = 0;
|
||||||
|
}
|
||||||
|
stream->id = 0xE0 | stream_number;
|
||||||
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
||||||
stream->is_video_stream = TRUE;
|
stream->is_video_stream = TRUE;
|
||||||
|
supports_user_specified_stream_number = TRUE;
|
||||||
break;
|
break;
|
||||||
case TSMUX_ST_VIDEO_JP2K:
|
case TSMUX_ST_VIDEO_JP2K:
|
||||||
stream->id = 0xBD;
|
stream->id = 0xBD;
|
||||||
|
@ -138,10 +147,16 @@ tsmux_stream_new (guint16 pid, guint stream_type)
|
||||||
case TSMUX_ST_AUDIO_AAC:
|
case TSMUX_ST_AUDIO_AAC:
|
||||||
case TSMUX_ST_AUDIO_MPEG1:
|
case TSMUX_ST_AUDIO_MPEG1:
|
||||||
case TSMUX_ST_AUDIO_MPEG2:
|
case TSMUX_ST_AUDIO_MPEG2:
|
||||||
/* FIXME: Assign sequential IDs? */
|
if (stream_number > 0x1F) {
|
||||||
|
GST_WARNING
|
||||||
|
("audio stream number %d is greater than 0x1F. Setting to 0.",
|
||||||
|
stream_number);
|
||||||
|
stream_number = 0;
|
||||||
|
}
|
||||||
stream->is_audio = TRUE;
|
stream->is_audio = TRUE;
|
||||||
stream->id = 0xC0;
|
stream->id = 0xC0 | stream_number;
|
||||||
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
||||||
|
supports_user_specified_stream_number = TRUE;
|
||||||
break;
|
break;
|
||||||
case TSMUX_ST_VIDEO_DIRAC:
|
case TSMUX_ST_VIDEO_DIRAC:
|
||||||
case TSMUX_ST_PS_AUDIO_LPCM:
|
case TSMUX_ST_PS_AUDIO_LPCM:
|
||||||
|
@ -209,6 +224,12 @@ tsmux_stream_new (guint16 pid, guint stream_type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!supports_user_specified_stream_number && stream_number != 0) {
|
||||||
|
GST_WARNING
|
||||||
|
("Attempt to set stream number %d for unsupported stream type %d",
|
||||||
|
stream_number, stream_type);
|
||||||
|
}
|
||||||
|
|
||||||
stream->first_ts = GST_CLOCK_STIME_NONE;
|
stream->first_ts = GST_CLOCK_STIME_NONE;
|
||||||
|
|
||||||
stream->last_pts = GST_CLOCK_STIME_NONE;
|
stream->last_pts = GST_CLOCK_STIME_NONE;
|
||||||
|
|
|
@ -225,7 +225,7 @@ struct TsMuxStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* stream management */
|
/* stream management */
|
||||||
TsMuxStream * tsmux_stream_new (guint16 pid, guint stream_type);
|
TsMuxStream * tsmux_stream_new (guint16 pid, guint stream_type, guint stream_number);
|
||||||
void tsmux_stream_free (TsMuxStream *stream);
|
void tsmux_stream_free (TsMuxStream *stream);
|
||||||
|
|
||||||
guint16 tsmux_stream_get_pid (TsMuxStream *stream);
|
guint16 tsmux_stream_get_pid (TsMuxStream *stream);
|
||||||
|
|
Loading…
Reference in a new issue