1 程序代码
使用Android中的SurfaceView播放RGB视频数据,SufaceView播放代码如下:
package com.zhoulee.surfaceviewdemo; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private static String TAG = "MySurfaceView"; private static String RGB_FILE_NAME = "/data/video/bxjg_352x288.rgba"; private static int PICTURE_WIDTH = 352; private static int PICTURE_HEIGHT = 288; private static int PICTURE_SIZE = PICTURE_WIDTH * PICTURE_HEIGHT * 4; private Rect m_srcRect; private Rect m_dstRect; private SurfaceHolder m_surfaceHolder; private boolean m_flag; private Canvas m_canvas; private FileInputStream m_fileInputStream; byte [] m_pixel = new byte[PICTURE_SIZE]; private Thread m_thread = new Thread(new Runnable() { @Override public void run() { while(m_flag) { m_canvas = m_surfaceHolder.lockCanvas(); m_canvas.drawColor(Color.BLACK); try { if(-1 == m_fileInputStream.read(m_pixel)) { break; } } catch (IOException e1) { e1.printStackTrace(); } ByteBuffer buffer = ByteBuffer.wrap(m_pixel); Bitmap videoBitmap = Bitmap.createBitmap(PICTURE_WIDTH, PICTURE_HEIGHT, Config.ARGB_8888); videoBitmap.copyPixelsFromBuffer(buffer); m_canvas.drawBitmap(videoBitmap, m_srcRect, m_dstRect, null); if(m_canvas != null) { m_surfaceHolder.unlockCanvasAndPost(m_canvas); } try { Thread.sleep(5); } catch(InterruptedException e) { e.printStackTrace(); } } } }); public MySurfaceView(Context context) { super(context); Log.i(TAG, "MySurfaceView Constructor"); m_flag = false; m_surfaceHolder = this.getHolder(); m_surfaceHolder.addCallback(this); m_srcRect = new Rect(0, 0, PICTURE_WIDTH, PICTURE_HEIGHT); m_dstRect = new Rect(800, 50, 800 + PICTURE_WIDTH, 50 + PICTURE_HEIGHT); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.i(TAG, "surfaceCtreated"); m_flag = true; try { m_fileInputStream = new FileInputStream(RGB_FILE_NAME); } catch (FileNotFoundException e) { e.printStackTrace(); } m_thread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.i(TAG, "surfaceChanged"); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.i(TAG, "surfaceDestroyed"); m_flag = false; } }
入口Activity代码如下:
package com.zhoulee.surfaceviewdemo; import android.app.Activity; import android.os.Bundle; public class SurfaceViewDemoActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MySurfaceView(this)); } }
2 参考资料
How to load RGB565 buffer to ImageView
Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系