FileDocCategorySizeDatePackage
JavaDecoder.javaAPI DocJMF 2.1.1e9970Mon May 12 12:20:46 BST 2003com.sun.media.codec.audio.mpa

JavaDecoder

public class JavaDecoder extends AudioCodec
Class declaration
author
Liang He
version
1.8, 08/21/02

Fields Summary
private int
pendingDataSize
private static final int
OUTSIZE
private byte[]
pendingData
private Decoder
decoder
private FrameInfo
info
private boolean
expectingSameInputBuffer
private long
accumTS
private AudioFormat
aFormat
float[]
fsamp
int[]
fsampOffset
int
MAXOUTFRAMESIZE
int
MIMINFRAMESIZE
int
outFrameSize
Constructors Summary
public JavaDecoder()
Constructor declaration

see


            
      
	inputFormats = new Format[] {

/**
 -ivg
 Disable MP3 decoding for now.
 
	    new AudioFormat(AudioFormat.MPEGLAYER3,
			    16000., 
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEGLAYER3, 
			    22050.,
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEGLAYER3, 
			    24000.,
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEGLAYER3, 
			    32000.,
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEGLAYER3, 
			    44100.,
 			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEGLAYER3, 
			    48000.,
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
 */

	    new AudioFormat(AudioFormat.MPEG,
			    16000., 
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEG,
			    22050., 
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEG,
			    24000., 
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEG,
			    32000., 
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEG,
			    44100., 
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED),
	    new AudioFormat(AudioFormat.MPEG,
			    48000., 
			    Format.NOT_SPECIFIED,
			    Format.NOT_SPECIFIED, 
			    Format.NOT_SPECIFIED,    // endian
			    AudioFormat.SIGNED), 
	};
    
Methods Summary
public synchronized voidclose()
Method declaration

see

	if (decoder != null) {
	    decoder = null;
	} 
	if (info != null) {
	    info = null;
	} 
    
public java.lang.StringgetName()
Method declaration

return
see

	return "MPEG Layer 3 Decoder";
    
public javax.media.Format[]getSupportedOutputFormats(javax.media.Format input)
Method declaration

param
input
return
see

	if (input == null) {
	    return new Format[] {
		new AudioFormat(AudioFormat.LINEAR)
	    };
	} else if (input instanceof AudioFormat) {
	    AudioFormat af = (AudioFormat) input;
	    outputFormats = new Format[] {
		new AudioFormat(AudioFormat.LINEAR,
				af.getSampleRate(), 
				af.getSampleSizeInBits(),
				af.getChannels(),
				AudioFormat.BIG_ENDIAN,
				/*Arch.isBigEndian()
				? AudioFormat.BIG_ENDIAN 
				: AudioFormat.LITTLE_ENDIAN, */
				AudioFormat.SIGNED)
	    };
	} else {
	    outputFormats = new Format[0];
	}
	return outputFormats;
    
public synchronized voidopen()
Method declaration

throws
ResourceUnavailableException
see

	if (decoder != null) {
	    close();
	} 

	try {
	    decoder = new codecLib.mpa.Decoder();
	    pendingDataSize = 0;
	    expectingSameInputBuffer = false;
	    accumTS = 0;
	    aFormat = (AudioFormat)outputFormat;
	    // System.err.println("Input format is " + inputFormat);
	    // System.err.println("Output format is " + outputFormat);
	    return;
	} catch (Throwable e) {
	    System.out.println("mpa JavaDecoder: open " + e);
	} 

	throw new ResourceUnavailableException("could not open " + getName());
    
public synchronized intprocess(javax.media.Buffer in, javax.media.Buffer out)
Method declaration

param
in
param
out
return
see


                 
           
	if (isEOM(in)) {
	    propagateEOM(out);
	    return BUFFER_PROCESSED_OK;
	} 

	Object inObject = in.getData();
	Object outObject = out.getData();

	if (outObject == null) {
	    outObject = new byte[OUTSIZE];
	    out.setData(outObject);
	} 

	if (!(inObject instanceof byte[]) ||
	    !(outObject instanceof byte[])) {
	    return BUFFER_PROCESSED_FAILED;
	} 

	byte[] inData = (byte[])inObject;
	byte[] outData = (byte[])outObject;
	int    inLength = in.getLength();
	int    inOffset = in.getOffset();
	int    outDataSize = outData.length;
	int    outOffset = 0;
	int    pendingDataOffset = 0;
	int    byteCount = 0;

	if (!expectingSameInputBuffer) {
	    if ((pendingDataSize + inLength) <= pendingData.length) {
		System.arraycopy(inData, inOffset,
				 pendingData, pendingDataSize, 
				 inLength);
		pendingDataSize += inLength;
	    }
	} 

	if (decoder != null) {
	    while (true) {

		// Does the output buffer have enough space left?
		if ((outDataSize - outOffset) < MAXOUTFRAMESIZE) {
		    break;
		} 

		// Does the input buffer have enough data?
		if (pendingDataSize < MIMINFRAMESIZE) {
		    break;
		} 

		if (info == null) {
		    info = new codecLib.mpa.FrameInfo();
		    try {
			decoder.getNextFrameInfo(info,
						 pendingData, 
						 pendingDataOffset, 
						 pendingDataSize);
			outFrameSize = info.getNumberOfSamples()
				     * info.getNumberOfChannels()
				     * 2;
		    } catch (codecLib.mpa.MPADException e) {
		        //System.out.println("mpa JavaDecoder: getNextFrameInfo " + e);
			info = null;
			break;
		    } 
		}

		try {
		    byteCount = decoder.decode(fsamp, fsampOffset, 
					       pendingData, 
					       pendingDataOffset, 
					       pendingDataSize);
		} catch (codecLib.mpa.MPADException e) {

		    if (e.getState() == codecLib.mpa.Constants.ERR_NOSUPPORT)
			return BUFFER_PROCESSED_FAILED;

		    try {
			decoder.getCurrFrameInfo(info);
		    } catch (codecLib.mpa.MPADException e2) {
			//System.out.println("mpa JavaDecoder: getCurrFrameInfo " + e2);
			info = null;
			break;
		    }

		    if (e.getState() == codecLib.mpa.Constants.ERR_NOPREV) { 
			byteCount = info.getHeaderOffset() + info.getFrameLength();
			pendingDataOffset += byteCount;
			pendingDataSize -= byteCount;
			continue;
		    }

		    //System.out.println("mpa JavaDecoder: decode " + e);
		    info = null;
		    break;
		} 

		if (info.getNumberOfChannels() == 1) {
		    codecLib.mpa.OutputConverter.convert(outData, outOffset, 
							 fsamp[0], fsampOffset[0], 
							 info.getNumberOfSamples());
		} else {
		    codecLib.mpa.OutputConverter.convert(outData, outOffset,
							 fsamp[0], fsampOffset[0],
							 fsamp[1], fsampOffset[1],
							 info.getNumberOfSamples());
		} 

		outOffset += outFrameSize;
		pendingDataOffset += byteCount;
		pendingDataSize -= byteCount;
	    } 
	} 

	// Move the last chunk to the beginning of the pendingData buffer
	if (pendingDataOffset != 0) {
	    System.arraycopy(pendingData, pendingDataOffset,
			     pendingData, 0, 
			     pendingDataSize);
	} 

	out.setLength(outOffset);
	out.setFormat(outputFormat);
	if (aFormat != null && accumTS != 0 && in.getTimeStamp() > 0)
	    out.setTimeStamp(in.getTimeStamp() + aFormat.computeDuration(accumTS));


	if (pendingDataSize > 1024) {
	    expectingSameInputBuffer = true;
	    accumTS += out.getLength();
	    return BUFFER_PROCESSED_OK | INPUT_BUFFER_NOT_CONSUMED;
	} else {
	    accumTS = 0;
	    expectingSameInputBuffer = false;
	    return BUFFER_PROCESSED_OK;
	} 
    
public synchronized voidreset()
Method declaration

see

	if (decoder != null) {
	    close();

	    try {
		open();
	    } catch (ResourceUnavailableException rue) {
		System.err.println("MP3 Decoder: " + rue);
	    } 
	}