Пример #1
0
 public void seek_helper(long offst, VorbisFileInstance instance)
 {
     //callbacks.seek_func(datasource, offst, SEEK_SET);
     fseek(datasource, offst, SEEK_SET);
     this.offset = offst;
     instance.oy.reset();
 }
Пример #2
0
        int open_seekable()
        {
            VorbisFileInstance instance = makeInstance();
            Info    initial_i           = new Info();
            Comment initial_c           = new Comment();
            int     serialno;
            long    end;
            int     ret;
            int     dataoffset;
            Page    og = new Page();

            // is this even vorbis...?
            int[] foo = new int[1];
            ret        = fetch_headers(initial_i, initial_c, foo, null, instance);
            serialno   = foo[0];
            dataoffset = (int)offset;           //!!
            instance.os.clear();
            if (ret == -1)
            {
                return(-1);
            }
            // we can seek, so set out learning all about this file
            skable = true;
            //(callbacks.seek_func)(datasource, 0, SEEK_END);
            fseek(datasource, 0, SEEK_END);
            //offset=end=(callbacks.tell_func)(datasource);
            offset = ftell(datasource);
            end    = offset;
            // We get the offset for the last page of the physical bitstream.
            // Most OggVorbis files will contain a single logical bitstream
            end = get_prev_page(og, instance);
            // moer than one logical bitstream?
            if (og.serialno() != serialno)
            {
                // Chained bitstream. Bisect-search each logical bitstream
                // section.  Do so based on serial number only
                if (bisect_forward_serialno(0, 0, end + 1, serialno, 0, instance) < 0)
                {
                    clear();
                    return(OV_EREAD);
                }
            }
            else
            {
                // Only one logical bitstream
                if (bisect_forward_serialno(0, end, end + 1, serialno, 0, instance) < 0)
                {
                    clear();
                    return(OV_EREAD);
                }
            }
            prefetch_all_headers(initial_i, initial_c, dataoffset, instance);
            //return(raw_seek(0));
            return(0);
        }
Пример #3
0
 public int get_next_page(Page page, long boundary, VorbisFileInstance instance)
 {
     if (boundary > 0)
     {
         boundary += offset;
     }
     while (true)
     {
         int more;
         if (boundary > 0 && offset >= boundary)
         {
             return(OV_FALSE);
         }
         more = instance.oy.pageseek(page);
         if (more < 0)
         {
             offset -= more;
         }
         else
         {
             if (more == 0)
             {
                 if (boundary == 0)
                 {
                     return(OV_FALSE);
                 }
                 //	  if(get_data()<=0)return -1;
                 int ret = get_data(instance);
                 if (ret == 0)
                 {
                     return(OV_EOF);
                 }
                 if (ret < 0)
                 {
                     return(OV_EREAD);
                 }
             }
             else
             {
                 int ret = (int)offset;                       //!!!
                 offset += more;
                 return(ret);
             }
         }
     }
 }
Пример #4
0
        private int get_prev_page(Page page, VorbisFileInstance instance)
        {
            long begin = offset;           //!!!
            int  ret;
            int  offst = -1;

            while (offst == -1)
            {
                begin -= CHUNKSIZE;
                if (begin < 0)
                {
                    begin = 0;
                }
                seek_helper(begin, instance);
                while (offset < begin + CHUNKSIZE)
                {
                    ret = get_next_page(page, begin + CHUNKSIZE - offset, instance);
                    if (ret == OV_EREAD)
                    {
                        return(OV_EREAD);
                    }
                    if (ret < 0)
                    {
                        break;
                    }
                    else
                    {
                        offst = ret;
                    }
                }
            }
            seek_helper(offst, instance); //!!!
            ret = get_next_page(page, CHUNKSIZE, instance);
            if (ret < 0)
            {
                //System.err.println("Missed page fencepost at end of logical bitstream Exiting");
                //System.exit(1);
                return(OV_EFAULT);
            }
            return(offst);
        }
Пример #5
0
        public int get_data(VorbisFileInstance instance)
        {
            int index = instance.oy.buffer(CHUNKSIZE);

            byte[] buffer = instance.oy.data;
            //  int bytes=callbacks.read_func(buffer, index, 1, CHUNKSIZE, datasource);
            int bytes = 0;

            try
            {
                bytes = datasource.Read(buffer, index, CHUNKSIZE);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
                return(OV_EREAD);
            }
            instance.oy.wrote(bytes);
            if (bytes == -1)
            {
                bytes = 0;
            }
            return(bytes);
        }
Пример #6
0
        public VorbisFileInstance makeInstance()
        {
            VorbisFileInstance instance = new VorbisFileInstance(this);

            return(instance);
        }
Пример #7
0
        // last step of the OggVorbis_File initialization; get all the
        // vorbis_info structs and PCM positions.  Only called by the seekable
        // initialization (local stream storage is hacked slightly; pay
        // attention to how that's done)
        public void prefetch_all_headers(Info first_i, Comment first_c, int dataoffset,
                                         VorbisFileInstance instance)
        {
            Page og = new Page();
            int  ret;

            vi          = new Info[links];
            vc          = new Comment[links];
            dataoffsets = new long[links];
            pcmlengths  = new long[links];
            serialnos   = new int[links];

            for (int i = 0; i < links; i++)
            {
                if (first_i != null && first_c != null && i == 0)
                {
                    // we already grabbed the initial header earlier.  This just
                    // saves the waste of grabbing it again
                    // !!!!!!!!!!!!!
                    vi[i] = first_i;
                    //memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
                    vc[i] = first_c;
                    //memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
                    dataoffsets[i] = dataoffset;
                }
                else
                {
                    // seek to the location of the initial header
                    seek_helper(offsets[i], instance); //!!!
                    if (fetch_headers(vi[i], vc[i], null, null, instance) == -1)
                    {
                        Console.Error.WriteLine("Error opening logical bitstream #" + (i + 1) + "\n");
                        dataoffsets[i] = -1;
                    }
                    else
                    {
                        dataoffsets[i] = offset;
                        instance.os.clear();
                    }
                }

                // get the serial number and PCM length of this link. To do this,
                // get the last page of the stream
                long end = offsets[i + 1];             //!!!
                seek_helper(end, instance);

                while (true)
                {
                    ret = get_prev_page(og, instance);
                    if (ret == -1)
                    {
                        // this should not be possible
                        Console.Error.WriteLine("Could not find last page of logical " +
                                                "bitstream #" + (i) + "\n");
                        vi[i].clear();
                        vc[i].clear();
                        break;
                    }
                    if (og.granulepos() != -1)
                    {
                        serialnos[i]  = og.serialno();
                        pcmlengths[i] = og.granulepos();
                        break;
                    }
                }
            }
        }
Пример #8
0
        // uses the local ogg_stream storage in vf; this is important for
        // non-streaming input sources
        public int fetch_headers(Info vi, Comment vc, int[] serialno, Page og_ptr, VorbisFileInstance instance)
        {
            //System.err.println("fetch_headers");
            Page   og = new Page();
            Packet op = new Packet();
            int    ret;

            if (og_ptr == null)
            {
                ret = get_next_page(og, CHUNKSIZE, instance);
                if (ret == OV_EREAD)
                {
                    return(OV_EREAD);
                }
                if (ret < 0)
                {
                    return(OV_ENOTVORBIS);
                }
                og_ptr = og;
            }

            if (serialno != null)
            {
                serialno[0] = og_ptr.serialno();
            }

            instance.os.init(og_ptr.serialno());

            // extract the initial header from the first page and verify that the
            // Ogg bitstream is in fact Vorbis data

            vi.init();
            vc.init();

            int i = 0;

            while (i < 3)
            {
                instance.os.pagein(og_ptr);
                while (i < 3)
                {
                    int result = instance.os.packetout(op);
                    if (result == 0)
                    {
                        break;
                    }
                    if (result == -1)
                    {
                        Console.Error.WriteLine("Corrupt header in logical bitstream.");
                        //goto bail_header;
                        vi.clear();
                        vc.clear();
                        instance.os.clear();
                        return(-1);
                    }
                    if (vi.synthesis_headerin(vc, op) != 0)
                    {
                        Console.Error.WriteLine("Illegal header in logical bitstream.");
                        //goto bail_header;
                        vi.clear();
                        vc.clear();
                        instance.os.clear();
                        return(-1);
                    }
                    i++;
                }
                if (i < 3)
                {
                    if (get_next_page(og_ptr, 1, instance) < 0)
                    {
                        Console.Error.WriteLine("Missing header in logical bitstream.");
                        //goto bail_header;
                        vi.clear();
                        vc.clear();
                        instance.os.clear();
                        return(-1);
                    }
                }
            }
            return(0);
        }
Пример #9
0
        public int bisect_forward_serialno(long begin, long searched, long end, int currentno, int m, VorbisFileInstance instance)
        {
            long endsearched = end;
            long next        = end;
            Page page        = new Page();
            int  ret;

            while (searched < endsearched)
            {
                long bisect;
                if (endsearched - searched < CHUNKSIZE)
                {
                    bisect = searched;
                }
                else
                {
                    bisect = (searched + endsearched) / 2;
                }

                seek_helper(bisect, instance);
                ret = get_next_page(page, -1, instance);
                if (ret == OV_EREAD)
                {
                    return(OV_EREAD);
                }
                if (ret < 0 || page.serialno() != currentno)
                {
                    endsearched = bisect;
                    if (ret >= 0)
                    {
                        next = ret;
                    }
                }
                else
                {
                    searched = ret + page.header_len + page.body_len;
                }
            }
            seek_helper(next, instance);
            ret = get_next_page(page, -1, instance);
            if (ret == OV_EREAD)
            {
                return(OV_EREAD);
            }

            if (searched >= end || ret == -1)
            {
                links          = m + 1;
                offsets        = new long[m + 2];
                offsets[m + 1] = searched;
            }
            else
            {
                ret = bisect_forward_serialno(next, offset, end, page.serialno(), m + 1, instance);
                if (ret == OV_EREAD)
                {
                    return(OV_EREAD);
                }
            }
            offsets[m] = begin;
            return(0);
        }