0

我正在编写一个 Android 应用程序来使用 OpenGL ES 2.0 从二进制文件播放视频。有一个大视频文件,其中包含完全未格式化的二进制像素数据(价值 1000 帧)。我正在使用 RandomAccessFile 打开文件,导航到正确的点并提取所需帧的像素数据。

我最初通过打开文件并在每次调用 onDrawFrame 时再次关闭它来非常粗略地完成此操作。

    //The following sits within the onDrawFrame activity:

    long time = SystemClock.uptimeMillis() % 4000L
    long frame = 0;
    frame = time/10;

    int w = 640; //width in pixels
    int h = 512; //height in pixels
    int nP = w * h; //number of pixels in frame and size of frame in bytes

    byte[] byteArray = new byte[nP]; //array to hold one frame


    try {

    RandomAccessFile f = new RandomAccessFile("//sdcard/8bitvid.bin", "r"); //open the video file

    f.seek(nP*frame);   //navigate to the correct frame
    f.read(byteArray);  //read frame
    f.close();          //close file
    }

我意识到这在很多方面都是错误的,但我刚刚从 Labview 迁移到 Java,这真是一个飞跃!所以我的问题是:

- 我应该如何在 onDrawFrame 调用之间保持文件打开?

- 如何在 onDrawFrame 的交互之间传递变量(即帧号)?

快速解释或只是指向相关示例的指针会很棒。

谢谢

卢克

4

1 回答 1

0

所以有几件事......你的二进制文件中可能有颜色信息,所以你应该在你的数组初始化中包含它 -

  int nP = w * h *3;  // RGB = 3 bytes, RGBA = 4 bytes.

另一件事是,每次调用 ondrawframe 时,您都需要重新打开文件。您只需执行一次。您可以将 RandomAccessFile f 声明为渲染器类的私有成员,并在构造函数上打开文件。如果您将其保持打开状态,则不会每次都重新打开它。这实际上可能是也可能不是问题。不过,为了跟踪您看到的帧数,我建议在类中创建一个私有 int 并在每次绘制帧时递增它。

所以这是我的建议:

class glVideoRenderer implements GLSurfaceView.Renderer{
  private int frameNumber = 0;
  RandomAccessFile f;


  public glVideoRenderer(){
     try{
        f= new RandomAccessFile("//sdcard/8bitvid.bin", "r");
      }
      catch(...
  }


  public void onDrawFrame(GL10 unused){
     ..... // whatever you need here    
     f.seek(nP*frameNumber++);   //navigate to the correct frame,  frameNumber increments after the line is executed
     ....... // update whatever you need here.
  }

} 
于 2013-01-22T20:34:23.393 回答