2013年4月6日 星期六

FFMPEG -- iPhone下的效能優化

近期需要使用 FFMPEG 在 iOS 設備下,因此對其效能優化作一討論。我的測試資料如下:
  • FFMPEG 版本為 Jan 27, 2013 
  • 測試程式使用 iFrameExtractor
  • 測試檔案使用的檔案為 http://mm2.pcslab.com/mm/7h800.mp4 (H.264 800kbs)
  • 測試設備為 iPad2

主要優化的目標是減少下列兩個行為的執行時間
  • Decode Frame
  • Scale and Render



程式修改
修改 iFrameExtractor Project 的 iFrameExtractorAppDelegate.m,分別計算以下兩段程式執行所需要的時間,
  • stepFrame() 當成是 decode 所需時間 
  • currentImage() 當成是 Scale + render 所需時間 (實際上 render 的動作應該在更後面) 
  • 每作完 30 次 displayNextFrame之後,計算平均時間

int vDecodeNum=0, vScaleNum=0, vDisplayNextFrameCount=0; float vDecodeTime=0.0, vScaleTime=0.0; -(void)displayNextFrame:(NSTimer *)timer { NSTimeInterval vTmpTime = [NSDate timeIntervalSinceReferenceDate]; if (![video stepFrame]) { [timer invalidate]; [playButton setEnabled:YES]; return; } vDecodeTime += [NSDate timeIntervalSinceReferenceDate] - vTmpTime; vDecodeNum++; vTmpTime = [NSDate timeIntervalSinceReferenceDate]; imageView.image = video.currentImage; vScaleTime += [NSDate timeIntervalSinceReferenceDate] - vTmpTime; vScaleNum++; vDisplayNextFrameCount++; if(vDisplayNextFrameCount==30) { NSLog(@"DecodeTime:%f, ScaleTime:%f", vDecodeTime/vDecodeNum, vScaleTime/vScaleNum); vDisplayNextFrameCount = 0; vDecodeNum=0; vScaleNum=0; vDecodeTime=0.0; vScaleTime=0.0 } }


測試結果如下:
  Decode Scale Note
1. 原始的 iFrame Extractor 6~11ms  12ms  
2. 將檔案放在記憶體內撥放 5~10ms  12ms 減少 I/O
3. ffmpeg library 使用 neon 指令集  1~2ms  12ms CPU硬體加速,效果明顯
4. 使用 OPEN GL ES 替代 currentImage + sws_scale 函數     Future work

     

結論:
  • 使用 ARM neon 指令集,可以大幅縮短 decode 時間。
  • 目前在 iPad2 與 iPad mini 下,使用neon指令集的優化,已可流暢的播放 720P 影像,因此 scale部分的優化暫且不作。

參考資料: