2011-12-03, 00:09
Fwiw, maybe in need of a bit of cleanup, but got something that is basically functional:
https://github.com/robclark/xbmc/tree/gstreamer-eglimg
What I ended up doing was add eglImage rendering support, so the decoder can pass the renderer an eglImage that can be bound to a texture. This is an alternative path to the 3x texture upload plus colorconvert in shader approach. Works fine on my pandaboard, framerate seems fine for 1080p playback on 1080p display, at least as long as the window manager doesn't get in the way and refuse to unredirect the fullscreen xbmc window (so flipping instead of blitting works).
I guess, in theory, since eglImage should be something that can be used by the renderer in a standard way, possibly the OpenMAX rendering code could be cleaned up to work in the same way. But I didn't have access to any hw on which I could test this so I left the existing OpenMAX related code as-is.
In addition to cleanup and removing debug stuff which might have gotten left, there is one remaining functional issue. The problem is that the DVDVideoCodecGStreamer instance gets deleted before the renderer. Which causes a segfault when the renderer is deleted:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x41c04110 (LWP 14210)]
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x00497c10 in CLinuxRendererGLES::UnRefBuf (this=<optimized out>, index=<optimized out>) at LinuxRendererGLES.cpp:139
#2 0x00497c58 in CLinuxRendererGLES::DeleteEGLIMAGETexture (this=0x12367c0, index=0) at LinuxRendererGLES.cpp:1456
#3 0x00497334 in CLinuxRendererGLES::UnInit (this=0x12367c0) at LinuxRendererGLES.cpp:766
#4 0x00495cba in CXBMCRenderManager::UnInit (this=0x945110) at RenderManager.cpp:337
#5 0x003ac2e0 in CDVDPlayer::CloseFile (this=0x4de6b008) at DVDPlayer.cpp:416
#6 0x003ac338 in CDVDPlayer::~CDVDPlayer (this=0x4de6b008, __in_chrg=<optimized out>) at DVDPlayer.cpp:329
#7 0x003ac768 in CDVDPlayer::~CDVDPlayer (this=0x4de6b008, __in_chrg=<optimized out>) at DVDPlayer.cpp:334
#8 0x006ffe68 in CApplication::OnMessage (this=0x9445a8, message=...) at Application.cpp:4603
#9 0x0038b480 in CGUIWindowManager::SendMessage (this=0x944f58, message=...) at GUIWindowManager.cpp:77
#10 0x0038b7ce in CGUIWindowManager::DispatchThreadMessages (this=0x944f58) at GUIWindowManager.cpp:784
#11 0x006fc61c in CApplication::Process (this=0x9445a8) at Application.cpp:4705
#12 0x0075bf26 in CXBApplicationEx::Run (this=0x9445a8) at XBApplicationEx.cpp:96
#13 0x001dc836 in main (argc=1, argv=0xbefff264) at xbmc.cpp:93
I'm not sure if there is some sane way to ensure the opposite order is preserved, so renderer is cleaned up before the decoder. Otherwise I need to think of a better way to do what is done in CDVDVideoCodecGStreamer::GetEGLImage() and CDVDVideoCodecGStreamer::ReleaseEGLImage(), which I need for two reasons:
https://github.com/robclark/xbmc/tree/gstreamer-eglimg
What I ended up doing was add eglImage rendering support, so the decoder can pass the renderer an eglImage that can be bound to a texture. This is an alternative path to the 3x texture upload plus colorconvert in shader approach. Works fine on my pandaboard, framerate seems fine for 1080p playback on 1080p display, at least as long as the window manager doesn't get in the way and refuse to unredirect the fullscreen xbmc window (so flipping instead of blitting works).
I guess, in theory, since eglImage should be something that can be used by the renderer in a standard way, possibly the OpenMAX rendering code could be cleaned up to work in the same way. But I didn't have access to any hw on which I could test this so I left the existing OpenMAX related code as-is.
In addition to cleanup and removing debug stuff which might have gotten left, there is one remaining functional issue. The problem is that the DVDVideoCodecGStreamer instance gets deleted before the renderer. Which causes a segfault when the renderer is deleted:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x41c04110 (LWP 14210)]
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x00497c10 in CLinuxRendererGLES::UnRefBuf (this=<optimized out>, index=<optimized out>) at LinuxRendererGLES.cpp:139
#2 0x00497c58 in CLinuxRendererGLES::DeleteEGLIMAGETexture (this=0x12367c0, index=0) at LinuxRendererGLES.cpp:1456
#3 0x00497334 in CLinuxRendererGLES::UnInit (this=0x12367c0) at LinuxRendererGLES.cpp:766
#4 0x00495cba in CXBMCRenderManager::UnInit (this=0x945110) at RenderManager.cpp:337
#5 0x003ac2e0 in CDVDPlayer::CloseFile (this=0x4de6b008) at DVDPlayer.cpp:416
#6 0x003ac338 in CDVDPlayer::~CDVDPlayer (this=0x4de6b008, __in_chrg=<optimized out>) at DVDPlayer.cpp:329
#7 0x003ac768 in CDVDPlayer::~CDVDPlayer (this=0x4de6b008, __in_chrg=<optimized out>) at DVDPlayer.cpp:334
#8 0x006ffe68 in CApplication::OnMessage (this=0x9445a8, message=...) at Application.cpp:4603
#9 0x0038b480 in CGUIWindowManager::SendMessage (this=0x944f58, message=...) at GUIWindowManager.cpp:77
#10 0x0038b7ce in CGUIWindowManager::DispatchThreadMessages (this=0x944f58) at GUIWindowManager.cpp:784
#11 0x006fc61c in CApplication::Process (this=0x9445a8) at Application.cpp:4705
#12 0x0075bf26 in CXBApplicationEx::Run (this=0x9445a8) at XBApplicationEx.cpp:96
#13 0x001dc836 in main (argc=1, argv=0xbefff264) at xbmc.cpp:93
I'm not sure if there is some sane way to ensure the opposite order is preserved, so renderer is cleaned up before the decoder. Otherwise I need to think of a better way to do what is done in CDVDVideoCodecGStreamer::GetEGLImage() and CDVDVideoCodecGStreamer::ReleaseEGLImage(), which I need for two reasons:
- reference counting.. I need to hold a reference to the original gst buffer that the eglImage is created from while the renderer is using it, to avoid it getting free'd or passed back to decoder for next frame, and
- defer creating the eglImage, to avoid creating the eglImage in the first case for frames that might be dropped. I think this will be less important down the road, with gst 0.11/1.0 stuff, I think we can stuff the eglImage in gst buffer metadata, and avoid unmapping/destroying the eglImage if the buffer is recycled. But for now we need something like this.