summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/ogg/gstoggmux.c80
-rw-r--r--ext/ogg/gstoggmux.h8
2 files changed, 54 insertions, 34 deletions
diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c
index c36b4fb..984b890 100644
--- a/ext/ogg/gstoggmux.c
+++ b/ext/ogg/gstoggmux.c
@@ -282,7 +282,7 @@ gst_ogg_mux_ogg_pad_destroy_notify (GstCollectData * data)
GstOggPadData *oggpad = (GstOggPadData *) data;
GstBuffer *buf;
- ogg_stream_clear (&oggpad->stream);
+ ogg_stream_clear (&oggpad->map.stream);
if (oggpad->pagebuffers) {
while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) {
@@ -384,8 +384,8 @@ gst_ogg_mux_request_new_pad (GstElement * element,
sizeof (GstOggPadData), gst_ogg_mux_ogg_pad_destroy_notify);
ogg_mux->active_pads++;
- oggpad->serial = serial;
- ogg_stream_init (&oggpad->stream, serial);
+ oggpad->map.serialno = serial;
+ ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno);
oggpad->packetno = 0;
oggpad->pageno = 0;
oggpad->eos = FALSE;
@@ -396,6 +396,8 @@ gst_ogg_mux_request_new_pad (GstElement * element,
oggpad->prev_delta = FALSE;
oggpad->data_pushed = FALSE;
oggpad->pagebuffers = g_queue_new ();
+ oggpad->map.headers = NULL;
+ oggpad->map.queued = NULL;
oggpad->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (newpad);
gst_pad_set_event_function (newpad,
@@ -751,7 +753,6 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
/* try to get a new buffer for this pad if needed and possible */
if (pad->buffer == NULL) {
GstBuffer *buf;
- gboolean incaps;
/* shift the buffer along if needed (it's okay if next_buffer is NULL) */
if (pad->buffer == NULL) {
@@ -770,13 +771,31 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT))
ogg_mux->delta_pad = pad;
- incaps = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
/* if we need headers */
if (pad->state == GST_OGG_PAD_STATE_CONTROL) {
/* and we have one */
- if (incaps) {
+ ogg_packet packet;
+ packet.packet = GST_BUFFER_DATA (buf);
+ packet.bytes = GST_BUFFER_SIZE (buf);
+ packet.granulepos = GST_BUFFER_OFFSET_END (buf);
+ if (packet.granulepos == -1)
+ packet.granulepos = 0;
+
+ /* if we're not yet in data mode, ensure we're setup on the first packet */
+ if (!pad->have_type) {
+ pad->have_type = gst_ogg_stream_setup_map (&pad->map, &packet);
+ if (!pad->have_type) {
+ pad->map.caps =
+ gst_caps_new_simple ("application/x-unknown", NULL);
+ }
+ GST_DEBUG_OBJECT (ogg_mux, "New pad has caps: %s",
+ gst_caps_to_string (pad->map.caps));
+ }
+
+
+ if (gst_ogg_stream_packet_is_header (&pad->map, &packet)) {
GST_DEBUG_OBJECT (ogg_mux,
- "got incaps buffer in control state, ignoring");
+ "got header buffer in control state, ignoring");
/* just ignore */
gst_buffer_unref (buf);
buf = NULL;
@@ -799,7 +818,7 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
/* Just gone to EOS. Flush existing page(s) */
pad->eos = TRUE;
- while (ogg_stream_flush (&pad->stream, &page)) {
+ while (ogg_stream_flush (&pad->map.stream, &page)) {
/* Place page into the per-pad queue */
ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page,
pad->first_delta);
@@ -974,7 +993,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
continue;
/* now figure out the headers */
- pad->headers = gst_ogg_mux_get_headers (pad);
+ pad->map.headers = gst_ogg_mux_get_headers (pad);
}
GST_LOG_OBJECT (mux, "creating BOS pages");
@@ -1000,9 +1019,9 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
GST_LOG_OBJECT (thepad, "looping over headers");
- if (pad->headers) {
- buf = GST_BUFFER (pad->headers->data);
- pad->headers = g_list_remove (pad->headers, buf);
+ if (pad->map.headers) {
+ buf = GST_BUFFER (pad->map.headers->data);
+ pad->map.headers = g_list_remove (pad->map.headers, buf);
} else if (pad->buffer) {
buf = pad->buffer;
gst_buffer_ref (buf);
@@ -1031,11 +1050,11 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
packet.e_o_s = 0;
/* swap the packet in */
- ogg_stream_packetin (&pad->stream, &packet);
+ ogg_stream_packetin (&pad->map.stream, &packet);
gst_buffer_unref (buf);
GST_LOG_OBJECT (thepad, "flushing out BOS page");
- if (!ogg_stream_flush (&pad->stream, &page))
+ if (!ogg_stream_flush (&pad->map.stream, &page))
g_critical ("Could not flush BOS page");
hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);
@@ -1079,7 +1098,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
GST_LOG_OBJECT (mux, "looping over headers for pad %s:%s",
GST_DEBUG_PAD_NAME (thepad));
- hwalk = pad->headers;
+ hwalk = pad->map.headers;
while (hwalk) {
GstBuffer *buf = GST_BUFFER (hwalk->data);
ogg_packet packet;
@@ -1100,7 +1119,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
packet.e_o_s = 0;
/* swap the packet in */
- ogg_stream_packetin (&pad->stream, &packet);
+ ogg_stream_packetin (&pad->map.stream, &packet);
gst_buffer_unref (buf);
/* if last header, flush page */
@@ -1108,7 +1127,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
GST_LOG_OBJECT (mux,
"flushing page as packet %" G_GUINT64_FORMAT " is first or "
"last packet", packet.packetno);
- while (ogg_stream_flush (&pad->stream, &page)) {
+ while (ogg_stream_flush (&pad->map.stream, &page)) {
GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);
GST_LOG_OBJECT (mux, "swapped out page");
@@ -1117,7 +1136,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
} else {
GST_LOG_OBJECT (mux, "try to swap out page");
/* just try to swap out a page then */
- while (ogg_stream_pageout (&pad->stream, &page) > 0) {
+ while (ogg_stream_pageout (&pad->map.stream, &page) > 0) {
GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);
GST_LOG_OBJECT (mux, "swapped out page");
@@ -1125,8 +1144,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
}
}
}
- g_list_free (pad->headers);
- pad->headers = NULL;
+ g_list_free (pad->map.headers);
+ pad->map.headers = NULL;
}
/* hbufs holds all buffers for the headers now */
@@ -1207,9 +1226,10 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
GST_LOG_OBJECT (pad->collect.pad,
GST_GP_FORMAT " stored packet %" G_GINT64_FORMAT
" will make page too long, flushing",
- GST_BUFFER_OFFSET_END (pad->buffer), (gint64) pad->stream.packetno);
+ GST_BUFFER_OFFSET_END (pad->buffer),
+ (gint64) pad->map.stream.packetno);
- while (ogg_stream_flush (&pad->stream, &page)) {
+ while (ogg_stream_flush (&pad->map.stream, &page)) {
/* end time of this page is the timestamp of the next buffer */
ogg_mux->pulling->timestamp_end = GST_BUFFER_TIMESTAMP (pad->buffer);
/* Place page into the per-pad queue */
@@ -1311,7 +1331,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
GST_LOG_OBJECT (pad->collect.pad, "got discont");
packet.packetno++;
/* No public API for this; hack things in */
- pad->stream.pageno++;
+ pad->map.stream.pageno++;
force_flush = TRUE;
} else {
GST_LOG_OBJECT (pad->collect.pad, "discont at stream start");
@@ -1323,7 +1343,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
GST_LOG_OBJECT (pad->collect.pad,
GST_GP_FORMAT " forced flush of page before this packet",
GST_BUFFER_OFFSET_END (pad->buffer));
- while (ogg_stream_flush (&pad->stream, &page)) {
+ while (ogg_stream_flush (&pad->map.stream, &page)) {
/* end time of this page is the timestamp of the next buffer */
ogg_mux->pulling->timestamp_end = GST_BUFFER_TIMESTAMP (pad->buffer);
ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page,
@@ -1368,7 +1388,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
if (packet.b_o_s == 1)
GST_DEBUG_OBJECT (pad->collect.pad, "swapping in BOS packet");
- ogg_stream_packetin (&pad->stream, &packet);
+ ogg_stream_packetin (&pad->map.stream, &packet);
pad->data_pushed = TRUE;
gp_time = GST_BUFFER_OFFSET (pad->buffer);
@@ -1387,7 +1407,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
/* let ogg write out the pages now. The packet we got could end
* up in more than one page so we need to write them all */
- if (ogg_stream_pageout (&pad->stream, &page) > 0) {
+ if (ogg_stream_pageout (&pad->map.stream, &page) > 0) {
/* we have a new page, so we need to timestamp it correctly.
* if this fresh packet ends on this page, then the page's granulepos
* comes from that packet, and we should set this buffer's timestamp */
@@ -1398,7 +1418,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
granulepos, (gint64) packet.packetno, GST_TIME_ARGS (timestamp));
GST_LOG_OBJECT (pad->collect.pad,
GST_GP_FORMAT " new page %ld",
- GST_GP_CAST (ogg_page_granulepos (&page)), pad->stream.pageno);
+ GST_GP_CAST (ogg_page_granulepos (&page)), pad->map.stream.pageno);
if (ogg_page_granulepos (&page) == granulepos) {
/* the packet we streamed in finishes on the current page,
@@ -1427,7 +1447,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
/* use an inner loop here to flush the remaining pages and
* mark them as delta frames as well */
- while (ogg_stream_pageout (&pad->stream, &page) > 0) {
+ while (ogg_stream_pageout (&pad->map.stream, &page) > 0) {
if (ogg_page_granulepos (&page) == granulepos) {
/* the page has taken up the new packet completely, which means
* the packet ends the page and we can update the gp time
@@ -1604,7 +1624,7 @@ gst_ogg_mux_init_collectpads (GstCollectPads * collect)
while (walk) {
GstOggPadData *oggpad = (GstOggPadData *) walk->data;
- ogg_stream_init (&oggpad->stream, oggpad->serial);
+ ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno);
oggpad->packetno = 0;
oggpad->pageno = 0;
oggpad->eos = FALSE;
@@ -1630,7 +1650,7 @@ gst_ogg_mux_clear_collectpads (GstCollectPads * collect)
GstOggPadData *oggpad = (GstOggPadData *) walk->data;
GstBuffer *buf;
- ogg_stream_clear (&oggpad->stream);
+ ogg_stream_clear (&oggpad->map.stream);
while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) {
gst_buffer_unref (buf);
diff --git a/ext/ogg/gstoggmux.h b/ext/ogg/gstoggmux.h
index 37b1fae..6812f82 100644
--- a/ext/ogg/gstoggmux.h
+++ b/ext/ogg/gstoggmux.h
@@ -25,6 +25,7 @@
#include <gst/gst.h>
#include <gst/base/gstcollectpads.h>
+#include "gstoggstream.h"
G_BEGIN_DECLS
@@ -49,13 +50,14 @@ typedef struct
{
GstCollectData collect; /* we extend the CollectData */
+ GstOggStream map;
+ gboolean have_type;
+
/* These two buffers make a very simple queue - they enter as 'next_buffer'
* and (usually) leave as 'buffer', except at EOS, when buffer will be NULL */
GstBuffer *buffer; /* the first waiting buffer for the pad */
GstBuffer *next_buffer; /* the second waiting buffer for the pad */
- gint serial;
- ogg_stream_state stream;
gint64 packetno; /* number of next packet */
gint64 pageno; /* number of next page */
guint64 duration; /* duration of current page */
@@ -71,8 +73,6 @@ typedef struct
GstOggPadState state; /* state of the pad */
- GList *headers;
-
GQueue *pagebuffers; /* List of pages in buffers ready for pushing */
gboolean new_page; /* starting a new page */