Ejemplo n.º 1
0
        static int _os_lacing_expand(ref ogg_stream_state os, int needed)
        {
            if (os.lacing_storage <= os.lacing_fill + needed)
            {
                void *ret = _ogg_realloc(os.lacing_vals, (os.lacing_storage + needed + 32) * sizeof(int));

                if (ret == null)
                {
                    ogg_stream_clear(ref os);
                    return(-1);
                }

                os.lacing_vals = (int *)ret;
                ret            = _ogg_realloc(os.granule_vals, (os.lacing_storage + needed + 32) * sizeof(long));

                if (ret == null)
                {
                    ogg_stream_clear(ref os);
                    return(-1);
                }

                os.granule_vals    = (long *)ret;
                os.lacing_storage += (needed + 32);
            }

            return(0);
        }
Ejemplo n.º 2
0
        static public int ogg_stream_packetin(ref ogg_stream_state os, ref ogg_packet op)
        {
            ogg_iovec_t[] iov = new ogg_iovec_t[1];

            iov[0].iov_base = op.packet;
            iov[0].iov_len  = op.bytes;

            return(ogg_stream_iovecin(ref os, ref iov, 1, op.e_o_s, op.granulepos));
        }
Ejemplo n.º 3
0
 static public int ogg_stream_packetpeek(ref ogg_stream_state os, ref ogg_packet op)
 {
     if (ogg_stream_check(ref os) != 0)
     {
         return(0);
     }
     else
     {
         return(_packetout(ref os, ref op, 0));
     }
 }
Ejemplo n.º 4
0
 static public int ogg_stream_eos(ref ogg_stream_state os)
 {
     if (ogg_stream_check(ref os) != 0)
     {
         return(1);
     }
     else
     {
         return(os.e_o_s);
     }
 }
Ejemplo n.º 5
0
        static public int ogg_stream_reset_serialno(ref ogg_stream_state os, int serialno)
        {
            if (ogg_stream_check(ref os) != 0)
            {
                return(-1);
            }

            ogg_stream_reset(ref os);
            os.serialno = serialno;

            return(0);
        }
Ejemplo n.º 6
0
        static public int ogg_stream_clear(ref ogg_stream_state os)
        {
            if (os == null)
            {
                return(-1);
            }

            if (os.header != null)
            {
                _ogg_free(os.header);
            }

            if (os.body_data != null)
            {
                _ogg_free(os.body_data);
            }

            if (os.lacing_vals != null)
            {
                _ogg_free(os.lacing_vals);
            }

            if (os.granule_vals != null)
            {
                _ogg_free(os.granule_vals);
            }

            os.body_data     = null;
            os.body_storage  = 0;
            os.body_fill     = 0;
            os.body_returned = 0;

            os.lacing_vals  = null;
            os.granule_vals = null;

            os.lacing_storage  = 1024;
            os.lacing_fill     = 0;
            os.lacing_packet   = 0;
            os.lacing_returned = 0;

            os.header      = null;
            os.header_fill = 0;

            os.b_o_s = 0;
            os.e_o_s = 0;

            os.serialno = 0;
            os.pageno   = 0;

            os.packetno   = 0;
            os.granulepos = 0;
            return(0);
        }
Ejemplo n.º 7
0
 static public int ogg_stream_check(ref ogg_stream_state os)
 {
     if (os == null)
     {
         return(-1);
     }
     else if (os.body_data == null)
     {
         return(-1);
     }
     else
     {
         return(0);
     }
 }
Ejemplo n.º 8
0
        /* Like the above, but an argument is provided to adjust the nominal page size for applications which are smart enough to provide their
         * own delay based flushing */

        static public int ogg_stream_pageout_fill(ref ogg_stream_state os, ref ogg_page og, int nfill)
        {
            int force = 0;

            if (ogg_stream_check(ref os) != 0)
            {
                return(0);
            }

            if ((os.e_o_s != 0 && os.lacing_fill != 0) || (os.lacing_fill != 0 && os.b_o_s == 0))
            {
                force = 1;
            }

            return(ogg_stream_flush_i(ref os, ref og, force, nfill));
        }
Ejemplo n.º 9
0
        /* Helpers for ogg_stream_encode; this keeps the structure and what's happening fairly clear */

        static int _os_body_expand(ref ogg_stream_state os, int needed)
        {
            if (os.body_storage <= os.body_fill + needed)
            {
                void *ret = _ogg_realloc(os.body_data, (os.body_storage + needed + 1024) * sizeof(byte));

                if (ret == null)
                {
                    ogg_stream_clear(ref os);
                    return(-1);
                }

                os.body_storage += (needed + 1024);
                os.body_data     = (byte *)ret;
            }

            return(0);
        }
Ejemplo n.º 10
0
        static public int ogg_stream_init(ref ogg_stream_state os, int serialno)
        {
            if (ogg_stream_clear(ref os) != 0)
            {
                return(1);
            }

            os.body_storage   = 16 * 1024;
            os.lacing_storage = 1024;
            os.header         = (byte *)_ogg_malloc(ogg_stream_state.HEADER_SIZE);
            os.body_data      = (byte *)_ogg_malloc(os.body_storage * sizeof(byte));
            os.lacing_vals    = (int *)_ogg_malloc(os.lacing_storage * sizeof(int));
            os.granule_vals   = (long *)_ogg_malloc(os.lacing_storage * sizeof(long));

            if (os.header == null || os.body_data == null || os.lacing_vals == null || os.granule_vals == null)
            {
                return(-1);
            }

            os.serialno = serialno;
            return(0);
        }
Ejemplo n.º 11
0
        static public int ogg_stream_reset(ref ogg_stream_state os)
        {
            if (ogg_stream_check(ref os) != 0)
            {
                return(-1);
            }

            os.body_fill     = 0;
            os.body_returned = 0;

            os.lacing_fill     = 0;
            os.lacing_packet   = 0;
            os.lacing_returned = 0;

            os.header_fill = 0;

            os.e_o_s      = 0;
            os.b_o_s      = 0;
            os.pageno     = -1;
            os.packetno   = 0;
            os.granulepos = 0;

            return(0);
        }
Ejemplo n.º 12
0
 public static extern int ogg_stream_flush_fill(ref ogg_stream_state os, ref ogg_page og, int fillbytes);
Ejemplo n.º 13
0
 public static extern int ogg_stream_flush(ref ogg_stream_state os, ref ogg_page og);
Ejemplo n.º 14
0
 public static extern int ogg_stream_packetin(ref ogg_stream_state os, ref ogg_packet op);
Ejemplo n.º 15
0
        /* add the incoming page to the stream state; we decompose the page
         * into packet segments here as well. */

        static public int ogg_stream_pagein(ref ogg_stream_state os, ref ogg_page og)
        {
            byte *header = og.header;
            byte *body   = og.body;

            int  bodysize   = og.body_len;
            int  version    = ogg_page_version(ref og);
            int  continued  = ogg_page_continued(ref og);
            int  bos        = ogg_page_bos(ref og);
            int  eos        = ogg_page_eos(ref og);
            long granulepos = ogg_page_granulepos(ref og);
            int  serialno   = ogg_page_serialno(ref og);
            int  pageno     = ogg_page_pageno(ref og);
            int  segments   = header[26];

            if (ogg_stream_check(ref os) != 0)
            {
                return(-1);
            }

            /* clean up 'returned data' */
            {
                int lr = os.lacing_returned;
                int br = os.body_returned;

                /* body data */
                if (br > 0)
                {
                    os.body_fill -= br;

                    if (os.body_fill > 0)
                    {
                        CopyMemory(os.body_data, os.body_data + br, os.body_fill);
                    }

                    os.body_returned = 0;
                }

                /* segment table */
                if (lr > 0)
                {
                    if (os.lacing_fill - lr > 0)
                    {
                        CopyMemory(os.lacing_vals, os.lacing_vals + lr, (os.lacing_fill - lr) * sizeof(int));
                    }
                    else
                    {
                        CopyMemory(os.granule_vals, os.granule_vals + lr, (os.lacing_fill - lr) * sizeof(long));
                    }
                }

                os.lacing_fill    -= lr;
                os.lacing_packet  -= lr;
                os.lacing_returned = 0;
            }

            /* check the serial number */
            if (serialno != os.serialno)
            {
                return(-1);
            }

            if (version > 0)
            {
                return(-1);
            }

            if (_os_lacing_expand(ref os, segments + 1) != 0)
            {
                return(-1);
            }

            /* are we in sequence? */
            if (pageno != os.pageno)
            {
                /* unroll previous partial packet (if any) */
                for (int i = os.lacing_packet; i < os.lacing_fill; i++)
                {
                    os.body_fill -= os.lacing_vals[i] & 0xff;
                }

                os.lacing_fill = os.lacing_packet;

                /* make a note of dropped data in segment table */
                if (os.pageno != -1)
                {
                    os.lacing_vals[os.lacing_fill++] = 0x400;
                    os.lacing_packet++;
                }
            }

            int segptr = 0;

            /* are we a 'continued packet' page? If so, we may need to skip some segments */
            if (continued != 0)
            {
                if (os.lacing_fill < 1 || os.lacing_vals[os.lacing_fill - 1] == 0x400)
                {
                    bos = 0;

                    for (segptr = 0; segptr < segments; segptr++)
                    {
                        int val = header[27 + segptr];

                        body     += val;
                        bodysize -= val;

                        if (val < 255)
                        {
                            segptr++;
                            break;
                        }
                    }
                }
            }

            if (bodysize > 0)
            {
                if (_os_body_expand(ref os, bodysize) != 0)
                {
                    return(-1);
                }

                CopyMemory(os.body_data + os.body_fill, body, bodysize);
                os.body_fill += bodysize;
            }

            int saved = -1;

            while (segptr < segments)
            {
                int val = og.header[27 + segptr];

                os.lacing_vals[os.lacing_fill]  = val;
                os.granule_vals[os.lacing_fill] = -1;

                if (bos != 0)
                {
                    os.lacing_vals[os.lacing_fill] |= 0x100;
                    bos = 0;
                }

                if (val < 255)
                {
                    saved = os.lacing_fill;
                }

                os.lacing_fill++;
                segptr++;

                if (val < 255)
                {
                    os.lacing_packet = os.lacing_fill;
                }
            }

            if (saved != -1)
            {
                os.granule_vals[saved] = granulepos;
            }

            if (eos != 0)
            {
                os.e_o_s = 1;

                if (os.lacing_fill > 0)
                {
                    os.lacing_vals[os.lacing_fill - 1] |= 0x200;
                }
            }

            os.pageno = pageno + 1;

            return(0);
        }
Ejemplo n.º 16
0
        static public int _packetout(ref ogg_stream_state os, ref ogg_packet op, int adv)
        {
            /* The last part of decode. We have the stream broken into packet segments. Now we need to group them into packets (or return the out of sync markers) */
            int ptr = os.lacing_returned;

            if (os.lacing_packet <= ptr)
            {
                return(0);
            }

            /* we need to tell the codec there's a gap; it might need to handle previous packet dependencies. */
            if ((os.lacing_vals[ptr] & 0x400) != 0)
            {
                os.lacing_returned++;
                os.packetno++;
                return(-1);
            }

            /* just using peek as an inexpensive way to ask if there's a whole packet waiting */
            if (op == null && adv == 0)
            {
                return(1);
            }

            /* Gather the whole packet. We'll have no holes or a partial packet */
            {
                int size  = os.lacing_vals[ptr] & 0xff;
                int bytes = size;
                int eos   = os.lacing_vals[ptr] & 0x200;
                int bos   = os.lacing_vals[ptr] & 0x100;

                while (size == 255)
                {
                    int val = os.lacing_vals[++ptr];

                    size = val & 0xff;

                    if ((val & 0x200) != 0)
                    {
                        eos = 0x200;
                    }

                    bytes += size;
                }

                if (op != null)
                {
                    op.e_o_s      = eos;
                    op.b_o_s      = bos;
                    op.packet     = os.body_data + os.body_returned;
                    op.packetno   = os.packetno;
                    op.granulepos = os.granule_vals[ptr];
                    op.bytes      = bytes;
                }

                if (adv != 0)
                {
                    os.body_returned  += bytes;
                    os.lacing_returned = ptr + 1;
                    os.packetno++;
                }
            }

            return(1);
        }
Ejemplo n.º 17
0
 public static extern int ogg_stream_reset_serialno(ref ogg_stream_state os, int serialno);
Ejemplo n.º 18
0
 public static extern int ogg_stream_clear(ref ogg_stream_state os);
Ejemplo n.º 19
0
 public static extern int ogg_stream_init(ref ogg_stream_state os, int serialno);
Ejemplo n.º 20
0
        /* submit data to the internal buffer of the framing engine */
        static public int ogg_stream_iovecin(ref ogg_stream_state os, ref ogg_iovec_t[] iov, int count, int e_o_s, long granulepos)
        {
            int bytes = 0;
            int lacing_vals;
            int i;

            if (ogg_stream_check(ref os) != 0)
            {
                return(-1);
            }

            for (i = 0; i < count; ++i)
            {
                bytes += iov[i].iov_len;
            }

            lacing_vals = bytes / 255 + 1;

            if (os.body_returned > 0)
            {
                /* advance packet data according to the body_returned pointer. We had to keep it around to return a pointer into the buffer last call */
                os.body_fill -= os.body_returned;

                if (os.body_fill > 0)
                {
                    CopyMemory(os.body_data, os.body_data + os.body_returned, os.body_fill);
                }

                os.body_returned = 0;
            }

            /* make sure we have the buffer storage */
            if (_os_body_expand(ref os, bytes) != 0 || _os_lacing_expand(ref os, lacing_vals) != 0)
            {
                return(-1);
            }

            /* Copy in the submitted packet.  Yes, the copy is a waste; this is the liability of overly clean abstraction for the time being. It will actually be fairly easy to eliminate the extra copy in the future */
            for (i = 0; i < count; i++)
            {
                CopyMemory(os.body_data + os.body_fill, iov[i].iov_base, iov[i].iov_len);
                os.body_fill += (int)iov[i].iov_len;
            }

            /* Store lacing vals for this packet */
            for (i = 0; i < lacing_vals - 1; i++)
            {
                os.lacing_vals[os.lacing_fill + i]  = 255;
                os.granule_vals[os.lacing_fill + i] = os.granulepos;
            }

            os.lacing_vals[os.lacing_fill + i] = bytes % 255;
            os.granulepos = os.granule_vals[os.lacing_fill + i] = granulepos;

            /* flag the first segment as the beginning of the packet */
            os.lacing_vals[os.lacing_fill] |= 0x100;
            os.lacing_fill += lacing_vals;

            /* for the sake of completeness */
            os.packetno++;

            if (e_o_s != 0)
            {
                os.e_o_s = 1;
            }

            return(0);
        }
Ejemplo n.º 21
0
        static public int ogg_stream_packetpeek(ref ogg_stream_state os)
        {
            ogg_packet op_null = null;

            return(ogg_stream_packetpeek(ref os, ref op_null));
        }
Ejemplo n.º 22
0
 static public int ogg_stream_destroy(ref ogg_stream_state os)
 {
     ogg_stream_clear(ref os);
     return(0);
 }
Ejemplo n.º 23
0
 public static extern int ogg_stream_check(ref ogg_stream_state os);
Ejemplo n.º 24
0
        /* Conditionally flush a page; force==0 will only flush nominal-size pages, force==1 forces us to flush a page regardless of page size so long as there's any data available at all. */
        static public int ogg_stream_flush_i(ref ogg_stream_state os, ref ogg_page og, int force, int nfill)
        {
            int i;
            int vals    = 0;
            int maxvals = (os.lacing_fill > 255 ? 255 : os.lacing_fill);
            int bytes   = 0;
            int acc     = 0;

            long granule_pos = -1;

            if (ogg_stream_check(ref os) != 0)
            {
                return(0);
            }

            if (maxvals == 0)
            {
                return(0);
            }

            /* construct a page */
            /* decide how many segments to include */

            /* If this is the initial header case, the first page must only include the initial header packet */
            if (os.b_o_s == 0) /* 'initial header page' case */
            {
                granule_pos = 0;

                for (vals = 0; vals < maxvals; vals++)
                {
                    if ((os.lacing_vals[vals] & 0xff) < 255)
                    {
                        vals++;
                        break;
                    }
                }
            }
            else
            {
                int packets_done     = 0;
                int packet_just_done = 0;

                for (vals = 0; vals < maxvals; vals++)
                {
                    if (acc > nfill && packet_just_done >= 4)
                    {
                        force = 1;
                        break;
                    }

                    acc += os.lacing_vals[vals] & 0xff;

                    if ((os.lacing_vals[vals] & 0xff) < 255)
                    {
                        granule_pos      = os.granule_vals[vals];
                        packet_just_done = ++packets_done;
                    }
                    else
                    {
                        packet_just_done = 0;
                    }

                    if (vals == 255)
                    {
                        force = 1;
                    }
                }
            }

            if (force == 0)
            {
                return(0);
            }

            /* construct the header in temp storage */
            os.header[0] = (byte)'O';
            os.header[1] = (byte)'g';
            os.header[2] = (byte)'g';
            os.header[3] = (byte)'S';

            /* stream structure version */
            os.header[4] = 0;

            /* continued packet flag? */
            os.header[5] = 0;

            if ((os.lacing_vals[0] & 0x100) == 0)
            {
                os.header[5] += 0x01;
            }

            /* first page flag? */
            if (os.b_o_s == 0)
            {
                os.header[5] += 0x02;
            }

            /* last page flag? */
            if (os.e_o_s != 0 && os.lacing_fill == vals)
            {
                os.header[5] += 0x04;
            }

            os.b_o_s = 1;

            /* 64 bits of PCM position */
            for (i = 6; i < 14; i++)
            {
                os.header[i]  = (byte)(granule_pos & 0xff);
                granule_pos >>= 8;
            }

            /* 32 bits of stream serial number */
            {
                long serialno = os.serialno;

                for (i = 14; i < 18; i++)
                {
                    os.header[i] = (byte)(serialno & 0xff);
                    serialno   >>= 8;
                }
            }

            /* 32 bits of page counter (we have both counter and page header because this val can roll over) */
            if (os.pageno == -1)
            {
                /* because someone called stream_reset; this would be a strange thing to do in an encode stream, but it has plausible uses */
                os.pageno = 0;
            }

            long pageno = os.pageno++;

            for (i = 18; i < 22; i++)
            {
                os.header[i] = (byte)(pageno & 0xff);
                pageno     >>= 8;
            }

            /* zero for computation; filled in later */
            os.header[22] = 0;
            os.header[23] = 0;
            os.header[24] = 0;
            os.header[25] = 0;

            /* segment table */
            os.header[26] = (byte)(vals & 0xff);

            for (i = 0; i < vals; i++)
            {
                os.header[i + 27] = (byte)(os.lacing_vals[i] & 0xff);
                bytes            += os.header[i + 27];
            }

            /* set pointers in the ogg_page struct */
            og.header      = os.header;
            og.header_len  = vals + 27;
            os.header_fill = vals + 27;
            og.body        = os.body_data + os.body_returned;
            og.body_len    = bytes;

            /* advance the lacing data and set the body_returned pointer */
            os.lacing_fill -= vals;
            CopyMemory(os.lacing_vals, os.lacing_vals + vals, os.lacing_fill * sizeof(int));
            CopyMemory(os.granule_vals, os.granule_vals + vals, os.lacing_fill * sizeof(long));
            os.body_returned += bytes;

            /* calculate the checksum */
            ogg_page_checksum_set(ref og);

            /* done */
            return(1);
        }
Ejemplo n.º 25
0
 public static extern int ogg_stream_reset(ref ogg_stream_state os);
Ejemplo n.º 26
0
        /* This will flush remaining packets into a page (returning nonzero), even if there is not enough data to trigger a flush normally
         * (undersized page). If there are no packets or partial packets to flush, ogg_stream_flush returns 0.  Note that ogg_stream_flush will
         * try to flush a normal sized page like ogg_stream_pageout; a call to ogg_stream_flush does not guarantee that all packets have flushed.
         * Only a return value of 0 from ogg_stream_flush indicates all packet data is flushed into pages.
         *
         * since ogg_stream_flush will flush the last page in a stream even if it's undersized, you almost certainly want to use ogg_stream_pageout
         * (and *not* ogg_stream_flush) unless you specifically need to flush a page regardless of size in the middle of a stream. */

        static public int ogg_stream_flush(ref ogg_stream_state os, ref ogg_page og)
        {
            return(ogg_stream_flush_i(ref os, ref og, 1, 4096));
        }
Ejemplo n.º 27
0
 public static extern int ogg_stream_destroy(ref ogg_stream_state os);
Ejemplo n.º 28
0
        /* Like the above, but an argument is provided to adjust the nominal page size for applications which are smart enough to provide their
         * own delay based flushing */

        static public int ogg_stream_flush_fill(ref ogg_stream_state os, ref ogg_page og, int nfill)
        {
            return(ogg_stream_flush_i(ref os, ref og, 1, nfill));
        }