mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
gst/matroska/matroska-demux.*: Allow an infinite number of stream inside Matroska containers and use a GPtrArray for ...
Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_finalize), (gst_matroska_demux_class_init), (gst_matroska_demux_init), (gst_matroska_demux_combine_flows), (gst_matroska_demux_reset), (gst_matroska_demux_stream_from_num), (gst_matroska_demux_tracknumber_unique), (gst_matroska_demux_add_stream), (gst_matroska_demux_send_event), (gst_matroska_demux_handle_seek_event), (gst_matroska_demux_sync_streams), (gst_matroska_demux_parse_blockgroup_or_simpleblock), (gst_matroska_demux_loop): * gst/matroska/matroska-demux.h: Allow an infinite number of stream inside Matroska containers and use a GPtrArray for storing them instead of allowing "only" 127 streams.
This commit is contained in:
parent
4ed1d36b7d
commit
d43e67fa70
3 changed files with 90 additions and 51 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2008-08-02 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
||||
* gst/matroska/matroska-demux.c: (gst_matroska_demux_finalize),
|
||||
(gst_matroska_demux_class_init), (gst_matroska_demux_init),
|
||||
(gst_matroska_demux_combine_flows), (gst_matroska_demux_reset),
|
||||
(gst_matroska_demux_stream_from_num),
|
||||
(gst_matroska_demux_tracknumber_unique),
|
||||
(gst_matroska_demux_add_stream), (gst_matroska_demux_send_event),
|
||||
(gst_matroska_demux_handle_seek_event),
|
||||
(gst_matroska_demux_sync_streams),
|
||||
(gst_matroska_demux_parse_blockgroup_or_simpleblock),
|
||||
(gst_matroska_demux_loop):
|
||||
* gst/matroska/matroska-demux.h:
|
||||
Allow an infinite number of stream inside Matroska containers and use
|
||||
a GPtrArray for storing them instead of allowing "only" 127 streams.
|
||||
|
||||
2008-08-02 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
||||
* gst/matroska/ebml-read.c: (gst_ebml_read_class_init),
|
||||
|
|
|
@ -173,14 +173,30 @@ gst_matroska_demux_base_init (gpointer klass)
|
|||
"Ronald Bultje <rbultje@ronald.bitfreak.net>");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_matroska_demux_finalize (GObject * object)
|
||||
{
|
||||
GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
|
||||
|
||||
if (demux->src) {
|
||||
g_ptr_array_free (demux->src, TRUE);
|
||||
demux->src = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;;
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
|
||||
"Matroska demuxer");
|
||||
|
||||
gobject_class->finalize = gst_matroska_demux_finalize;
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
|
||||
gstelement_class->send_event =
|
||||
|
@ -193,8 +209,6 @@ static void
|
|||
gst_matroska_demux_init (GstMatroskaDemux * demux,
|
||||
GstMatroskaDemuxClass * klass)
|
||||
{
|
||||
gint i;
|
||||
|
||||
demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
|
||||
gst_pad_set_activate_function (demux->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
|
||||
|
@ -204,9 +218,8 @@ gst_matroska_demux_init (GstMatroskaDemux * demux,
|
|||
GST_EBML_READ (demux)->sinkpad = demux->sinkpad;
|
||||
|
||||
/* initial stream no. */
|
||||
for (i = 0; i < GST_MATROSKA_DEMUX_MAX_STREAMS; i++) {
|
||||
demux->src[i] = NULL;
|
||||
}
|
||||
demux->src = NULL;
|
||||
|
||||
demux->writing_app = NULL;
|
||||
demux->muxing_app = NULL;
|
||||
demux->index = NULL;
|
||||
|
@ -261,8 +274,9 @@ gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
|
|||
goto done;
|
||||
|
||||
/* only return NOT_LINKED if all other pads returned NOT_LINKED */
|
||||
for (i = 0; i < GST_MATROSKA_DEMUX_MAX_STREAMS; i++) {
|
||||
GstMatroskaTrackContext *ostream = demux->src[i];
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
|
||||
|
||||
if (ostream == NULL)
|
||||
continue;
|
||||
|
@ -292,16 +306,21 @@ gst_matroska_demux_reset (GstElement * element)
|
|||
demux->state = GST_MATROSKA_DEMUX_STATE_START;
|
||||
|
||||
/* clean up existing streams */
|
||||
for (i = 0; i < GST_MATROSKA_DEMUX_MAX_STREAMS; i++) {
|
||||
if (demux->src[i] != NULL) {
|
||||
if (demux->src[i]->pad != NULL) {
|
||||
gst_element_remove_pad (GST_ELEMENT (demux), demux->src[i]->pad);
|
||||
}
|
||||
gst_caps_replace (&demux->src[i]->caps, NULL);
|
||||
gst_matroska_track_free (demux->src[i]);
|
||||
demux->src[i] = NULL;
|
||||
if (demux->src) {
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
|
||||
|
||||
if (context->pad != NULL)
|
||||
gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
|
||||
|
||||
gst_caps_replace (&context->caps, NULL);
|
||||
gst_matroska_track_free (context);
|
||||
}
|
||||
g_ptr_array_free (demux->src, TRUE);
|
||||
}
|
||||
demux->src = g_ptr_array_new ();
|
||||
|
||||
demux->num_streams = 0;
|
||||
demux->num_a_streams = 0;
|
||||
demux->num_t_streams = 0;
|
||||
|
@ -342,8 +361,11 @@ gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
|
|||
{
|
||||
guint n;
|
||||
|
||||
for (n = 0; n < demux->num_streams; n++) {
|
||||
if (demux->src[n] != NULL && demux->src[n]->num == track_num) {
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
for (n = 0; n < demux->src->len; n++) {
|
||||
GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
|
||||
|
||||
if (context->num == track_num) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
@ -636,9 +658,13 @@ gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
|
|||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i <= demux->num_streams; i++)
|
||||
if (demux->src[i] && demux->src[i]->num == num)
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
|
||||
|
||||
if (context->num == num)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -657,13 +683,6 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
GstTagList *list = NULL;
|
||||
gchar *codec = NULL;
|
||||
|
||||
if (demux->num_streams >= GST_MATROSKA_DEMUX_MAX_STREAMS) {
|
||||
GST_WARNING_OBJECT (demux,
|
||||
"Maximum number of streams (%d) exceeded, skipping",
|
||||
GST_MATROSKA_DEMUX_MAX_STREAMS);
|
||||
return gst_ebml_read_skip (ebml); /* skip-and-continue */
|
||||
}
|
||||
|
||||
DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
|
||||
|
||||
/* start with the master */
|
||||
|
@ -675,7 +694,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
/* allocate generic... if we know the type, we'll g_renew()
|
||||
* with the precise type */
|
||||
context = g_new0 (GstMatroskaTrackContext, 1);
|
||||
demux->src[demux->num_streams] = context;
|
||||
g_ptr_array_add (demux->src, context);
|
||||
context->index = demux->num_streams;
|
||||
context->type = 0; /* no type yet */
|
||||
context->default_duration = 0;
|
||||
|
@ -687,6 +706,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
GST_MATROSKA_TRACK_LACING;
|
||||
context->last_flow = GST_FLOW_OK;
|
||||
demux->num_streams++;
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
|
||||
|
||||
|
@ -783,7 +803,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
context->type = 0;
|
||||
break;
|
||||
}
|
||||
demux->src[demux->num_streams - 1] = context;
|
||||
g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -802,7 +822,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
break;
|
||||
}
|
||||
videocontext = (GstMatroskaTrackVideoContext *) context;
|
||||
demux->src[demux->num_streams - 1] = context;
|
||||
g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
|
||||
|
||||
while (ret == GST_FLOW_OK) {
|
||||
if ((ret =
|
||||
|
@ -1031,7 +1051,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
break;
|
||||
|
||||
audiocontext = (GstMatroskaTrackAudioContext *) context;
|
||||
demux->src[demux->num_streams - 1] = context;
|
||||
g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
|
||||
|
||||
while (ret == GST_FLOW_OK) {
|
||||
if ((ret =
|
||||
|
@ -1343,7 +1363,8 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
|
|||
GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
|
||||
|
||||
demux->num_streams--;
|
||||
demux->src[demux->num_streams] = NULL;
|
||||
g_ptr_array_remove_index (demux->src, demux->num_streams);
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
if (context) {
|
||||
gst_matroska_track_free (context);
|
||||
}
|
||||
|
@ -1641,10 +1662,11 @@ gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
|
|||
GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
|
||||
GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
for (i = 0; i < demux->num_streams; i++) {
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMatroskaTrackContext *stream;
|
||||
|
||||
stream = demux->src[i];
|
||||
stream = g_ptr_array_index (demux->src, i);
|
||||
gst_event_ref (event);
|
||||
gst_pad_push_event (stream->pad, event);
|
||||
|
||||
|
@ -1822,10 +1844,12 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
|||
|
||||
/* send newsegment event to all source pads and update the time */
|
||||
gst_matroska_demux_send_event (demux, newsegment_event);
|
||||
for (i = 0; i < demux->num_streams; i++) {
|
||||
demux->src[i]->pos = entry->time;
|
||||
demux->src[i]->set_discont = TRUE;
|
||||
demux->src[i]->last_flow = GST_FLOW_OK;
|
||||
g_assert (demux->src->len == demux->num_streams);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
|
||||
context->pos = entry->time;
|
||||
context->set_discont = TRUE;
|
||||
context->last_flow = GST_FLOW_OK;
|
||||
}
|
||||
demux->segment.last_stop = entry->time;
|
||||
|
||||
|
@ -2984,10 +3008,11 @@ gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
|
|||
GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (demux->segment.last_stop));
|
||||
|
||||
for (stream_nr = 0; stream_nr < demux->num_streams; stream_nr++) {
|
||||
g_assert (demux->num_streams == demux->src->len);
|
||||
for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
|
||||
GstMatroskaTrackContext *context;
|
||||
|
||||
context = demux->src[stream_nr];
|
||||
context = g_ptr_array_index (demux->src, stream_nr);
|
||||
|
||||
GST_LOG_OBJECT (demux,
|
||||
"Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
|
||||
|
@ -3634,7 +3659,7 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
|||
break;
|
||||
}
|
||||
|
||||
stream = demux->src[stream_num];
|
||||
stream = g_ptr_array_index (demux->src, stream_num);
|
||||
|
||||
/* time (relative to cluster time) */
|
||||
time = ((gint16) GST_READ_UINT16_BE (data));
|
||||
|
@ -3812,7 +3837,7 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
|||
guint64 duration = 0;
|
||||
gint64 lace_time = 0;
|
||||
|
||||
stream = demux->src[stream_num];
|
||||
stream = g_ptr_array_index (demux->src, stream_num);
|
||||
|
||||
if (cluster_time != GST_CLOCK_TIME_NONE) {
|
||||
/* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
|
||||
|
@ -3896,7 +3921,7 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
|||
}
|
||||
|
||||
if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT)
|
||||
&& demux->src[stream_num]->set_discont) {
|
||||
&& stream->set_discont) {
|
||||
/* When doing seeks or such, we need to restart on key frames or
|
||||
* decoders might choke. */
|
||||
goto done;
|
||||
|
@ -4521,11 +4546,13 @@ gst_matroska_demux_loop (GstPad * pad)
|
|||
if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < demux->num_streams; i++) {
|
||||
if (demux->src[i]->pos >= demux->segment.stop) {
|
||||
g_assert (demux->num_streams == demux->src->len);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
|
||||
if (context->pos >= demux->segment.stop) {
|
||||
GST_INFO_OBJECT (demux, "Reached end of segment (%" G_GUINT64_FORMAT
|
||||
"-%" G_GUINT64_FORMAT ") on pad %s:%s", demux->segment.start,
|
||||
demux->segment.stop, GST_DEBUG_PAD_NAME (demux->src[i]->pad));
|
||||
demux->segment.stop, GST_DEBUG_PAD_NAME (context->pad));
|
||||
ret = GST_FLOW_UNEXPECTED;
|
||||
goto pause;
|
||||
}
|
||||
|
|
|
@ -40,10 +40,6 @@ G_BEGIN_DECLS
|
|||
#define GST_IS_MATROSKA_DEMUX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MATROSKA_DEMUX))
|
||||
|
||||
/* The spec says that more than 127 stream is discouraged so
|
||||
* take this as a limit for now */
|
||||
#define GST_MATROSKA_DEMUX_MAX_STREAMS 127
|
||||
|
||||
typedef enum {
|
||||
GST_MATROSKA_DEMUX_STATE_START,
|
||||
GST_MATROSKA_DEMUX_STATE_HEADER,
|
||||
|
@ -61,7 +57,7 @@ typedef struct _GstMatroskaDemux {
|
|||
|
||||
/* pads */
|
||||
GstPad *sinkpad;
|
||||
GstMatroskaTrackContext *src[GST_MATROSKA_DEMUX_MAX_STREAMS];
|
||||
GPtrArray *src;
|
||||
GstClock *clock;
|
||||
guint num_streams;
|
||||
guint num_v_streams;
|
||||
|
|
Loading…
Reference in a new issue