com.jcraft.jogg.StreamState Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jorbis Show documentation
Show all versions of jorbis Show documentation
Maven artifact for JOrbis library. http://www.jcraft.com/jorbis/
The newest version!
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* JOrbis
* Copyright (C) 2000 ymnk, JCraft,Inc.
*
* Written by: 2000 ymnk
*
* Many thanks to
* Monty 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;
public class StreamState{
byte[] body_data; /* bytes from packet bodies */
int body_storage; /* storage elements allocated */
int body_fill; /* elements stored; fill mark */
private int body_returned; /* elements of fill returned */
int[] lacing_vals; /* The values that will go to the segment table */
long[] granule_vals; /* pcm_pos values for headers. Not compact
this way, but it is simple coupled to the
lacing fifo */
int lacing_storage;
int lacing_fill;
int lacing_packet;
int lacing_returned;
byte[] header=new byte[282]; /* working space for header encode */
int header_fill;
public int e_o_s; /* set when we have buffered the last packet in the
logical bitstream */
int b_o_s; /* set after we've written the initial page
of a logical bitstream */
int serialno;
int pageno;
long packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a seperate abstraction
layer) also knows about the gap */
long granulepos;
public StreamState(){
init();
}
StreamState(int serialno){
this();
init(serialno);
}
void init(){
body_storage=16*1024;
body_data=new byte[body_storage];
lacing_storage=1024;
lacing_vals=new int[lacing_storage];
granule_vals=new long[lacing_storage];
}
public void init(int serialno){
if(body_data==null){
init();
}
else{
for(int i=0; i0)
return (-1);
lacing_expand(segments+1);
// are we in sequence?
if(_pageno!=pageno){
int i;
// unroll previous partial packet (if any)
for(i=lacing_packet; i0)
lacing_vals[lacing_fill-1]|=0x200;
}
pageno=_pageno+1;
return (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 gurantee that all packets have flushed.
Only a return value of 0 from ogg_stream_flush indicates all packet
data is flushed into pages.
ogg_stream_page 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 need to flush an undersized
page in the middle of a stream for some reason. */
public int flush(Page og){
int i;
int vals=0;
int maxvals=(lacing_fill>255 ? 255 : lacing_fill);
int bytes=0;
int acc=0;
long granule_pos=granule_vals[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(b_o_s==0){ /* 'initial header page' case */
granule_pos=0;
for(vals=0; vals4096)
break;
acc+=(lacing_vals[vals]&0x0ff);
granule_pos=granule_vals[vals];
}
}
/* construct the header in temp storage */
System.arraycopy("OggS".getBytes(), 0, header, 0, 4);
/* stream structure version */
header[4]=0x00;
/* continued packet flag? */
header[5]=0x00;
if((lacing_vals[0]&0x100)==0)
header[5]|=0x01;
/* first page flag? */
if(b_o_s==0)
header[5]|=0x02;
/* last page flag? */
if(e_o_s!=0&&lacing_fill==vals)
header[5]|=0x04;
b_o_s=1;
/* 64 bits of PCM position */
for(i=6; i<14; i++){
header[i]=(byte)granule_pos;
granule_pos>>>=8;
}
/* 32 bits of stream serial number */
{
int _serialno=serialno;
for(i=14; i<18; i++){
header[i]=(byte)_serialno;
_serialno>>>=8;
}
}
/* 32 bits of page counter (we have both counter and page header
because this val can roll over) */
if(pageno==-1)
pageno=0; /* because someone called
stream_reset; this would be a
strange thing to do in an
encode stream, but it has
plausible uses */
{
int _pageno=pageno++;
for(i=18; i<22; i++){
header[i]=(byte)_pageno;
_pageno>>>=8;
}
}
/* zero for computation; filled in later */
header[22]=0;
header[23]=0;
header[24]=0;
header[25]=0;
/* segment table */
header[26]=(byte)vals;
for(i=0; i4096|| /* 'page nominal size' case */
lacing_fill>=255|| /* 'segment table full' case */
(lacing_fill!=0&&b_o_s==0)){ /* 'initial header page' case */
return flush(og);
}
return 0;
}
public int eof(){
return e_o_s;
}
public int reset(){
body_fill=0;
body_returned=0;
lacing_fill=0;
lacing_packet=0;
lacing_returned=0;
header_fill=0;
e_o_s=0;
b_o_s=0;
pageno=-1;
packetno=0;
granulepos=0;
return (0);
}
}