我在网上搜索,但有关于这个信息非常少。RTMP自适应比特率算法
我有一个实时广播应用程序,通过RTMP堆栈发送编码的H264视频帧和来自摄像头&麦克风使用Android MediaCodec SDK的AAC音频块。
我的直播视频是720p和我的目标与2500Kbps伟大的品质。这显然需要一个非常好的网络连接,如果您使用数据计划,则意味着4G。
问题是,即使以最大的连接就会出现低峰充血,所以会有瞬间在网络不能举行这样重流。由于我想提供高可靠性,因此我希望在自己的应用中包含自动适应性比特率,以便降低图像质量或降低可靠性。
的事情是 - 如何实现这种自动适应网络条件,而不会丢失帧?它甚至有可能吗?我已经使用了专业编码设备,如Cerevo,他们不会丢失帧 - 但是,由于P帧在网络中丢失,我的应用总是会出现一些糟糕的拖动。
这是我目前有:
private long adaptBitrate(long idleNanos, Frame frame) {
int bytes = frame.getSize();
long nowNanos = System.nanoTime();
if (nowNanos - mLastNanos > 1000L * 1000 * 1000) {
double idle = (double) idleNanos/(double) (nowNanos - mLastNanos);
float actualBitrate = newBitrate;
int size = mBuffer.size();
String s = "Bitrate: " + actualBitrate/1000
+ " kbps In-Flight:" + bytes
+ " idle: " + idle;
if (size > MAX_BUF_SIZE && size > mLastSize) {
Log.i(TAG, "adaptBitrate: Dropping bitrate");
newBitrate = (int) ((double) actualBitrate * BITRATE_DROP_MULTIPLIER);
if (newBitrate < MIN_BITRATE) {
newBitrate = MIN_BITRATE;
}
s += " late => " + newBitrate;
mRtmpHandler.requestBitrate(newBitrate);
} else if (size <= 2 && idle > IDLE_THRESHOLD) {
mIdleFrames++;
if(mIdleFrames >= MIN_IDLE_FRAMES){
Log.i(TAG, "adaptBitrate: Raising bitrate");
newBitrate = (int) ((double) newBitrate * BITRATE_RAISE_MULTIPLIER);
if (newBitrate > MAX_BITRATE) {
newBitrate = MAX_BITRATE;
}
s += " idle => " + newBitrate;
mRtmpHandler.requestBitrate(newBitrate);
mIdleFrames = 0;
}
}
debugThread(Log.VERBOSE, s);
mLastNanos = System.nanoTime();
mLastSize = size;
idleNanos = 0;
}
return idleNanos;
}
所以,如果我的缓冲区超过阈值,我降低了比特率。如果我的应用程序花费太多时间等待新帧,对于多个连续帧,则提高比特率。
不管我多么谨慎,我总是会丢失重要的信息,并且我的信息流会一直中断,直到下一个关键帧到达(2秒)。有时似乎网络可以保持一定的比特率(例如稳定在1500kbps),但图像仍然会有一些拖动,就好像一帧丢失了一样。拥有良好的网络条件,一切都很顺利。
如何将这些流媒体设备处理这些情况?它总是看起来不错,没有拖动或跳过的帧...
那么你知道设备编码器本身是否真正支持模式切换?换句话说,当你模拟一个完美连接的转换时会发生什么?此外,这是一个实时流式场景,就像聊天,或者只是通常的广播? – ThomasRS
实时播报。不知道你所说的“模式切换”是什么意思,如果你的意思是适应比特率,我会测量输出比特流,并且匹配所需的比特率,所以它有效地改变了比特率。如果我没有弄错的话,所有来自4.3的设备都支持这一点。 –