IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android端WebRTC启用H264编码-sdp中无H264信息 -> 正文阅读

[移动开发]Android端WebRTC启用H264编码-sdp中无H264信息

Android端WebRTC启用H264编码

目前Android的使用WebRTC仅支持硬件上 H.264 解码和编码,并且仅支持部分芯片组。因此,如果设备不支持硬件 H.264 或具有不受支持的芯片组,您将只能使用 VP8、VP9。支持的芯片组仅有OMX.qcom.*OMX.Exynos.*,不支持的要自行添加。

这里也是在createOffersdp中没有H264信息的原因

VideoEncoderFactory创建

在创建PeerConnectionFactory,可以设VideoEncoderFactory

val encoderFactory = DefaultVideoEncoderFactory(eglBaseContext, true, true)
val peerConnectionFactory = PeerConnectionFactory.builder()
            .setVideoEncoderFactory(encoderFactory)
            .createPeerConnectionFactory()

DefaultVideoEncoderFactory类

public class DefaultVideoEncoderFactory implements VideoEncoderFactory {
	/**
     * 硬解件编码工厂
     */
    private final VideoEncoderFactory hardwareVideoEncoderFactory;
    /**
     * 软件编码工厂
     */
    private final VideoEncoderFactory softwareVideoEncoderFactory = new SoftwareVideoEncoderFactory();

    public DefaultVideoEncoderFactory(Context eglContext, boolean enableIntelVp8Encoder, boolean enableH264HighProfile) {
    	//创建硬解编码工厂
        this.hardwareVideoEncoderFactory = new HardwareVideoEncoderFactory(eglContext, enableIntelVp8Encoder, enableH264HighProfile);
    }
	/**
     * 注意这个构造方法仅包可见
     */
    DefaultVideoEncoderFactory(VideoEncoderFactory hardwareVideoEncoderFactory) {
        this.hardwareVideoEncoderFactory = hardwareVideoEncoderFactory;
    }
    ...
}

DefaultVideoEncoderFactory、HardwareVideoEncoderFactory、SoftwareVideoEncoderFactory类均实现了VideoEncoderFactory接口

VideoEncoderFactory

/**
 * 用于创建视频编码器工厂
 */
public interface VideoEncoderFactory {
	/** 
	 * 为给定的视频编解码器创建一个编码器。
	 */
    @Nullable
    @CalledByNative
    VideoEncoder createEncoder(VideoCodecInfo var1);
	/**
     * 枚举支持的视频编解码器列表。这个方法只会被调用一次,结果将被缓存。
     */
    @CalledByNative
    VideoCodecInfo[] getSupportedCodecs();

    @CalledByNative
    default VideoCodecInfo[] getImplementations() {
        return this.getSupportedCodecs();
    }

    @CalledByNative
    default VideoEncoderFactory.VideoEncoderSelector getEncoderSelector() {
        return null;
    }
}

关键在于getSupportedCodecs()HardwareVideoEncoderFactory中是如何实现的?

@Override
public VideoCodecInfo[] getSupportedCodecs() {
	// Android19以下不支持硬解编码.
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        return new VideoCodecInfo[0];
    }

    List<VideoCodecInfo> supportedCodecInfos = new ArrayList<>();
    // 按优先顺序生成支持的编解码器列表:
    // VP8, VP9, H264 (high profile), and H264 (baseline profile).
    for (VideoCodecType type : new VideoCodecType[]{VideoCodecType.VP8, VideoCodecType.VP9, VideoCodecType.H264}) {
		//查找编解码器类型,这里是关键
		MediaCodecInfo codec = findCodecForType(type);
		if (codec != null) {
			String name = type.name();
            // supported by the decoder.
            if (type == VideoCodecType.H264 && isH264HighProfileSupported(codec)) {
                supportedCodecInfos.add(new VideoCodecInfo(
                            name, MediaCodecUtils.getCodecProperties(type, /* highProfile= */ true)));
            }
			supportedCodecInfos.add(new VideoCodecInfo(
                        name, MediaCodecUtils.getCodecProperties(type, /* highProfile= */ false)));
		}
    }
	return supportedCodecInfos.toArray(new VideoCodecInfo[0]);
}

findCodecForType(VideoCodecType),根据类型查找支持的编解码器

private MediaCodecInfo findCodecForType(VideoCodecType type) {
    for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
        MediaCodecInfo info = null;
        try {
            info = MediaCodecList.getCodecInfoAt(i);
        } catch (IllegalArgumentException e) {
        	//无法检索编码器编解码器信息
            Logging.e(TAG, "Cannot retrieve encoder codec info", e);
        }
        //编解器信息为null,或者不是编解码器不是编码器
		if (info == null || !info.isEncoder()) {
            continue;
        }
        //判断编解码器是否支持,这里就会去判断不同的芯片组是否支持
		if (isSupportedCodec(info, type)) {
			return info;
		}
	}
    return null; // 不支持的类型
}

isSupportedCodec(MediaCodecInfo, VideoCodecType):判断MediaCodecInfo和VideoCodecType结合设备芯片组信息是否支持

private boolean isSupportedCodec(MediaCodecInfo info, VideoCodecType type) {
	if (!MediaCodecUtils.codecSupportsType(info, type)) {
		return false;
	}
	// Check for a supported color format.
	if (MediaCodecUtils.selectColorFormat(
                MediaCodecUtils.ENCODER_COLOR_FORMATS, /*这一步其实就可以判断编解码器是否支持了给定的类型了,如果不抛异常的话*/info.getCapabilitiesForType(type.mimeType()))
                == null) {
		return false;
	}
	return isHardwareSupportedInCurrentSdk(info, type) && isMediaCodecAllowed(info);
}

/**
 * 结合当前的sdk,再次判断是否支持
 */
private boolean isHardwareSupportedInCurrentSdk(MediaCodecInfo info, VideoCodecType type) {
	switch (type) {
		case VP8:
			return isHardwareSupportedInCurrentSdkVp8(info);
        case VP9:
			return isHardwareSupportedInCurrentSdkVp9(info);
		case H264:
			return isHardwareSupportedInCurrentSdkH264(info);
	}
	return false;
}

private boolean isHardwareSupportedInCurrentSdkH264(MediaCodecInfo info) {
	//H264 硬件在此类型设备上可能表现不佳。"SAMSUNG-SGH-I337", "Nexus 7", "Nexus 4"
	if (H264_HW_EXCEPTION_MODELS.contains(Build.MODEL)) {
		return false;
	} else {
		String name = info.getName();
		//问题就在这,写死的仅支持的硬件编码器解码器组件名称的前缀。
		//所以要在后面自行追加我们自己设备支持H264名称信息。
		return name.startsWith("OMX.qcom.") && VERSION.SDK_INT >= 19 || name.startsWith("OMX.Exynos.") && VERSION.SDK_INT >= 21;
	}
}

至此,分析流程结束,如有错误或其它更好的方法,欢迎指正。

Github传送门

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:09:58  更:2021-08-30 12:10:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:49:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码