您需要替换函数调用ffmpeg
用于读取文件,使用那些将重试直到文件完成写入的文件。
首先,你可以编写你自己的处理器,并提供一个回调到ffio_init_context()
,它会重试读取,直到文件被完全写入(你必须确定一个函数的方法能够告诉文件完成)。
其次,你可以决定哪些函数调用ffmpeg
用来读取文件(可能read()
或fread()
),并使用LD_PRELOAD夹着一个替代品,将重试,直到该文件已完成写入。这有点hackish,但它可以工作。像这样的东西(这仅仅是现成的,袖口的代码演示如何能做到这一点。如果你幸运的话,这可能连工作...。):
read.c:
// most libc implementations also provide another symbol
// for library functions that starts with "_"
extern ssize_t _read(int, void *, size-t);
ssize_t read(int fd, void *buffer, size_t bytes)
{
ssize_t bytesRead;
for (;;)
{
bytesRead = _read(fd, buffer, bytes);
if (bytesRead != 0 || fileIsComplete(fd))
{
break;
}
}
return (bytesRead);
}
您需要执行fileIsComplete()
以检查文件是否已完全写入 - 如果文件尚未完成,请稍后将其编辑为sleep
,否则您将会疯狂地旋转。如果ffmpeg
未使用read()
,则必须找出它正在使用的内容,例如fread()
。
如果libc中不具备的功能(S)ffmpeg
备用下划线为前缀的符号用来读取这个文件,你必须做这样的事情(例如是fread()
:
FREAD。 C:
// function pointer to the real fread() function
static size_t (*real_fread)(void *, size_t, size_t, FILE *) = NULL;
size_t fread(void *buffer, size_t size, size_t n, FILE *stream)
{
// might need to mutex this for multithreaded apps
if (real_fread == NULL)
{
real_fread = dlsym(RTLD_NEXT, "fread");
}
size_t result;
for (;;)
{
result = real_fread(buffer, size, n, stream);
if ((result != 0) || fileIsComplete(stream))
{
break;
}
}
return(result);
}
只需编译插入C代码到一个共享对象和使用LD_PRELOAD有ffmpeg
使用插入read()
功能需要注意的是在这两种情况下,你必须添加适当的头文件(或可能跳过。他们因为你可能会得到重新宣布的错误 - 在哪些c因为您可能必须自己提供像RTLD_NEXT
这样的值的正确定义)。
这样做可能会非常棘手获得工作的权利,如所有调用您的插入功能(S)将通过您的图书馆与你的LD_PRELOAD组运行的任何进程。您可能最好使用包装脚本来设置LD_PRELOAD,然后运行ffmpeg
,因此只需要处理ffmpeg
与插入库的配合。
而ffmpeg
可能无法很好地处理部分读取 - 您可能需要修改代码以保持读取,直到文件完成或读取了一定数量的字节,例如请求的字节数。