use*_*364 5 c++ video vlc transcoding libvlc
我想写一帧视频帧到*.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 */
}
Run Code Online (Sandbox Code Playgroud)
我怎么能写没有这个功能struct ctx,SDL_LockMutex和SDL_LockSurface?
你可以想象,我不是一个非常有经验的程序员,所以请耐心等待我;)
在此先感谢!
我真的不知道libvlc,但是你可以根据这个特定的例子去除SDL.
在这个例子中,你必须通过一些不同的函数传递给libvlc回调函数 ......
libvlc_video_set_callbacks(mp, lock, unlock, display, &ctx);
Run Code Online (Sandbox Code Playgroud)
现在,要完全理解这个锁定函数正在做什么,您需要了解一些多线程以及图像如何存储在内存中.
本质上,为了确保没有任何内容访问libvlc在写入时所使用的内存区域,它会"锁定"一种称为互斥锁的东西.如果您尝试锁定已被其他东西锁定的互斥锁,则当前执行将等待直到它被解锁.
如果你在半边写的时候访问了这些像素,你能想象它会有多可怕吗?它可能是半写的,然后你会用它来保存你的yuv文件.这将是灾难性的.
锁定功能所做的第二件事是指定内存中vlc可用于加载图像帧的区域.此示例使用SDL_Surface,但如果您小心,可以创建自己的SDL_Surface .
所以,如果你只使用libvlc,你会想要找到这些东西的替代品.
我将从上面的列表中按相反的顺序排列.在示例中,它们使用SDL_Surface但是如果您无法使用它,则必须在内存中创建自己的结构以存储像素数据(如果您想要提取它).一种简单的方法是创建一个正确大小的char数组.我将使用ctx结构,因为它很方便:我知道你问过不使用它,但在这种情况下它非常有用,因为我们需要将多条信息传递给lock函数.
struct ctx
{
unsigned char *pixeldata;
};
Run Code Online (Sandbox Code Playgroud)
现在,在主函数的某处,您需要在内存中创建区域.如果您知道视频大小和每像素使用的位数(bpp):这非常简单.但是要非常小心,如果你没有正确地做到这一点:你可能最终导致内存损坏.
ctx.pixeldata = new unsigned char[width * height * bpp];
Run Code Online (Sandbox Code Playgroud)
确保在程序结束时正确删除它...
delete[] ctx.pixeldata;
Run Code Online (Sandbox Code Playgroud)
接下来就是互斥体.这不是严格需要的,但是你可以遇到我上面提到的问题.如果您确实想使用互斥锁,则需要在libvlc_video_set_callbacks中指定解锁函数(如果不想使用互斥锁,可以指定NULL解锁).
问题是你将为此目的使用互斥锁(如果你想使用一个,我建议你这样做)?如果您使用的是较新的C++ 11标准,则可以使用std :: mutex.如果你不是,那么你将不得不找到像boost boost文件库那样的东西,或者写一些类似你自己的东西.如果您使用的是C++ 11,则需要将其添加到ctx结构中...
#include <mutex>
struct ctx
{
unsigned char *pixeldata;
std::mutex imagemutex;
};
Run Code Online (Sandbox Code Playgroud)
现在为实际的锁定功能本身.
static void *lock(void *data, void **p_pixels)
{
struct ctx *ctx = data;
ctx->imagemutex.lock()
*p_pixels = ctx->pixeldata;
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
你的解锁功能会是这样的......
static void unlock(void *data, void *id, void *const *p_pixels)
{
struct ctx *ctx = data;
ctx->unlock();
assert(id == NULL);
}
Run Code Online (Sandbox Code Playgroud)
无论何时您想要安全地访问该像素数据......
ctx->imagemutex.lock();
/* Access Data Here */
ctx->imagemutex.unlock();
Run Code Online (Sandbox Code Playgroud)
我想简单介绍一下SDL.虽然它可以用于将视频显示到屏幕,但您不需要.就个人而言,如果您没有经验,我建议您继续使用SDL并在示例中进一步删除显示代码.它在这个例子中为你处理内存,所以如果你不知道怎么做,它比编写你自己的安全代码容易一些.
| 归档时间: |
|
| 查看次数: |
5219 次 |
| 最近记录: |