/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc.videoengine;
// The following four imports are needed saveBitmapToJPEG which
// is for debug only
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class ViESurfaceRenderer implements Callback {
private final static String TAG = "WEBRTC";
// the bitmap used for drawing.
private Bitmap bitmap = null;
private ByteBuffer byteBuffer = null;
private SurfaceHolder surfaceHolder;
// Rect of the source bitmap to draw
private Rect srcRect = new Rect();
// Rect of the destination canvas to draw to
private Rect dstRect = new Rect();
private float dstTopScale = 0;
private float dstBottomScale = 1;
private float dstLeftScale = 0;
private float dstRightScale = 1;
public ViESurfaceRenderer(SurfaceView view) {
surfaceHolder = view.getHolder();
if(surfaceHolder == null)
return;
surfaceHolder.addCallback(this);
}
// surfaceChanged and surfaceCreated share this function
private void changeDestRect(int dstWidth, int dstHeight) {
dstRect.right = (int)(dstRect.left + dstRightScale * dstWidth);
dstRect.bottom = (int)(dstRect.top + dstBottomScale * dstHeight);
}
public void surfaceChanged(SurfaceHolder holder, int format,
int in_width, int in_height) {
Log.d(TAG, "ViESurfaceRender::surfaceChanged");
changeDestRect(in_width, in_height);
Log.d(TAG, "ViESurfaceRender::surfaceChanged" +
" in_width:" + in_width + " in_height:" + in_height +
" srcRect.left:" + srcRect.left +
" srcRect.top:" + srcRect.top +
" srcRect.right:" + srcRect.right +
" srcRect.bottom:" + srcRect.bottom +
" dstRect.left:" + dstRect.left +
" dstRect.top:" + dstRect.top +
" dstRect.right:" + dstRect.right +
" dstRect.bottom:" + dstRect.bottom);
}
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = surfaceHolder.lockCanvas();
if(canvas != null) {
Rect dst = surfaceHolder.getSurfaceFrame();
if(dst != null) {
changeDestRect(dst.right - dst.left, dst.bottom - dst.top);
Log.d(TAG, "ViESurfaceRender::surfaceCreated" +
" dst.left:" + dst.left +
" dst.top:" + dst.top +
" dst.right:" + dst.right +
" dst.bottom:" + dst.bottom +
" srcRect.left:" + srcRect.left +
" srcRect.top:" + srcRect.top +
" srcRect.right:" + srcRect.right +
" srcRect.bottom:" + srcRect.bottom +
" dstRect.left:" + dstRect.left +
" dstRect.top:" + dstRect.top +
" dstRect.right:" + dstRect.right +
" dstRect.bottom:" + dstRect.bottom);
}
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "ViESurfaceRenderer::surfaceDestroyed");
bitmap = null;
byteBuffer = null;
}
public Bitmap CreateBitmap(int width, int height) {
Log.d(TAG, "CreateByteBitmap " + width + ":" + height);
if (bitmap == null) {
try {
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
}
catch (Exception e) {
}
}
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
srcRect.left = 0;
srcRect.top = 0;
srcRect.bottom = height;
srcRect.right = width;
return bitmap;
}
public ByteBuffer CreateByteBuffer(int width, int height) {
Log.d(TAG, "CreateByteBuffer " + width + ":" + height);
if (bitmap == null) {
bitmap = CreateBitmap(width, height);
byteBuffer = ByteBuffer.allocateDirect(width * height * 2);
}
return byteBuffer;
}
public void SetCoordinates(float left, float top,
float right, float bottom) {
Log.d(TAG, "SetCoordinates " + left + "," + top + ":" +
right + "," + bottom);
dstLeftScale = left;
dstTopScale = top;
dstRightScale = right;
dstBottomScale = bottom;
}
// It saves bitmap data to a JPEG picture, this function is for debug only.
@SuppressLint("SdCardPath")
private void saveBitmapToJPEG(int width, int height) {
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteOutStream);
try{
FileOutputStream output = new FileOutputStream(String.format(
"/sdcard/render_%d.jpg", System.currentTimeMillis()));
output.write(byteOutStream.toByteArray());
output.flush();
output.close();
}
catch (FileNotFoundException e) {
}
catch (IOException e) {
}
}
public void DrawByteBuffer() {
if(byteBuffer == null)
return;
byteBuffer.rewind();
bitmap.copyPixelsFromBuffer(byteBuffer);
DrawBitmap();
}
public void DrawBitmap() {
if(bitmap == null)
return;
Canvas canvas = surfaceHolder.lockCanvas();
if(canvas != null) {
// The follow line is for debug only
// saveBitmapToJPEG(srcRect.right - srcRect.left,
// srcRect.bottom - srcRect.top);
canvas.drawBitmap(bitmap, srcRect, dstRect, null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}