我已经用C ++构建了RTSP服务器。它只有一个目的,那就是将HEVC视频从硬件编码器流式传输到任意数量的客户端。到目前为止,OPTIONS,SETUP,DESCRIBE,PLAY都可以与ffplay正确对话(VLC似乎不喜欢它是交错流),但是每次发送数据包时,我都会在播放器上弹出Illegal temporal ID in RTP/HEVC
。 / p>
我已经检查了视频流数据包。每个似乎都以以下十六进制开头:00 00 00 01
。从RTP HEVC标准来看,NAL应该是2个字节而不是4个,因此我尝试剥离前两个字节,但这只是混淆ffplay。另外,我似乎使用的HEVC分析仪正确地将4字节的开始序列标识为有效的NAL,因此我认为是我没有正确分割视频或缺少NAL知识。
我对此代码的“新鲜”表示敬意。它是一个原型!这就是我处理发送每个RTP数据包的方式。请注意,BIN
函数采用二进制数的QString
并生成QBitArray
。
void Session::setSocket(QTcpSocket *soc)
{
if (socket != nullptr) soc->disconnect();
socket = soc;
soc->connect(exporter, &Exporters::RTSPServerExporter::send, soc, [soc, this]
(QSharedPointer<vector<vector<uint8_t>>> data){
if (state != PLAY) return;
for(auto line : *data) {
//We construct the RTP header
QString header = BIN(0, 8);
header += BIN(12 + line.size(), 16);
header += "10"; // V
header += "0"; // P
header += "0"; // X
header += "0000"; // CC
header += "0"; // M
header += "1100000"; // PT
header += BIN(++seq, 16); // SEQ
header += BIN(time, 32);; //Timestamp estimate
header += BIN(0, 32); // SSRC
QBitArray b = BIN(header);
QByteArray ret((b.count()/8), '\0');
for (int i = 0; i < b.count(); i++) { //send line by line. This is my guess at the problem!
ret[i/8] = static_cast<char>(ret.at(i/8) | ((b[i]?1:0) << (7-(i%8))));
}
ret.prepend(QString("$").toLocal8Bit());
soc->write(ret);
soc->write(reinterpret_cast<char*>(line.data()), line.size());
soc->flush();
}
time += 3;
}, Qt::DirectConnection);
}
我的猜测是我将其拆分为错误。我只是发送硬件编码器输出的每一行。我真的不知道线代表什么,这就是给我的。
任何帮助将不胜感激。随时要求提供任何有用的信息!