1

I am experiencing frame drop issue with video playback. We just moved from ICS to KK4.4. Video is very small 320x240 resolution. There is no audio to make things simple.

Systrace is at following location: https://www.dropbox.com/s/bee6xymg3kpn4ft/mytrace2.html?dl=0

I have enabled Triple Buffering and hwcomposer is generating fake vsync's to the SurfaceFlinger.

I can see following issues:

  1. Triple buffering not enabled properly since videodecoder allocates 7 buffers queue. In case Triple buffering was working fine for each frame that gets queued from TimedEventQueue(OnVideoEvent), the buffer that should get dequeued should be 2 slots behind. For Ex: if we queue buf 4 then buf 2 should be dequeued but whats is getting dequeued is immediate previous buffer which surfaceflinger only releases when it gets the chance to run the next time. Hence the delay and whichin turn causes cancelbuffers for video to catch up.

  2. SurfaceFlinger itself taking some time to finish.

  3. Vsync not getting turned on at appropriate times say every 33ms for a 30 fps video. An Issue with vsync generation logic in HWComposer or vsync not being enabled by eventControl due to no actual buffers being Queued?

Updating from the below comment that I made: Other things that I have noted is that async and mDequeueBufferCannotBlock flags are both false and hence getMinUndequeuedBufferCount() returns 1 and thus we see the immediate previous buffer being asked for dequeue rather than a buffer 2 slots behind. PLease let me know if there is hole in above understanding. And anything that i can do to get around this

Any help is greatly appreciated.

1 Answers1

1
  1. The video codecs decide how many buffers they need. BufferQueue configuration is a negotiation.

  2. I don't see where SurfaceFlinger is taking a long time to finish. Look at the /system/bin/surfaceflinger line -- it's working quickly.

  3. There is no value in waking up and doing work when there's no work to do, so VSYNC gets switched off if there's nothing happening. Your latter assumption is correct -- if you look at the SurfaceView row you can see a correlation between no buffers available and no wake-up in SurfaceFlinger.

I'm seeing 180ms between the arrival of frames on the SurfaceView BufferQueue, which is about 5.5fps. There's some long onVideoEvent sections in the mediaserver process -- what codec are you using?

You described this as a "frame drop" issue -- which player are you using?

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Thanks for the reply. We are using OMX codec and stock android video player. Now OnVideoEvent is taking more time because dequeuebuffer is taking long time most of the time. Now DequeueBuffer is taking a long time since the surfaceView its trying to dequeue is still being held by surface flinger. Surface flinger released it only in the next instance of itself after it acquired the next buffer. – Vineet Bajaj Sep 17 '15 at 17:21
  • Other things that I have noted is that async and mDequeueBufferCannotBlock flags are both false and hence getMinUndequeuedBufferCount() returns 1 and thus we see the immediate previous buffer being asked for dequeue rather than a buffer 2 slots behind. PLease let me know if there is hole in above understanding. And anything that i can do to get around this. – Vineet Bajaj Sep 17 '15 at 17:22
  • Anything that can help me.. :) – Vineet Bajaj Sep 18 '15 at 09:13
  • Get a systrace of Grafika's player on the same video (or use a test clip with the "play at 60 fps" box checked). Compare the behavior and try to figure out why they're different. (If they're not different, that's interesting too.) The "scheduled swap" activity is useful as a SurfaceFlinger+systrace "tone generator" if you want to see how the system looks at different frame rates. Bottom line is that it's possible to play video at 60fps, so if it's not my inclination is to look at the source (codec/decoder) rather than the parts in the middle or end. – fadden Sep 18 '15 at 15:11