Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Libass #942

Merged
merged 3 commits into from

6 participants

@elupus
Collaborator

Use the libass changed flag during rendering to avoid re-uploading glyphs on each frame when nothing changed.

elupus added some commits
@elupus elupus [overlays] always run overlay conversion routine
This allows the conversion rutines to decide
if the previously generated gpu overlay is
still usable.
113e648
@elupus elupus [libass] expose changed event to user of renderer 62b017e
@elupus elupus [libass] don't re-uploading glyphs to GPU if not changed
This uses the changed flag from libass to avoid uploading
the texture containing glyphs and the vertex buffer with
positions on every renderered frame.

This will not avoid upload in the case of only position
change which should be possible too.
88abe76
@elupus elupus was assigned
@elupus
Collaborator

I would like to get this in this merge window if possible. But would need some testing on opengl, have only tested win32 and build tested linux. Testing this on some low perf platform would be nice.

@Memphiz
Owner

This also affects ios i guess? Have it on my testing - todo -list for after work ...

@alanwww1
Collaborator

@elupus: I'd test it on Linux, just tell me what to look at or what to pay attention for.

Thanks

@elupus
Collaborator
@Memphiz
Owner

Thumbs up from me. I think you've got around 5000 new friends from the iOS fanbase with this commit :). At least on my problematic testfiles this commits fix the cpu peak out / framerate dropping. Great :)

We should stick this in in may, when the other platform testers give a sign-off too.

@linusyang

@Memphiz Good news for all iOS/ATV2 users!

@elupus elupus merged commit 6d4087c into xbmc:master
@jpsdr

I think the result is unfortunately this : http://trac.xbmc.org/ticket/13023

@jpsdr

I've removed (put in comment) the following code :
if(o->m_overlay)
{
if(changes == 0)
return o->m_overlay->Acquire();
}
in the file OverlayRenderer.cpp, and it solved the issue.
It seems that unfortunately the value of "changes" is not accurate enough... or things should be done differently.

@elupus
Collaborator

That screenshot was awesome. I now have a hunch what is going on. I think we are not removing old libass overlays. Previously that would not show since they would be rendered exactly on top of eachother.

This might finally explains the insane CPU usage from ass subtitles. I'll look at it later.

@elupus
Collaborator

Since my computer is insanely slow at the moment and download is taking forever. If you could try adding

remove = true;

at

https://github.com/xbmc/xbmc/blob/master/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h#L36

@jpsdr

Doing this ?
{
m_libass = libass;
remove = true;
libass->Acquire();
}
I'll try this evening, and report result.

@jpsdr

... "remove" is underlined when i add it => unknow variable... So, i don't even try to compile. Are you sure it is the correct name or correct place ?

@elupus
Collaborator
@elupus
Collaborator

I've added replace = true; in master and it indeed fixes the insane CPU usage and this bug. Probably should be backported to eden.

@jpsdr

Hello.
Something always bothering me since this commit, without realy being able to truly point it, until it "pops" to me playing one of the test file i regularly use for regression check. Basicaly, i had often the feeling that some subtitles disapeared "too soon". With that file, it has suddenly been obvious. You can get the file here : http://jpsdr.free.fr/XBMC/Test-4.rar
I've checked the file with mpc-hc, and subtitles are displayed properly, but not with xbmc. You can quickly check, at the begining, when "The Vajra are not our true ennemy." disapeared, karaoke at top left also disapeard, when it shouldn't. Also, when next karaoke begin, you can see during a very bref time (at leat on a TV at 24fps), something which is like the previous karaoke.

@jpsdr

I've made several tests.
I've first commented the following code :
if(o->m_overlay)
{
if(changes == 0)
return o->m_overlay->Acquire();
}
in the file OverlayRenderer.cpp
but, it doesn't solve the issue, display of subtitles was still broken.
Then, i've also commented the following : "replace = true" in DVDOverlaySSA.h, and it solved the issue.

@jpsdr

I've opened a ticket : http://trac.xbmc.org/ticket/13302

@jester-xbmc

@jpsdr as you seem to have a working patch, can you (if you don't have one already) do a fork from XBMC on github, do the change and then do a PR (Pull Request) so it's easier for the dev's to pull it in (as this is a closed PR)
@elupus Also I remember there was a PR with backports from Eden, i'm not sure this one made it

@jpsdr

It's not from my point of view a "working" patch. It's just information for elupus, because what i've done is almost a total removing of all the work of this commit. A true real fix is above my knowledge, again, it's just the result of my experiments for when elupus will take a look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 6, 2012
  1. @elupus

    [overlays] always run overlay conversion routine

    elupus authored
    This allows the conversion rutines to decide
    if the previously generated gpu overlay is
    still usable.
  2. @elupus
  3. @elupus

    [libass] don't re-uploading glyphs to GPU if not changed

    elupus authored
    This uses the changed flag from libass to avoid uploading
    the texture containing glyphs and the vertex buffer with
    positions on every renderered frame.
    
    This will not avoid upload in the case of only position
    change which should be possible too.
This page is out of date. Refresh to see the latest.
View
61 xbmc/cores/VideoRenderers/OverlayRenderer.cpp
@@ -31,6 +31,7 @@
#include "windowing/WindowingFactory.h"
#include "settings/Settings.h"
#include "threads/SingleLock.h"
+#include "utils/MathUtils.h"
#if defined(HAS_GL) || defined(HAS_GLES)
#include "OverlayRendererGL.h"
#elif defined(HAS_DX)
@@ -104,10 +105,7 @@ void CRenderer::AddOverlay(CDVDOverlay* o, double pts)
SElement e;
e.pts = pts;
- if(o->m_overlay)
- e.overlay = o->m_overlay->Acquire();
- else
- e.overlay_dvd = o->Acquire();
+ e.overlay_dvd = o->Acquire();
m_buffers[m_decode].push_back(e);
}
@@ -179,15 +177,19 @@ void CRenderer::Render()
SElementV& list = m_buffers[m_render];
for(SElementV::iterator it = list.begin(); it != list.end(); it++)
{
- COverlay*& o = it->overlay;
+ COverlay* o = NULL;
- if(!o && it->overlay_dvd)
+ if(it->overlay)
+ o = it->overlay->Acquire();
+ else if(it->overlay_dvd)
o = Convert(it->overlay_dvd, it->pts);
if(!o)
continue;
Render(o);
+
+ o->Release();
}
}
@@ -281,29 +283,62 @@ void CRenderer::Render(COverlay* o)
o->Render(state);
}
+COverlay* CRenderer::Convert(CDVDOverlaySSA* o, double pts)
+{
+ CRect src, dst;
+ g_renderManager.GetVideoRect(src, dst);
+
+ int width = MathUtils::round_int(dst.Width());
+ int height = MathUtils::round_int(dst.Height());
+
+ int changes = 0;
+ ASS_Image* images = o->m_libass->RenderImage(width, height, pts, &changes);
+
+ if(o->m_overlay)
+ {
+ if(changes == 0)
+ return o->m_overlay->Acquire();
+ }
+
+#if defined(HAS_GL) || defined(HAS_GLES)
+ return new COverlayGlyphGL(images, width, height);
+#elif defined(HAS_DX)
+ return new COverlayQuadsDX(images, width, height);
+#endif
+ return NULL;
+}
+
+
COverlay* CRenderer::Convert(CDVDOverlay* o, double pts)
{
- COverlay* r = o->m_overlay;
+ COverlay* r = NULL;
+
+ if(o->IsOverlayType(DVDOVERLAY_TYPE_SSA))
+ r = Convert((CDVDOverlaySSA*)o, pts);
+ else if(o->m_overlay)
+ r = o->m_overlay->Acquire();
+
if(r)
- return r->Acquire();
+ {
+ if(o->m_overlay)
+ o->m_overlay->Release();
+ o->m_overlay = r->Acquire();
+ return r;
+ }
#if defined(HAS_GL) || defined(HAS_GLES)
if (o->IsOverlayType(DVDOVERLAY_TYPE_IMAGE))
r = new COverlayTextureGL((CDVDOverlayImage*)o);
else if(o->IsOverlayType(DVDOVERLAY_TYPE_SPU))
r = new COverlayTextureGL((CDVDOverlaySpu*)o);
- else if(o->IsOverlayType(DVDOVERLAY_TYPE_SSA))
- r = new COverlayGlyphGL((CDVDOverlaySSA*)o, pts);
#elif defined(HAS_DX)
if (o->IsOverlayType(DVDOVERLAY_TYPE_IMAGE))
r = new COverlayImageDX((CDVDOverlayImage*)o);
else if(o->IsOverlayType(DVDOVERLAY_TYPE_SPU))
r = new COverlayImageDX((CDVDOverlaySpu*)o);
- else if(o->IsOverlayType(DVDOVERLAY_TYPE_SSA))
- r = new COverlayQuadsDX((CDVDOverlaySSA*)o, pts);
#endif
- if(r && !o->IsOverlayType(DVDOVERLAY_TYPE_SSA))
+ if(r)
o->m_overlay = r->Acquire();
return r;
}
View
1  xbmc/cores/VideoRenderers/OverlayRenderer.h
@@ -119,6 +119,7 @@ namespace OVERLAY {
void Render(COverlay* o);
COverlay* Convert(CDVDOverlay* o, double pts);
+ COverlay* Convert(CDVDOverlaySSA* o, double pts);
void Release(COverlayV& list);
void Release(SElementV& list);
View
11 xbmc/cores/VideoRenderers/OverlayRendererDX.cpp
@@ -160,11 +160,8 @@ static bool LoadTexture(int width, int height, int stride
return true;
}
-COverlayQuadsDX::COverlayQuadsDX(CDVDOverlaySSA* o, double pts)
+COverlayQuadsDX::COverlayQuadsDX(ASS_Image* images, int width, int height)
{
- CRect src, dst;
- g_renderManager.GetVideoRect(src, dst);
-
m_width = 1.0;
m_height = 1.0;
m_align = ALIGN_VIDEO;
@@ -172,14 +169,10 @@ COverlayQuadsDX::COverlayQuadsDX(CDVDOverlaySSA* o, double pts)
m_x = 0.0f;
m_y = 0.0f;
m_count = 0;
-
- int width = MathUtils::round_int(dst.Width());
- int height = MathUtils::round_int(dst.Height());
-
m_fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
SQuads quads;
- if(!convert_quad(o, pts, width, height, quads))
+ if(!convert_quad(images, quads))
return;
float u, v;
View
3  xbmc/cores/VideoRenderers/OverlayRendererDX.h
@@ -31,6 +31,7 @@ class CDVDOverlay;
class CDVDOverlayImage;
class CDVDOverlaySpu;
class CDVDOverlaySSA;
+typedef struct ass_image ASS_Image;
namespace OVERLAY {
@@ -38,7 +39,7 @@ namespace OVERLAY {
: public COverlayMainThread
{
public:
- COverlayQuadsDX(CDVDOverlaySSA* o, double pts);
+ COverlayQuadsDX(ASS_Image* images, int width, int height);
virtual ~COverlayQuadsDX();
void Render(SRenderState& state);
View
11 xbmc/cores/VideoRenderers/OverlayRendererGL.cpp
@@ -246,11 +246,8 @@ COverlayTextureGL::COverlayTextureGL(CDVDOverlaySpu* o)
m_height = (float)(max_y - min_y);
}
-COverlayGlyphGL::COverlayGlyphGL(CDVDOverlaySSA* o, double pts)
+COverlayGlyphGL::COverlayGlyphGL(ASS_Image* images, int width, int height)
{
- CRect src, dst;
- g_renderManager.GetVideoRect(src, dst);
-
m_vertex = NULL;
m_width = 1.0;
m_height = 1.0;
@@ -258,14 +255,10 @@ COverlayGlyphGL::COverlayGlyphGL(CDVDOverlaySSA* o, double pts)
m_pos = POSITION_RELATIVE;
m_x = 0.0f;
m_y = 0.0f;
-
- int width = MathUtils::round_int(dst.Width());
- int height = MathUtils::round_int(dst.Height());
-
m_texture = 0;
SQuads quads;
- if(!convert_quad(o, pts, width, height, quads))
+ if(!convert_quad(images, quads))
return;
glGenTextures(1, &m_texture);
View
4 xbmc/cores/VideoRenderers/OverlayRendererGL.h
@@ -29,6 +29,7 @@ class CDVDOverlay;
class CDVDOverlayImage;
class CDVDOverlaySpu;
class CDVDOverlaySSA;
+typedef struct ass_image ASS_Image;
#if defined(HAS_GL) || HAS_GLES == 2
@@ -53,7 +54,8 @@ namespace OVERLAY {
: public COverlayMainThread
{
public:
- COverlayGlyphGL(CDVDOverlaySSA* o, double pts);
+ COverlayGlyphGL(ASS_Image* images, int width, int height);
+
virtual ~COverlayGlyphGL();
void Render(SRenderState& state);
View
3  xbmc/cores/VideoRenderers/OverlayRendererUtil.cpp
@@ -182,9 +182,8 @@ uint32_t* convert_rgba(CDVDOverlaySpu* o, bool mergealpha
return rgba;
}
-bool convert_quad(CDVDOverlaySSA* o, double pts, int width, int height, SQuads& quads)
+bool convert_quad(ASS_Image* images, SQuads& quads)
{
- ASS_Image* images = o->m_libass->RenderImage(width, height, pts);
ASS_Image* img;
if (!images)
View
5 xbmc/cores/VideoRenderers/OverlayRendererUtil.h
@@ -25,6 +25,7 @@
class CDVDOverlayImage;
class CDVDOverlaySpu;
class CDVDOverlaySSA;
+typedef struct ass_image ASS_Image;
namespace OVERLAY {
@@ -62,8 +63,6 @@ namespace OVERLAY {
uint32_t* convert_rgba(CDVDOverlaySpu* o, bool mergealpha
, int& min_x, int& max_x
, int& min_y, int& max_y);
- bool convert_quad(CDVDOverlaySSA* o, double pts
- , int width, int height
- , SQuads& quads);
+ bool convert_quad(ASS_Image* images, SQuads& quads);
}
View
4 xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp
@@ -150,7 +150,7 @@ bool CDVDSubtitlesLibass::CreateTrack(char* buf)
return true;
}
-ASS_Image* CDVDSubtitlesLibass::RenderImage(int imageWidth, int imageHeight, double pts)
+ASS_Image* CDVDSubtitlesLibass::RenderImage(int imageWidth, int imageHeight, double pts, int *changes)
{
CSingleLock lock(m_section);
if(!m_renderer || !m_track)
@@ -160,7 +160,7 @@ ASS_Image* CDVDSubtitlesLibass::RenderImage(int imageWidth, int imageHeight, dou
}
m_dll.ass_set_frame_size(m_renderer, imageWidth, imageHeight);
- return m_dll.ass_render_frame(m_renderer, m_track, DVD_TIME_TO_MSEC(pts), NULL);
+ return m_dll.ass_render_frame(m_renderer, m_track, DVD_TIME_TO_MSEC(pts), changes);
}
ASS_Event* CDVDSubtitlesLibass::GetEvents()
View
2  xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.h
@@ -33,7 +33,7 @@ class CDVDSubtitlesLibass : public IDVDResourceCounted<CDVDSubtitlesLibass>
CDVDSubtitlesLibass();
virtual ~CDVDSubtitlesLibass();
- ASS_Image* RenderImage(int imageWidth, int imageHeight, double pts);
+ ASS_Image* RenderImage(int imageWidth, int imageHeight, double pts, int* changes = NULL);
ASS_Event* GetEvents();
int GetNrOfEvents();
Something went wrong with that request. Please try again.