当前位置: 首页 > 知识库问答 >
问题:

RTMP自适应码率算法

韶和璧
2023-03-14

我在网上搜索了一下,但这方面的信息很少。

我有一个直播应用程序,在那里我发送编码的H264视频帧和AAC音频块产生的相机和麦克风使用Android MediaCodec SDK,通过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),但图像仍然会有一些拖拽,就好像中途丢失了一帧。有了良好的网络条件,一切顺利。

共有1个答案

终睿
2023-03-14

令人惊讶的是,网上确实没有关于广播方自适应比特率的信息。当我不得不用RTSP和两个rtp套接字实现类似的东西时,我采用了类似的方法,创建了一个轮询类,当数据包缓冲区>$GOOD_PCT空闲时,它将适度增加mediacodec的比特率,当队列小于$BAD_PCT空闲时,它将积极地将比特率减半,如果介于两者之间,则不执行任何操作。在这里部分看到。我不确定我有一个完整的图片,您的解决方案基于张贴的代码,但您是在直接调整mediacodec比特率,对吗?唯一一次发生损坏是当我从mediacodec请求同步帧时,所以如果它在您的代码中,请避免发生这种情况。希望这有帮助。

 类似资料:
  • 问题内容: 我正在使用TensorFlow训练神经网络。这就是我初始化的方式: 这里的问题是,我不知道如何为学习速率设置更新规则或为它设置衰减值。 在这里如何使用自适应学习率? 问题答案: 首先,旨在对所有步骤中的所有变量使用恒定的学习率。TensorFlow还提供了开箱即用的自适应优化器,包括和,这些可以用作即插即用的替代品。 但是,如果您希望通过原始的梯度下降来控制学习速率,则可以利用以下事实

  • 我开发了一个带有dash.js的html5视频播放器,可以播放流媒体mpeg dash内容。它工作得很好。 现在我需要在WPF上运行同样的程序。使用webbrowser来运行我已经开发的html5听起来很肮脏,但我不知道我能用什么来让流媒体工作。 有什么提示吗?

  • 主要内容:其他类型的自适应阈值在简单的阈值处理中,阈值是全局的,即对于图像中的所有像素是相同的。 自适应阈值法是针对较小区域计算阈值的方法,因此对于不同区域将存在不同的阈值。 在OpenCV中,可以使用类的方法对图像执行自适应阈值操作。 以下是此方法的语法。 该方法接受以下参数 - src - 表示源(输入)图像的类的对象。 dst - 表示目标(输出)图像的类的对象。 thresh - 表示阈值的双重类型的变量。 maxva

  • Material Design 中的响应式布局适用于任何尺寸的屏幕。自适应 UI 手册包含:保证布局一致性的灵活网格、内容如何在不同屏幕上重绘的断点细节以及关于一个应用如何从小的屏幕缩放到超大屏幕的描述。 断点 为了最优的用户体验,Material 用户界面应该适应如下断点宽度的布局:480、600、840、960、1280、1440 以及 1600 dp。 1.布局中的总结和细节显示内容 600

  • 本文向大家介绍jsp页面iframe高度自适应的js代码,包括了jsp页面iframe高度自适应的js代码的使用技巧和注意事项,需要的朋友参考一下 以下操作写在body里面,form表单外 test.jsp如下:

  • 我应用以下滤波器来去除信号上的50Hz净噪声: 我用Q玩过,但它不够好。