Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add buffering to video renderers #2777

Merged
merged 20 commits into from
May 31, 2013
Merged

Add buffering to video renderers #2777

merged 20 commits into from
May 31, 2013

Conversation

elupus
Copy link
Contributor

@elupus elupus commented May 22, 2013

This replaces: #2309

It implements a render queue in the renderers allowing main thread to continue rendering more frames while we are decoding. This should reduce the likelihood of stuttering due to high cpu load.

The default queue size is 3. Thus 1 additional frames. This is likely a candidate for advanced settings since it will allocate full pictures frames in memory during playback. This could be increased on systems that have enough memory.

The queue will always select the last decoded frame that has a present time that has passed. This mean it will potentially drop frames at output stage. This has the added benefit of us finally being able to play 50fps video's on 30hz displays and 60fps video's on 50hz displays without causing total audio desync.

@elupus
Copy link
Contributor Author

elupus commented May 22, 2013

This need testing on vaap, rbpi and omx. I'm not sure what android uses in playback, but it won't hurt to test it there too.

@FernetMenta
Copy link
Contributor

maybe we should drop the OMXPlayer commit: 3e9c2b9785fba9336192b203e26285c53273b5c9 from this pr, only keep the required change to configure. It will correct out of sync subs but regression in performance. The current code in OMXPlayer is not correct because it just skips driving the gui but this requires more work to get this fixed without sacrifice current performance.

@wsnipex
Copy link
Member

wsnipex commented May 23, 2013

ubuntu packages for testing: https://launchpad.net/~wsnipex/+archive/xbmc-pr-tests

@elupus
Copy link
Contributor Author

elupus commented May 23, 2013

There is a performance issue with the queue (should not be worse than old code) causing it to not queue items unless decode is quite a lot faster than display. This is due to our large scale locks in rendermanager.

FlipPage get's blocked on a shared lock during render. The queue and the present info need to be on a separate lock from the shared lock.

@elupus
Copy link
Contributor Author

elupus commented May 25, 2013

I'm starting to feel quite happy with this pull now. But again, i need testing on OMX. I think dxva/vaapi/vdpau/vda are fine.

@FernetMenta
Copy link
Contributor

@elupus I needed this change for successful compilation on RPi: FernetMenta@1876d2a
I did some quick tests and did not see any (new) problems. As mentioned before, OMXPlayers's interface to renderer is borked anyway and needs rework.

@huceke
Copy link
Contributor

huceke commented May 28, 2013

Looking ok to me on the PI. Waiting for feedback from popcornmix.

@popcornmix
Copy link
Member

I'll try to test this tonight with some borderline performance clips and see if things are better or worse.
In principle I like the change.

@elupus
Copy link
Contributor Author

elupus commented May 28, 2013

Note. Rbpi is limited to tw buffers at the moment. Change that 0 in
configure to 3 and verify it ends up at that if the Rbpi codes can handle
it.

@popcornmix
Copy link
Member

@elupus
You are refering to whether GL is double or triple buffered on Pi? It is triple buffered by default.

@rbej
Copy link

rbej commented May 28, 2013

Little out of sync internal subs [1/17] in this video sample on Rpi.

http://www.mediafire.com/download/eo6q1udxdj64ppf/The.Hobbit.An.Unexpected.Journey.2012.1080p.BluRay.10bit.48fps.edition.DTS.x264-HDMaNiAcS-sample.mkv

On FernetMenta version this patch subs sync is perfect.

@elupus
Copy link
Contributor Author

elupus commented May 28, 2013

Nope not glx buffering, I'm not sure how the Rbpi renders frames. Is it
using the gl renderer at all? or is it blended in with some external
overlay?

Regarding subs, it aught to be identical to before the pull? But I think I
see an easy way to improve it.

@popcornmix
Copy link
Member

Video is separate from GL on Pi (an external overlay).
Yes, subs sync was off before this pull. It did get fixed in some versions of FernetMenta's "buffering" pull request, although it seemed tricky to fix without causing a performance loss (by blocking OMXPlayerVideo.cpp thread).

@FernetMenta
Copy link
Contributor

Currently OMXplayer just skips driving the gl layer when getting late. This causes out-of-sync subs but a gain in performance. Buffering alone in the gl layer won't cure the loss in performance when keeping video and gl in sync. The gl layer still gets cleared and flipped on every cycle. It has to be treated like a dirty region in order to get both, synced subs and performance.
This is out of scope of this pr, hence we left out the first part as well. There should be no difference between after and before this pr.

@elupus
Copy link
Contributor Author

elupus commented May 28, 2013

I just pushed a shot in the dark at an RBPI improvement. It will avoid blocking rbpi thread, and queue up overlays.

@popcornmix
Copy link
Member

I checked out master and wound the clock frequency down until my test clip just played without buffering.
I then applied this PR without 284f9c3. I think I'm okay with performance. It seemed a little worse, but there's a certain amount of variance in this test. It did play without buffering on a number of runs.

My test clip did not contain subtitles.

284f9c3 was less successful. That clearly seemed to hurt performance (it buffered every time on about 10 runs).
It also makes subtitles appear 6 seconds early. (Probably the diffrerence in timestamps of frames being added to GPU fifo and decoded frames appearing on screen).

OMXMediaTime() is the time of the currently displayed video frame which can be several seconds behind the pts values of packets arriving at OMXPlayerVideo.cpp. You need the pts of the subtitle being rendered to match OMXMediaTime().

@popcornmix
Copy link
Member

I think I'm seeing a regression. If I play a file through json. Then play it again (or a different one) without quitting back to UI, I get no video. I hear the audio, the home menu is still present (no visualisation). I can select "fullscreen" from menu, but I just get a blank screen.

Once in this state I can't play any video (even if video is quit first). Restarting xbmc allows video to work again.

This required 3 plays to get into this bad state:
http://pastebin.com/0KuMduT4

if(m_presentstep == PRESENT_IDLE)
{
if(GetNextRender() >= 0)
m_presentstep = PRESENT_READY;

This comment was marked as spam.

@kraqh3d
Copy link

kraqh3d commented May 31, 2013

I've not any issues with video playlists but some dvd's don't play correctly. The menu seems to render correctly, but for some movies the last frame of the menu gets stuck on screen. The audio for the movie will play behind it and xbmc becomes unresponsive. It won't respond to the remote or to events sent from xbmc-send to localhost. The same problematic videos play in Frodo and in Gotham without the patch applied. (They were the same ones I used when testing the dvd_reader patch.) I just noticed the new commit, 00ad3e6. My build is from before this commit. I will test with it as soon as a I can to see if it fixes the problem.

@elupus
Copy link
Contributor Author

elupus commented May 31, 2013

Yea that should fix that issue. Dvds reconfigure all the time.

@FernetMenta
Copy link
Contributor

It can still hang due to negative timeouts in WaitForBuffer, it did so during my last tests.

@elupus
Copy link
Contributor Author

elupus commented May 31, 2013

That is a bit strange. That should just cause a huge timeout value. Why
don't we get a buffer?

@FernetMenta
Copy link
Contributor

It happened on stop and video player thread was waiting with that huge timeout in m_presentevent.wait

iirc main thread was waiting for player to exit which was waiting for video player.

@kraqh3d
Copy link

kraqh3d commented May 31, 2013

I've got an iso that fails consistently and that commit didn't fix it. The same thing happens. Nothing looks anomalous from the log. I'll be away for the weekend but can help debug after I'm back.

@elupus
Copy link
Contributor Author

elupus commented May 31, 2013

I'm rebasing and merging within in the hour. @kraqh3d i would think your issue is the negative timestamp problem.

FernetMenta and others added 14 commits May 31, 2013 19:59
This is how many references to pictures that can be retained when
calling Decode the next time around
We don't even need to hold lock here potentially
This allow renderer to queue up frames for display after decode.

Original Implementation By: Rainer Hochecker <fernetmenta@online.de>
Allo dropping a frame that is about to be rendered, if it is late
and there already exist a replacement frame that should be presented
now.
RenderManager can now take care of this in a much more intellegent
fashion
This looks rather messy. But is solves an important performance issue
where decode thread would be blocked waiting flip by render thread while
it was rendering current frame.

Without this faster than display rate decode is not possible
elupus added a commit that referenced this pull request May 31, 2013
Add buffering to video renderers
@elupus elupus merged commit 3fcde70 into xbmc:master May 31, 2013
@Voyager1
Copy link

this causes major regression on dvd with menu playback. Tested several dvds, after I go through the dvd menu, select "play", the image freezes and all I hear is sound, but no video starts. The only thing I can do is kill xbmc. Excerpt debug Log:

22:56:38 T:9832   DEBUG: CDVDInputStreamNavigator::ProcessBlock - Cell change: Title 1, Chapter 1
22:56:38 T:9832   DEBUG: CDVDInputStreamNavigator::ProcessBlock - At position 0% inside the feature
22:56:38 T:9832   DEBUG: DVDNAV_CELL_CHANGE
22:56:38 T:9832   DEBUG: DVDNAV_NAV_PACKET - DISCONTINUITY FROM:8287266 TO:375733 DIFF:-7911533
22:56:38 T:5600   DEBUG: CAESinkDirectSound::CheckPlayStatus: Resuming Playback
22:56:38 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:56:38 T:9064 WARNING: Previous line repeats 3 times.
22:56:38 T:9064   DEBUG: CDVDPlayerVideo - CDVDMsg::GENERAL_SYNCHRONIZE
22:56:38 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:56:39 T:10920 WARNING: Previous line repeats 5 times.
22:56:39 T:10920   DEBUG: CDVDPlayerAudio:: Discontinuity1 - was:2993715.829705, should be:2824000.000000, error:-169715.829705
22:56:39 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:56:39 T:10920 WARNING: Previous line repeats 3 times.
22:56:39 T:10920   DEBUG: CDVDPlayerAudio:: Discontinuity1 - was:3205081.026865, should be:3100957.031292, error:-104123.995573
22:56:39 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:56:43 T:9064 WARNING: Previous line repeats 101 times.
22:56:43 T:9064   DEBUG: CPullupCorrection: detected pattern of length 1: 40000.00, frameduration: 40000.000000
22:56:43 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:56:58 T:9832 WARNING: Previous line repeats 364 times.
22:56:58 T:9832   DEBUG: CDVDPlayer::ProcessSubData: Got complete SPU packet
22:56:58 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:57:03 T:8864 WARNING: Previous line repeats 136 times.
22:57:03 T:8864   DEBUG: Thread JobWorker 8864 terminating (autodelete)
22:57:03 T:8312   DEBUG: Thread JobWorker 8312 terminating (autodelete)
22:57:03 T:7356   DEBUG: Thread JobWorker 7356 terminating (autodelete)
22:57:03 T:4528   DEBUG: Thread JobWorker 4528 terminating (autodelete)
22:57:03 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:57:05 T:9832 WARNING: Previous line repeats 49 times.
22:57:05 T:9832   DEBUG: CDVDPlayer::ProcessSubData: Got complete SPU packet
22:57:05 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer
22:57:13 T:9832 WARNING: Previous line repeats 197 times.
22:57:13 T:9832   DEBUG: CDVDPlayer::ProcessSubData: Got complete SPU packet
22:57:13 T:9064 WARNING: CRenderManager::WaitForBuffer - timeout waiting for buffer

@Voyager1
Copy link

update - this is the same problem @kraqh3d described. Last frame of the menu stays stuck instead of playing the video.

@elupus elupus deleted the renderbuf branch May 31, 2013 21:33
@elupus
Copy link
Contributor Author

elupus commented May 31, 2013

yup. seeing it too. just can't figure out what the heck is going on. my xcode keeps crashing.

@elupus
Copy link
Contributor Author

elupus commented Jun 1, 2013

hang should be resolved at df90ddd

@Voyager1
Copy link

Voyager1 commented Jun 1, 2013

it is resolved indeed - thanks!

@rbej
Copy link

rbej commented Jun 1, 2013

When stop playing movie on Rpi, picture freeze and only hard reset helps.

http://pastebin.com/Q0guRnse

@FernetMenta
Copy link
Contributor

omxplayer still suffers from negative timeout. I will prepare a pr.

@FernetMenta
Copy link
Contributor

@popcornmix could do do this with #2798? dvdplayer clamps timeout for WaitForBuffers to positive values.

@popcornmix
Copy link
Member

@FernetMenta
I will re-merge with latest dvdplayer when that goes in, although that PR is waiting on a commit from @elupus.

@elupus
Copy link
Contributor Author

elupus commented Jun 1, 2013

@popcornmix those cleanups are already in.

@rbej
Copy link

rbej commented Jun 2, 2013

This patch fixed frezze picture on Rpi #2798, but cause out of sync subs (subs display some 1.5s too fast)

@elupus
Copy link
Contributor Author

elupus commented Jun 2, 2013

Rbpis output logic need to be looked over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants