diff options
-rw-r--r-- | ext/ogg/gstoggmux.c | 80 | ||||
-rw-r--r-- | ext/ogg/gstoggmux.h | 8 |
2 files changed, 54 insertions, 34 deletions
diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index c36b4fb58..984b89035 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 37b1fae09..6812f82ca 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 */ |