我正在实施一个3D VR播放器,对于视频解码,我正在使用Libvlc。
为了渲染视频,我有一个纹理缓冲区和一个内存缓冲区,当VLC解码帧时,主循环将数据复制到纹理。
我已经测试了两种不同的机制来锁定内存缓冲区,当vlc转储一个帧时,首先我尝试了一个互斥锁,如示例所示,但性能很糟糕,我还测试了使用原子操作的无锁机制,表现并不完美但更好。
我得到的最好的结果就是没有锁定所有的缓冲区,它的工作非常顺利,但有时候主循环和vlc循环变得不同步,然后撕裂和卡顿是显而易见的。
所以我的问题是,锁定缓冲区的最佳方法是什么?任何方式都不要失去表现?
以下是重要的代码部分:
- 视频上下文结构
typedef struct _videoContext
{
libvlc_instance_t* instance;
libvlc_media_t* media;
libvlc_media_player_t* player;
unsigned char *pixeldata;
unsigned char currentFrame;
int width;
int height;
int duration;
int time;
int volume;
bool finished;
std::atomic<bool> lock;
} videoContext;
- 视频事件功能
static void *lock(void *data, void **p_pixels)
{
videoContext* context = (videoContext*)data;
bool expected = false;
while (!context->lock.compare_exchange_strong(expected, true))
Sleep(0);
p_pixels[0] = context->pixeldata;
return NULL;
}
static void unlock(void *data, void *id, void *const *p_pixels)
{
videoContext* context = (videoContext*)data;
context->time = libvlc_media_player_get_time(context->player);
context->lock.store(false);
context->currentFrame++;
}
- 主要循环功能
if (vctx->currentFrame != currentFrame && vctx->lock.compare_exchange_strong(exchangeExpected, true))
{
currentFrame = vctx->currentFrame;
Texture::setData(&videoTexture, vctx->pixeldata, vctx->width, vctx->height);
vctx->lock.store(false);
}