2017-04-06 66 views
6

我在網上搜索,但有關於這個信息非常少。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),但圖像仍然會有一些拖動,就好像一幀丟失了一樣。擁有良好的網絡條件,一切都很順利。

如何將這些流媒體設備處理這些情況?它總是看起來不錯,沒有拖動或跳過的幀...

+0

那麼你知道設備編碼器本身是否真正支持模式切換?換句話說,當你模擬一個完美連接的轉換時會發生什麼?此外,這是一個實時流式場景,就像聊天,或者只是通常的廣播? – ThomasRS

+0

實時播報。不知道你所說的「模式切換」是什麼意思,如果你的意思是適應比特率,我會測量輸出比特流,並且匹配所需的比特率,所以它有效地改變了比特率。如果我沒有弄錯的話,所有來自4.3的設備都支持這一點。 –

回答

0

令人驚訝的是,確實沒有關於廣播公司自適應比特率的信息。當我必須通過RTSP和兩個rtp套接字來實現這樣的事情時,我採取了類似的方法,創建了一個輪詢類,當數據包緩衝區大於$ GOOD_PCT時,可以適度增加媒體編解碼器的比特率,當隊列時將其大幅減半低於$ BAD_PCT免費,如果它介於兩者之間,則什麼也不做。 Partially seen here。我不確定我是否有完整的基於發佈代碼的解決方案圖片,但是您直接調整媒體編碼比特率,是否正確?唯一一次我發生了損壞的情況是我從mediacodec請求了一個同步幀,所以如果它在你的代碼中,請避免這一點。希望這可以幫助。