FernetMenta / xbmc

Fork of XBMC Main PVR Development Repository.
http://xbmc.org
Other
55 stars 20 forks source link

MPEG4 "Sync playback to display" not fluent #103

Open iLLiac4 opened 11 years ago

iLLiac4 commented 11 years ago

When playing the file mpeg4 (yuv420) with selected option "Sync playback to display" the movie does not run fluent. If you you disable this option it runs as it should.

Log: http://pastebin.com/VhYYFprF http://pastebin.com/j63T4jc5

Mediainfo: General Complete name : xvid.cd1.avi Format : AVI Format/Info : Audio Video Interleave File size : 699 MiB Duration : 1h 8mn Overall bit rate : 1 428 Kbps Writing application : VirtualDubMod 1.5.10.2 (build 2540/release) Writing library : VirtualDubMod build 2540/release Video ID : 0 Format : MPEG-4 Visual Format profile : Advanced Simple@L5 Format settings, BVOP : 2 Format settings, QPel : No Format settings, GMC : No warppoints Format settings, Matrix : Default (H.263) Muxing mode : Packed bitstream Codec ID : XVID Codec ID/Hint : XviD Duration : 1h 8mn Bit rate : 971 Kbps Width : 640 pixels Height : 272 pixels Display aspect ratio : 2.35:1 Frame rate : 23.976 fps Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Compression mode : Lossy Bits/(Pixel*Frame) : 0.233 Stream size : 475 MiB (68%) Writing library : XviD 61

Audio ID : 1 Format : AC-3 Format/Info : Audio Coding 3 Mode extension : CM (complete main) Format settings, Endianness : Big Codec ID : 2000 Duration : 1h 8mn Bit rate mode : Constant Bit rate : 448 Kbps Channel(s) : 6 channels Channel positions : Front: L C R, Side: L R, LFE Sampling rate : 48.0 KHz Bit depth : 16 bits Compression mode : Lossy Stream size : 219 MiB (31%) Alignment : Split accross interleaves Interleave, duration : 42 ms (1.00 video frame) Interleave, preload duration : 500 ms

FernetMenta commented 11 years ago

Please post full debug log. I can't even see you system spec.

iLLiac4 commented 11 years ago

http://pastebin.com/1NV9kzAz

fritsch commented 11 years ago

@iLLiac4: As talked via IRC -> DirtyRegions Methods 3 instead of DirtyRegions 1 fixed the issue

[quote] 18:51 < iLLiac4> (fritsch) I have set to

3 and now the video yuv420 is smooth. [/quote] @FernetMenta: Is there anything, that needs to be set, when non hw accel formats are played back in order to get the DirtyRegions "off"? From my understanding it should not run at all, when a movies is playing?
FernetMenta commented 11 years ago

@fritsch What relationship do you see to dirty regions?

fritsch commented 11 years ago

@FernetMenta: After he set it to 3 (the safe method) - he did not have any problems with the original file anymore. That was a question above :-)

Dirty Regions renders the screen within a given timeout, when this time is passed and the screen is not dirty, it stops. My understanding is, that it should not do anything when a movie is playing, cause it is always dirty. The question now was: How does the player indicate the DirtyRegion code to stop doing anything and just render what comes on screen.

iLLiac4 commented 11 years ago

After setting Dirty Region to 3 the file worked flawlessly even with Sync to Playback enabled" "I did not know that DR has any influence on playback. CPU is very low around 10-20%% when playing those files with even boblight enabled. I am in full screen and only in video. I did try to enable vdpau in advanced settings before (when the DR was set to 1) and it did not show the video at all.

FernetMenta commented 11 years ago

hmm, DR should have no influence when video is playing in full screen mode.

FernetMenta commented 11 years ago

@fritsch I have never understood dr flip timeout. At least on Linux OpenGL it does not make any sense to flip the buffers if nothing was rendered. This is what nofliptimeout does, it continues flipping the buffers after the last rendering.

An algorithm of 1 means that only those regions of the screen are rendered which are inside the largest dirty region, 3 means that the entire screen is rendered if only one pixel has become dirty.

In case of video full screen the entire screen get rendered anyway and buffers are flipped as well.

So if this setting really makes any difference to full screen, there is either something wrong from the beginning which shows off when playing a video or ... any ideas?

fritsch commented 11 years ago

@FernetMenta: I looked a bit longer at the code last time to understand the difference between nofliptimeout difference between zero and 1000. In facth the "Methodes" be it 1, 2, 3 don't know anything about the fliptimeout and don't know anything about when they "do their" job. It all runs in a very little code, directly in Application.cpp:

bool flip; if (g_advancedSettings.m_guiDirtyRegionNoFlipTimeout >= 0) flip = hasRendered || (now - m_lastRenderTime) < (unsigned int)g_advancedSettings.m_guiDirtyRegionNoFlipTimeout; else flip = true;

a bit above, they ask: if (hasRendered) m_lastRenderTime = now;

So whenever "something, someone" set hasRendered, it starts to flip - Now - the big question - what happens when a movies plays? Normally DR should not be used to update the screen - I don't understand where the player tells: "Now here movie comes in fullscreen - DR shut up!".

fritsch commented 11 years ago
  if (g_graphicsContext.IsFullScreenVideo() && IsPlaying() && vsync_mode == VSYNC_VIDEO)
    g_Windowing.SetVSync(true);
  else if (vsync_mode == VSYNC_ALWAYS)
    g_Windowing.SetVSync(true);
  else if (vsync_mode != VSYNC_DRIVER)
    g_Windowing.SetVSync(false);

  if(!g_Windowing.BeginRender())
    return;

It should jump out after this .... so the DR should not play a role when video is playing, something like:

if(IsPlaying())
return;

is probably missing?

I don't know - again such a part of code which is not very well documented.

FernetMenta commented 11 years ago

go some lines above:

    if (!extPlayerActive && g_graphicsContext.IsFullScreenVideo() && !IsPaused())
    {
      m_frameEvent.Reset();
      m_bPresentFrame = g_renderManager.HasFrame();
      if (!m_bPresentFrame && m_frameEvent.WaitMSec(100))
        m_bPresentFrame = g_renderManager.HasFrame();
      hasRendered = true;
    }

hasRendered == true means flip

Nevertheless DR sill get processed in RenderNoPresent -> g_windowManager.Render();

fritsch commented 11 years ago

Yes. But now the problem arises:

if(flip)
{
    g_graphicsContext.Flip(dirtyRegions);
    g_renderManager.NotifyDisplayFlip();
}

So - it does not make a difference wether it is fullscreen, playing or not, it always calls the g_graphicsContex.Flip with the dirtyRegions ...

Should there be something like:

if(flip)
  if(!IsPlaying)
  {
    g_graphicsContext.Flip(dirtyRegions);
    g_renderManager.NotifyDisplayFlip();
  }
  else
  {
   g_graphicsContex.DoWhatRealyMustBeDone();
   g_renderManager.NotifyDisplayFlip();
  }
}

To really get the whole screen flipped?

FernetMenta commented 11 years ago

RenderSystemGL ignores the dirtyRegions parameter.

FernetMenta commented 11 years ago

mp4 decoding was broken for vdpau, it's fixed and default now: 9b53d9c2b3f7350feae27366ed4a029e1eda98a2

iLLiac4 commented 11 years ago

Hi! Mpeg4 is still not working right. When used VDPUA the picture is somehow 'dizzy'.

Info: http://imageshack.us/photo/my-images/252/snap14b.jpg/ http://imageshack.us/photo/my-images/13/snap13vq.jpg/ info: http://imageshack.us/photo/my-images/138/snap15p.jpg/ Media Info: http://pastebin.com/06TyQM9R