mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-20 13:28:21 +00:00
ext/ogg/gstoggdemux.c: Some cleanups.
Original commit message from CVS: * ext/ogg/gstoggdemux.c: (gst_ogg_page_copy), (gst_ogg_page_free), (gst_ogg_pad_init), (gst_ogg_pad_dispose), (gst_ogg_pad_reset), (gst_ogg_pad_stream_out), (gst_ogg_pad_submit_page), (gst_ogg_chain_reset), (gst_ogg_demux_perform_seek): Some cleanups. Handle continued pages in reverse mode.
This commit is contained in:
parent
22411eeb35
commit
b8583561da
|
@ -1,3 +1,12 @@
|
||||||
|
2006-11-24 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* ext/ogg/gstoggdemux.c: (gst_ogg_page_copy), (gst_ogg_page_free),
|
||||||
|
(gst_ogg_pad_init), (gst_ogg_pad_dispose), (gst_ogg_pad_reset),
|
||||||
|
(gst_ogg_pad_stream_out), (gst_ogg_pad_submit_page),
|
||||||
|
(gst_ogg_chain_reset), (gst_ogg_demux_perform_seek):
|
||||||
|
Some cleanups.
|
||||||
|
Handle continued pages in reverse mode.
|
||||||
|
|
||||||
2006-11-24 Wim Taymans <wim@fluendo.com>
|
2006-11-24 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* ext/vorbis/vorbisdec.c: (vorbis_dec_push_forward),
|
* ext/vorbis/vorbisdec.c: (vorbis_dec_push_forward),
|
||||||
|
|
|
@ -51,6 +51,28 @@ GST_DEBUG_CATEGORY_STATIC (gst_ogg_demux_debug);
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_ogg_demux_setup_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_ogg_demux_setup_debug);
|
||||||
#define GST_CAT_DEFAULT gst_ogg_demux_debug
|
#define GST_CAT_DEFAULT gst_ogg_demux_debug
|
||||||
|
|
||||||
|
static ogg_page *
|
||||||
|
gst_ogg_page_copy (ogg_page * page)
|
||||||
|
{
|
||||||
|
ogg_page *p = g_new0 (ogg_page, 1);
|
||||||
|
|
||||||
|
/* make a copy of the page */
|
||||||
|
p->header = g_memdup (page->header, page->header_len);
|
||||||
|
p->header_len = page->header_len;
|
||||||
|
p->body = g_memdup (page->body, page->body_len);
|
||||||
|
p->body_len = page->body_len;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ogg_page_free (ogg_page * page)
|
||||||
|
{
|
||||||
|
g_free (page->header);
|
||||||
|
g_free (page->body);
|
||||||
|
g_free (page);
|
||||||
|
}
|
||||||
|
|
||||||
#define GST_TYPE_OGG_PAD (gst_ogg_pad_get_type())
|
#define GST_TYPE_OGG_PAD (gst_ogg_pad_get_type())
|
||||||
#define GST_OGG_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_PAD, GstOggPad))
|
#define GST_OGG_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_PAD, GstOggPad))
|
||||||
#define GST_OGG_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_PAD, GstOggPad))
|
#define GST_OGG_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_PAD, GstOggPad))
|
||||||
|
@ -138,6 +160,7 @@ struct _GstOggPad
|
||||||
GstClockTime first_time; /* the timestamp of the second page or granuletime of first page */
|
GstClockTime first_time; /* the timestamp of the second page or granuletime of first page */
|
||||||
|
|
||||||
ogg_stream_state stream;
|
ogg_stream_state stream;
|
||||||
|
GList *continued;
|
||||||
|
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
GstFlowReturn last_ret; /* last return of _pad_push() */
|
GstFlowReturn last_ret; /* last return of _pad_push() */
|
||||||
|
@ -301,6 +324,7 @@ gst_ogg_pad_init (GstOggPad * pad)
|
||||||
pad->first_time = GST_CLOCK_TIME_NONE;
|
pad->first_time = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
pad->have_type = FALSE;
|
pad->have_type = FALSE;
|
||||||
|
pad->continued = NULL;
|
||||||
pad->headers = NULL;
|
pad->headers = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +353,11 @@ gst_ogg_pad_dispose (GObject * object)
|
||||||
g_list_free (pad->headers);
|
g_list_free (pad->headers);
|
||||||
pad->headers = NULL;
|
pad->headers = NULL;
|
||||||
|
|
||||||
|
/* clear continued pages */
|
||||||
|
g_list_foreach (pad->continued, (GFunc) gst_ogg_page_free, NULL);
|
||||||
|
g_list_free (pad->continued);
|
||||||
|
pad->continued = NULL;
|
||||||
|
|
||||||
ogg_stream_reset (&pad->stream);
|
ogg_stream_reset (&pad->stream);
|
||||||
|
|
||||||
G_OBJECT_CLASS (ogg_pad_parent_class)->dispose (object);
|
G_OBJECT_CLASS (ogg_pad_parent_class)->dispose (object);
|
||||||
|
@ -535,7 +564,13 @@ static void
|
||||||
gst_ogg_pad_reset (GstOggPad * pad)
|
gst_ogg_pad_reset (GstOggPad * pad)
|
||||||
{
|
{
|
||||||
ogg_stream_reset (&pad->stream);
|
ogg_stream_reset (&pad->stream);
|
||||||
/* FIXME: need a discont here */
|
|
||||||
|
/* clear continued pages */
|
||||||
|
g_list_foreach (pad->continued, (GFunc) gst_ogg_page_free, NULL);
|
||||||
|
g_list_free (pad->continued);
|
||||||
|
pad->continued = NULL;
|
||||||
|
|
||||||
|
pad->last_ret = GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the filter function for selecting the elements we can use in
|
/* the filter function for selecting the elements we can use in
|
||||||
|
@ -1176,27 +1211,22 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* submit a page to an oggpad, this function will then submit all
|
/* flush at most @npackets from the stream layer. All packets if
|
||||||
* the packets in the page.
|
* @npackets is 0;
|
||||||
*/
|
*/
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_ogg_pad_submit_page (GstOggPad * pad, ogg_page * page)
|
gst_ogg_pad_stream_out (GstOggPad * pad, gint npackets)
|
||||||
{
|
{
|
||||||
ogg_packet packet;
|
|
||||||
int ret;
|
|
||||||
gboolean done = FALSE;
|
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
gboolean done = FALSE;
|
||||||
GstOggDemux *ogg;
|
GstOggDemux *ogg;
|
||||||
|
|
||||||
ogg = GST_OGG_DEMUX (GST_PAD_PARENT (pad));
|
ogg = pad->ogg;
|
||||||
|
|
||||||
if (ogg_stream_pagein (&pad->stream, page) != 0)
|
|
||||||
goto choked;
|
|
||||||
|
|
||||||
if (ogg_page_continued (page))
|
|
||||||
GST_LOG_OBJECT (ogg, "have continued page");
|
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
|
int ret;
|
||||||
|
ogg_packet packet;
|
||||||
|
|
||||||
ret = ogg_stream_packetout (&pad->stream, &packet);
|
ret = ogg_stream_packetout (&pad->stream, &packet);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1220,9 +1250,100 @@ gst_ogg_pad_submit_page (GstOggPad * pad, ogg_page * page)
|
||||||
gst_ogg_pad_reset (pad);
|
gst_ogg_pad_reset (pad);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (npackets > 0) {
|
||||||
|
npackets--;
|
||||||
|
done = (npackets == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
could_not_submit:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (ogg,
|
||||||
|
"could not submit packet for stream %08x, error: %d", pad->serialno,
|
||||||
|
result);
|
||||||
|
gst_ogg_pad_reset (pad);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* submit a page to an oggpad, this function will then submit all
|
||||||
|
* the packets in the page.
|
||||||
|
*/
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_ogg_pad_submit_page (GstOggPad * pad, ogg_page * page)
|
||||||
|
{
|
||||||
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
GstOggDemux *ogg;
|
||||||
|
gboolean continued = FALSE;
|
||||||
|
|
||||||
|
ogg = pad->ogg;
|
||||||
|
|
||||||
|
if (ogg->segment.rate < 0.0) {
|
||||||
|
gint npackets;
|
||||||
|
|
||||||
|
continued = ogg_page_continued (page);
|
||||||
|
|
||||||
|
/* number of completed packets in the page */
|
||||||
|
npackets = ogg_page_packets (page);
|
||||||
|
if (!continued) {
|
||||||
|
/* page is not continued so it contains at least one packet start */
|
||||||
|
if (npackets == 0)
|
||||||
|
npackets = 1;
|
||||||
|
}
|
||||||
|
GST_LOG_OBJECT (ogg, "continued: %d, %d packets", continued, npackets);
|
||||||
|
|
||||||
|
if (npackets == 0) {
|
||||||
|
GST_LOG_OBJECT (ogg, "no decodable packets, we need a previous page");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ogg_stream_pagein (&pad->stream, page) != 0)
|
||||||
|
goto choked;
|
||||||
|
|
||||||
|
/* flush all packets in the stream layer */
|
||||||
|
result = gst_ogg_pad_stream_out (pad, 0);
|
||||||
|
|
||||||
|
if (pad->continued) {
|
||||||
|
ogg_packet packet;
|
||||||
|
|
||||||
|
/* now send the continued pages to the stream layer */
|
||||||
|
while (pad->continued) {
|
||||||
|
ogg_page *p = (ogg_page *) pad->continued->data;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (ogg, "submitting continued page %p", p);
|
||||||
|
if (ogg_stream_pagein (&pad->stream, p) != 0)
|
||||||
|
goto choked;
|
||||||
|
|
||||||
|
pad->continued = g_list_delete_link (pad->continued, pad->continued);
|
||||||
|
|
||||||
|
/* free the page */
|
||||||
|
gst_ogg_page_free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (ogg, "flushing last continued packet");
|
||||||
|
/* flush 1 continued packet in the stream layer */
|
||||||
|
result = gst_ogg_pad_stream_out (pad, 1);
|
||||||
|
|
||||||
|
/* flush all remaining packets, we pushed them in the previous round.
|
||||||
|
* We don't use _reset() because we still want to get the discont when
|
||||||
|
* we submit a next page. */
|
||||||
|
while (ogg_stream_packetout (&pad->stream, &packet) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* keep continued pages (only in reverse mode) */
|
||||||
|
if (continued) {
|
||||||
|
ogg_page *p = gst_ogg_page_copy (page);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (ogg, "keeping continued page %p", p);
|
||||||
|
pad->continued = g_list_prepend (pad->continued, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
choked:
|
choked:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (ogg,
|
GST_WARNING_OBJECT (ogg,
|
||||||
|
@ -1232,14 +1353,6 @@ choked:
|
||||||
/* we continue to recover */
|
/* we continue to recover */
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
could_not_submit:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (ogg,
|
|
||||||
"could not submit packet for stream %08x, error: %d", pad->serialno,
|
|
||||||
result);
|
|
||||||
gst_ogg_pad_reset (pad);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1288,6 +1401,18 @@ gst_ogg_chain_mark_discont (GstOggChain * chain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ogg_chain_reset (GstOggChain * chain)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < chain->streams->len; i++) {
|
||||||
|
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
|
|
||||||
|
gst_ogg_pad_reset (pad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstOggPad *
|
static GstOggPad *
|
||||||
gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
|
||||||
{
|
{
|
||||||
|
@ -2072,13 +2197,8 @@ gst_ogg_demux_perform_seek (GstOggDemux * ogg, GstEvent * event)
|
||||||
* make sure the streaming thread is not messing with the stream */
|
* make sure the streaming thread is not messing with the stream */
|
||||||
for (i = 0; i < ogg->chains->len; i++) {
|
for (i = 0; i < ogg->chains->len; i++) {
|
||||||
GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);
|
GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i);
|
||||||
gint j;
|
|
||||||
|
|
||||||
for (j = 0; j < chain->streams->len; j++) {
|
gst_ogg_chain_reset (chain);
|
||||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j);
|
|
||||||
|
|
||||||
ogg_stream_reset (&pad->stream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue