我在網上搜索,但有關於這個信息非常少。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的設備都支持這一點。 –