syncstate.java

来自「java ogg player library. for play back o」· Java 代码 · 共 276 行

JAVA
276
字号
/* JOrbis * Copyright (C) 2000 ymnk, JCraft,Inc. *   * Written by: 2000 ymnk<ymnk@jcraft.com> *    * Many thanks to  *   Monty <monty@xiph.org> and  *   The XIPHOPHORUS Company http://www.xiph.org/ . * JOrbis has been based on their awesome works, Vorbis codec. *    * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version.    * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Library General Public License for more details. *  * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package com.jcraft.jogg;// 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_decode_buffer().  The app either copies into the// buffer, or passes it directly to read(), etc.  We then call// ogg_decode_wrote() to tell how many bytes we just added.//// Pages are returned (pointers into the buffer in ogg_sync_state)// by ogg_decode_stream().  The page is then submitted to// ogg_decode_page() along with the appropriate// ogg_stream_state* (ie, matching serialno).  We then get raw// packets out calling ogg_stream_packet() with a// ogg_stream_state.  See the 'frame-prog.txt' docs for details and// example code.public class SyncState{  public byte[] data;  int storage;  int fill;  int returned;  int unsynced;  int headerbytes;  int bodybytes;  public int clear(){    data=null;    return(0);  }// !!!!!!!!!!!!//  byte[] buffer(int size){  public int buffer(int size){    // first, clear out any space that has been previously returned    if(returned!=0){      fill-=returned;      if(fill>0){	System.arraycopy(data, returned, data, 0, fill);      }      returned=0;    }    if(size>storage-fill){      // We need to extend the internal buffer      int newsize=size+fill+4096; // an extra page to be nice      if(data!=null){	byte[] foo=new byte[newsize];	System.arraycopy(data, 0, foo, 0, data.length);	data=foo;      }      else{	data=new byte[newsize];      }      storage=newsize;    }    // expose a segment at least as large as requested at the fill mark//    return((char *)oy->data+oy->fill);//    return(data);    return(fill);  }  public int wrote(int bytes){    if(fill+bytes>storage)return(-1);    fill+=bytes;    return(0);  }// sync the stream.  This is meant to be useful for finding page// boundaries.//// return values for this:// -n) skipped n bytes//  0) page not ready; more data (no bytes skipped)//  n) page synced at current location; page length n bytes  private Page pageseek=new Page();  private  byte[] chksum=new byte[4];  public int pageseek(Page og){    int page=returned;    int next;    int bytes=fill-returned;      if(headerbytes==0){      int _headerbytes,i;      if(bytes<27)return(0); // not enough for a header        /* verify capture pattern *///!!!!!!!!!!!      if(data[page]!='O' ||	 data[page+1]!='g' ||	 data[page+2]!='g' ||	 data[page+3]!='S'){        headerbytes=0;        bodybytes=0;          // search for possible capture        next=0;        for(int ii=0; ii<bytes-1; ii++){          if(data[page+1+ii]=='O'){next=page+1+ii; break;}        }    //next=memchr(page+1,'O',bytes-1);        if(next==0) next=fill;        returned=next;        return(-(next-page));      }      _headerbytes=(data[page+26]&0xff)+27;      if(bytes<_headerbytes)return(0); // not enough for header + seg table          // count up body length in the segment table          for(i=0;i<(data[page+26]&0xff);i++){        bodybytes+=(data[page+27+i]&0xff);      }      headerbytes=_headerbytes;    }      if(bodybytes+headerbytes>bytes)return(0);      // The whole test page is buffered.  Verify the checksum    synchronized(chksum){      // Grab the checksum bytes, set the header field to zero          System.arraycopy(data, page+22, chksum, 0, 4);      data[page+22]=0;      data[page+23]=0;      data[page+24]=0;      data[page+25]=0;          // set up a temp page struct and recompute the checksum      Page log=pageseek;      log.header_base=data;      log.header=page;      log.header_len=headerbytes;      log.body_base=data;      log.body=page+headerbytes;      log.body_len=bodybytes;      log.checksum();      // Compare      if(chksum[0]!=data[page+22] ||         chksum[1]!=data[page+23] ||         chksum[2]!=data[page+24] ||         chksum[3]!=data[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        System.arraycopy(chksum, 0, data, page+22, 4);        // Bad checksum. Lose sync */        headerbytes=0;        bodybytes=0;        // search for possible capture        next=0;        for(int ii=0; ii<bytes-1; ii++){          if(data[page+1+ii]=='O'){next=page+1+ii; break;}        }        //next=memchr(page+1,'O',bytes-1);        if(next==0) next=fill;        returned=next;        return(-(next-page));      }    }      // yes, have a whole page all ready to go    {      page=returned;      if(og!=null){        og.header_base=data;        og.header=page;        og.header_len=headerbytes;	og.body_base=data;        og.body=page+headerbytes;        og.body_len=bodybytes;      }      unsynced=0;      returned+=(bytes=headerbytes+bodybytes);      headerbytes=0;      bodybytes=0;      return(bytes);    }//  headerbytes=0;//  bodybytes=0;//  next=0;//  for(int ii=0; ii<bytes-1; ii++){//    if(data[page+1+ii]=='O'){next=page+1+ii;}//  }//  //next=memchr(page+1,'O',bytes-1);//  if(next==0) next=fill;//  returned=next;//  return(-(next-page));  }// sync the stream and get a page.  Keep trying until we find a page.// Supress '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  public int pageout(Page og){    // 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    while(true){      int ret=pageseek(og);      if(ret>0){        // have a page        return(1);      }      if(ret==0){        // need more data        return(0);      }          // head did not start a synced page... skipped some bytes      if(unsynced==0){        unsynced=1;        return(-1);      }      // loop. keep looking    }  }// clear things to an initial state.  Good to call, eg, before seeking  public int reset(){    fill=0;    returned=0;    unsynced=0;    headerbytes=0;    bodybytes=0;    return(0);  }  public void init(){}  public int getDataOffset(){ return returned; }      public int getBufferOffset(){ return fill;  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?