LibVLC教程,不带SDL
LibVLC tutorial without SDL?
我正在尝试逐帧写入视频到*。yuv文件,找到了这个关于将视频渲染成SDL表面的教程。
现在我不确定如何在没有SDL库的情况下使用此代码。例如,锁函数:
static void *lock(void *data, void **p_pixels)
{
struct ctx *ctx = data;
SDL_LockMutex(ctx->mutex);
SDL_LockSurface(ctx->surf);
*p_pixels = ctx->surf->pixels;
return NULL; /* picture identifier, not needed here */
}
没有struct ctx
, SDL_LockMutex
, SDL_LockSurface
怎么写这个函数?
你可以想象,我不是一个非常有经验的程序员,所以请耐心等待我;)
提前感谢!
我不太了解libvlc,但下面是基于这个特定示例删除SDL的方法。
<标题>删除SDL h1> 这个例子中,有几个不同的函数你必须传递给libvlc回调函数…libvlc_video_set_callbacks(mp, lock, unlock, display, &ctx);
现在,为了完全理解这个锁函数在做什么,你需要了解一点多线程以及图像是如何存储在内存中的。
本质上,为了确保libvlc在写入内存时没有任何东西访问它所使用的内存区域,它"锁定"了一个被称为互斥锁的东西。如果您试图锁定一个已经被其他对象锁定的互斥锁,则当前执行将等待直到它被解锁。
如果你在它写了一半的时候访问这些像素,你能想象它会有多可怕吗?它可能只写了一半,然后您将使用它保存到您的yuv文件中。
lock函数做的第二件事是在内存中指定vlc可以用来加载图像帧的区域。这个例子使用了SDL_Surface,但是你也可以创建你自己的
所以,如果你只使用libvlc,你会想要找到一个替代这些东西。
我将按照上面列表的倒序排列。在这个例子中,他们使用SDL_Surface,但是如果你不能使用它,你将不得不在内存中创建自己的结构来存储像素数据,如果你想提取它。一个简单的方法是创建一个正确大小的字符数组。我将使用ctx结构体,因为它很方便:我知道您要求不要使用它,但它在这种情况下非常有用,因为我们需要将多条信息传递给锁函数。
struct ctx
{
unsigned char *pixeldata;
};
现在,在主函数的某个地方,您需要在内存中创建该区域。如果您知道视频大小和每像素使用多少比特(bpp):这非常简单。但是要非常小心,如果你做得不对:你可能会导致内存损坏。
ctx.pixeldata = new unsigned char[width * height * bpp];
确保在程序结束时正确删除这个…
delete[] ctx.pixeldata;
下一个是互斥锁。这并不是严格需要的,但是你可能会遇到我上面提到的问题。如果你想使用互斥锁,你需要在libvlc_video_set_callback中指定一个unlock函数(如果你不想使用互斥锁,你可以为unlock指定NULL)。
问题是您将为此目的使用什么互斥锁(如果您想使用一个,我建议您这样做)?如果您使用的是较新的c++ 11标准,则可以使用std::mutex。如果没有,那么您将不得不寻找其他的东西,比如boost线程库,或者自己编写类似的东西。如果你使用的是c++ 11,你可以将它添加到ctx结构体中…
#include <mutex>
struct ctx
{
unsigned char *pixeldata;
std::mutex imagemutex;
};
现在来看实际的锁函数本身。
static void *lock(void *data, void **p_pixels)
{
struct ctx *ctx = data;
ctx->imagemutex.lock()
*p_pixels = ctx->pixeldata;
return NULL;
}
你的解锁功能应该是这样的…
static void unlock(void *data, void *id, void *const *p_pixels)
{
struct ctx *ctx = data;
ctx->unlock();
assert(id == NULL);
}
当你想安全地访问像素数据时…
ctx->imagemutex.lock();
/* Access Data Here */
ctx->imagemutex.unlock();
使用SDL 我想简单地补充一些关于SDL的东西。虽然它可以用来将视频显示到屏幕上,但您不需要这样做。就我个人而言,如果您没有那么丰富的经验,我建议您继续使用SDL并删除示例后面的显示代码。在本例中,它为您处理内存,因此如果您不知道如何编写,它比您自己编写安全代码要容易一些。
标题>- 使用不带参数的函数访问结构元素
- 不带大括号的枚举形式
- 将静态库链接到不带-fPIC的共享库中
- 检查不带转换的扫描格式
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 不带预处理器的调用方法/文件的文件名/行号
- 如何打印不带空格的输入整数?
- 带<T>或不带 (C++) 的类模板
- 声明C++数组(带或不带 "new" 关键字)
- 不带轮询的 SDL2 事件回调
- 多个'if'语句,不带'else'
- 使用不带缓冲区变量的冲刺
- "extern"声明以及带有和不带参数列表的类模板实例的后续定义
- 打印标准::<char>不带无关字符的矢量
- f 是指向函数的指针,该函数采用 int,并返回指向不带任何内容并返回双精度的函数的指针
- 调用多个类而不带 if 语句
- 在 c++ 中,rand() 在执行有调试和不带调试的程序时生成不同的结果
- 删除动态数组上不带方括号的内容
- 定义不带大小或零大小的数组
- LibVLC教程,不带SDL