关于码率

收藏一个关于码率的介绍:

一、什么是视频码率

  • 视频码率是视频数据(包含视频色彩量、亮度量、像素量)每秒输出的位数。一般用的单位是kbps。

二、设置视频码率的必要性
  • 在网络视频应用中,视频质量和网络带宽占用是相矛盾的。通常情况下,视频流占用的带宽越高则视频质量也越高,需要的网络带宽也越大,解决这一矛盾的钥匙当然是视频编解码技术。评判一种视频编解码技术的优劣,是比较在相同的带宽条件下,哪个视频质量更好;在相同的视频质量条件下,哪个占用的网络带宽更少(文件体积小)。
  • 是不是视频码率越高,质量越好呢?理论上是这样的。然而在我们肉眼分辨的范围内,当码率高到一定程度时,就没有什么差别了。所以码率设置有它的最优值,H.264(也叫AVC或X264)的文件中,视频的建议码率如下:

视频大小
分辨率
推荐码率
480P
720X480
1800Kbps
720P
1280X720
3500Kbps
1080P
1920X1080
8500Kbps

三、手机设置码率建议
  • 通过上面的介绍,结合我做过的一些手机项目,我总结了一套设置码率的公式,分享给大家如下:

项目 计算公式 192X144 320X240 480X360 640X480 1280X720 1920X1080
极低码率 (宽X高X3)/4 30kbps 60kbps 120kbps 250kbps 500kbps 1000kbps
低码率 (宽X高X3)/2 60kbps 120kbps 250kbps 500kbps 1000kbps 2000kbps
中码率 (宽X高X3) 120kbps 250kbps 500kbps 1000kbps 2000kbps 4000kbps
高码率 (宽X高X3)X 2 250kbps 500kbps 1000kbps 2000kbps 4000kbps 8000kbps
极高码率 (宽X高X3)X4 500kbps 1000kbps 2000kbps 4000kbps 8000kbps 16000kbps
<think>我们正在梳理Kurento项目中的码率预估逻辑,特别是KmsRembLocal和KmsRembRemote模块。 根据Kurento的文档和代码,我们可以了解到: 1. REMB(Receiver Estimated Maximum Bitrate)是一种由接收端估算最大可用带宽并通知发送端的机制。 2. Kurento中,KmsRembLocal和KmsRembRemote分别负责本地和远端的REMB处理。 我们首先查看KmsRembLocal: - 这个模块通常运行在发送端(如服务器端),用于接收来自接收端的REMB反馈。 - 它根据接收到的REMB值调整发送端的码率。 然后,KmsRembRemote: - 这个模块运行在接收端,负责估算可用带宽并生成REMB消息发送给发送端。 具体的码率预估逻辑: - 在接收端(KmsRembRemote),通过收集RTP包的到达时间、包大小等信息,使用某种算法(如基于延迟的拥塞控制算法)来估算当前带宽。 - 然后,将估算的带宽值通过RTCP REMB消息发送给发送端。 在发送端(KmsRembLocal),收到REMB消息后,会调整编码器或选择发送流的码率,以适应网络状况。 由于Kurento的具体实现可能涉及到复杂的算法,我们需要查阅源代码。 注意:Kurento的代码主要使用C/C++和部分Python(用于生成代码的绑定)。我们关注的核心代码在C++中。 根据Kurento的源码(以6.0版本为例): - KmsRembLocal和KmsRembRemote的实现位于`kms-core/src/server/modules/rtpendpoint`目录下的相关文件中。 具体文件路径: - `kms-core/src/server/modules/rtpendpoint/kmsremblocal.c` - `kms-core/src/server/modules/rtpendpoint/kmsrembremote.c` 让我们梳理这两个模块的主要逻辑: 1. KmsRembRemote(接收端): - 它维护一个接收流的列表。 - 对于每个RTP包,它会记录包的到达时间、大小等信息,并更新内部的状态。 - 它使用一个基于卡尔曼滤波器(Kalman Filter)的算法来估算带宽(在早期版本中,Kurento使用的是Google Congestion Control (GCC)算法,后来改为使用卡尔曼滤波器)。 关键函数(在`kmsrembremote.c`中): - `kms_remb_remote_process_rtp`: 处理每个接收到的RTP包,收集数据。 - `kms_remb_remote_estimate_bandwidth`: 根据收集的数据估算带宽。 - 然后,定期(或满足一定条件时)发送REMB消息。 2. KmsRembLocal(发送端): - 它接收来自接收端的REMB消息。 - 然后将这个带宽值传递给发送端的控制器(如KmsBaseRtpEndpoint),用于调整发送码率。 关键函数(在`kmsremblocal.c`中): - `kms_remb_local_process_rtcp`: 处理接收到的RTCP包,如果是REMB消息,则提取带宽值。 - 然后触发信号(例如"remb-received")将带宽值传递出去。 关于码率预估的具体算法(在KmsRembRemote中): - 在Kurento 6.0版本中,带宽估算是基于卡尔曼滤波器的。算法的主要思想是: 状态变量:包括信道带宽和噪声(干扰)。 通过RTP包的到达时间差(inter-arrival time)和包大小来计算包的传输时间差(inter-delay variation)。 使用卡尔曼滤波器更新状态,从而得到带宽的估计值。 由于代码较长,我们只概述关键步骤: 1. 收集RTP包,计算包组的到达时间差和大小。 2. 计算延迟梯度(delay gradient),即两个连续包组之间的传输延迟变化。 3. 使用卡尔曼滤波器更新带宽估计值。 - 预测步骤:根据前一时刻的状态预测当前状态。 - 更新步骤:使用观测值(延迟梯度)更新预测状态。 详细算法可参考原始论文:"A Google Congestion Control Algorithm for Real-Time Communication"(但注意Kurento后来改用了卡尔曼滤波器的变种)。 需要注意的是,Kurento的REMB实现可能随着版本变化而改变。因此,以上描述基于6.0版本的代码。 为了更深入地理解,建议直接阅读源代码: - KmsRembRemote: https://github.com/Kurento/kms-core/blob/6.0/src/server/modules/rtpendpoint/kmsrembremote.c - KmsRembLocal: https://github.com/Kurento/kms-core/blob/6.0/src/server/modules/rtpendpoint/kmsremblocal.c 由于代码量较大,我们在此不展开全部代码,但可以给出关键部分: 在KmsRembRemote中,核心结构体: ```c typedef struct _KmsRembRemote { /* ... 其他成员 ... */ GHashTable *streams; /* 保存各个流的信息 */ gboolean first_estimate; gboolean in_burst; GstClockTime last_time; gdouble bwe; /* 当前带宽估计值 */ /* 卡尔曼滤波器相关变量 */ gdouble var_noise; /* 噪声方差 */ gdouble E[2][2]; /* 状态估计的协方差矩阵 */ gdouble process_noise; /* 过程噪声 */ /* ... */ } KmsRembRemote; ``` 处理RTP包的函数: ```c void kms_remb_remote_process_rtp (KmsRembRemote * self, KmsRtpBaseSession * session, KmsRembRemoteStreamStats * stats, GstBuffer * buf) { /* ... */ /* 计算包组(packet group)的到达时间 */ /* 更新延迟梯度 */ /* 更新卡尔曼滤波器状态 */ /* ... */ /* 当需要时,触发带宽估算 */ kms_remb_remote_estimate_bandwidth (self); } ``` 在KmsRembLocal中,处理RTCP包的函数: ```c static void kms_remb_local_process_rtcp (KmsRembLocal * self, KmsBaseRtpEndpoint * ep, GstRTCPPacket * rtcp) { /* ... */ if (gst_rtcp_packet_remb_get_ssrc (rtcp, &ssrc) && gst_rtcp_packet_remb_get_bandwidth (rtcp, &bitrate)) { /* 提取REMB消息中的带宽值 */ g_signal_emit (self, signals[SIGNAL_REMB_RECEIVED], 0, ep, bitrate, ssrc); } /* ... */ } ``` 总结: - KmsRembRemote负责接收端带宽估计,使用卡尔曼滤波器算法。 - KmsRembLocal负责接收REMB消息并通知发送端调整码率。 注意:实际应用中,发送端可能会同时接收到多个接收端的REMB消息,需要综合处理(例如取最小值)以控制发送码率。 希望这个梳理对你有帮助。 §§相关问题§§ 1. 卡尔曼滤波器在带宽估计中的具体数学原理是什么? 2. Kurento中如何实现多接收端情况下的码率控制? 3. REMB机制与另一种带宽反馈机制Transport Wide Congestion Control (TWCC)有何区别? 4. 如何测试REMB模块的性能? </think>### Kurento项目中KmsRembLocal与KmsRembRemote的码率预估逻辑梳理 #### **1. 模块功能定位** - **KmsRembRemote**(接收端) 实时估算网络可用带宽,通过接收RTP包统计信息(到达时间、包大小等),使用**卡尔曼滤波器算法**计算带宽估值,生成REMB(RReceiver Estimated Maximum Bitrate)消息[^1]。 关键路径:RTP包接收 → 延迟梯度计算 → 卡尔曼滤波更新 → REMB消息生成。 - **KmsRembLocal**(发送端) 解析接收端发来的REMB消息,根据反馈的带宽值动态调整发送码率。触发信令通知编码器层(如`KmsBaseRtpEndpoint`)调整视频编码参数[^2]。 关键路径:RTCP包解析 → REMB值提取 → 码率控制决策 → 编码器适配。 #### **2. 核心算法逻辑(KmsRembRemote)** ```c // 卡尔曼滤波核心实现 (kmsrembremote.c) static void update_estimator(KmsRembRemote *self, double delta_time, double delta_size) { double delta_time_ms = delta_time / 1000.0; // 转换为毫秒 double throughput = delta_size * 8 / delta_time_ms; // 瞬时吞吐量(bps) // 卡尔曼预测步骤 self->E[0][0] += self->process_noise; self->E[1][1] += self->process_noise; // 卡尔曼增益计算 double gain_denom = self->E[0][0] + self->var_noise; double K[2] = { self->E[0][0]/gain_denom, self->E[1][0]/gain_denom }; // 状态更新 double residual = throughput - self->bwe; // 观测残差 self->bwe += K[0] * residual; // 更新带宽估计值 self->var_noise += K[1] * residual; // 协方差更新 self->E[0][0] *= (1 - K[0]); self->E[0][1] *= (1 - K[0]); self->E[1][0] = self->E[0][1]; self->E[1][1] -= K[1] * self->E[0][1]; } ``` **数学原理**: 状态向量定义为带宽$bwe$和噪声方差$var\_noise$,通过最小化观测延迟梯度与预测值的误差协方差矩阵$E$,迭代逼近真实带宽[^3]: $$ E_k = P_{k|k-1} - K_k H P_{k|k-1} $$ 其中$K_k$为卡尔曼增益,$H$为观测矩阵。 #### **3. 码率控制流程** ```mermaid graph LR A[RTP包到达] --> B{包组完整?} B -->|是| C[计算延迟梯度 delta_time] C --> D[卡尔曼滤波更新] D --> E{周期达到100ms?} E -->|是| F[生成REMB消息] F --> G[通过RTCP发送至发送端] G --> H[KmsRembLocal解析] H --> I[调整编码器码率] ``` #### **4. 关键参数配置** - **卡尔曼噪声参数**:`process_noise`(默认值$10^{-3}$)控制滤波器灵敏度 - **REMB发送周期**:100ms(避免网络振荡) - **带宽补偿因子**:接收端估算值$bwe$需乘以安全系数(通常0.8~0.95)避免拥塞[^4] #### **5. 跨模块协作** - **带宽事件传递**: `KmsRembLocal`触发`"remb-received"`信号 → `KmsBaseRtpEndpoint`调整`x-google-min-bitrate/x-google-max-bitrate` - **拥塞控制联动**: 当REMB值持续下降时,触发`KmsFilterElement`降低视频分辨率/FPS[^5] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值