示例#1
0
        /* sync the stream and get a page.  Keep trying until we find a page.
         * Suppress 'sync errors' after reporting the first.
         *
         * return values:
         * -1) recapture (hole in data)
         * 0) need more data
         * 1) page returned
         *
         * Returns pointers into buffered data; invalidated by next call to
         * _stream, _clear, _init, or _buffer */

        static public int ogg_sync_pageout(ref ogg_sync_state oy, ref ogg_page og)
        {
            if (ogg_sync_check(ref oy) != 0)
            {
                return(0);
            }

            /* all we need to do is verify a page at the head of the stream
             * buffer.  If it doesn't verify, we look for the next potential
             * frame */

            for (;;)
            {
                int ret = ogg_sync_pageseek(ref oy, ref og);

                if (ret > 0)
                {
                    /* have a page */
                    return(1);
                }

                if (ret == 0)
                {
                    /* need more data */
                    return(0);
                }

                if (oy.unsynced == 0)
                {
                    oy.unsynced = 1;
                    return(-1);
                }
            }
        }
示例#2
0
        static public int ogg_sync_destroy(ref ogg_sync_state oy)
        {
            if (oy != null)
            {
                ogg_sync_clear(ref oy);
            }

            return(0);
        }
示例#3
0
        /* clear things to an initial state. Good to call, eg, before seeking */
        static public int ogg_sync_reset(ref ogg_sync_state oy)
        {
            if (ogg_sync_check(ref oy) != 0)
            {
                return(-1);
            }

            oy.fill        = 0;
            oy.returned    = 0;
            oy.unsynced    = 0;
            oy.headerbytes = 0;
            oy.bodybytes   = 0;

            return(0);
        }
示例#4
0
        static public int ogg_sync_wrote(ref ogg_sync_state oy, int bytes)
        {
            if (ogg_sync_check(ref oy) != 0)
            {
                return(-1);
            }

            if (oy.fill + bytes > oy.storage)
            {
                return(-1);
            }

            oy.fill += bytes;
            return(0);
        }
示例#5
0
 static public int ogg_sync_check(ref ogg_sync_state oy)
 {
     if (oy == null)
     {
         return(-1);
     }
     else if (oy.storage < 0)
     {
         return(-1);
     }
     else
     {
         return(0);
     }
 }
示例#6
0
        static public byte *ogg_sync_buffer(ref ogg_sync_state oy, int size)
        {
            if (ogg_sync_check(ref oy) != 0)
            {
                return(null);
            }

            /* first, clear out any space that has been previously returned */
            if (oy.returned > 0)
            {
                oy.fill -= oy.returned;

                if (oy.fill > 0)
                {
                    CopyMemory(oy.data, oy.data + oy.returned, oy.fill);
                }

                oy.returned = 0;
            }

            if (size > oy.storage - oy.fill)
            {
                /* We need to extend the internal buffer */
                int newsize = size + oy.fill + 4096; /* an extra page to be nice */

                if (oy.data != null)
                {
                    oy.data = (byte *)_ogg_realloc(oy.data, newsize);
                }
                else
                {
                    oy.data = (byte *)_ogg_malloc(newsize);
                }

                oy.storage = newsize;
            }

            /* expose a segment at least as large as requested at the fill mark */
            return(oy.data + oy.fill);
        }
示例#7
0
        static public int ogg_sync_clear(ref ogg_sync_state oy)
        {
            if (oy == null)
            {
                return(1);
            }

            if (oy.data != null)
            {
                _ogg_free(oy.data);
            }

            oy.data = null;

            oy.storage  = 0;
            oy.fill     = 0;
            oy.returned = 0;

            oy.unsynced    = 0;
            oy.headerbytes = 0;
            oy.bodybytes   = 0;

            return(0);
        }
示例#8
0
 public static extern int ogg_sync_pageout(ref ogg_sync_state oy, ref ogg_page og);
示例#9
0
 public static extern int ogg_sync_wrote(ref ogg_sync_state oy, int bytes);
示例#10
0
 public static extern IntPtr ogg_sync_buffer(ref ogg_sync_state oy, int size);
示例#11
0
 public static extern int ogg_sync_reset(ref ogg_sync_state oy);
示例#12
0
 public static extern int ogg_sync_destroy(ref ogg_sync_state oy);
示例#13
0
 public static extern int ogg_sync_clear(ref ogg_sync_state oy);
示例#14
0
 public static extern int ogg_sync_check(ref ogg_sync_state oy);
示例#15
0
 public static extern int ogg_sync_init(ref ogg_sync_state oy);
示例#16
0
        /* DECODING PRIMITIVES: packet streaming layer */

        /* This has two layers to place more of the multi-serialno and paging control in the application's hands.  First, we expose a data buffer
         * using ogg_sync_buffer().  The app either copies into the buffer, or passes it directly to read(), etc.  We then call
         * ogg_sync_wrote() to tell how many bytes we just added.
         *
         * Pages are returned (pointers into the buffer in ogg_sync_state) by ogg_sync_pageout().  The page is then submitted to
         * ogg_stream_pagein() along with the appropriate ogg_stream_state* (ie, matching serialno).  We then get raw packets out calling ogg_stream_packetout() with a
         * ogg_stream_state. */

        /* initialize the struct to a known state */

        static public int ogg_sync_init(ref ogg_sync_state oy)
        {
            return(ogg_sync_clear(ref oy));
        }
示例#17
0
        static public int ogg_sync_pageseek(ref ogg_sync_state oy, ref ogg_page og)
        {
            byte *page = oy.data + oy.returned;
            byte *next = null;

            int bytes = oy.fill - oy.returned;

            if (ogg_sync_check(ref oy) != 0)
            {
                return(0);
            }

            if (oy.headerbytes == 0)
            {
                int headerbytes;

                if (bytes < 27)
                {
                    return(0);
                }

                if
                (
                    page[0] != 'O' ||
                    page[1] != 'g' ||
                    page[2] != 'g' ||
                    page[3] != 'S'
                )
                {
                    goto sync_fail;
                }
                else
                {
                    headerbytes = page[26] + 27;

                    if (bytes < headerbytes)
                    {
                        return(0);
                    }

                    for (int i = 0; i < page[26]; i++)
                    {
                        oy.bodybytes += page[27 + i];
                    }

                    oy.headerbytes = headerbytes;
                }
            }

            if (oy.bodybytes + oy.headerbytes > bytes)
            {
                return(0);
            }

            /* The whole test page is buffered. Verify the checksum */
            {
                byte[] chksum = new byte[4];

                ogg_page log = new ogg_page();

                /* Grab the checksum bytes, set the header field to zero */
                Marshal.Copy((IntPtr)(page + 22), chksum, 0, 4);
                ZeroMemory(page + 22, 4);

                /* set up a temp page struct and recompute the checksum */
                log.header     = page;
                log.header_len = oy.headerbytes;
                log.body       = page + oy.headerbytes;
                log.body_len   = oy.bodybytes;

                ogg_page_checksum_set(ref log);

                /* Compare */
                if
                (
                    chksum[0] != page[22] ||
                    chksum[1] != page[23] ||
                    chksum[2] != page[24] ||
                    chksum[3] != page[25]
                )
                {
                    /* D'oh.  Mismatch! Corrupt page (or miscapture and not a page at all) */
                    /* replace the computed checksum with the one actually read in */
                    Marshal.Copy(chksum, 0, (IntPtr)(page + 22), 4);

                    /* Bad checksum. Lose sync */
                    goto sync_fail;
                }
            }

            /* yes, have a whole page all ready to go */
            {
                byte *_page = oy.data + oy.returned;

                bytes = oy.headerbytes + oy.bodybytes;

                if (og != null)
                {
                    og.header     = _page;
                    og.header_len = oy.headerbytes;
                    og.body       = _page + oy.headerbytes;
                    og.body_len   = oy.bodybytes;
                }

                oy.unsynced    = 0;
                oy.returned   += bytes;
                oy.headerbytes = 0;
                oy.bodybytes   = 0;

                return(bytes);
            }

sync_fail:
            oy.headerbytes = 0;
            oy.bodybytes   = 0;

            for (int i = 1; i < bytes; i++)
            {
                if (page[i] == 'O')
                {
                    next = (byte *)(page + i);
                    break;
                }
            }

            if (next == null)
            {
                next = oy.data + oy.fill;
            }

            oy.returned = (int)(next - oy.data);
            return((int)-(next - page));
        }