1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.mediadump; 18 19 import java.io.BufferedReader; 20 import java.io.File; 21 import java.io.FileInputStream; 22 import java.io.FileReader; 23 import java.io.FilenameFilter; 24 import java.lang.Integer; 25 import java.nio.ByteBuffer; 26 import java.nio.ShortBuffer; 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.Properties; 30 import java.util.Random; 31 import java.util.Timer; 32 import java.util.TimerTask; 33 34 import android.app.Activity; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.content.SharedPreferences; 38 import android.graphics.Bitmap; 39 import android.graphics.BitmapFactory; 40 import android.graphics.Canvas; 41 import android.os.Bundle; 42 import android.os.Handler; 43 import android.os.Message; 44 import android.util.Log; 45 import android.view.Gravity; 46 import android.view.MotionEvent; 47 import android.view.View; 48 import android.widget.ImageView; 49 import android.widget.LinearLayout; 50 import android.widget.MediaController; 51 import android.widget.MediaController.MediaPlayerControl; 52 53 54 /** 55 * A simple player to display the raw rgb files that are generated from 56 * VideDumpView class. It reads the "/sdcard/mediadump/prop.xml" to get 57 * the meta data such as width, height, frame rate, and bytes per pixel. 58 */ 59 public class RgbPlayerActivity extends Activity { 60 61 @Override 62 protected void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 65 setContentView(new RgbView(this)); 66 } 67 68 private static class RgbView extends View implements MediaPlayerControl { 69 private static final String TAG = "RgbView"; 70 private Bitmap mBitmap; 71 private int mStartX = 0; 72 private int mStartY = 0; 73 private int mWidth = 0; 74 private int mHeight = 0; 75 private int mBytesPerPixel = 0; 76 private int mBytesPerLine = 0; 77 private int mBytesPerImage = 0; 78 private byte[] mImageBytes; 79 private ByteBuffer mFlipBuf; 80 81 private int mFrameRate = 0; 82 83 private MediaController mMediaController; 84 private boolean mMediaControllerAttached; 85 private boolean mIsPlaying = false; 86 private int mImageIndex = 0; 87 private List<String> mImageList; 88 private Timer mTimer; 89 private TimerTask mImageTask = new TimerTask() { 90 @Override 91 public void run() { 92 if (mIsPlaying) { 93 mImageIndex++; 94 LoadImage(); 95 } 96 } 97 }; 98 private Handler mHandler = new Handler() { 99 @Override 100 public void handleMessage(Message msg) { 101 super.handleMessage(msg); 102 invalidate(); 103 } 104 }; 105 106 107 public RgbView(Context context) { 108 super(context); 109 110 // read properties 111 Properties prop = new Properties(); 112 try { 113 prop.loadFromXML(new FileInputStream("/sdcard/mediadump/prop.xml")); 114 } catch (java.io.IOException e) { 115 Log.e(TAG, e.getMessage(), e); 116 } 117 118 try { 119 mStartX = Integer.parseInt(prop.getProperty("startX")); 120 mStartY = Integer.parseInt(prop.getProperty("startY")); 121 mWidth = Integer.parseInt(prop.getProperty("width")); 122 mHeight = Integer.parseInt(prop.getProperty("height")); 123 mBytesPerPixel = Integer.parseInt(prop.getProperty("bytesPerPixel")); 124 mFrameRate = Integer.parseInt(prop.getProperty("frameRate")); 125 } catch (java.lang.NumberFormatException e) { 126 Log.e(TAG, e.getMessage(), e); 127 } 128 129 mBytesPerLine = mWidth * mBytesPerPixel; 130 mBytesPerImage = mHeight * mBytesPerLine; 131 mFlipBuf = ByteBuffer.allocate(mBytesPerImage); 132 mBitmap = Bitmap.createBitmap(mWidth, mHeight, 133 mBytesPerPixel == 2 134 ? Bitmap.Config.RGB_565 135 : Bitmap.Config.ARGB_8888); 136 137 mImageList = new ArrayList<String>(); 138 try { 139 BufferedReader reader = new BufferedReader( 140 new FileReader("/sdcard/mediadump/images.lst")); 141 String line; 142 while ((line = reader.readLine()) != null) { 143 mImageList.add(line); 144 } 145 reader.close(); 146 } catch (java.io.IOException e) { 147 Log.e(TAG, e.getMessage(), e); 148 } 149 150 mMediaController = new MediaController(context); 151 mTimer = new Timer(); 152 LoadImage(); 153 } 154 155 private void attachMediaController() { 156 if (mMediaController != null) { 157 if (!mMediaControllerAttached) { 158 mMediaController.setMediaPlayer(this); 159 View anchorView = this.getParent() instanceof View ? 160 (View)this.getParent() : this; 161 mMediaController.setAnchorView(anchorView); 162 mMediaController.setEnabled(true); 163 mMediaControllerAttached = true; 164 mTimer.scheduleAtFixedRate(mImageTask, 0, 1000 / mFrameRate); 165 } 166 mMediaController.show(); 167 } 168 } 169 170 @Override 171 public boolean onTouchEvent(MotionEvent event) { 172 attachMediaController(); 173 return true; 174 } 175 176 private void LoadImage() { 177 try { 178 if (mImageIndex < 0 || mImageIndex >= mImageList.size()) { 179 mImageIndex = 0; 180 mIsPlaying = false; 181 } 182 183 String filename = mImageList.get(mImageIndex); 184 185 FileInputStream in = new FileInputStream(filename); 186 mImageBytes = new byte[mBytesPerImage]; 187 in.read(mImageBytes); 188 } catch (Exception e) { 189 Log.e("Error reading file", e.toString()); 190 } 191 192 // Flip the image vertically since the image from MediaDump is 193 // upside down. 194 for (int i = mHeight - 1; i >= 0; i--) { 195 mFlipBuf.put(mImageBytes, i * mBytesPerLine, mBytesPerLine); 196 } 197 mFlipBuf.rewind(); 198 mBitmap.copyPixelsFromBuffer(mFlipBuf); 199 mFlipBuf.rewind(); 200 mHandler.sendEmptyMessage(0); 201 } 202 203 @Override 204 protected void onDraw(Canvas canvas) { 205 canvas.drawBitmap(mBitmap, mStartX, mStartY, null); 206 } 207 208 public boolean canPause() { 209 return true; 210 } 211 212 public boolean canSeekBackward() { 213 return true; 214 } 215 216 public boolean canSeekForward() { 217 return true; 218 } 219 220 public int getBufferPercentage() { 221 return 1; 222 } 223 224 public int getCurrentPosition() { 225 return mImageIndex * 1000 / mFrameRate; 226 } 227 228 public int getDuration() { 229 return mImageList.size() * 1000 / mFrameRate; 230 } 231 232 public boolean isPlaying() { 233 return mIsPlaying; 234 } 235 236 public void pause() { 237 mIsPlaying = false; 238 } 239 240 public void seekTo(int pos) { 241 mImageIndex = pos * mFrameRate / 1000; 242 } 243 244 public void start() { 245 mIsPlaying = true; 246 } 247 248 @Override 249 public int getAudioSessionId() { 250 return 0; 251 } 252 } 253 254 } 255