Esempio n. 1
0
        public int header_out(Packet op)
        {
            csBuffer opb=new csBuffer();
            opb.writeinit();

            if(pack(opb)!=0) { return OV_EIMPL; }

            op.packet_base = new byte[opb.bytes()];
            op.packet=0;
            op.bytes=opb.bytes();
            Array.Copy(opb.buf(), 0, op.packet_base, 0, op.bytes);
            op.b_o_s=0;
            op.e_o_s=0;
            op.granulepos=0;
            return 0;
        }
Esempio n. 2
0
        // The Vorbis header is in three packets; the initial small packet in
        // the first page that identifies basic parameters, a second packet
        // with bitstream comments and a third packet that holds the
        // codebook.
        public int synthesis_headerin(Comment vc, Packet op)
        {
            csBuffer opb=new csBuffer();

            if(op!=null) {
                opb.readinit(op.packet_base, op.packet, op.bytes);

                // Which of the three types of header is this?
                // Also verify header-ness, vorbis
                {
                    byte[] buffer=new byte[6];
                    int packtype=opb.read(8);
                    //memset(buffer,0,6);
                    opb.read(buffer,6);
                    if(buffer[0]!='v' || buffer[1]!='o' || buffer[2]!='r' ||
                            buffer[3]!='b' || buffer[4]!='i' || buffer[5]!='s') {
                        // not a vorbis header
                        return(-1);
                    }
                    switch(packtype) {
                    case 0x01: // least significant *bit* is read first
                        if(op.b_o_s==0) {
                            // Not the initial packet
                            return(-1);
                        }
                        if(rate!=0) {
                            // previously initialized info header
                            return(-1);
                        }
                        return(unpack_info(opb));
                    case 0x03: // least significant *bit* is read first
                        if(rate==0) {
                            // um... we didn't get the initial header
                            return(-1);
                        }
                        return(vc.unpack(opb));
                    case 0x05: // least significant *bit* is read first
                        if(rate==0 || vc.vendor==null) {
                            // um... we didn;t get the initial header or comments yet
                            return(-1);
                        }
                        return(unpack_books(opb));
                    default:
                        // Not a valid vorbis header type
                        //return(-1);
                        break;
                    }
                }
            }
            return(-1);
        }
Esempio n. 3
0
        //  static void v_writestring(csBuffer o, byte[] s){
        //    int i=0;
        //    while(s[i]!=0){
        //      o.write(s[i++],8);
        //    }
        //  }
        //  static void v_readstring(csBuffer o, byte[] buf, int bytes){
        //    int i=0
        //    while(bytes--!=0){
        //      buf[i++]=o.read(8);
        //    }
        //  }
        //  private csBuffer opb_blocksize=new csBuffer();
        public int blocksize(Packet op)
        {
            //codec_setup_info     *ci=vi->codec_setup;
            csBuffer opb=new csBuffer();
            //    synchronized(opb_blocksize){
            int mode;

            opb.readinit(op.packet_base, op.packet, op.bytes);

            /* Check the packet type */
            if(opb.read(1)!=0) {
                /* Oops.  This is not an audio data packet */
                return(OV_ENOTAUDIO);
            }
            {
                int modebits=0;
                int v=modes;
                while(v>1) {
                    modebits++;
                    v = (int)((uint)v >> 1);
                }

                /* read our mode and pre/post windowsize */
                mode=opb.read(modebits);
            }
            if(mode==-1) { return(OV_EBADPACKET); }
            return(blocksizes[mode_param[mode].blockflag]);
            //    }
        }
Esempio n. 4
0
		public int synthesis(Packet op)
		{
			Info vi=vd.vi;
 
			// first things first.  Make sure decode is ready
			// ripcord();
			opb.readinit(op.packet_base, op.packet, op.bytes);

			// Check the packet type
			if(opb.read(1)!=0)
			{
				// Oops.  This is not an audio data packet
				return(-1);
			}

			// read our mode and pre/post windowsize
			int _mode=opb.read(vd.modebits);
			if(_mode==-1)return(-1);
  
			mode=_mode;
			W=vi.mode_param[mode].blockflag;
			if(W!=0)
			{
				lW=opb.read(1);
				nW=opb.read(1);
				if(nW==-1) return(-1);
			}
			else
			{
				lW=0;
				nW=0;
			}
  
			// more setup
			granulepos=op.granulepos;
			sequence=op.packetno-3; // first block is third packet
			eofflag=op.e_o_s;

			// alloc pcm passback storage
			pcmend=vi.blocksizes[W];
			//pcm=alloc(vi.channels);
			if(pcm.Length<vi.channels)
			{
				pcm=new float[vi.channels][];
			}
			for(int i=0;i<vi.channels;i++)
			{
				if(pcm[i]==null || pcm[i].Length<pcmend)
				{
					pcm[i]=new float[pcmend];
					//pcm[i]=alloc(pcmend);
				}
				else
				{
					for(int j=0;j<pcmend;j++){ pcm[i][j]=0; }
				}
			}

			// unpack_header enforces range checking
			int type=vi.map_type[vi.mode_param[mode].mapping];
			return(FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]));
		}
Esempio n. 5
0
        // uses the local ogg_stream storage in vf; this is important for
        // non-streaming input sources
        int fetch_headers(Info vi, Comment vc, int[] serialno, Page og_ptr)
        {
            //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);
                if(ret==OV_EREAD) { return OV_EREAD; }
                if(ret<0) { return OV_ENOTVORBIS; }
                og_ptr=og;
            }

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

            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) {
                os.pagein(og_ptr);
                while(i<3) {
                    int result=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();
                        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();
                        os.clear();
                        return -1;
                    }
                    i++;
                }
                if(i<3)
                    if(get_next_page(og_ptr, 1)<0) {
                        Console.Error.WriteLine("Missing header in logical bitstream.");
                        //goto bail_header;
                        vi.clear();
                        vc.clear();
                        os.clear();
                        return -1;
                    }
            }
            return 0;
        }
Esempio n. 6
0
        // fetch and process a packet.  Handles the case where we're at a
        // bitstream boundary and dumps the decoding machine.  If the decoding
        // machine is unloaded, it loads it.  It also keeps pcm_offset up to
        // date (seek and read both use this.  seek uses a special hack with
        // readp).
        //
        // return: -1) hole in the data (lost packet)
        //          0) need more date (only if readp==0)/eof
        //          1) got a packet
        int process_packet(int readp)
        {
            Page og=new Page();

            // handle one packet.  Try to fetch it from current stream state
            // extract packets from page
            while(true) {
                // process a packet if we can.  If the machine isn't loaded,
                // neither is a page
                if(decode_ready) {
                    Packet op=new Packet();
                    int result=os.packetout(op);
                    long granulepos;
                    // if(result==-1)return(-1); // hole in the data. For now, swallow
                    // and go. We'll need to add a real
                    // error code in a bit.
                    if(result>0) {
                        // got a packet.  process it
                        granulepos=op.granulepos;
                        if(vb.synthesis(op)==0) {
                            // lazy check for lazy
                            // header handling.  The
                            // header packets aren't
                            // audio, so if/when we
                            // submit them,
                            // vorbis_synthesis will
                            // reject them
                            // suck in the synthesis data and track bitrate
                            {
                                int oldsamples=vd.synthesis_pcmout(null, null);
                                vd.synthesis_blockin(vb);
                                samptrack+=vd.synthesis_pcmout(null, null)-oldsamples;
                                bittrack+=op.bytes*8;
                            }

                            // update the pcm offset.
                            if(granulepos!=-1 && op.e_o_s==0) {
                                int link=(skable?current_link:0);
                                int samples;
                                // this packet has a pcm_offset on it (the last packet
                                // completed on a page carries the offset) After processing
                                // (above), we know the pcm position of the *last* sample
                                // ready to be returned. Find the offset of the *first*
                                //
                                // As an aside, this trick is inaccurate if we begin
                                // reading anew right at the last page; the end-of-stream
                                // granulepos declares the last frame in the stream, and the
                                // last packet of the last page may be a partial frame.
                                // So, we need a previous granulepos from an in-sequence page
                                // to have a reference point.  Thus the !op.e_o_s clause above

                                samples=vd.synthesis_pcmout(null, null);
                                granulepos-=samples;
                                for(int i=0; i<link; i++) {
                                    granulepos+=pcmlengths[i];
                                }
                                pcm_offset=granulepos;
                            }
                            return(1);
                        }
                    }
                }

                if(readp==0) { return(0); }
                if(get_next_page(og,-1)<0) { return(0); } // eof. leave unitialized

                // bitrate tracking; add the header's bytes here, the body bytes
                // are done by packet above
                bittrack+=og.header_len*8;

                // has our decoding just traversed a bitstream boundary?
                if(decode_ready) {
                    if(current_serialno!=og.serialno()) {
                        decode_clear();
                    }
                }

                // Do we need to load a new machine before submitting the page?
                // This is different in the seekable and non-seekable cases.
                //
                // In the seekable case, we already have all the header
                // information loaded and cached; we just initialize the machine
                // with it and continue on our merry way.
                //
                // In the non-seekable (streaming) case, we'll only be at a
                // boundary if we just left the previous logical bitstream and
                // we're now nominally at the header of the next bitstream

                if(!decode_ready) {
                    int i;
                    if(skable) {
                        current_serialno=og.serialno();

                        // match the serialno to bitstream section.  We use this rather than
                        // offset positions to avoid problems near logical bitstream
                        // boundaries
                        for(i=0; i<links; i++) {
                            if(serialnos[i]==current_serialno) { break; }
                        }
                        if(i==links) { return(-1); } // sign of a bogus stream.  error out,
                        // leave machine uninitialized
                        current_link=i;

                        os.init(current_serialno);
                        os.reset();

                    }
                    else {
                        // we're streaming
                        // fetch the three header packets, build the info struct
                        int[] foo = new int[1];
                        int ret=fetch_headers(vi[0], vc[0], foo, og);
                        current_serialno=foo[0];
                        if(ret!=0) { return ret; }
                        current_link++;
                        i=0;
                    }
                    make_decode_ready();
                }
                os.pagein(og);
            }
        }
Esempio n. 7
0
		public int packetout(Packet op)
		{

			/* 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=lacing_returned;

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

			if((lacing_vals[ptr]&0x400)!=0)
			{
				/* We lost sync here; let the app know */
				lacing_returned++;

				/* we need to tell the codec there's a gap; it might need to
					   handle previous packet dependencies. */
				packetno++;
				return(-1);
			}

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

			op.packet_base=body_data;
			op.packet=body_returned;
			op.e_o_s=lacing_vals[ptr]&0x200; /* last packet of the stream? */
			op.b_o_s=lacing_vals[ptr]&0x100; /* first packet of the stream? */
			bytes+=size;

			while(size==255)
			{
				int val=lacing_vals[++ptr];
				size=val&0xff;
				if((val&0x200)!=0)op.e_o_s=0x200;
				bytes+=size;
			}

			op.packetno=packetno;
			op.granulepos=granule_vals[ptr];
			op.bytes=bytes;

			//System.out.println(this+" # body_returned="+body_returned);
			body_returned+=bytes;
			//System.out.println(this+"## body_returned="+body_returned);

			lacing_returned=ptr+1;
		}
			packetno++;
			return(1);
		}
Esempio n. 8
0
		/* submit data to the internal buffer of the framing engine */
		public int packetin(Packet op)
		{
			int lacing_val=op.bytes/255+1;

			if(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 */
    
				body_fill-=body_returned;
				if(body_fill!=0)
				{
					Array.Copy(body_data, body_returned, body_data, 0, body_fill);
				}
				body_returned=0;
			}

			/* make sure we have the buffer storage */
			body_expand(op.bytes);
			lacing_expand(lacing_val);

			/* 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 */

			Array.Copy(op.packet_base, op.packet, body_data, body_fill, op.bytes);
			body_fill+=op.bytes;
			//System.out.println("add: "+body_fill);

			/* Store lacing vals for this packet */
			int j;
			for(j=0;j<lacing_val-1;j++)
			{
				lacing_vals[lacing_fill+j]=255;
				granule_vals[lacing_fill+j]=granulepos;
			}
			lacing_vals[lacing_fill+j]=(op.bytes)%255;
			granulepos=granule_vals[lacing_fill+j]=op.granulepos;

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

			lacing_fill+=lacing_val;

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

			if(op.e_o_s!=0)e_o_s=1;
			return(0);
		}