15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2013, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgpackage org.webrtc; 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgimport java.nio.ByteBuffer; 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgimport java.util.Arrays; 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/** 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Java version of VideoRendererInterface. In addition to allowing clients to 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * define their own rendering behavior (by passing in a Callbacks object), this 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * class also provides a createGui() method for creating a GUI-rendering window 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * on various platforms. 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgpublic class VideoRenderer { 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org /** Java version of cricket::VideoFrame. */ 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public static class I420Frame { 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public final int width; 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public final int height; 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public final int[] yuvStrides; 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public final ByteBuffer[] yuvPlanes; 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org /** 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Construct a frame of the given dimensions with the specified planar 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * data. If |yuvPlanes| is null, new planes of the appropriate sizes are 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * allocated. 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public I420Frame( 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int width, int height, int[] yuvStrides, ByteBuffer[] yuvPlanes) { 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org this.width = width; 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org this.height = height; 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org this.yuvStrides = yuvStrides; 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (yuvPlanes == null) { 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org yuvPlanes = new ByteBuffer[3]; 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org yuvPlanes[0] = ByteBuffer.allocateDirect(yuvStrides[0] * height); 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org yuvPlanes[1] = ByteBuffer.allocateDirect(yuvStrides[1] * height); 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org yuvPlanes[2] = ByteBuffer.allocateDirect(yuvStrides[2] * height); 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org this.yuvPlanes = yuvPlanes; 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org /** 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copy the planes out of |source| into |this| and return |this|. Calling 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this with mismatched frame dimensions is a programming error and will 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * likely crash. 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public I420Frame copyFrom(I420Frame source) { 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!Arrays.equals(yuvStrides, source.yuvStrides) || 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org width != source.width || height != source.height) { 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org throw new RuntimeException("Mismatched dimensions! Source: " + 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org source.toString() + ", destination: " + toString()); 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org copyPlane(source.yuvPlanes[0], yuvPlanes[0]); 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org copyPlane(source.yuvPlanes[1], yuvPlanes[1]); 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org copyPlane(source.yuvPlanes[2], yuvPlanes[2]); 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return this; 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org @Override 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public String toString() { 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return width + "x" + height + ":" + yuvStrides[0] + ":" + yuvStrides[1] + 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ":" + yuvStrides[2]; 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Copy the bytes out of |src| and into |dst|, ignoring and overwriting 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // positon & limit in both buffers. 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private void copyPlane(ByteBuffer src, ByteBuffer dst) { 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org src.position(0).limit(src.capacity()); 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dst.put(src); 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dst.position(0).limit(dst.capacity()); 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org /** The real meat of VideoRendererInterface. */ 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public static interface Callbacks { 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public void setSize(int width, int height); 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public void renderFrame(I420Frame frame); 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // |this| either wraps a native (GUI) renderer or a client-supplied Callbacks 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // (Java) implementation; so exactly one of these will be non-0/null. 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org final long nativeVideoRenderer; 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private final Callbacks callbacks; 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public static VideoRenderer createGui(int x, int y) { 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org long nativeVideoRenderer = nativeCreateGuiVideoRenderer(x, y); 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (nativeVideoRenderer == 0) { 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return null; 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return new VideoRenderer(nativeVideoRenderer); 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public VideoRenderer(Callbacks callbacks) { 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org nativeVideoRenderer = nativeWrapVideoRenderer(callbacks); 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org this.callbacks = callbacks; 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private VideoRenderer(long nativeVideoRenderer) { 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org this.nativeVideoRenderer = nativeVideoRenderer; 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org callbacks = null; 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public void dispose() { 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org free(nativeVideoRenderer); 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private static native long nativeCreateGuiVideoRenderer(int x, int y); 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private static native long nativeWrapVideoRenderer(Callbacks callbacks); 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private static native void free(long nativeVideoRenderer); 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 137