当前位置: 首页 > article >正文

Android MediaCodec设置H264 Profile到High

     H264 High Profile压缩率高,能降低码率,这里记录下MediaCodec Profile设置到High遇到的一些问题。

     Android 4.1 就引入了MediaCodecInfo.CodecProfileLevel类,下面截取H264(AVC)的Profile和Level定义:

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package android.media;

public final class MediaCodecInfo {

    /**
     * Encapsulates the profiles available for a codec component.
     */
    public static final class CodecProfileLevel {
        // These constants were originally in-line with OMX values, but this
        // correspondence is no longer maintained.

        // Profiles and levels for AVC Codec, corresponding to the definitions in
        // "SERIES H: AUDIOVISUAL AND MULTIMEDIA SYSTEMS,
        // Infrastructure of audiovisual services – Coding of moving video
        // Advanced video coding for generic audiovisual services"
        // found at
        // https://www.itu.int/rec/T-REC-H.264-201704-I

        /**
         * AVC Baseline profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileBaseline = 0x01;

        /**
         * AVC Main profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileMain     = 0x02;

        /**
         * AVC Extended profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileExtended = 0x04;

        /**
         * AVC High profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileHigh     = 0x08;

        /**
         * AVC High 10 profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileHigh10   = 0x10;

        /**
         * AVC High 4:2:2 profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileHigh422  = 0x20;

        /**
         * AVC High 4:4:4 profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileHigh444  = 0x40;

        /**
         * AVC Constrained Baseline profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileConstrainedBaseline = 0x10000;

        /**
         * AVC Constrained High profile.
         * See definition in
         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
         * Annex A.
         */
        public static final int AVCProfileConstrainedHigh     = 0x80000;

        public static final int AVCLevel1       = 0x01;
        public static final int AVCLevel1b      = 0x02;
        public static final int AVCLevel11      = 0x04;
        public static final int AVCLevel12      = 0x08;
        public static final int AVCLevel13      = 0x10;
        public static final int AVCLevel2       = 0x20;
        public static final int AVCLevel21      = 0x40;
        public static final int AVCLevel22      = 0x80;
        public static final int AVCLevel3       = 0x100;
        public static final int AVCLevel31      = 0x200;
        public static final int AVCLevel32      = 0x400;
        public static final int AVCLevel4       = 0x800;
        public static final int AVCLevel41      = 0x1000;
        public static final int AVCLevel42      = 0x2000;
        public static final int AVCLevel5       = 0x4000;
        public static final int AVCLevel51      = 0x8000;
        public static final int AVCLevel52      = 0x10000;
        public static final int AVCLevel6       = 0x20000;
        public static final int AVCLevel61      = 0x40000;
        public static final int AVCLevel62      = 0x80000;
 }
}

     其中AVCProfileConstrainedBaseline 和 AVCProfileConstrainedHigh 是安卓8.1 引入的; AVCLevel52 是安卓5.0 引入的; AVCLevel6, AVCLevel61, AVCLevel62 是安卓10 引入的;

     AVC High profile 和 AVC Constrained High profile的区别: 1. 从名字就可以看出Constrained High是High的子集;  2. Constrained High 不支持B slice(B帧); 3.  Constrained High 只支持帧编码,不支持场编码和帧场自适应编码; 

    另外Level也要选择合适的,  GB28181-2016要求本地录像帧率不低于25fps, 网络传输时重要图像帧率宜25fps. GB28181-2022要求一类视频监控点、二类视频监控点的本地录像和网络传输的最大视频帧率应不低于25fps. 这里以视频30fps为例, 安卓摄像头常用的几个分辨率最小支持的Level如下:

分辨率最小支持的Level
640*4803
1280*720(720p)3.1
1920*1280(1080p)

4

3840*2160(4k)5.1

   虽然安卓5.0已引入android.media.MediaFormat.KEY_PROFILE, 安卓6.0 引入android.media.MediaFormat.KEY_LEVEL. 但安卓7.0及以上AVC Profile设置才有效, 并且要求Profile和Level必须一起设置.

   我的代码也提供了Mediacode编码参数设置接口, Java 和 NDK 两种MediaCodec接口方式都支持:

    // Copyright (C) 1130758427@qq.com
   
    /**
	 * 设置视频硬编码是否使用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);


	/*
	 * 设置视频硬编码质量, 安卓9及以上支持, 仅当硬编码器码率控制模式(BitrateMode)是CQ(constant-quality mode)时才有效
	 * @param hw_quality: -1表示不设置, 请参考: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);

  经测试MTK、 海思(鸿蒙系统)、 三星、全志、晶晨、瑞芯微等编码器AVC Profile设置都可以成功。


http://www.kler.cn/a/6171.html

相关文章:

  • C++, STL容器 array:固定大小数组深度解析
  • 机器学习--python基础库之Matplotlib (1) 超级详细!!!
  • vs code 使用教程
  • DeepSeek 部署过程中的问题
  • 树莓派卷积神经网络实战车牌检测与识别
  • 不同数据库与 WebGL 集成
  • Hadoop - HDFS文件系统
  • 宝塔Linux面板部署Python flask项目
  • MacOS中安装和配置Podman
  • linux系统编程(6)--守护进程
  • IDEA vs Eclipse:使用体验对比
  • 蓝桥杯算法全集之多重背包问题I(动态规划算法)
  • Vim超详细下载安装与使用教程
  • C语言模拟实现:atoi函数
  • unity物理碰撞检测和触发器碰撞检测的区别
  • 强引用和弱引用区别
  • php面向对象讲解
  • 2023年全国最新保安员精选真题及答案42
  • 计算机网络中端到端与点到点的区别
  • 【创作赢红包】求最大公因数与最小公倍数
  • 【新2023Q2模拟题JAVA】华为OD机试 - 总最快检测效率 or 核酸检测效率
  • 【云原生进阶之容器】第五章容器运行时5.5--容器运行时之Kata Containers
  • 2023年南京晓庄学院五年一贯制专转本秘书学专业考试大纲
  • 让ChatGPT告诉你Java的发展前景
  • Java小课堂:自定义注解(案例:自定义DecimalFormat注解)
  • TiDB入门篇-数据物理备份和恢复