Android测量每秒帧数Frames Per Second (FPS)的方法

本文实例讲述了Android测量每秒帧数Frames Per Second (FPS)的方法。分享给大家供大家参考。具体如下:

MainThread.java:

package net.obviam.droidz;
import java.text.DecimalFormat;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
/**
 * @author impaler
 *
 * The Main thread which contains the game loop. The thread must have access to
 * the surface view and holder to trigger events every game tick.
 */
public class MainThread extends Thread {
 private static final String TAG = MainThread.class.getSimpleName();
 // desired fps
 private final static int MAX_FPS = 50;
 // maximum number of frames to be skipped
 private final static int MAX_FRAME_SKIPS = 5;
 // the frame period
 private final static int FRAME_PERIOD = 1000 / MAX_FPS;
 // Stuff for stats */
 private DecimalFormat df = new DecimalFormat("0.##"); // 2 dp
 // we'll be reading the stats every second
 private final static int STAT_INTERVAL = 1000; //ms
 // the average will be calculated by storing
 // the last n FPSs
 private final static int FPS_HISTORY_NR = 10;
 // last time the status was stored
 private long lastStatusStore = 0;
 // the status time counter
 private long statusIntervalTimer = 0l;
 // number of frames skipped since the game started
 private long totalFramesSkipped   = 0l;
 // number of frames skipped in a store cycle (1 sec)
 private long framesSkippedPerStatCycle = 0l;
 // number of rendered frames in an interval
 private int frameCountPerStatCycle = 0;
 private long totalFrameCount = 0l;
 // the last FPS values
 private double fpsStore[];
 // the number of times the stat has been read
 private long statsCount = 0;
 // the average FPS since the game started
 private double averageFps = 0.0;
 // Surface holder that can access the physical surface
 private SurfaceHolder surfaceHolder;
 // The actual view that handles inputs
 // and draws to the surface
 private MainGamePanel gamePanel;
 // flag to hold game state
 private boolean running;
 public void setRunning(boolean running) {
  this.running = running;
 }
 public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
  super();
  this.surfaceHolder = surfaceHolder;
  this.gamePanel = gamePanel;
 }
 @Override
 public void run() {
  Canvas canvas;
  Log.d(TAG, "Starting game loop");
  // initialise timing elements for stat gathering
  initTimingElements();
  long beginTime;  // the time when the cycle begun
  long timeDiff;  // the time it took for the cycle to execute
  int sleepTime;  // ms to sleep (<0 if we're behind)
  int framesSkipped; // number of frames being skipped
  sleepTime = 0;
  while (running) {
   canvas = null;
   // try locking the canvas for exclusive pixel editing
   // in the surface
   try {
    canvas = this.surfaceHolder.lockCanvas();
    synchronized (surfaceHolder) {
     beginTime = System.currentTimeMillis();
     framesSkipped = 0; // resetting the frames skipped
     // update game state
     this.gamePanel.update();
     // render state to the screen
     // draws the canvas on the panel
     this.gamePanel.render(canvas);
     // calculate how long did the cycle take
     timeDiff = System.currentTimeMillis() - beginTime;
     // calculate sleep time
     sleepTime = (int)(FRAME_PERIOD - timeDiff);
     if (sleepTime > 0) {
      // if sleepTime > 0 we're OK
      try {
       // send the thread to sleep for a short period
       // very useful for battery saving
       Thread.sleep(sleepTime);
      } catch (InterruptedException e) {}
     }
     while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
      // we need to catch up
      this.gamePanel.update(); // update without rendering
      sleepTime += FRAME_PERIOD; // add frame period to check if in next frame
      framesSkipped++;
     }
     if (framesSkipped > 0) {
      Log.d(TAG, "Skipped:" + framesSkipped);
     }
     // for statistics
     framesSkippedPerStatCycle += framesSkipped;
     // calling the routine to store the gathered statistics
     storeStats();
    }
   } finally {
    // in case of an exception the surface is not left in
    // an inconsistent state
    if (canvas != null) {
     surfaceHolder.unlockCanvasAndPost(canvas);
    }
   } // end finally
  }
 }
 /**
  * The statistics - it is called every cycle, it checks if time since last
  * store is greater than the statistics gathering period (1 sec) and if so
  * it calculates the FPS for the last period and stores it.
  *
  * It tracks the number of frames per period. The number of frames since
  * the start of the period are summed up and the calculation takes part
  * only if the next period and the frame count is reset to 0.
  */
 private void storeStats() {
  frameCountPerStatCycle++;
  totalFrameCount++;
  // check the actual time
  statusIntervalTimer += (System.currentTimeMillis() - statusIntervalTimer);
  if (statusIntervalTimer >= lastStatusStore + STAT_INTERVAL) {
   // calculate the actual frames pers status check interval
   double actualFps = (double)(frameCountPerStatCycle / (STAT_INTERVAL / 1000));
   //stores the latest fps in the array
   fpsStore[(int) statsCount % FPS_HISTORY_NR] = actualFps;
   // increase the number of times statistics was calculated
   statsCount++;
   double totalFps = 0.0;
   // sum up the stored fps values
   for (int i = 0; i < FPS_HISTORY_NR; i++) {
    totalFps += fpsStore[i];
   }
   // obtain the average
   if (statsCount < FPS_HISTORY_NR) {
    // in case of the first 10 triggers
    averageFps = totalFps / statsCount;
   } else {
    averageFps = totalFps / FPS_HISTORY_NR;
   }
   // saving the number of total frames skipped
   totalFramesSkipped += framesSkippedPerStatCycle;
   // resetting the counters after a status record (1 sec)
   framesSkippedPerStatCycle = 0;
   statusIntervalTimer = 0;
   frameCountPerStatCycle = 0;
   statusIntervalTimer = System.currentTimeMillis();
   lastStatusStore = statusIntervalTimer;
//   Log.d(TAG, "Average FPS:" + df.format(averageFps));
   gamePanel.setAvgFps("FPS: " + df.format(averageFps));
  }
 }
 private void initTimingElements() {
  // initialise timing elements
  fpsStore = new double[FPS_HISTORY_NR];
  for (int i = 0; i < FPS_HISTORY_NR; i++) {
   fpsStore[i] = 0.0;
  }
  Log.d(TAG + ".initTimingElements()", "Timing elements for stats initialised");
 }
}

希望本文所述对大家的java程序设计有所帮助。

(0)

相关推荐

  • Android View 测量流程(Measure)全面解析

    前言 上一篇文章,笔者主要讲述了DecorView以及ViewRootImpl相关的作用,这里回顾一下上一章所说的内容:DecorView是视图的顶级View,我们添加的布局文件是它的一个子布局,而ViewRootImpl则负责渲染视图,它调用了一个performTraveals方法使得ViewTree开始三大工作流程,然后使得View展现在我们面前.本篇文章主要内容是:详细讲述View的测量(Measure)流程,主要以源码的形式呈现,源码均取自Android API 21. 从ViewRoo

  • Android View如何测量

    对于Android View的测量,我们一句话总结为:"给我位置和大小,我就知道您长到那里". 为了让大家更好的理解这个结论,我这里先讲一个日常生活中的小故事:不知道大家玩过"瞎子画画"的游戏没,一个人蒙上眼睛,拿笔去画板上画一些指定的图案,另外一个人则充当他的"眼睛",通过语言告诉他在画板那个位置画一个多大的图案.倘若,这个人不告诉那个蒙着眼睛的人,在那个画一个多大的图案.那么这个蒙着眼睛的人此时真是"河里赶大车----------没

  • Android视图的绘制流程(上) View的测量

    综述 View的绘制流程可以分为三大步,它们分别是measure,layout和draw过程.measure表示View的测量过程,用于测量View的宽度和高度:layout用于确定View在父容器的位置:draw则是负责将View绘制到屏幕中.下面主要来看一下View的Measure过程. 测量过程 View的绘制流程是从ViewRoot的performTraversals方法开始的,ViewRoot对应ViewRootImpl类.ViewRoot在performTraversals中会调用p

  • Android测量每秒帧数Frames Per Second (FPS)的方法

    本文实例讲述了Android测量每秒帧数Frames Per Second (FPS)的方法.分享给大家供大家参考.具体如下: MainThread.java: package net.obviam.droidz; import java.text.DecimalFormat; import android.graphics.Canvas; import android.util.Log; import android.view.SurfaceHolder; /** * @author impa

  • python 读取视频,处理后,实时计算帧数fps的方法

    实时计算每秒的帧数 cap = cv2.VideoCapture("DJI_0008.MOV") #cap = cv2.VideoCapture(0) # Define the codec and create VideoWriter object #fourcc = cv2.cv.FOURCC(*'XVID') fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('output1.avi', fourcc, 2

  • 使用python-opencv读取视频,计算视频总帧数及FPS的实现

    如下所示: 1.计算总帧数 import os import cv2 video_cap = cv2.VideoCapture('ffmpeg_test.avi') frame_count = 0 all_frames = [] while(True): ret, frame = video_cap.read() if ret is False: break all_frames.append(frame) frame_count = frame_count + 1 # The value be

  • android 获取视频第一帧作为缩略图的方法

    今天,简单讲讲android里如何获取一个视频文件的第一帧作为缩略图显示在界面上. 之前,我说个最近需要从服务器下载视频文件,但是下载后肯定需要显示视频的缩略图在界面上给用户看,于是想到显示视频的第一帧作为缩略图.但是我不知道具体怎么写,于是在网上查找资料,最终是解决了问题.这里记录一下. 一.使用MediaMetadataRetriever获取视频的第一帧作为缩略图 /** * 获取视频文件截图 * * @param path 视频文件的路径 * @return Bitmap 返回获取的Bit

  • JS实现获取GIF总帧数的方法详解

    目录 前言 写在前面 思路分析 什么是Gif 组成结构 解析原理 数据块分析 Header Block Logical Screen Descriptor Global Color Table Graphics Control Extension Image Descriptor Image Data 实现代码 测试用例 插件地址 前言 有一个Gif图片,我们想要获取它的总帧数,超过一定帧数的图片告知用户不可上传,在服务端有很多现成的库可以使用,这种做法不是很友好,前端需要先将gif上传至服务端

  • Android布局之FrameLayout帧布局

    前言 作为android六大布局中最为简单的布局之一,该布局直接在屏幕上开辟出了一块空白区域, 当我们往里面添加组件的时候,所有的组件都会放置于这块区域的左上角; 帧布局的大小由子控件中最大的子控件决定,如果都组件都一样大的话,同一时刻就只能能看到最上面的那个组件了! 当然我们也可以为组件添加layout_gravity属性,从而制定组件的对其方式 帧布局在游戏开发方面用的比较多,等下后面会给大家演示一下比较有意思的两个实例 (-)帧布局简介 帧布局容器为每个加入的其中的组件创建一个空白的区域称

  • php读取flash文件高宽帧数背景颜色的方法

    本文实例讲述了php读取flash文件高宽帧数背景颜色的方法.分享给大家供大家参考. 具体实现方法如下: 复制代码 代码如下: <?php /* 示例:   $file = '/data/ad_files/5/5.swf';   $flash = new flash();   $flash = $flash->getswfinfo($file);   echo " 文件的宽高是:".$flash["width"].":".$info[

  • Android动画之逐帧动画(Frame Animation)实例详解

    本文实例分析了Android动画之逐帧动画.分享给大家供大家参考,具体如下: 在开始实例讲解之前,先引用官方文档中的一段话: Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画.Frame动画可以被定义在XML文件中,也可以完全编码实现. 如果被定义在XML文件中,我们可以放置在/res下的anim或drawable目录中(/res/[anim | drawable]/filename.xml),文件名可以作为资源ID在代码中引用:如果由完全由编码实现,我

  • js获取 gif 的帧数的代码实例

    使用 javascript 获取 GIF 图的帧数,如果帧数过大,则不让传到服务器 这里是使用一个插件: github地址为: https://github.com/buzzfeed/libgif-js <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <meta name="viewport" con

  • Android开发实现布局帧布局霓虹灯效果示例

    本文实例讲述了Android开发实现布局帧布局霓虹灯效果.分享给大家供大家参考,具体如下: 效果图: 实现方式: FrameLayout中,设置8个TextView,在主函数中,设计颜色数组,通过有序替换他们颜色,实现渐变效果. java代码:MainActivity public class MainActivity extends AppCompatActivity { private int currentColor = 0; /* 定义颜色数组 实现颜色切换 类似鱼片切换 */ fina

随机推荐