mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 07:38:16 +00:00
mpegtsmux: provide API for subclasses to override stream creation
This commit is contained in:
parent
80bfa16c95
commit
ea011a3266
5 changed files with 90 additions and 8 deletions
|
@ -25,10 +25,29 @@ GST_DEBUG_CATEGORY (atscmux_debug);
|
|||
#define GST_CAT_DEFAULT atscmux_debug
|
||||
|
||||
G_DEFINE_TYPE (ATSCMux, atscmux, GST_TYPE_MPEG_TSMUX)
|
||||
#define parent_class atscmux_parent_class
|
||||
static TsMuxStream *atscmux_create_new_stream (guint16 new_pid,
|
||||
TsMuxStreamType stream_type, MpegTsMux * mpegtsmux)
|
||||
{
|
||||
return tsmux_stream_new (new_pid, stream_type);
|
||||
}
|
||||
|
||||
static void atscmux_class_init (ATSCMuxClass * klass)
|
||||
static TsMux *
|
||||
atscmux_create_ts_mux (MpegTsMux * mpegtsmux)
|
||||
{
|
||||
TsMux *ret = ((MpegTsMuxClass *) parent_class)->create_ts_mux (mpegtsmux);
|
||||
|
||||
tsmux_set_new_stream_func (ret,
|
||||
(TsMuxNewStreamFunc) atscmux_create_new_stream, mpegtsmux);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
atscmux_class_init (ATSCMuxClass * klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||
MpegTsMuxClass *mpegtsmux_class = (MpegTsMuxClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (atscmux_debug, "atscmux", 0, "ATSC muxer");
|
||||
|
||||
|
@ -36,6 +55,8 @@ G_DEFINE_TYPE (ATSCMux, atscmux, GST_TYPE_MPEG_TSMUX)
|
|||
"ATSC Transport Stream Muxer", "Codec/Muxer",
|
||||
"Multiplexes media streams into an ATSC-compliant Transport Stream",
|
||||
"Mathieu Duponchelle <mathieu@centricular.com>");
|
||||
|
||||
mpegtsmux_class->create_ts_mux = atscmux_create_ts_mux;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -171,6 +171,7 @@ static void gst_mpegtsmux_get_property (GObject * object, guint prop_id,
|
|||
|
||||
static void mpegtsmux_reset (MpegTsMux * mux, gboolean alloc);
|
||||
static void mpegtsmux_dispose (GObject * object);
|
||||
static void mpegtsmux_constructed (GObject * object);
|
||||
static void alloc_packet_cb (GstBuffer ** _buf, void *user_data);
|
||||
static gboolean new_packet_cb (GstBuffer * buf, void *user_data,
|
||||
gint64 new_pcr);
|
||||
|
@ -200,6 +201,8 @@ static void mpegtsmux_set_header_on_caps (MpegTsMux * mux);
|
|||
static gboolean mpegtsmux_src_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event);
|
||||
|
||||
static TsMux *mpegtsmux_default_create_ts_mux (MpegTsMux * mux);
|
||||
|
||||
#if 0
|
||||
static void mpegtsmux_set_index (GstElement * element, GstIndex * index);
|
||||
static GstIndex *mpegtsmux_get_index (GstElement * element);
|
||||
|
@ -260,12 +263,15 @@ mpegtsmux_class_init (MpegTsMuxClass * klass)
|
|||
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_mpegtsmux_set_property);
|
||||
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_mpegtsmux_get_property);
|
||||
gobject_class->dispose = mpegtsmux_dispose;
|
||||
gobject_class->constructed = mpegtsmux_constructed;
|
||||
|
||||
gstelement_class->request_new_pad = mpegtsmux_request_new_pad;
|
||||
gstelement_class->release_pad = mpegtsmux_release_pad;
|
||||
gstelement_class->change_state = mpegtsmux_change_state;
|
||||
gstelement_class->send_event = mpegtsmux_send_event;
|
||||
|
||||
klass->create_ts_mux = mpegtsmux_default_create_ts_mux;
|
||||
|
||||
#if 0
|
||||
gstelement_class->set_index = GST_DEBUG_FUNCPTR (mpegtsmux_set_index);
|
||||
gstelement_class->get_index = GST_DEBUG_FUNCPTR (mpegtsmux_get_index);
|
||||
|
@ -347,9 +353,6 @@ mpegtsmux_init (MpegTsMux * mux)
|
|||
mux->prog_map = NULL;
|
||||
mux->alignment = MPEGTSMUX_DEFAULT_ALIGNMENT;
|
||||
mux->bitrate = TSMUX_DEFAULT_BITRATE;
|
||||
|
||||
/* initial state */
|
||||
mpegtsmux_reset (mux, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -437,9 +440,11 @@ mpegtsmux_reset (MpegTsMux * mux, gboolean alloc)
|
|||
}
|
||||
|
||||
if (alloc) {
|
||||
mux->tsmux = tsmux_new ();
|
||||
tsmux_set_write_func (mux->tsmux, new_packet_cb, mux);
|
||||
tsmux_set_alloc_func (mux->tsmux, alloc_packet_cb, mux);
|
||||
MpegTsMuxClass *klass = GST_MPEG_TSMUX_GET_CLASS (mux);
|
||||
|
||||
g_assert (klass->create_ts_mux);
|
||||
|
||||
mux->tsmux = klass->create_ts_mux (mux);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,6 +478,15 @@ mpegtsmux_dispose (GObject * object)
|
|||
GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
mpegtsmux_constructed (GObject * object)
|
||||
{
|
||||
MpegTsMux *mux = GST_MPEG_TSMUX (object);
|
||||
|
||||
/* initial state */
|
||||
mpegtsmux_reset (mux, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mpegtsmux_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -2063,3 +2077,13 @@ mpegtsmux_send_event (GstElement * element, GstEvent * event)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static TsMux *
|
||||
mpegtsmux_default_create_ts_mux (MpegTsMux * mux)
|
||||
{
|
||||
TsMux *tsmux = tsmux_new ();
|
||||
tsmux_set_write_func (tsmux, new_packet_cb, mux);
|
||||
tsmux_set_alloc_func (tsmux, alloc_packet_cb, mux);
|
||||
|
||||
return tsmux;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ G_BEGIN_DECLS
|
|||
|
||||
#define GST_TYPE_MPEG_TSMUX (mpegtsmux_get_type())
|
||||
#define GST_MPEG_TSMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_MPEG_TSMUX, MpegTsMux))
|
||||
#define GST_MPEG_TSMUX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_MPEG_TSMUX,MpegTsMuxClass))
|
||||
|
||||
#define CLOCK_BASE 9LL
|
||||
#define CLOCK_FREQ (CLOCK_BASE * 10000) /* 90 kHz PTS clock */
|
||||
|
@ -172,8 +173,15 @@ struct MpegTsMux {
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* MpegTsMuxClass:
|
||||
* @create_ts_mux: Optional.
|
||||
* Called in order to create the #TsMux object.
|
||||
*/
|
||||
struct MpegTsMuxClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
TsMux * (*create_ts_mux) (MpegTsMux *mux);
|
||||
};
|
||||
|
||||
struct MpegTsPadData {
|
||||
|
|
|
@ -153,6 +153,9 @@ tsmux_new (void)
|
|||
mux->si_sections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
NULL, (GDestroyNotify) tsmux_section_free);
|
||||
|
||||
mux->new_stream_func = (TsMuxNewStreamFunc) tsmux_stream_new;
|
||||
mux->new_stream_data = NULL;
|
||||
|
||||
return mux;
|
||||
}
|
||||
|
||||
|
@ -193,6 +196,26 @@ tsmux_set_alloc_func (TsMux * mux, TsMuxAllocFunc func, void *user_data)
|
|||
mux->alloc_func_data = user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* tsmux_set_new_stream_func:
|
||||
* @mux: a #TsMux
|
||||
* @func: a user callback function
|
||||
* @user_data: user data passed to @func
|
||||
*
|
||||
* Set the callback function and user data to be called when @mux needs
|
||||
* to create a new stream.
|
||||
* @user_data will be passed as user data in @func.
|
||||
*/
|
||||
void
|
||||
tsmux_set_new_stream_func (TsMux * mux, TsMuxNewStreamFunc func,
|
||||
void *user_data)
|
||||
{
|
||||
g_return_if_fail (mux != NULL);
|
||||
|
||||
mux->new_stream_func = func;
|
||||
mux->new_stream_data = user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* tsmux_set_pat_interval:
|
||||
* @mux: a #TsMux
|
||||
|
@ -556,6 +579,7 @@ tsmux_create_stream (TsMux * mux, TsMuxStreamType stream_type, guint16 pid,
|
|||
guint16 new_pid;
|
||||
|
||||
g_return_val_if_fail (mux != NULL, NULL);
|
||||
g_return_val_if_fail (mux->new_stream_func != NULL, NULL);
|
||||
|
||||
if (pid == TSMUX_PID_AUTO) {
|
||||
new_pid = tsmux_get_new_pid (mux);
|
||||
|
@ -567,7 +591,7 @@ tsmux_create_stream (TsMux * mux, TsMuxStreamType stream_type, guint16 pid,
|
|||
if (tsmux_find_stream (mux, new_pid))
|
||||
return NULL;
|
||||
|
||||
stream = tsmux_stream_new (new_pid, stream_type);
|
||||
stream = mux->new_stream_func (new_pid, stream_type, mux->new_stream_data);
|
||||
|
||||
mux->streams = g_list_prepend (mux->streams, stream);
|
||||
mux->nb_streams++;
|
||||
|
|
|
@ -102,6 +102,7 @@ typedef struct TsMux TsMux;
|
|||
|
||||
typedef gboolean (*TsMuxWriteFunc) (GstBuffer * buf, void *user_data, gint64 new_pcr);
|
||||
typedef void (*TsMuxAllocFunc) (GstBuffer ** buf, void *user_data);
|
||||
typedef TsMuxStream * (*TsMuxNewStreamFunc) (guint16 new_pid, TsMuxStreamType stream_type, void *user_data);
|
||||
|
||||
struct TsMuxSection {
|
||||
TsMuxPacketInfo pi;
|
||||
|
@ -175,6 +176,9 @@ struct TsMux {
|
|||
/* callback to alloc new packet buffer */
|
||||
TsMuxAllocFunc alloc_func;
|
||||
void *alloc_func_data;
|
||||
/* callback to create a new stream */
|
||||
TsMuxNewStreamFunc new_stream_func;
|
||||
void *new_stream_data;
|
||||
|
||||
/* scratch space for writing ES_info descriptors */
|
||||
guint8 es_info_buf[TSMUX_MAX_ES_INFO_LENGTH];
|
||||
|
@ -190,6 +194,7 @@ void tsmux_free (TsMux *mux);
|
|||
/* Setting muxing session properties */
|
||||
void tsmux_set_write_func (TsMux *mux, TsMuxWriteFunc func, void *user_data);
|
||||
void tsmux_set_alloc_func (TsMux *mux, TsMuxAllocFunc func, void *user_data);
|
||||
void tsmux_set_new_stream_func (TsMux * mux, TsMuxNewStreamFunc func, void *user_data);
|
||||
void tsmux_set_pat_interval (TsMux *mux, guint interval);
|
||||
guint tsmux_get_pat_interval (TsMux *mux);
|
||||
void tsmux_resend_pat (TsMux *mux);
|
||||
|
|
Loading…
Reference in a new issue