FileDocCategorySizeDatePackage
JavaRGBToYUV.javaAPI DocJMF 2.1.1e10079Mon May 12 12:20:46 BST 2003com.sun.media.codec.video.colorspace

JavaRGBToYUV

public class JavaRGBToYUV extends BasicCodec

Fields Summary
private static final String
PLUGIN_NAME
private FrameProcessingControl
frameControl
private boolean
dropFrame
Constructors Summary
public JavaRGBToYUV()


      
	int NS = Format.NOT_SPECIFIED;
	
	inputFormats = new Format [] {
	    new RGBFormat(null, NS, Format.byteArray, NS,
			  24,
			  NS, NS, NS, NS, NS, NS, NS),
	    new RGBFormat(null, NS, Format.intArray, NS,
			  32,
			  0xFF0000, 0xFF00, 0xFF, 1, NS, NS, NS),
	    new RGBFormat(null, NS, Format.intArray, NS,
			  32,
			  0xFF, 0xFF00, 0xFF0000, 1, NS, NS, NS),
	};

	outputFormats = new Format [] {
	    new YUVFormat(YUVFormat.YUV_420)
	};

	if (frameControl == null) {
	    class FPC implements FrameProcessingControl {
		public void setFramesBehind(float frames) {
		    if (frames > 0) {
			dropFrame = true;
		    } else {
			dropFrame = false;
		    }
		}

		public boolean setMinimalProcessing(boolean minimal) {
		    dropFrame = minimal;
		    return dropFrame;
		}

		public Component getControlComponent() {
		    return null;
		}

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

	    }

	    frameControl = new FPC();
	    controls = new Control[1];
	    controls[0] = frameControl;
	}

    
Methods Summary
protected intconvert24(javax.media.Buffer inBuffer, javax.media.Buffer outBuffer)

	RGBFormat rgb = (RGBFormat) inBuffer.getFormat();
	YUVFormat yuv = (YUVFormat) outBuffer.getFormat();
	Dimension size = rgb.getSize();
	byte [] outData = (byte[]) outBuffer.getData();
	byte [] inData = (byte[]) inBuffer.getData();
	boolean flipped = rgb.getFlipped() == Format.TRUE;
	int increment = (flipped)? -1 : 1;
	int ystride = yuv.getStrideY();
	int uvstride = yuv.getStrideUV();
	int pointerY = yuv.getOffsetY() +
	               ystride * ((flipped)? (size.height - 1) : 0);
	int pointerU = yuv.getOffsetU() +
	               uvstride * ((flipped)? (size.height/2 - 1) : 0);
	int pointerV = yuv.getOffsetV() +
	               uvstride * ((flipped)? (size.height/2 - 1) : 0);
	int pRGB = 0;
	int rgbscan = rgb.getLineStride();
	int pixstride = rgb.getPixelStride();
	int rOffset = rgb.getRedMask() - 1;
	int gOffset = rgb.getGreenMask() - 1;
	int bOffset = rgb.getBlueMask() - 1;
	int yval, uval, vval;
	int rval, gval, bval;

	for (int y = 0; y < size.height; y+=2) {
	    for (int x = 0; x < size.width; x+=2) {
		// First pixel, first row
		rval = inData[pRGB+rOffset] & 0xFF;
		gval = inData[pRGB+gOffset] & 0xFF;
		bval = inData[pRGB+bOffset] & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval = (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval = (rval*439 - gval*368 - bval*71) / 1000 + 128;
		//System.err.println(yval + " " + uval + " " + vval);
		outData[pointerY] = (byte) (yval & 0xFF);

		// Second pixel, first row
		rval = inData[pRGB+rOffset+pixstride] & 0xFF;
		gval = inData[pRGB+gOffset+pixstride] & 0xFF;
		bval = inData[pRGB+bOffset+pixstride] & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval += (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval += (rval*439 - gval*368 - bval*71) / 1000 + 128;

		outData[pointerY+1] = (byte) (yval & 0xFF);

		// First pixel, second row
		rval = inData[pRGB+rOffset+rgbscan] & 0xFF;
		gval = inData[pRGB+gOffset+rgbscan] & 0xFF;
		bval = inData[pRGB+bOffset+rgbscan] & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval += (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval += (rval*439 - gval*368 - bval*71) / 1000 + 128;
		
		outData[pointerY+(increment*ystride)] = (byte) (yval & 0xFF);

		// Second pixel, second row
		rval = inData[pRGB+rOffset+rgbscan+pixstride] & 0xFF;
		gval = inData[pRGB+gOffset+rgbscan+pixstride] & 0xFF;
		bval = inData[pRGB+bOffset+rgbscan+pixstride] & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval += (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval += (rval*439 - gval*368 - bval*71) / 1000 + 128;
		
		outData[pointerY+(increment*ystride)+1] = (byte) (yval & 0xFF);
		outData[pointerU] = (byte) ((uval >> 2) & 0xFF);
		outData[pointerV] = (byte) ((vval >> 2) & 0xFF);
		pointerY += 2;
		pointerU++;
		pointerV++;
		pRGB += pixstride * 2;
	    }
	    pRGB += (rgbscan * 2) - (size.width * pixstride);
	    pointerY += (increment * ystride * 2) - size.width;
	    pointerU += (increment * uvstride) - (size.width / 2);
	    pointerV += (increment * uvstride) - (size.width / 2);
	}
	return BUFFER_PROCESSED_OK;
    
protected intconvertInt(javax.media.Buffer inBuffer, javax.media.Buffer outBuffer)

	RGBFormat rgb = (RGBFormat) inBuffer.getFormat();
	YUVFormat yuv = (YUVFormat) outBuffer.getFormat();
	Dimension size = rgb.getSize();
	byte [] outData = (byte[]) outBuffer.getData();
	int [] inData = (int[]) inBuffer.getData();
	boolean flipped = rgb.getFlipped() == Format.TRUE;
	int increment = (flipped)? -1 : 1;
	int ystride = yuv.getStrideY();
	int uvstride = yuv.getStrideUV();
	int pointerY = yuv.getOffsetY() +
	               ystride * ((flipped)? (size.height - 1) : 0);
	int pointerU = yuv.getOffsetU() +
	               uvstride * ((flipped)? (size.height/2 - 1) : 0);
	int pointerV = yuv.getOffsetV() +
	               uvstride * ((flipped)? (size.height/2 - 1) : 0);
	int pRGB = 0;
	int rgbscan = rgb.getLineStride();
	int rOffset = 16;
	int gOffset = 8;
	int bOffset = 0;
	int yval, uval, vval;
	int rval, gval, bval;

	if (rgb.getRedMask() == 0xFF) { // XBGR
	    rOffset = 0;
	    bOffset = 16;
	}

	for (int y = 0; y < size.height; y+=2) {
	    for (int x = 0; x < size.width; x+=2) {
		// First pixel, first row
		rval = (inData[pRGB] >> rOffset) & 0xFF;
		gval = (inData[pRGB] >> gOffset) & 0xFF;
		bval = (inData[pRGB] >> bOffset) & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval = (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval = (rval*439 - gval*368 - bval*71) / 1000 + 128;
		//System.err.println(yval + " " + uval + " " + vval);
		outData[pointerY] = (byte) (yval & 0xFF);

		// Second pixel, first row
		rval = (inData[pRGB+1] >> rOffset) & 0xFF;
		gval = (inData[pRGB+1] >> gOffset) & 0xFF;
		bval = (inData[pRGB+1] >> bOffset) & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval += (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval += (rval*439 - gval*368 - bval*71) / 1000 + 128;

		outData[pointerY+1] = (byte) (yval & 0xFF);

		// First pixel, second row
		rval = (inData[pRGB+rgbscan] >> rOffset) & 0xFF;
		gval = (inData[pRGB+rgbscan] >> gOffset) & 0xFF;
		bval = (inData[pRGB+rgbscan] >> bOffset) & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval += (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval += (rval*439 - gval*368 - bval*71) / 1000 + 128;
		
		outData[pointerY+(increment*ystride)] = (byte) (yval & 0xFF);

		// Second pixel, second row
		rval = (inData[pRGB+rgbscan+1] >> rOffset) & 0xFF;
		gval = (inData[pRGB+rgbscan+1] >> gOffset) & 0xFF;
		bval = (inData[pRGB+rgbscan+1] >> bOffset) & 0xFF;
		yval = (rval*257 + gval*504 + bval*98) / 1000 + 16;
		uval += (-rval*148 - gval*291 + bval*439) / 1000 + 128;
		vval += (rval*439 - gval*368 - bval*71) / 1000 + 128;
		
		outData[pointerY+(increment*ystride)+1] = (byte) (yval & 0xFF);
		outData[pointerU] = (byte) ((uval >> 2) & 0xFF);
		outData[pointerV] = (byte) ((vval >> 2) & 0xFF);
		pointerY += 2;
		pointerU++;
		pointerV++;
		pRGB += 2;
	    }
	    pRGB += (rgbscan * 2) - size.width;
	    pointerY += (increment * ystride * 2) - size.width;
	    pointerU += (increment * uvstride) - (size.width / 2);
	    pointerV += (increment * uvstride) - (size.width / 2);
	}
	return BUFFER_PROCESSED_OK;
    
public java.lang.StringgetName()

	return PLUGIN_NAME;
    
public javax.media.Format[]getSupportedOutputFormats(javax.media.Format input)


	if (input == null)
	    return outputFormats;
	else if (input instanceof RGBFormat &&
		 matches(input, inputFormats) != null) {
	    RGBFormat rgb = (RGBFormat) input;
	    Dimension size = rgb.getSize();
	    float frameRate = rgb.getFrameRate();
	    int bpp = rgb.getBitsPerPixel();
	    int scan = (size.width + 1) & ~1;
	    
	    YUVFormat output = new YUVFormat(size,
					     scan * size.height * 3 / 2,
					     Format.byteArray,
					     frameRate,
					     YUVFormat.YUV_420,
					     scan, scan / 2,
					     0, scan * size.height,
					     (scan * size.height * 5) / 4);

	    Format [] outputs = new Format [] {output};
	    return outputs;
	} else {
	    return new Format[0];
	}
    
public intprocess(javax.media.Buffer inBuffer, javax.media.Buffer outBuffer)

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

	if (dropFrame) {
	    outBuffer.setFlags(outBuffer.getFlags() | Buffer.FLAG_DISCARD);
	    return BUFFER_PROCESSED_OK;
	}

	Format inF = inBuffer.getFormat();

	if ( !(inF instanceof RGBFormat) ||
	     inBuffer.getData() == null )
	    return BUFFER_PROCESSED_FAILED;

	Object inData = inBuffer.getData();
	validateByteArraySize(outBuffer,
			      ((VideoFormat)outputFormat).getMaxDataLength());

	outBuffer.setFormat(outputFormat);
	outBuffer.setLength(((VideoFormat)outputFormat).getMaxDataLength());
	if (((RGBFormat)inF).getBitsPerPixel() == 24) 
	    return convert24(inBuffer, outBuffer);
	else
	    return convertInt(inBuffer, outBuffer);
    
public voidreset()

    
public javax.media.FormatsetInputFormat(javax.media.Format input)

	Format ret = super.setInputFormat(input);
	if (opened) {
	    outputFormat = getSupportedOutputFormats(ret)[0];
	}
	return ret;