1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.webrtc.videoengine; 12 13 // The following four imports are needed saveBitmapToJPEG which 14 // is for debug only 15 import java.io.ByteArrayOutputStream; 16 import java.io.FileNotFoundException; 17 import java.io.FileOutputStream; 18 import java.io.IOException; 19 import java.nio.ByteBuffer; 20 21 import android.graphics.Bitmap; 22 import android.graphics.Canvas; 23 import android.graphics.Rect; 24 import android.view.SurfaceHolder; 25 import android.view.SurfaceView; 26 import android.view.SurfaceHolder.Callback; 27 28 import org.webrtc.Logging; 29 30 public class ViESurfaceRenderer implements Callback { 31 32 private final static String TAG = "WEBRTC"; 33 34 // the bitmap used for drawing. 35 private Bitmap bitmap = null; 36 private ByteBuffer byteBuffer = null; 37 private SurfaceHolder surfaceHolder; 38 // Rect of the source bitmap to draw 39 private Rect srcRect = new Rect(); 40 // Rect of the destination canvas to draw to 41 private Rect dstRect = new Rect(); 42 private float dstTopScale = 0; 43 private float dstBottomScale = 1; 44 private float dstLeftScale = 0; 45 private float dstRightScale = 1; 46 ViESurfaceRenderer(SurfaceView view)47 public ViESurfaceRenderer(SurfaceView view) { 48 surfaceHolder = view.getHolder(); 49 if(surfaceHolder == null) 50 return; 51 surfaceHolder.addCallback(this); 52 } 53 54 // surfaceChanged and surfaceCreated share this function changeDestRect(int dstWidth, int dstHeight)55 private void changeDestRect(int dstWidth, int dstHeight) { 56 dstRect.right = (int)(dstRect.left + dstRightScale * dstWidth); 57 dstRect.bottom = (int)(dstRect.top + dstBottomScale * dstHeight); 58 } 59 surfaceChanged(SurfaceHolder holder, int format, int in_width, int in_height)60 public void surfaceChanged(SurfaceHolder holder, int format, 61 int in_width, int in_height) { 62 Logging.d(TAG, "ViESurfaceRender::surfaceChanged"); 63 64 changeDestRect(in_width, in_height); 65 66 Logging.d(TAG, "ViESurfaceRender::surfaceChanged" + 67 " in_width:" + in_width + " in_height:" + in_height + 68 " srcRect.left:" + srcRect.left + 69 " srcRect.top:" + srcRect.top + 70 " srcRect.right:" + srcRect.right + 71 " srcRect.bottom:" + srcRect.bottom + 72 " dstRect.left:" + dstRect.left + 73 " dstRect.top:" + dstRect.top + 74 " dstRect.right:" + dstRect.right + 75 " dstRect.bottom:" + dstRect.bottom); 76 } 77 surfaceCreated(SurfaceHolder holder)78 public void surfaceCreated(SurfaceHolder holder) { 79 Canvas canvas = surfaceHolder.lockCanvas(); 80 if(canvas != null) { 81 Rect dst = surfaceHolder.getSurfaceFrame(); 82 if(dst != null) { 83 changeDestRect(dst.right - dst.left, dst.bottom - dst.top); 84 Logging.d(TAG, "ViESurfaceRender::surfaceCreated" + 85 " dst.left:" + dst.left + 86 " dst.top:" + dst.top + 87 " dst.right:" + dst.right + 88 " dst.bottom:" + dst.bottom + 89 " srcRect.left:" + srcRect.left + 90 " srcRect.top:" + srcRect.top + 91 " srcRect.right:" + srcRect.right + 92 " srcRect.bottom:" + srcRect.bottom + 93 " dstRect.left:" + dstRect.left + 94 " dstRect.top:" + dstRect.top + 95 " dstRect.right:" + dstRect.right + 96 " dstRect.bottom:" + dstRect.bottom); 97 } 98 surfaceHolder.unlockCanvasAndPost(canvas); 99 } 100 } 101 surfaceDestroyed(SurfaceHolder holder)102 public void surfaceDestroyed(SurfaceHolder holder) { 103 Logging.d(TAG, "ViESurfaceRenderer::surfaceDestroyed"); 104 bitmap = null; 105 byteBuffer = null; 106 } 107 CreateBitmap(int width, int height)108 public Bitmap CreateBitmap(int width, int height) { 109 Logging.d(TAG, "CreateByteBitmap " + width + ":" + height); 110 if (bitmap == null) { 111 try { 112 android.os.Process.setThreadPriority( 113 android.os.Process.THREAD_PRIORITY_DISPLAY); 114 } 115 catch (Exception e) { 116 } 117 } 118 bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); 119 srcRect.left = 0; 120 srcRect.top = 0; 121 srcRect.bottom = height; 122 srcRect.right = width; 123 return bitmap; 124 } 125 CreateByteBuffer(int width, int height)126 public ByteBuffer CreateByteBuffer(int width, int height) { 127 Logging.d(TAG, "CreateByteBuffer " + width + ":" + height); 128 if (bitmap == null) { 129 bitmap = CreateBitmap(width, height); 130 byteBuffer = ByteBuffer.allocateDirect(width * height * 2); 131 } 132 return byteBuffer; 133 } 134 SetCoordinates(float left, float top, float right, float bottom)135 public void SetCoordinates(float left, float top, 136 float right, float bottom) { 137 Logging.d(TAG, "SetCoordinates " + left + "," + top + ":" + 138 right + "," + bottom); 139 dstLeftScale = left; 140 dstTopScale = top; 141 dstRightScale = right; 142 dstBottomScale = bottom; 143 } 144 145 // It saves bitmap data to a JPEG picture, this function is for debug only. saveBitmapToJPEG(int width, int height)146 private void saveBitmapToJPEG(int width, int height) { 147 ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); 148 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteOutStream); 149 150 try{ 151 FileOutputStream output = new FileOutputStream(String.format( 152 "/sdcard/render_%d.jpg", System.currentTimeMillis())); 153 output.write(byteOutStream.toByteArray()); 154 output.flush(); 155 output.close(); 156 } 157 catch (FileNotFoundException e) { 158 } 159 catch (IOException e) { 160 } 161 } 162 DrawByteBuffer()163 public void DrawByteBuffer() { 164 if(byteBuffer == null) 165 return; 166 byteBuffer.rewind(); 167 bitmap.copyPixelsFromBuffer(byteBuffer); 168 DrawBitmap(); 169 } 170 DrawBitmap()171 public void DrawBitmap() { 172 if(bitmap == null) 173 return; 174 175 Canvas canvas = surfaceHolder.lockCanvas(); 176 if(canvas != null) { 177 // The follow line is for debug only 178 // saveBitmapToJPEG(srcRect.right - srcRect.left, 179 // srcRect.bottom - srcRect.top); 180 canvas.drawBitmap(bitmap, srcRect, dstRect, null); 181 surfaceHolder.unlockCanvasAndPost(canvas); 182 } 183 } 184 185 } 186