title: Displaying 450 image files from SDCard at 30fps on android
body: <p>I am trying to develop an app that takes a 15 seconds of video, allows the user to apply different filters, shows the preview of the effect, then allows to save the processed video to sdcard. I use ffmpeg to split the video into JPEG frames, apply the desired filter using GPUImage to all the frames, then use ffmpeg to encode the frames back to a video. Everything works fine except the part where user selects the filter. When user selects a filter, the app is supposed to display the preview of the video with the filter applied. Though 450 frames get the filter applied fairly quick, displaying the images sequentially at 30 fps (to make the user feel the video is being played) is performing poorly. I tried different approaches but the maximum frame rate I could attain even on the fastest devices is 10 to 12 fps. </p>
  
  <p>The AnimationDrawable technique doesn't work in this case because it requires the entire images to be buffered into memory which in this case is huge. App crashes.</p>
  
  <p>The below code is the best performing one so far (10 to 12 fps).</p>
  
  <pre><code>package com.example.animseqvideo;
  import ......
  
  public class MainActivity extends Activity {
      Handler handler;
      Runnable runnable;
      final int interval = 33; // 30.30 FPS
      ImageView myImage;
      int i=0;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          myImage = (ImageView) findViewById(R.id.imageView1);
  
          handler = new Handler();
          runnable = new Runnable(){
              public void run() {
  
                  i++;  if(i&gt;450)i=1;
  
                  File imgFile = new  File(Environment.getExternalStorageDirectory().getPath() + "/com.example.animseqvideo/image"+ String.format("%03d", i)   +".jpg");
                  if(imgFile.exists()){
                      Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
                      myImage.setImageBitmap(myBitmap);
                  }
  //SOLUTION EDIT - MOVE THE BELOW LINE OF CODE AS THE FIRST LINE OF run() AND FPS=30 !!!
  
                  handler.postDelayed(runnable, interval);
              }
          };
          handler.postAtTime(runnable, System.currentTimeMillis()+interval);
          handler.postDelayed(runnable, interval);
      }
  }
  </code></pre>
  
  <p>I understand that the process of getting an image from SDCard, decoding it, then displaying it onto the screen involves the performance of the SDCard reading, the CPUs performance and graphics performance of the device. But I am wondering if there is a way I could save a few milliseconds in each iteration. Any suggestion would be of great help at this point.</p>