FileDocCategorySizeDatePackage
CodecChain.javaAPI DocJMF 2.1.1e6165Mon May 12 12:20:46 BST 2003com.sun.media.util

CodecChain

public class CodecChain extends Object

Fields Summary
static final int
STAGES
protected Codec[]
codecs
protected Buffer[]
buffers
protected Format[]
formats
protected Renderer
renderer
private boolean
deallocated
protected boolean
firstBuffer
private boolean
rtpFormat
Constructors Summary
Methods Summary
protected booleanbuildChain(javax.media.Format input)


	Vector pluginList;
	Vector formatList = new Vector(10);

	if ((pluginList = SimpleGraphBuilder.findRenderingChain(input, formatList)) == null)
	    return false;

	int len = pluginList.size();
	codecs = new Codec[len-1];
	buffers = new ExtBuffer[len-1];
    	formats = new Format[len];

	formats[0] = input;

	Log.comment("Monitor codec chain:");

	for (int j = 0; j < codecs.length; j++) {
	    codecs[j] = (Codec) pluginList.elementAt(len-j-1);
	    // Output format for each codec.
	    formats[j+1] = (Format) formatList.elementAt(len-j-2);
	    buffers[j] = new ExtBuffer();
	    buffers[j].setFormat(formats[j+1]);
	    Log.write("    codec: " + codecs[j]);
	    Log.write("      format: " + formats[j]);
	}

	renderer = (Renderer)pluginList.elementAt(0);

	Log.write("    renderer: " + renderer);
	Log.write("      format: " + formats[codecs.length] + "\n");

	if (input.getEncoding() != null) {
	    String enc = input.getEncoding().toUpperCase();
	    if (enc.endsWith("RTP"))
		rtpFormat = true;
	}

	return true;
    
public voidclose()

	for (int i = 0; i < codecs.length; i++) {
	    codecs[i].close();
	}
	if (renderer != null)
	    renderer.close();
    
public voiddeallocate()

	if (deallocated)
	    return;
	if (renderer != null)
	    renderer.close();
	deallocated = true;
    
private intdoProcess(int codecNo, javax.media.Buffer input, boolean render)


	Format format = input.getFormat();
	if (codecNo == codecs.length) {
	    // end of chain, render if necessary
	    if (render) {

		// Check for mid-stream format change.
		if (renderer != null &&
		    formats[codecNo] != null && 
		    formats[codecNo] != format && 
		    !formats[codecNo].equals(format) &&
		    !input.isDiscard()) {
		    // Input format changed.
		    if (renderer.setInputFormat(format) == null) {
			// Format change failed.
			Log.error("Monitor failed to handle mid-stream format change:");
			Log.error("  old: " + formats[codecNo]);
			Log.error("  new: " + format);
			return PlugIn.BUFFER_PROCESSED_FAILED;
		    }

		    // Format change handled successfully.
		    formats[codecNo] = format;
		}

		try {
		    return renderer.process(input);
		} catch (Exception e) {
		    Log.dumpStack(e);
		    return PlugIn.BUFFER_PROCESSED_FAILED;
		} catch (Error err) {
		    Log.dumpStack(err);
		    return PlugIn.BUFFER_PROCESSED_FAILED;
		}
		
	    } else
		return PlugIn.BUFFER_PROCESSED_OK;
	} else {
	    // If raw format, no need to decode just to keep state
	    if (isRawFormat(format)) {
		if (!render) {
		    return PlugIn.BUFFER_PROCESSED_OK;
		}
	    } else {
		// We need to assume these buffers might have Key/NonKey frames
		if (!rtpFormat && firstBuffer) {
		    if ((input.getFlags() & Buffer.FLAG_KEY_FRAME) == 0) {
			return PlugIn.BUFFER_PROCESSED_OK;
		    }
		    firstBuffer = false;
		}
	    }

	    // Decode to render or atleast to keep state
	    // Process this codec
	    Codec codec = codecs[codecNo];
	    int returnVal;

	    // Check for mid-stream format change.
	    if (codec != null &&
		formats[codecNo] != null && 
		formats[codecNo] != format && 
		!formats[codecNo].equals(format) &&
		!input.isDiscard()) {
		// Input format changed.
		if (codec.setInputFormat(format) == null) {
		    // Format change failed.
		    Log.error("Monitor failed to handle mid-stream format change:");
		    Log.error("  old: " + formats[codecNo]);
		    Log.error("  new: " + format);
		    return PlugIn.BUFFER_PROCESSED_FAILED;
		}

		// Format change handled successfully.
		formats[codecNo] = format;
	    }

	    do {
		//System.err.println("format = " + input.getFormat());

		try {
		    returnVal = codec.process(input, buffers[codecNo]);
		} catch (Exception e) {
		    Log.dumpStack(e);
		    return PlugIn.BUFFER_PROCESSED_FAILED;
		} catch (Error err) {
		    Log.dumpStack(err);
		    return PlugIn.BUFFER_PROCESSED_FAILED;
		}
		
		//System.err.println("codecNo: " + codecNo + " return val = " + returnVal);
		if (returnVal == PlugIn.BUFFER_PROCESSED_FAILED)
		    return PlugIn.BUFFER_PROCESSED_FAILED;
		if ((returnVal & PlugIn.OUTPUT_BUFFER_NOT_FILLED) == 0) {
		    //System.err.println("Calling process");
		    if (!(buffers[codecNo].isDiscard() || buffers[codecNo].isEOM()))
			doProcess(codecNo + 1, buffers[codecNo], render);
		    buffers[codecNo].setOffset(0);
		    buffers[codecNo].setLength(0);
		    buffers[codecNo].setFlags(0);
		}
	    } while ((returnVal & PlugIn.INPUT_BUFFER_NOT_CONSUMED) != 0);

	    return returnVal;
	}
    
public java.awt.ComponentgetControlComponent()

	return null;
    
booleanisRawFormat(javax.media.Format format)


       
	return false;
    
public booleanprefetch()

	if (!deallocated)
	    return true;
        try {
	    renderer.open();
	} catch (ResourceUnavailableException e) { 
	    return false;
	}
	renderer.start();
	deallocated = false;
	return true;
    
public intprocess(javax.media.Buffer buffer, boolean render)

	int codecNo = 0;
	return doProcess(codecNo, buffer, render);
    
public voidreset()

	firstBuffer = true;
	for (int i = 0; i < codecs.length; i++) {
	    if (codecs[i] != null)
		codecs[i].reset();
	}