我用GStreamer写了一个小的HTTP视频流服务器。本质上,客户端执行GET请求并接收连续的HTTP流。
流应该同步发送,即以与比特率相同的速度发送。问题是一些播放器(mplayer是一个突出的例子)不能很好地缓冲可变比特率内容,因此缺乏每隔一秒。
我想通过立即传输第一个,比如说5mb,忽略管道的时钟来规避缓冲区不足。流的其余部分应以适当的速度传输。
我认为设置fdsink sync=TRUE
为前5 MB, sync=FALSE
从那时起应该做的技巧,但这不起作用,因为fdsink
耐心地等待管道时钟赶上已经发送的数据。在我使用非常低比特率的测试中,有好几秒钟没有数据传输。
我的fdink reader线程现在看起来像这样:
static void *readerThreadFun(void*) {
int fastStart = TRUE;
g_object_set(G_OBJECT(fdsink0), "sync", FALSE, NULL);
for(uint64_t position = 0;;) {
// (On the other side there is node.js,
// that's why I don't do the HTTP chunking here)
ssize_t readCount = splice(gstreamerFd, NULL, remoteFd,
NULL, 1<<20, SPLICE_F_MOVE|SPLICE_F_MORE);
if(readCount == 0) {
break;
} else if(readCount < 0) {
goto error;
}
position += readCount;
if(fastStart && position >= 5*1024*1024) {
fastStart = FALSE;
g_object_set(G_OBJECT(fdsink0), "sync", TRUE, NULL);
}
}
...
}
如何让GStreamer"忘记"挂钟必须赶上的持续时间?有一些"重置"功能吗?我误解sync
了吗?在GStreamer中还有其他实现"快速启动"的方法吗?
这不是我想要的解决方案:
gst_base_sink_set_ts_offset
(GST_BASE_SINK(fdsink0), -10ll*1000*1000*1000);
接收器将立即流式传输前10秒。