Многим разработчикам при настройке параметров кодирования видео не хватает соответствующего опыта настройки полосы пропускания для разных разрешений. Фактически, на соотношение между разрешением видео и требуемой полосой пропускания влияет множество факторов, включая метод кодирования видео, частоту кадров, степень динамичности видео. контент и т. д. Ниже мы анализируем приблизительную пропускную способность, необходимую для разных разрешений:
На платформе Android существует несколько методов кодирования видео, каждый из которых имеет свои особенности и применимые сценарии. Если это высокопроизводительное устройство Android с мощным процессором и возможностями обработки графики, вы можете рассмотреть возможность использования методов кодирования с высокой степенью сжатия, таких как H.265 или VP9, чтобы получить лучшее качество видео и снизить требования к пропускной способности. Для устройств низкого и среднего уровня может существовать компромисс между эффективностью кодирования и производительностью устройства. H.264 может быть более подходящим выбором для обеспечения плавного воспроизведения видео и низкого потребления ресурсов.
Если взять в качестве примера RTMP-конец Daniu Live SDK, диапазон скорости кода для оценки обычно задается на основе ширины и высоты видео, частоты кадров, типа кодирования H.264, H.265 и т. д., а затем устанавливается:
Платформа Android RTMP прямая трансляция push 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 следующая:
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, По умолчанию не используется, Устройства ниже Android 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);
/*
* Установите жестко запрограммированную сложность видео, Поддерживается Android 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);
/*
* Установите жестко запрограммированное качество видео, Поддерживается Android 9 и выше, Только если режим управления скоростью передачи данных жесткого кодера (BitrateMode) установлен на CQ (постоянное качество). Это действительно только тогда, когда режим
* @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, Поддерживается Android 7 и выше.
* @param hw_avc_profile: 0 означает использование значения по умолчанию, 0x01: Baseline, 0x02: Main, 0x08: High, 0x10000: ConstrainedBaseline, 0x80000: ConstrainedHigh;
* Уведомление: ConstrainedBaseline и ConstrainedHigh Возможно, большинство устройств не поддерживают его,
* Рекомендуется H.264 High или ВОЗ ConstrainedHigh, Если используемый вами мобильный телефон не может декодировать его методом жесткого декодирования, лучше настроить Baseline.
* Если установленный профиль не поддерживается аппаратным кодировщиком, кодировщик будет использовать значение по умолчанию.
* Код:android.media.MediaCodecInfo.CodecProfileLevel
* @return {0} if successful
*/
public native int SetAVCHWEncoderProfile(long handle, int hw_avc_profile);
/*
* Установите жестко закодированный уровень H.264, Это действительно только в том случае, если установлен профиль. Поддерживается Android 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,
* Если установленный уровень слишком высок и не поддерживается хардкодером, SDK внесет соответствующие коррективы внутри себя.
* Уведомление: Минимальный поддерживаемый уровень 640*480 при 25 кадрах в секунду — Level3. Минимальный поддерживаемый уровень 720p — Level3.1. Минимальный поддерживаемый уровень 1080p — уровень 4.
* Код:android.media.MediaCodecInfo.CodecProfileLevel
* @return {0} if successful
*/
public native int SetAVCHWEncoderLevel(long handle, int hw_avc_level);
/*
* Установите жестко запрограммированный максимальный битрейт видео, Для Android нет соответствующей документации, Поэтому не рекомендуется его устанавливать,
* @param hw_max_bitrate: максимальная скорость передачи данных в секунду, Единица бит/с
* @return {0} if successful
*/
public native int SetVideoHWEncoderMaxBitrate(long handle, long hw_max_bitrate);
Следует отметить, что приведенные выше значения являются лишь приблизительными диапазонами пропускной способности, а фактическая требуемая полоса пропускания может варьироваться в зависимости от конкретных обстоятельств. В плохих сетевых средах, чтобы обеспечить плавное воспроизведение видео, платформа воспроизведения видео может автоматически уменьшать разрешение и скорость передачи данных видео, тем самым снижая требования к полосе пропускания.