我在网上搜索但是关于此的信息非常少。
我有一个实时广播应用程序,我发送编码的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),但图像仍然会有一些拖动,好像一帧丢失了。在良好的网络条件下,一切都很顺利。
这些流媒体设备如何处理这些情况?它总是看起来很棒,根本没有拖动或跳过框架......
答案 0 :(得分:0)
令人惊讶的是,确实没有来自广播公司方面的关于自适应比特率的在线信息。当我不得不用RTSP和两个rtp套接字来实现这样的东西时,我采用了类似的方法,创建了一个轮询类,当数据包缓冲区> $ GOOD_PCT空闲时,它会适度地增加mediacodec的比特率,当它的时候积极地将它减半。队列小于$ BAD_PCT免费,如果介于两者之间则不执行任何操作。 Partially seen here。我不确定我是否根据发布的代码全面了解您的解决方案,但您是直接调整mediacodec比特率,对吗?我腐败的唯一一次是当我从mediacodec请求同步帧时,所以如果它在你的代码中,请避免它。希望这会有所帮助。