/*
* @(#)BufferedEncoder.java 1.6 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.ibm.media.codec.audio;
import javax.media.format.*;
import javax.media.format.*;
import javax.media.*;
import com.sun.media.*;
public abstract class BufferedEncoder extends AudioCodec {
//actual read and write bytes by the native code
protected int[] readBytes=new int[1];
protected int[] writeBytes=new int[1];
protected int[] frameNumber=new int[1];
protected Buffer history = new Buffer();
protected int[] regions;
protected int[] regionsTypes;
protected int pendingFrames;
protected int packetSize=-1;
public int getPacketSize() {
return packetSize;
}
public int setPacketSize(int newPacketSize) {
//sbd: add packet validity here
packetSize=newPacketSize;
return packetSize;
}
public void reset() {
history.setLength(0);
codecReset();
}
protected abstract void codecReset();
protected int historySize;
public int process(Buffer inputBuffer, Buffer outputBuffer) {
if (pendingFrames>0) {
//System.out.println("packetizing");
return BUFFER_PROCESSED_OK;
}
if (!checkInputBuffer(inputBuffer) ) {
return BUFFER_PROCESSED_FAILED;
}
if (isEOM(inputBuffer) ) {
propagateEOM(outputBuffer);
return BUFFER_PROCESSED_OK;
}
int inpOffset=inputBuffer.getOffset();
int inpLength=inputBuffer.getLength();
int outLength = 0;
int outOffset = 0;
byte[] inpData = (byte[]) inputBuffer.getData();
byte[] outData = validateByteArraySize(outputBuffer, calculateOutputSize(inpData.length + historySize) );
int historyLength = history.getLength();
byte[] historyData = validateByteArraySize(history, historySize);
int framesNumber= calculateFramesNumber(inpData.length + historySize);
if ( (regions == null) || (regions.length < framesNumber+1) )
regions = new int[framesNumber + 1];
if ( (regionsTypes == null) || (regionsTypes.length < framesNumber) )
regionsTypes = new int[framesNumber];
if (historyLength != 0) {
int bytesToCopy = (historyData.length - historyLength);
if (bytesToCopy > inpLength) {
bytesToCopy = inpLength;
}
System.arraycopy(inpData, inpOffset,
historyData,historyLength,
bytesToCopy);
codecProcess(historyData, 0,
outData, outOffset,
historyLength + bytesToCopy ,
readBytes, writeBytes, frameNumber, regions, regionsTypes);
if (readBytes[0] <= 0) {
if (writeBytes[0] <= 0) {
//System.err.println("Returning output buffer not filled");
return OUTPUT_BUFFER_NOT_FILLED;
} else {
updateOutput(outputBuffer, outputFormat, writeBytes[0], 0);
//System.err.println("Returning OK");
return BUFFER_PROCESSED_OK;
}
}
//System.out.println("1: "+inpLength+" "+readBytes[0]+" "+writeBytes[0]);
outOffset += writeBytes[0];
outLength += writeBytes[0];
inpOffset += (readBytes[0]-historyLength);
inpLength += (historyLength-readBytes[0]);
}
codecProcess(inpData,inpOffset, outData,outOffset,inpLength,readBytes,writeBytes,frameNumber,regions, regionsTypes);
//System.out.println("2: "+inpLength+" "+readBytes[0]+" "+writeBytes[0]);
// debug
//for (int i=0; i<frameNumber[0];i++ ) {
// System.out.println(i+" "+regions[i]+" - "+regions[i+1]+" type "+regionsTypes[i]);
//}
outLength += writeBytes[0];
inpOffset += readBytes[0];
inpLength -= readBytes[0];
System.arraycopy (inpData,inpOffset,historyData,0,inpLength);
history.setLength(inpLength);
updateOutput(outputBuffer, outputFormat, outLength, 0);
return BUFFER_PROCESSED_OK;
}
protected abstract int calculateOutputSize(int inputSize);
protected abstract int calculateFramesNumber(int inputSize);
protected abstract boolean codecProcess(byte[] inpData,int readPtr,
byte[] outData,int writePtr,
int inpLength,
int[] readBytes,int[] writeBytes,
int[] frameNumber,
int[] regions,int[] regiostypes);
}
|