|
From: <me...@us...> - 2008-02-21 22:49:39
|
Revision: 929
http://gmyth.svn.sourceforge.net/gmyth/?rev=929&view=rev
Author: melunko
Date: 2008-02-21 14:49:45 -0800 (Thu, 21 Feb 2008)
Log Message:
-----------
Fixed eos problems and more than one track limitation
Modified Paths:
--------------
trunk/gst-gpac/src/gpacmux.c
Modified: trunk/gst-gpac/src/gpacmux.c
===================================================================
--- trunk/gst-gpac/src/gpacmux.c 2008-02-21 17:54:48 UTC (rev 928)
+++ trunk/gst-gpac/src/gpacmux.c 2008-02-21 22:49:45 UTC (rev 929)
@@ -35,9 +35,14 @@
gint track_number;
guint32 di; /* outDescriptionIndex */
+ GstBuffer *buffer;
+ GstBuffer *next_buffer;
+
guint32 frame_count;
gboolean is_video;
+ gboolean eos;
+
} GstGpacPad;
struct _GstGpacMux
@@ -46,6 +51,7 @@
GstPad *srcpad;
GstCollectPads *collect;
+ gint active_pads;
GF_ISOFile *file;
@@ -109,6 +115,13 @@
static GstStateChangeReturn gst_gpac_mux_change_state (GstElement * element,
GstStateChange transition);
+static GstGpacPad* gst_gpac_mux_queue_pads (GstGpacMux * gpac_mux);
+static GstFlowReturn gst_gpac_mux_process_pad (GstGpacMux * gpac_mux, GstGpacPad *pad);
+static gboolean gst_gpac_mux_all_pads_eos (GstCollectPads * pads);
+static gint gst_gpac_mux_compare_pads (GstGpacMux * ogg_mux, GstGpacPad *first,
+ GstGpacPad *second);
+
+
static GstElementClass *parent_class = NULL;
GType
@@ -216,13 +229,6 @@
GstGpacPad *gpacpad = (GstGpacPad *) data;
GstBuffer *buf;
-/* if (gpacpad->pagebuffers) {
- while ((buf = g_queue_pop_head (gpacpad->pagebuffers)) != NULL) {
- gst_buffer_unref (buf);
- }
- g_queue_free (gpacpad->pagebuffers);
- gpacpad->pagebuffers = NULL;
- }*/
}
static GstPadLinkReturn
@@ -282,7 +288,7 @@
/* create new pad with the name */
GST_DEBUG_OBJECT (gpac_mux, "Creating new pad for serial %d", serial);
- printf ("XXXX new pad from template\n");
+
newpad = gst_pad_new_from_template (templ, padname);
g_free (padname);
@@ -294,6 +300,7 @@
gpacpad = (GstGpacPad *)
gst_collect_pads_add_pad_full (gpac_mux->collect, newpad,
sizeof (GstGpacPad), gst_gpac_mux_gpac_pad_destroy_notify);
+ gpac_mux->active_pads++;
/* gpac new track */
gpacpad->is_video = is_video;
@@ -411,92 +418,128 @@
return gst_pad_push (mux->srcpad, buffer);
}
+static GstFlowReturn
+gst_gpac_mux_collected (GstCollectPads * pads, GstGpacMux * gpac_mux)
+{
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstGpacPad *pad;
+ gint active_before;
+
+ GST_LOG_OBJECT (gpac_mux, "collected");
+
+ active_before = gpac_mux->active_pads;
+
+ pad = gst_gpac_mux_queue_pads (gpac_mux);
+ if (!pad) {
+ return GST_FLOW_WRONG_STATE;
+ }
+
+ if (pad->buffer) {
+ ret = gst_gpac_mux_process_pad (gpac_mux, pad);
+ }
+
+ if (gpac_mux->active_pads < active_before) {
+ /* If the active pad count went down, this mean at least one pad has gone
+ * EOS. Since CollectPads only calls _collected() once when all pads are
+ * EOS, and our code doesn't _pop() from all pads we need to check that by
+ * peeking on all pads, else we won't be called again and the muxing will
+ * not terminate (push out EOS). */
+ printf ("XXXX um pad foi desativado %" GST_PTR_FORMAT "\n", pad);
+
+ /* if all the pads have been removed, flush all pending data */
+ if ((ret == GST_FLOW_OK) && gst_gpac_mux_all_pads_eos (pads)) {
+ GST_LOG_OBJECT (gpac_mux, "no pads remaining, flushing data");
+
+ do {
+ pad = gst_gpac_mux_queue_pads (gpac_mux);
+ if (pad)
+ ret = gst_gpac_mux_process_pad (gpac_mux, pad);
+ } while ((ret == GST_FLOW_OK) && (pad != NULL));
+
+ /* gpac file close (eos) */
+ // Fixme: this should flush all data to src pad
+ // Fixme: where to release gpac_mux->file?
+ printf ("CCCCCCCCCCCCCCCCcclosing the file\n");
+ gf_isom_close (gpac_mux->file);
+
+
+ GST_DEBUG_OBJECT (gpac_mux, "Pushing EOS");
+ gst_pad_push_event (gpac_mux->srcpad, gst_event_new_eos ());
+ }
+ }
+
+ return ret;
+
+}
+
static gboolean
-all_pads_eos (GstCollectPads * pads)
+gst_gpac_mux_all_pads_eos (GstCollectPads * pads)
{
- GSList *iter;
+ GSList *walk;
gboolean alleos = TRUE;
- iter = pads->data;
- while (iter) {
+ walk = pads->data;
+ while (walk) {
GstBuffer *buf;
- GstCollectData *data = (GstCollectData *) iter->data;
+ GstCollectData *data = (GstCollectData *) walk->data;
buf = gst_collect_pads_peek (pads, data);
if (buf) {
alleos = FALSE;
gst_buffer_unref (buf);
- goto beach;
+ break;
}
- iter = iter->next;
+ walk = walk->next;
}
-beach:
+
return alleos;
}
-
+
+
static GstFlowReturn
-gst_gpac_mux_collected (GstCollectPads * pads, GstGpacMux * gpac_mux)
+gst_gpac_mux_process_pad (GstGpacMux *gpac_mux, GstGpacPad *pad)
{
GstFlowReturn ret = GST_FLOW_OK;
- GSList *iter;
- GstBuffer *buf;
- gint i = 0;
+ GF_ISOSample *sample;
- GST_LOG_OBJECT (gpac_mux, "collected");
-
- iter = gpac_mux->collect->data;
- while (iter) {
- GstCollectData *data = (GstCollectData *) iter->data;
- GstGpacPad *pad = (GstGpacPad *) data;
-
- buf = gst_collect_pads_pop (gpac_mux->collect, data);
- if (buf == NULL) {
- iter = g_slist_next (iter);
- continue;
+ if (pad->buffer == NULL) {
+ printf ("Buffer is null, wrong state\n");
+ return GST_FLOW_WRONG_STATE;
}
- GST_LOG_OBJECT (data->pad, "popped buffer %" GST_PTR_FORMAT, buf);
- /* gpac output */
- printf ("xxxxxx buffer size: %d\n", GST_BUFFER_SIZE(buf)); fflush (stdout);
- if (pad->frame_count < 300) {
- GF_ISOSample *sample = gf_isom_sample_new();
+ /* gpac output */
+ printf ("xxxxxx buffer size: %d\n", GST_BUFFER_SIZE(pad->buffer)); fflush (stdout);
+ printf ("xxxx frames %d\n", pad->frame_count);
- sample->dataLength = GST_BUFFER_SIZE(buf);
- sample->data = GST_BUFFER_DATA(buf);
- sample->CTS_Offset = 0;
+ sample = gf_isom_sample_new();
+ sample->dataLength = GST_BUFFER_SIZE(pad->buffer);
+ sample->data = GST_BUFFER_DATA(pad->buffer);
+ sample->CTS_Offset = 0;
- if (pad->is_video) {
- sample->IsRAP = 0;
- sample->DTS += 1000*pad->frame_count;
- } else {
- sample->IsRAP = 0;
- sample->DTS = 2048*pad->frame_count;
- }
+ if (pad->is_video) {
+ sample->IsRAP = 0;
+ sample->DTS += 1000*pad->frame_count;
+ } else {
+ sample->IsRAP = 0;
+ sample->DTS = 2048*pad->frame_count;
+ }
- gf_isom_add_sample(gpac_mux->file, pad->track_number,
- pad->di, sample);
- sample->data = NULL;
+ gf_isom_add_sample(gpac_mux->file, pad->track_number,
+ pad->di, sample);
+ sample->data = NULL;
- gf_isom_sample_del(&sample);
+ gf_isom_sample_del(&sample);
- printf ("xxxx frames %d\n", pad->frame_count);
- } else if (pad->frame_count == 300) {
- printf ("XXX closing gpac output file\n"); fflush (stdout);
- gf_isom_close (gpac_mux->file);
- }
+ /* gstreamer output (push) */
+ ret = gst_gpac_mux_push_buffer (gpac_mux, pad->buffer);
+ pad->buffer = NULL;
- /* gstreamer output (push) */
- if (gst_gpac_mux_push_buffer (gpac_mux, buf) != GST_FLOW_OK) {
- printf ("EEEEEEEE push failed\n");
- }
-
- iter = g_slist_next (iter);
- pad->frame_count++;
- i++;
+ if (ret != GST_FLOW_OK) {
}
- /* fixme */
+ pad->frame_count++;
+
return ret;
}
@@ -504,13 +547,13 @@
static void
gst_gpac_mux_init_collectpads (GstCollectPads * collect)
{
- GSList *walk;
+ GSList *iter;
- walk = collect->data;
- while (walk) {
- GstGpacPad *gpacpad = (GstGpacPad *) walk->data;
+ iter = collect->data;
+ while (iter) {
+ GstGpacPad *gpacpad = (GstGpacPad *) iter->data;
- //ogg_stream_init (&gpacpad->stream, gpacpad->serial);
+ //gpac_stream_init (&gpacpad->stream, gpacpad->serial);
//gpacpad->packetno = 0;
//gpacpad->pageno = 0;
//gpacpad->eos = FALSE;
@@ -521,7 +564,7 @@
//gpacpad->prev_delta = FALSE;
//gpacpad->pagebuffers = g_queue_new ();
- walk = g_slist_next (walk);
+ iter = g_slist_next (iter);
}
}
@@ -529,10 +572,10 @@
static void
gst_gpac_mux_clear_collectpads (GstCollectPads * collect)
{
- GSList *walk;
+ GSList *iter;
- for (walk = collect->data; walk; walk = g_slist_next (walk)) {
- GstGpacPad *gpacpad = (GstGpacPad *) walk->data;
+ for (iter = collect->data; iter; iter = g_slist_next (iter)) {
+ GstGpacPad *gpacpad = (GstGpacPad *) iter->data;
GstBuffer *buf;
//gpac_stream_clear (&gpacpad->stream);
@@ -588,6 +631,97 @@
}
+static GstGpacPad *
+gst_gpac_mux_queue_pads (GstGpacMux * gpac_mux)
+{
+ GstGpacPad *bestpad = NULL;//, *still_hungry = NULL;
+ GSList *iter;
+
+ /* try to make sure we have a buffer from each usable pad first */
+ iter = gpac_mux->collect->data;
+ while (iter) {
+ GstGpacPad *pad;
+ GstCollectData *data;
+
+ data = (GstCollectData *) iter->data;
+ pad = (GstGpacPad *) data;
+
+ iter = g_slist_next (iter);
+
+ GST_LOG_OBJECT (data->pad, "looking at pad for buffer");
+
+ /* try to get a new buffer for this pad if needed and possible */
+ if (pad->buffer == NULL) {
+ GstBuffer *buf;
+
+ buf = gst_collect_pads_pop (gpac_mux->collect, data);
+ GST_LOG_OBJECT (data->pad, "popped buffer %" GST_PTR_FORMAT, buf);
+
+ /* On EOS we get a NULL buffer */
+ if (buf == NULL) {
+ printf ("EENENENENENEND OF STREAM EOS\n");
+ GST_DEBUG_OBJECT (data->pad, "EOS on pad");
+ if (!pad->eos) {
+ /* it's no longer active */
+ gpac_mux->active_pads--;
+ pad->eos = TRUE;
+
+ }
+ }
+
+ pad->buffer = buf;
+ }
+
+ /* we should have a buffer now, see if it is the best pad to
+ * pull on */
+ if (gst_gpac_mux_compare_pads (gpac_mux, bestpad, pad) > 0) {
+ GST_LOG_OBJECT (data->pad,
+ "new best pad, with buffers %" GST_PTR_FORMAT, pad->buffer);
+ bestpad = pad;
+ }
+ }
+
+ return bestpad;
+}
+
+static gint
+gst_gpac_mux_compare_pads (GstGpacMux * ogg_mux, GstGpacPad *first,
+ GstGpacPad *second)
+{
+ guint64 firsttime, secondtime;
+
+ /* if the first pad doesn't contain anything or is even NULL, return
+ * the second pad as best candidate and vice versa */
+ if (first == NULL || (first->buffer == NULL))
+ return 1;
+ if (second == NULL || (second->buffer == NULL))
+ return -1;
+
+ /* no timestamp on first buffer, it must go first */
+ if (first->buffer)
+ firsttime = GST_BUFFER_TIMESTAMP (first->buffer);
+ if (firsttime == GST_CLOCK_TIME_NONE)
+ return -1;
+
+ /* no timestamp on second buffer, it must go first */
+ if (second->buffer)
+ secondtime = GST_BUFFER_TIMESTAMP (second->buffer);
+ if (secondtime == GST_CLOCK_TIME_NONE)
+ return 1;
+
+ /* first buffer has higher timestamp, second one should go first */
+ if (secondtime < firsttime)
+ return 1;
+ /* second buffer has higher timestamp, first one should go first */
+ else if (secondtime > firsttime)
+ return -1;
+
+ /* same priority if all of the above failed */
+ return 0;
+}
+
+
+
static gboolean
gst_gpac_mux_plugin_init (GstPlugin * plugin)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|