Hi,
I've written the software for a digital signage product that we're developing which uses the iMX6. The screen content is configurable, and is rendered using OpenGL ES (to an SDL generated window - not using X11). It's possible to set up the screen layout such that is has video on a part of the screen, and I'm handling the video using a combination of ffmpeg's libav and a custom decoder that utilises the iMX6 VPU.
To render the video to the OpenGL ES scene, I initially create a ring buffer of 3 textures and then call glTexDirectVIV for each texture and store the pointer that's returned. Then as the video plays, I have a thread that copies the decoded video frames to the textures using the pointers that I initially received via glTexDirectVIV (I'm using NEON instructions to copy the frames as quickly as possible).
The result is quite impressive, given that it's not a zero copy solution. I'm getting about 60 fps for fairly complex OpenGL ES scenes with a video playing in the middle of it.
I'm experiencing a problem though, where after a period of time (seems fairly random - anywhere from a few seconds to a few hours) the video starts to flicker with black frames. It initially looks like every third frame is black, and then after a while every 2 out of 3 frames, and then it turns completely black - so I'm immediately thinking it's a problem with my ring buffer of 3 textures. I've been through the code trying to diagnose the issue, and the problem doesn't occur if I don't use glTexDirectVIV and just copy the frames using glTexSubImage2D, but that causes the frame rate to drop.
I now have it where I can connect a USB keyboard to the device, and when I hit a certain key it re-calls glTexDirectVIV to refresh the pointers that I have stored for the 3 textures. That's all that happens when I hit the keyboard key. Now when the video starts to flicker, when I hit this key then the flickering immediately stops.
So I've concluded that the GPU must be moving the textures in the GPU memory, thus invalidating the pointers that I have stored by my initial glTexDirectVIV call.
I originally referred to this when I wrote my code:
Computer Vision on i.MX Processors: Video to Texture Streaming (Part 3) - i.MX6 processor
and with regard to glTexDirectVIV, it states "This function should be called just once in your code! (this was my mistake for a long time.....)".
My question is - should I in fact be calling glTexDirectVIV on every video frame before I copy the data, rather than assume the pointers will stay valid? That's what I'm starting to consider, but I'm a little concerned that it might cause a different problem that I'm not aware of, given the statement on that blogspot page.
If I am supposed to only call glTexDirectVIV once initially, how can I get around this problem that I'm seeing where the GPU seems to move the textures and therefore invalidates my stored pointers? Is there a way I can detect that this has happened, or prevent it happening in the first place?
Thanks
Hi Rik,
Which GPU version are you using? which BSP? you are not using X11, then I suppose you are using 4.9.88 version, where supposedly fixed all glTexDirectVIV issues.
Hi,
Thanks for the reply.
I'm using a SOM from one of our suppliers (the RM3 from Blue Chip Technology, RM3 ARM Dual/Quad-Core Cortex A9 Module | Blue Chip Technology). It has the i.MX6 Quad, which I believe has the Vivante GC2000 GPU?
I'm using buildroot to create the system, and the kernel is 4.1.15 which comes from GitHub - bluechiptechnology/linux-4.1.15-bctre3: kernel for RE3 boards based on Freescale Linux 4.1....
Are you suggesting that if I contact Blue Chip and we use kernel version 4.9.88 or later, then that would solve my problem?
Many thanks,
Rik