FileDocCategorySizeDatePackage
NativeDecoder.javaAPI DocJMF 2.1.1e11135Mon May 12 12:20:46 BST 2003com.sun.media.codec.video.jpeg

NativeDecoder

public final class NativeDecoder extends BasicCodec

Fields Summary
private VideoFormat
inputFormat
private RGBFormat
outputFormat
private static boolean
loaded
private static boolean
canLoad
private int
peer
int
returnVal
private boolean
dropFrame
private boolean
minimal
private int
decimation
Constructors Summary
public NativeDecoder()
Codec Methods


           

    // Initialize default formats.
      
	inputFormats = new VideoFormat[2];
	inputFormats[0] = new VideoFormat(VideoFormat.JPEG);
	inputFormats[1] = new VideoFormat(VideoFormat.MJPG);
	outputFormats = new RGBFormat[1];
	outputFormats[0] = new RGBFormat();

	FrameProcessingControl fpc = new FrameProcessingControl() {
	    public boolean setMinimalProcessing(boolean newMinimal) {
		minimal = newMinimal;
		return minimal;
	    }

	    public void setFramesBehind(float frames) {
		if (frames >= 1)
		    dropFrame = true;
		else
		    dropFrame = false;
	    }

	    public Component getControlComponent() {
		return null;
	    }

            public int getFramesDropped() {
                return 0;       ///XXX not implemented
            }

	};

	controls = new Control[1];
	controls[0] = fpc;
    
Methods Summary
public synchronized voidclose()

	if (peer != 0)
	    freeJPEGDecoder(peer);
	peer = 0;
	super.close();
    
private final VideoFormat[]computeOutputFormats(javax.media.Format in)

	// Calculate the properties
	VideoFormat jpeg = (VideoFormat) in;
	Dimension size = jpeg.getSize();
	if (size == null)
	    size = new Dimension(320, 240);
	int area = ((size.width + 7) & ~7) * ((size.height + 7) & ~7);
	RGBFormat [] rgb = new RGBFormat[] {
	    new RGBFormat(size,
			  area * 3,
			  Format.byteArray,
			  jpeg.getFrameRate(),
			  24,
			  1, 2, 3,
			  3, size.width * 3,
			  RGBFormat.TRUE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area * 3,
			  Format.byteArray,
			  jpeg.getFrameRate(),
			  24,
			  3, 2, 1,
			  3, size.width * 3,
			  RGBFormat.TRUE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area,
			  Format.intArray,
			  jpeg.getFrameRate(),
			  32,
			  0xFF0000, 0xFF00, 0xFF,
			  1, size.width,
			  RGBFormat.TRUE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area,
			  Format.intArray,
			  jpeg.getFrameRate(),
			  32,
			  0xFF, 0xFF00, 0xFF0000,
			  1, size.width,
			  RGBFormat.TRUE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area * 3,
			  Format.byteArray,
			  jpeg.getFrameRate(),
			  24,
			  1, 2, 3,
			  3, size.width * 3,
			  RGBFormat.FALSE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area * 3,
			  Format.byteArray,
			  jpeg.getFrameRate(),
			  24,
			  3, 2, 1,
			  3, size.width * 3,
			  RGBFormat.FALSE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area,
			  Format.intArray,
			  jpeg.getFrameRate(),
			  32,
			  0xFF0000, 0xFF00, 0xFF,
			  1, size.width,
			  RGBFormat.FALSE,
			  Format.NOT_SPECIFIED),
	    new RGBFormat(size,
			  area,
			  Format.intArray,
			  jpeg.getFrameRate(),
			  32,
			  0xFF, 0xFF00, 0xFF0000,
			  1, size.width,
			  RGBFormat.FALSE,
			  Format.NOT_SPECIFIED)
	};
	return rgb;
    
private native intdecodeJPEGToByte(int peer, byte[] inData, int inLength, int width, int height, byte[] outData, int outLength, boolean flipped, int red, int green, int blue, int bitsPerPixel)

private native intdecodeJPEGToInt(int peer, byte[] inData, int inLength, int width, int height, int[] outData, int outLength, boolean flipped, int red, int green, int blue, int bitsPerPixel)

private native intdecodeJPEGToNBA(int peer, byte[] inData, int inLength, int width, int height, long outData, int outLength, boolean flipped, int red, int green, int blue, int bitsPerPixel)

protected voidfinalize()

	close();
    
private native booleanfreeJPEGDecoder(int peer)

protected javax.media.FormatgetInputFormat()

	return inputFormat;
    
public java.lang.StringgetName()

	return "JPEG Decoder";
    
protected javax.media.FormatgetOutputFormat()

	return outputFormat;
    
public javax.media.Format[]getSupportedOutputFormats(javax.media.Format in)

	if (in == null)
	    return outputFormats;

	// Make sure the input is RGB video format
	if (!verifyInputFormat(in))
	    return new Format[0];

	return computeOutputFormats(in);
    
private native intinitJPEGDecoder(int width, int height)
Native Methods

public voidopen()

	if (!canLoad)
	    throw new ResourceUnavailableException("Unable to load" +
						   " native JPEG converter");

	if (!loaded) {
	    try {
		JMFSecurityManager.loadLibrary( "jmutil");
		JMFSecurityManager.loadLibrary( "jmjpeg");
		loaded = true;
	    } catch (Throwable t) {
		canLoad = false;
		throw new ResourceUnavailableException("Unable to load " +
						       "native JPEG decoder");
	    }
	}

	if (inputFormat == null || outputFormat == null)
	    throw new ResourceUnavailableException("Formats not set " +
						   "on the JPEG decoder");

	if (peer != 0)
	    close();

	Dimension size = inputFormat.getSize();
	
	try {
	    peer = initJPEGDecoder(size.width, size.height);
	} catch (Throwable t) {
	}
	
	if (inputFormat instanceof JPEGFormat) {
	    decimation = ((JPEGFormat)inputFormat).getDecimation();
	}
	
	if (peer == 0)
	    throw new ResourceUnavailableException("Unable to initialize JPEG decoder");
	super.open();
    
public synchronized intprocess(Buffer inBuffer, Buffer outBuffer)

	Object header = null;
	Format inFormat;
	Format outFormat = null;
	byte [] inData;
	boolean flipped;

	// EndOfMedia?
	if (isEOM(inBuffer)) {
	    propagateEOM(outBuffer);
	    return BUFFER_PROCESSED_OK;
	}

	// Dropping frames?
	if (minimal || dropFrame) {
	    outBuffer.setFlags(outBuffer.getFlags() | Buffer.FLAG_DISCARD);
	    return BUFFER_PROCESSED_OK;
	}
	
	inFormat = inBuffer.getFormat();
	inData = (byte[]) inBuffer.getData();

	if (inBuffer.getLength() < 1)
	    return BUFFER_PROCESSED_OK;

	if (!inFormat.equals(inputFormat)) {
	    setInputFormat(inFormat);
	    close();
	}

	if (outFormat == null) {
	    outBuffer.setFormat(outputFormat);
	    outFormat = outputFormat;
	}

	Object outData = validateData(outBuffer, 0, true);

	flipped = ((RGBFormat)outFormat).getFlipped() == RGBFormat.TRUE;
	if (peer == 0) {
	    try {
		open();
	    } catch (ResourceUnavailableException re) {
		return BUFFER_PROCESSED_FAILED;
	    }
	}

	Dimension size = inputFormat.getSize();
	synchronized (NativeEncoder.processLock) {
	    if (outData instanceof byte[]) {
		returnVal =
		    decodeJPEGToByte(peer,
				     inData,
				     inBuffer.getLength(),
				     size.width,
				     size.height,
				     (byte[]) outData,
				     outputFormat.getMaxDataLength(),
				     flipped,
				     outputFormat.getRedMask(),
				     outputFormat.getGreenMask(),
				     outputFormat.getBlueMask(),
				     outputFormat.getBitsPerPixel());
		
		outBuffer.setLength(size.width * size.height *
				    outputFormat.getBitsPerPixel() / 8);
	    } else if (outData instanceof int[]) {
		returnVal =
		    decodeJPEGToInt(peer,
				    inData,
				    inBuffer.getLength(),
				    size.width,
				    size.height,
				    (int[]) outData,
				    outputFormat.getMaxDataLength(),
				    flipped,
				    outputFormat.getRedMask(),
				    outputFormat.getGreenMask(),
				    outputFormat.getBlueMask(),
				    outputFormat.getBitsPerPixel());
		outBuffer.setLength(size.width * size.height);
	    } else if (outData instanceof NBA) {
		NBA nba = (NBA) outData;
		returnVal =
		    decodeJPEGToNBA(peer,
				    inData,
				    inBuffer.getLength(),
				    size.width,
				    size.height,
				    nba.getNativeData(),
				    outputFormat.getMaxDataLength(),
				    flipped,
				    outputFormat.getRedMask(),
				    outputFormat.getGreenMask(),
				    outputFormat.getBlueMask(),
				    outputFormat.getBitsPerPixel());
		outBuffer.setLength(size.width * size.height);
		if (outputFormat.getDataType() == Format.byteArray)
		    outBuffer.setLength(outBuffer.getLength() *
					outputFormat.getBitsPerPixel() / 8);
	    }
	}
	if (returnVal > 0) {
	    outBuffer.setOffset(0);
	    inBuffer.setLength(0);
	    outBuffer.setFlags(outBuffer.getFlags() | Buffer.FLAG_KEY_FRAME);
	    outBuffer.setTimeStamp(inBuffer.getTimeStamp());
	    return BUFFER_PROCESSED_OK;
	}
	outBuffer.setDiscard(true);
	return BUFFER_PROCESSED_FAILED;
    
public voidreset()

	// Anything to do?
    
public javax.media.FormatsetInputFormat(javax.media.Format input)

	if (!verifyInputFormat(input))
	    return null;
	inputFormat = (VideoFormat) input;
	if (opened) {
	    close();
	    outputFormat = updateRGBFormat(inputFormat, outputFormat);
	}
	return input;
    
public javax.media.FormatsetOutputFormat(javax.media.Format output)

	if (matches(output, outputFormats) == null){
	    return null;
	}
	outputFormat = (RGBFormat) output;
	return output;
    
private booleanverifyInputFormat(javax.media.Format input)

	if (!(input instanceof VideoFormat))
	    return false;
	if (input.getEncoding().equalsIgnoreCase(VideoFormat.JPEG) ||
	    input.getEncoding().equalsIgnoreCase(VideoFormat.MJPG) )
	    return true;
	return false;