好多开发者,在设置视频编码参数的时候,对不同分辨率的带宽设置,缺乏相关的经验,实际上,视频分辨率与所需带宽之间的关系受到多个因素的影响,包括视频编码方式、帧率、视频内容的动态程度等。下面,我们对不同分辨率大致所需带宽的分析:
Android平台上,有多种视频编码方式可供选择,每种编码方式都有其特点和适用场景。如果是高端 Android 设备,具有较强的处理器和图形处理能力,可以考虑使用 H.265 或 VP9 等高压缩比的编码方式,以获得更好的视频质量和更低的带宽需求。对于中低端设备,可能需要权衡编码效率和设备性能。H.264 可能是更合适的选择,以确保视频的流畅播放和较低的资源占用。
以大牛直播SDK的RTMP推送端为例,一般是根据视频宽高、帧率、H.264、H.265编码类型等,给出评估的码率范围,然后设置:
Android平台RTMP直播推送SDK
//估计硬编码码率, 可以根据实际机型调整
public static int estimate_video_hardware_kbps(int width, int height, int fps, boolean is_h264) {
int kbps;
int area = width * height;
if (area <= (320 * 300))
kbps = is_h264?350:280;
else if (area <= (370 * 320))
kbps = is_h264?470:400;
else if (area <= (640 * 360))
kbps = is_h264?850:650;
else if (area <= (640 * 480))
kbps = is_h264?1200:800;
else if (area <= (800 * 600))
kbps = is_h264?1300:950;
else if (area <= (900 * 700))
kbps = is_h264?1600:1100;
else if (area <= (1280 * 720))
kbps = is_h264?2100:1500;
else if (area <= (1366 * 768))
kbps = is_h264?2300:1900;
else if (area <= (1600 * 900))
kbps = is_h264?2800:2300;
else if (area <= (1600 * 1050))
kbps =is_h264?3100:2500;
else if (area <= (1920 * 1088))
kbps = is_h264?4200:2800;
else
kbps = is_h264?4500:3500;
kbps = (int)(kbps*fps*1.0/25.0 + 0.5);
return kbps;
}
Android APP层调用逻辑如下:
if (videoEncodeType == 1) {
int kbps = LibPublisherWrapper.estimate_video_hardware_kbps(width, height, fps, true);
Log.i(TAG, "h264HWKbps: " + kbps);
int isSupportH264HWEncoder = lib_publisher.SetSmartPublisherVideoHWEncoder(handle, kbps);
if (isSupportH264HWEncoder == 0) {
lib_publisher.SetNativeMediaNDK(handle, 0);
lib_publisher.SetVideoHWEncoderBitrateMode(handle, 1); // 0:CQ, 1:VBR, 2:CBR
lib_publisher.SetVideoHWEncoderQuality(handle, 39);
lib_publisher.SetAVCHWEncoderProfile(handle, 0x08); // 0x01: Baseline, 0x02: Main, 0x08: High
// lib_publisher.SetAVCHWEncoderLevel(handle, 0x200); // Level 3.1
// lib_publisher.SetAVCHWEncoderLevel(handle, 0x400); // Level 3.2
// lib_publisher.SetAVCHWEncoderLevel(handle, 0x800); // Level 4
lib_publisher.SetAVCHWEncoderLevel(handle, 0x1000); // Level 4.1 多数情况下,这个够用了
//lib_publisher.SetAVCHWEncoderLevel(handle, 0x2000); // Level 4.2
// lib_publisher.SetVideoHWEncoderMaxBitrate(handle, ((long)h264HWKbps)*1300);
Log.i(TAG, "Great, it supports h.264 hardware encoder!");
}
} else if (videoEncodeType == 2) {
int kbps = LibPublisherWrapper.estimate_video_hardware_kbps(width, height, fps, false);
Log.i(TAG, "hevcHWKbps: " + kbps);
int isSupportHevcHWEncoder = lib_publisher.SetSmartPublisherVideoHevcHWEncoder(handle, kbps);
if (isSupportHevcHWEncoder == 0) {
lib_publisher.SetNativeMediaNDK(handle, 0);
lib_publisher.SetVideoHWEncoderBitrateMode(handle, 1); // 0:CQ, 1:VBR, 2:CBR
lib_publisher.SetVideoHWEncoderQuality(handle, 39);
// libPublisher.SetVideoHWEncoderMaxBitrate(handle, ((long)hevcHWKbps)*1200);
Log.i(TAG, "Great, it supports hevc hardware encoder!");
}
}
JNI层接口设计如下:
/*
* SmartPublisherJniV2.java
* WeChat:xinsheng120
* Created by daniusdk.com on 2015/09/20.
*/
/**
* Set Video H.264 HW Encoder, if support HW encoder, it will return 0(设置H.264硬编码)
*
* @param kbps: the kbps of different resolution.
*
* @return {0} if successful
*/
public native int SetSmartPublisherVideoHWEncoder(long handle, int kbps);
/**
* Set Video H.265(hevc) hardware encoder, if support H.265(hevc) hardware encoder, it will return 0(设置H.265硬编码)
*
* @param kbps: the kbps of different resolution.
*
* @return {0} if successful
*/
public native int SetSmartPublisherVideoHevcHWEncoder(long handle, int kbps);
/**
* 设置视频硬编码是否使用 Native Media NDK, 默认是不使用, 安卓5.0以下设备不支持
* @param handle
* @param is_native: 0表示不使用, 1表示使用, sdk默认是0.
* @return {0} if successful
*/
public native int SetNativeMediaNDK(long handle, int is_native);
/*
* 设置视频硬编码码率控制模式
* @param hw_bitrate_mode: -1表示使用默认值, 不设置也会使用默认值, 0:CQ, 1:VBR, 2:CBR, 3:CBR_FD, 请参考:android.media.MediaCodecInfo.EncoderCapabilities
* 注意硬编码和手机硬件有关,多数手机只支持部分码率模式, 另外硬编码设备差异很大,不同设备同一码率控制模式效果可能不一样
* @return {0} if successful
*/
public native int SetVideoHWEncoderBitrateMode(long handle, int hw_bitrate_mode);
/*
* 设置视频硬编码复杂度, 安卓5.0及以上支持
* @param hw_complexity: -1表示不设置, 请参考:android.media.MediaCodecInfo.EncoderCapabilities.getComplexityRange() 和 android.media.MediaFormat.KEY_COMPLEXITY
* 注意硬编码和手机硬件有关,部分手机可能不支持此设置
* @return {0} if successful
*/
public native int SetVideoHWEncoderComplexity(long handle, int hw_complexity);
/*
* 设置视频硬编码质量, 安卓9及以上支持, 仅当硬编码器码率控制模式(BitrateMode)是CQ(constant-quality mode)时才有效
* @param hw_quality: -1表示不设置, 请参考:android.media.MediaCodecInfo.EncoderCapabilities.getQualityRange() 和 android.media.MediaFormat.KEY_QUALITY
* 注意硬编码和手机硬件有关,部分手机可能不支持此设置
* @return {0} if successful
*/
public native int SetVideoHWEncoderQuality(long handle, int hw_quality);
/*
* 设置H.264硬编码Profile, 安卓7及以上支持
* @param hw_avc_profile: 0表示使用默认值, 0x01: Baseline, 0x02: Main, 0x08: High, 0x10000: ConstrainedBaseline, 0x80000: ConstrainedHigh;
* 注意: ConstrainedBaseline 和 ConstrainedHigh 可能多数设备不支持,
* H.264推荐使用 High 或者 ConstrainedHigh, 如果您使用的手机硬解码解不了,那还是设置Baseline
* 如果设置的Profile硬编码器不支持,应编码器会使用默认值
* 具体参考:android.media.MediaCodecInfo.CodecProfileLevel
* @return {0} if successful
*/
public native int SetAVCHWEncoderProfile(long handle, int hw_avc_profile);
/*
* 设置H.264硬编码Level, 这个只有在设置了Profile的情况下才有效, 安卓7及以上支持
* @param hw_avc_level: 0表示使用默认值, 0x100: Level3, 0x200: Level3.1, 0x400: Level3.2,
* 0x800: Level4, 0x1000: Level4.1, 0x2000: Level4.2,
* 0x4000: Level5, 0x8000: Level5.1, 0x10000: Level5.2,
* 0x20000: Level6, 0x40000: Level6.1, 0x80000: Level6.2,
* 如果设置的level太高硬编码器不支持,SDK内部会做相应调整
* 注意: 640*480@25fps最小支持的是Level3, 720p最小支持的是Level3.1, 1080p最小支持的是Level4
* 具体参考:android.media.MediaCodecInfo.CodecProfileLevel
* @return {0} if successful
*/
public native int SetAVCHWEncoderLevel(long handle, int hw_avc_level);
/*
* 设置视频硬编码最大码率, 安卓没有相关文档说明, 所以不建议设置,
* @param hw_max_bitrate: 每秒最大码率, 单位bps
* @return {0} if successful
*/
public native int SetVideoHWEncoderMaxBitrate(long handle, long hw_max_bitrate);
需要注意的是,以上只是大致的带宽范围,实际所需带宽可能会因具体情况而有所不同。在网络环境较差的情况下,为了保证视频的流畅播放,视频播放平台可能会自动降低视频的分辨率和码率,从而减少带宽需求。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。