/*
* @(#)NativeDecoder.java 1.22 03/04/24
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.media.codec.video.cinepak;
import javax.media.*;
import javax.media.format.*;
import javax.media.format.*;
import com.sun.media.*;
import com.ibm.media.codec.video.*;
import java.awt.Dimension;
import com.sun.media.util.Arch;
public final class NativeDecoder extends VideoCodec {
static {
JMFSecurityManager.loadLibrary("jmutil");
JMFSecurityManager.loadLibrary("jmcvid");
}
////////////////////////////////////////////////////////////////////////////
// Constants
// RGB bit masks
private int rMask = 0x000000ff;
private int gMask = 0x0000ff00;
private int bMask = 0x00ff0000;
private NBA refData;
private native boolean initNative(int bitsPerPixel,
int rMask, int gMask, int bMask);
private native boolean freeNative();
private native boolean decodeNative(int bytesPerPixel,
Object inData, long outDataBytes,
Object outCopy, long outCopyBytes,
int outMaxLength);
////////////////////////////////////////////////////////////////////////////
// Variables
/** reference to the native data structure **/
private int nativeData;
/** reference to the color map conversion **/
private int [] colorMap = null;
public NativeDecoder() {
supportedInputFormats = new VideoFormat[] {new VideoFormat(VideoFormat.CINEPAK) };
defaultOutputFormats = new VideoFormat[] {
new RGBFormat(
null, Format.NOT_SPECIFIED, Format.intArray,
Format.NOT_SPECIFIED, // frame rate
32,
0xff, 0xff00, 0xff0000,
1,Format.NOT_SPECIFIED,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
null, Format.NOT_SPECIFIED, Format.intArray,
Format.NOT_SPECIFIED, // frame rate
32,
0xff0000, 0xff00, 0xff,
1,Format.NOT_SPECIFIED,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
null, Format.NOT_SPECIFIED, Format.shortArray,
Format.NOT_SPECIFIED, // frame rate
16,
0xf800, 0x07e0, 0x001f,
1,Format.NOT_SPECIFIED,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
),
new RGBFormat(
null, Format.NOT_SPECIFIED, Format.shortArray,
Format.NOT_SPECIFIED, // frame rate
16,
0x7c00, 0x03e0, 0x001f,
1,Format.NOT_SPECIFIED,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
null, Format.NOT_SPECIFIED, Format.byteArray,
Format.NOT_SPECIFIED, // frame rate
24,
1, 2, 3,
3,Format.NOT_SPECIFIED,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
null, Format.NOT_SPECIFIED, Format.byteArray,
Format.NOT_SPECIFIED, // frame rate
24,
3, 2, 1,
3,Format.NOT_SPECIFIED,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) };
PLUGIN_NAME = "Cinepak Decoder";
}
protected Format[] getMatchingOutputFormats(Format in) {
VideoFormat ivf = (VideoFormat) in;
Dimension inSize = ivf.getSize();
int lineStride = (inSize.width + 3) & 0xFFFFFFFC;
int rowStride = (inSize.height + 3) & 0xFFFFFFFC;
int length = lineStride * rowStride;
supportedOutputFormats= new VideoFormat[] {
new RGBFormat(
inSize, length, Format.intArray,
ivf.getFrameRate(),
32,
0xff, 0xff00, 0xff0000,
1,lineStride,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
inSize, length, Format.intArray,
ivf.getFrameRate(),
32,
0xff0000, 0xff00, 0xff,
1,lineStride,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
inSize, length, Format.shortArray,
ivf.getFrameRate(),
16,
0xf800, 0x07e0, 0x001f,
1,lineStride,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
inSize, length, Format.shortArray,
ivf.getFrameRate(),
16,
0x7c00, 0x03e0, 0x001f,
1,lineStride,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) ,
new RGBFormat(
inSize, length * 3 , Format.byteArray,
ivf.getFrameRate(),
24,
1, 2, 3,
3, lineStride * 3,
Format.FALSE,
Format.NOT_SPECIFIED
) ,
new RGBFormat(
inSize, length * 3 , Format.byteArray,
ivf.getFrameRate(),
24,
3, 2, 1,
3, lineStride * 3,
Format.FALSE,
Format.NOT_SPECIFIED
) };
return supportedOutputFormats;
}
public void open() throws ResourceUnavailableException {
try {
// JMFSecurityManager.loadLibrary("jmutil");
// JMFSecurityManager.loadLibrary("jmcvid");
initDecoder();
super.open();
return;
} catch (Throwable e) {
}
System.err.println("could not open "+PLUGIN_NAME);
throw new ResourceUnavailableException("could not open "+PLUGIN_NAME);
}
public void close() {
freeNative();
super.close();
}
public void reset() {
}
public Format setInputFormat(Format input) {
Format ret = super.setInputFormat(input);
if (ret == null)
return null;
if (opened) {
Dimension size = ((VideoFormat)input).getSize();
RGBFormat oldFormat = (RGBFormat) outputFormat;
int lineStride = ((size.width + 3) & 0xFFFFFFFC) * oldFormat.getPixelStride();
int rowStride = (size.height + 3) & 0xFFFFFFFC;
int length = lineStride * rowStride;
outputFormat = new RGBFormat(size,
length,
oldFormat.getDataType(),
((VideoFormat)input).getFrameRate(),
oldFormat.getBitsPerPixel(),
oldFormat.getRedMask(),
oldFormat.getGreenMask(),
oldFormat.getBlueMask(),
oldFormat.getPixelStride(),
lineStride,
oldFormat.getFlipped(),
oldFormat.getEndian()
);
}
return ret;
}
// called when video resize is detected, by checkFormat()
protected void videoResized() {
initDecoder();
}
protected void initDecoder() {
RGBFormat ovf = (RGBFormat)outputFormat;
rMask = ovf.getRedMask();
gMask = ovf.getGreenMask();
bMask = ovf.getBlueMask();
int bitsPerPixel = ovf.getBitsPerPixel() ;
// Translate from position to mask
if (bitsPerPixel == 24 && ovf.getDataType() == Format.byteArray) {
int bypp = bitsPerPixel / 8;
if (Arch.isLittleEndian()) {
rMask = 0xFF << ((rMask - 1) * 8);
gMask = 0xFF << ((gMask - 1) * 8);
bMask = 0xFF << ((bMask - 1) * 8);
} else {
rMask = 0xFF << ((rMask - 1) * 8);
gMask = 0xFF << ((gMask - 1) * 8);
bMask = 0xFF << ((bMask - 1) * 8);
}
}
initNative(bitsPerPixel, rMask, gMask, bMask);
}
public int process(Buffer inputBuffer, Buffer outputBuffer) {
Object outData;
if (!checkInputBuffer(inputBuffer) ) {
return BUFFER_PROCESSED_FAILED;
}
if (isEOM(inputBuffer) ) {
propagateEOM(outputBuffer);
return BUFFER_PROCESSED_OK;
}
VideoFormat ivf = (VideoFormat) inputBuffer.getFormat();
int inLength = inputBuffer.getLength();
int inMaxLength = ivf.getMaxDataLength();
int outMaxLength = outputFormat.getMaxDataLength();
Class outputClass = outputFormat.getDataType() ;
outputBuffer.setFormat(outputFormat);
byte[] inData = (byte[]) inputBuffer.getData();
outData = validateData(outputBuffer, 0, true);
int bytesPerPixel = ((RGBFormat)outputFormat).getBitsPerPixel() / 8;
long outDataBytes = 0;
if (outData instanceof NBA)
outDataBytes = ((NBA)outData).getNativeData();
//System.err.println("outDataBytes = " + outDataBytes);
if (refData == null || refData.getSize() < outMaxLength) {
refData = new NBA(outputFormat.getDataType(),
outMaxLength);
}
//System.err.println("outMaxLength = " + outMaxLength);
decodeNative(bytesPerPixel, inData, refData.getNativeData(), outData, outDataBytes, outMaxLength);
updateOutput(outputBuffer, outputFormat, outMaxLength, 0);
return BUFFER_PROCESSED_OK;
}
}
|