FileDocCategorySizeDatePackage
MIDPVideoRenderer.javaAPI DocphoneME MR2 API (J2ME)21448Wed May 02 16:47:10 BST 2007com.sun.mmedia

MIDPVideoRenderer

public final class MIDPVideoRenderer extends VideoRenderer implements MIDPVideoPainter, javax.microedition.media.control.VideoControl
VideoControl implementation for MIDP

Fields Summary
private MMItem
mmItem
If the application requests an Item
private javax.microedition.lcdui.Canvas
canvas
If the application requests to draw in a Canvas
private boolean
fsmode
Full screen mode flag
private boolean
closed
Is the player closed
private int
mode
The display mode
private boolean
cvis
Container visible flag. True if the Canvas is visible
private boolean
pvis
Application specified visibility flag. True if setVisible(true)
private BasicPlayer
player
Player which is being controlled
private int
dx
Display X
private int
tmpdx
private int
dy
Display Y
private int
tmpdy
private int
dw
Display Width
private int
tmpdw
private int
dh
Display Height
private int
tmpdh
private int
videoWidth
Source width
private int
videoHeight
Source height
private byte[]
tempSnapData
Storage for the snapshot
private static final boolean
TRACE_FRAMERATE
To check the frame rate
private int
frameCount
To check the frame rate
private long
frameStartTime
To check the frame rate
private static final String
UNSUP_PARAMS
private Object
dispBoundsLock
used to protect dx, dy, dw, dh set & read
public static final int
RGB565
Rendering interface
public static final int
RGB888
public static final int
XRGB888
public static final int
XBGR888
public static final int
RGBX888
public static final int
YUV420_PLANAR
public static final int
YUV422_PLANAR
public static final int
YUYV
public static final int
UYVY
public static final int
YVYU
public static final int
NATIVE_RENDER
public static final int
USE_ALPHA
int
rgbMode
int
pWidth
int
pHeight
int[]
rgbData
int[]
scaledRGB
byte[]
pngData
int
pngDataLength
boolean
nativeRender
boolean
useAlpha
private javax.microedition.lcdui.Image
image
private MMHelper
mmh
Constructors Summary
MIDPVideoRenderer(javax.microedition.media.Player p, int sourceWidth, int sourceHeight)
VideoControl implementation

    
           

          
        setSourceSize(sourceWidth, sourceHeight);
        if (p instanceof BasicPlayer) {
            this.player = (BasicPlayer)p;
        } else {
            System.err.println("video renderer can't work with Players of this class: " + p.toString());
        }
    
Methods Summary
private static voidcheckPermission()
Check for the image snapshot permission.

exception
SecurityException if the permission is not allowed by this token

        PermissionAccessor.checkPermissions(PermissionAccessor.PERMISSION_VIDEO_SNAPSHOT);
    
private voidcheckState()

        if (mode == -1)
            throw new IllegalStateException("initDisplayMode not called yet");
    
public synchronized voidclose()

        if (!closed && canvas != null)
            mmh.unregisterPlayer(canvas, this);
        rgbData = null;
        scaledRGB = null;
        pngData = null;
        closed = true;
    
public intgetDisplayHeight()

        checkState();
        return dh;
    
public intgetDisplayWidth()

        checkState();
        return dw;
    
public intgetDisplayX()

        return dx;
    
public intgetDisplayY()

        return dy;
    
intgetPreferredRGBMode()

        return RGB888;
    
public byte[]getSnapshot(java.lang.String imageType)

        throw new MediaException("Not supported");
    
public intgetSourceHeight()

        return videoHeight;
    
public intgetSourceWidth()

        return videoWidth;
    
public javax.microedition.media.ControlgetVideoControl()


       
        return (VideoControl)this;
    
public voidhideVideo()

        if (canvas != null && cvis) {
            cvis = false;
            canvas.repaint();
        }
    
public java.lang.ObjectinitDisplayMode(int mode, java.lang.Object container)

        if (this.mode != -1)
            throw new IllegalStateException("mode is already set");
        
        if (mode == USE_DIRECT_VIDEO) {
            if (!(container instanceof Canvas))
                throw new IllegalArgumentException(
                    "container needs to be a Canvas for USE_DIRECT_VIDEO mode");
            
            if (mmh == null) {
                mmh = MMHelper.getMMHelper();
                if (mmh == null)
                    throw new IllegalArgumentException(
                            "unable to set USE_DIRECT_VIDEO mode");
            }

            this.mode = mode;
            fsmode = false;
            cvis = true;
            canvas = (Canvas) container;
            mmh.registerPlayer(canvas, this);
            setVisible(false); // By default video is not shown in USE_DIRECT_VIDEO mode
            return null;
            
        } else if (mode == USE_GUI_PRIMITIVE) {
            if (container != null && 
                (!(container instanceof String) ||
                 !(container.equals("javax.microedition.lcdui.Item"))))
                throw new IllegalArgumentException("container needs to be a javax.microedition.lcdui.Item for USE_GUI_PRIMITIVE mode");

            this.mode = mode;
            fsmode = false;
            cvis = true;
            mmItem = new MMItem();
            setVisible(true);
            return mmItem;
            
        } else {
            throw new IllegalArgumentException("unsupported mode");
        }
    
public voidinitRendering(int mode, int width, int height)

        rgbMode = mode & 0x7F; // mask out NATIVE_RENDER
        nativeRender = (mode & NATIVE_RENDER) > 0;
        useAlpha = (mode & USE_ALPHA) > 0;
        pWidth = width;
        pHeight = height;
    
public voidpaintVideo(javax.microedition.lcdui.Graphics g)
Paint video into canvas - in USE_DIRECT_VIDEO mode

        // Don't paint if Canvas visible flag is false
        if (!pvis || !cvis)
            return;
        
        // Save the clip region
        int cx = g.getClipX();
        int cy = g.getClipY();
        int cw = g.getClipWidth();
        int ch = g.getClipHeight();
        // Change the clip to clip the video area
        g.clipRect(dx, dy, dw, dh);
        
        // Check if its within our bounds
        if (g.getClipWidth() > 0 && g.getClipHeight() > 0 && pvis) {
            int w = dw, h = dh;
            if (w > videoWidth) w = videoWidth;
            if (h > videoHeight) h = videoHeight;
            try {
                synchronized (this) {
                    if (pngData != null) {
                        if (image != null) {

                        }
                        image = Image.createImage(pngData, 0, pngDataLength);
                        // We're rendering an image
                        if (dw != videoWidth || dh != videoHeight) {
                            // Scale first and display
                            int [] scaledRGB = scaleToDest(image);
                            g.drawRGB(scaledRGB, 0, dw, dx, dy, dw, dh, useAlpha);
                        } else {
                            // No scaling
                            g.drawImage(image, dx, dy,
                                        Graphics.LEFT | Graphics.TOP);
                        }
                    } else if (rgbData != null) {
                        // We're rendering an RGB array
                        if (dw != videoWidth || dh != videoHeight) {
                            // Scale first and display
                            int [] scaledRGB = scaleToDest(rgbData);
                            g.drawRGB(scaledRGB, 0, dw, dx, dy, dw, dh, useAlpha);
                        } else {
                            // No scaling
                            g.drawRGB(rgbData, 0, videoWidth, dx, dy, w, h, useAlpha);
                        }
                    }
                }
            } finally {
                // Revert the clip region
                g.setClip(cx, cy, cw, ch);
            }
        } else {
            g.setClip(cx, cy, cw, ch);
        }
        if (TRACE_FRAMERATE) {
            if (frameStartTime == 0) {
                frameStartTime = System.currentTimeMillis();
            } else {
                frameCount++;
                if ((frameCount % 30) == 0) {
                    int frameRate = (int) ( (frameCount * 1000) / (System.currentTimeMillis() - frameStartTime + 1));
                    //System.err.println("Frame Rate = " + frameRate);
                }
            }
        }
    
public voidrender(int[] data)
Public render method

        render((Object)data);
    
synchronized booleanrender(java.lang.Object data)
Renders the data to the screen at the component's location and size, if component is visible. Returns true if displayed, false if not.

        if (data == null)
            return false;
        if (data instanceof int[])
            update((int[]) data);
        else
            return false;
        
        return true;
    
synchronized booleanrenderImage(byte[] imageData, int imageLength)

        // Keep these values, in case snapshot is requested
        pngData = imageData;
        pngDataLength = imageLength;

        if (!pvis)
            return false;

        if (canvas != null) {
            if (cvis)
                canvas.repaint(dx, dy, dw, dh);
        } else if (mmItem != null) {
            mmItem.renderImage(imageData, imageLength);
        }
        return true;
    
private int[]scaleToDest(int[] source)
Scales an input rgb image to the destination size.

        int ldw = 0;
        int ldh = 0;
        synchronized (dispBoundsLock) {
            ldw = dw;
            ldh = dh;
        }
        synchronized (this) { // To avoid interference with close()
            if (scaledRGB == null || scaledRGB.length < ldw * ldh)
                scaledRGB = new int[ldw * ldh];
            // Scale using nearest neighbor
            int dp = 0;
            for (int y = 0; y < ldh; y++) {
                for (int x = 0; x < ldw; x++) {
                    scaledRGB[dp++] = source[((y * videoHeight) / ldh) * videoWidth +
                                            ((x * videoWidth) / ldw)];
                }
            }
            return scaledRGB;
        }
    
private int[]scaleToDest(javax.microedition.lcdui.Image img)
Scale an image to the destination size. This first gets the pixels from the image and then uses the other scaleToDist() to do the scaling.

        if (rgbData == null)
            rgbData = new int[videoWidth * videoHeight];
        int width = img.getWidth();
        int height = img.getHeight();
        img.getRGB(rgbData, 0, videoWidth, 0, 0, width, height);
        return scaleToDest(rgbData);
    
public voidsetDisplayFullScreen(boolean fullScreenMode)

        checkState();
        if (fsmode != fullScreenMode) {
            fsmode = fullScreenMode;
            if (fsmode) { //switching from Normal to Full Screen
                synchronized (dispBoundsLock) {
                    tmpdx = dx;
                    tmpdy = dy;
                    tmpdw = dw;
                    tmpdh = dh;
                }
                if (mode == USE_DIRECT_VIDEO) {
                    canvas.setFullScreenMode(true);
                } else {
                    canvas = mmItem.toFullScreen(this, this);
                    if (canvas == null) {
                        // No owner or no display - thus invisible
                        // Do nothing, but simulate fullscreen (lock sizes - for compliance)
                        return;
                    }                        
                }
                synchronized (dispBoundsLock) {
                    dx = 0;
                    dy = 0;
                                        
                    // Keep aspect ratio
                    int scrw = canvas.getWidth();
                    int scrh = canvas.getHeight();
                    dw = scrh * videoWidth / videoHeight;
                    if (dw > scrw) {
                        dw = scrw;
                        dh = scrw * videoHeight / videoWidth;
                        dy = (scrh - dh) / 2;
                    } else {
                        dh = scrh;
                        dx = (scrw - dw) / 2;
                    }
                }
                if (cvis)
                    canvas.repaint();

            } else { //switching from Full to Normal Screen
                synchronized (dispBoundsLock) {
                    dx = tmpdx;
                    dy = tmpdy;
                    dw = tmpdw;
                    dh = tmpdh;
                }
                if (mode == USE_DIRECT_VIDEO) {
                    canvas.setFullScreenMode(false);
                    if (pvis && cvis)
                        canvas.repaint();
                } else {
                    mmItem.toNormal();
                    canvas = null;
                    if (pvis)
                        mmItem.forcePaint(null);
                }
            }
            player.sendEvent(PlayerListener.SIZE_CHANGED, this);
        }
    
public voidsetDisplayLocation(int x, int y)

        checkState();
        // Applicable only in USE_DIRECT_VIDEO mode
        if (mode == USE_DIRECT_VIDEO) {
            if (fsmode) { // Just store location in fullscreen mode
                synchronized (dispBoundsLock) {
                    tmpdx = x;
                    tmpdy = y;
                }
            } else {
                synchronized (dispBoundsLock) {
                    dx = x;
                    dy = y;
                }
                if (pvis && cvis)
                    canvas.repaint();
            }
        }
    
public voidsetDisplaySize(int width, int height)

        checkState();
        if (width < 1 || height < 1)
            throw new IllegalArgumentException("Invalid size");
        
        boolean sizeChanged = (dw != width || dh != height);
        
        if (fsmode) { // Just store sizes in fullscreen mode
            synchronized (dispBoundsLock) {
                tmpdw = width;
                tmpdh = height;
            }
        } else {
            synchronized (dispBoundsLock) {
                dw = width;
                dh = height;
            }
            if (pvis)
                if (mmItem != null)
                    mmItem.forcePaint(null);
                else if (cvis)                   
                    canvas.repaint();
        }
        // Makes sense only if NOT in Full Screen mode
        if (sizeChanged && !fsmode)
            player.sendEvent(PlayerListener.SIZE_CHANGED, this);
    
voidsetMode(int mode)

        rgbMode = mode & 0x7F;
        nativeRender = (mode >= 128);
    
voidsetSourceSize(int sourceWidth, int sourceHeight)

        
        videoWidth = sourceWidth;
        videoHeight = sourceHeight;
        
        // Default display width and height
        synchronized (dispBoundsLock) {
            dw = videoWidth;
            dh = videoHeight;
        }
    
public voidsetVisible(boolean visible)

        checkState();
        pvis = visible;
        if (canvas != null) // USE_DIRECT_VIDEO
            canvas.repaint();
        else if (mmItem != null) // USE_GUI_PRIMITIVE
            mmItem.forcePaint(null);
    
public voidshowVideo()
Enable/disable rendering for canvas (USE_DIRECT_VIDEO mode)

        if (canvas != null && !cvis) {
            cvis = true;
            canvas.repaint();
        }
    
private inttryParam(java.lang.String tok, java.lang.String prop, int def)

        if (tok.startsWith(prop)) {
            tok = tok.substring(prop.length(), tok.length());
            try {
                return Integer.parseInt(tok);
            } catch (NumberFormatException nfe) {
            }
        }
        return def;
    
private voidupdate(int[] frame)

        if (rgbMode != XBGR888)
            return;

        rgbData = frame;

        if (!pvis)
            return;
                
        if (canvas != null) {
            if (cvis) {
                canvas.repaint(dx, dy, dw, dh);
            }
        } else if (mmItem != null) {
            mmItem.forcePaint(frame);
        }