前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android平台硬件编码总结一

Android平台硬件编码总结一

作者头像
deep_sadness
发布2018-08-30 10:56:36
2.7K0
发布2018-08-30 10:56:36
举报
文章被收录于专栏:Flutter入门

MediaCodec编码的套路

状态

来自官网的状态图

codec_status.png

创建

  • find Support Codec 通过这种方式可以得到当前设备所有的MedaCodecInfo
代码语言:javascript
复制
public static final String VIDEO_AVC = MIMETYPE_VIDEO_AVC; // H.264 Advanced Video Coding
    public static final String AUDIO_AAC = MIMETYPE_AUDIO_AAC; // H.264 Advanced Audio Coding

    //得到制定的MimeType的Codec
    public static Single<List<MediaCodecInfo>> getAdaptiveEncoderCodec(String mimeType) {
        return Observable
                .fromArray(getMediaCodecInfos())
                .filter(mediaCodecInfo -> {
                    if (mediaCodecInfo.isEncoder()) {
                        try {
                            MediaCodecInfo.CodecCapabilities capabilitiesForType = mediaCodecInfo.getCapabilitiesForType(mimeType);
                            return capabilitiesForType != null;
                        } catch (Exception e) {
                            e.printStackTrace();
                            return false;
                        }
                    }
                    return false;
                })
                .toList()
                ;
    }

    private static MediaCodecInfo[] getMediaCodecInfos() {
        //获取当前可以支持的MediaCodec
        MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
        //得到所有CodecInfos
        return mediaCodecList.getCodecInfos();
    }
  • MediaFormat 再通过我们自己的配置和选择的MediaCodecInfo进行创建MediaFormat
代码语言:javascript
复制
MediaFormat toFormat() {
        //通过MimeType创建宽和高
        MediaFormat format = MediaFormat.createVideoFormat(mimeType, width, height);
        //设置ColorFormat .因为这里是mediaProjection来的数据,所以是 Color_FomatSurface
        //如果是使用camera,则这里是 COLOR_FormatYUV420SemiPlanar
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);

        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
        format.setInteger(MediaFormat.KEY_FRAME_RATE, framerate);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iframeInterval);
        if (codecProfileLevel != null && codecProfileLevel.profile != 0 && codecProfileLevel.level != 0) {
            format.setInteger(MediaFormat.KEY_PROFILE, codecProfileLevel.profile);
            format.setInteger("level", codecProfileLevel.level);
        }
        // maybe useful
        // format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 10_000_000);
        return format;
    }
  • 启动MediaCodec
代码语言:javascript
复制
MediaFormat format = createMediaFormat();
Log.d("Encoder", "Create media format: " + format);

String mimeType = format.getString(MediaFormat.KEY_MIME);
final MediaCodec encoder = createEncoder(mimeType);
try {
    //这里是通过异步的方式创建
     encoder.setCallback(this.mCallback == null ? null : mCodecCallback);
    //调用configure方法,让Codec进入configured状态
     encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    //如果需要codec提供输入的surface,则在configured状态后,创建
     onEncoderConfigured(encoder);
    //开启encoder
     encoder.start();
 } catch (MediaCodec.CodecException e) {
     Log.e("Encoder", "Configure codec failure!\n  with format" + format, e);
     throw e;
}

Input

  • 实例1:从Camera中得到数据

camera_input.png

  • 实例2:从MediaProjection创建的VirtualDisplay中得到数据

virtualdisplay_input.png

output

从MediaCodec中得到编码好的数据。例如H264裸流数据进行处理。

  • 同步的方式

sync_output.png

  • 异步的方式

async_output.png

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.04.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MediaCodec编码的套路
    • 状态
      • 创建
        • Input
          • output
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档