2017-04-06 23 views
6

私はオンラインで検索しましたが、これに関する情報はほとんどありません。RTMP適応型ビットレートアルゴリズム

私は、Android MediaCodec SDKを使用して、&カメラからエンコードされたH264ビデオフレームとAACオーディオチャンクをRTMPスタック経由で送信しています。

私のライブストリームは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と2つのrtpソケットでこれを実装しなければならなかったとき、同様のアプローチをとって、パケットバッファが$ GOOD_PCT以上のときにmediacodecのビットレートを適度に増加させるポーリングクラスを作成し、キューを積極的に半分にしました$ BAD_PCT未満のフリーであり、間にあった場合は何もしません。 Partially seen here。私は投稿されたコードに基づいてあなたのソリューションの完全な画像を持っているかどうかはわかりませんが、直接mediacodecビットレートを調整していますか?私が腐敗した唯一の時間は、私がmediacodecから同期フレームを要求したときです。それがあなたのコードにあればそれを避けてください。お役に立てれば。

関連する問題