[Android Video Framework] MediaCodec.cpp详解

MediaCodec是Android Video Framework中一个很重要的类,可以被NuPlayer直接使用
也可以被MediaCodec.java通过JNI的方式直接调用,可以赋予app很高的自由性,
是多媒体开发中的一个很重要的类

1、创建MediaCodec

创建MediaCodec有两种方式,一种是 CreateByType, 根据应用或NuPlayer传递下来的MIME来创建;
另一种是 CreateByComponentName,根据传递下来的ComponentName来创建。
具体方法如下:

CreateByType:

sp<MediaCodec> MediaCodec::CreateByType(
        const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid,
        uid_t uid) {
    VTRACE_CALL();
    sp<MediaCodec> codec = new MediaCodec(looper, pid, uid);

    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
    if (err != NULL) {
        *err = ret;
    }
    return ret == OK ? codec : NULL; // NULL deallocates codec.
}

CreateByComponentName:

// static
sp<MediaCodec> MediaCodec::CreateByComponentName(
        const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid, uid_t uid) {
    VTRACE_CALL();
    sp<MediaCodec> codec = new MediaCodec(looper, pid, uid);

    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
    if (err != NULL) {
        *err = ret;
    }
    return ret == OK ? codec : NULL; // NULL deallocates codec.
}

这两个方法较简单,
1、 调用 MediaCodec 构造函数
2、调用 init 函数
构造函数很简单,没有什么逻辑,我们分析一下 init 函数

MediaCodec::init 函数中逻辑较多
主要分为以下几步:
1、 创建ACodec
2、 与 ACodec, ACodecBufferChannel等类建立消息关联机制
3、发送 kWhatInit 消息,并等待返回

1.1 创建ACodec

status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
    VTRACE_METHOD();
    mResourceManagerService->init();

    // save init parameters for reset
    mInitName = name;
    mInitNameIsType = nameIsType;
    mInitIsEncoder = encoder;

    // Current video decoders do not return from OMX_FillThisBuffer
    // quickly, violating the OpenMAX specs, until that is remedied
    // we need to invest in an extra looper to free the main event
    // queue.

    mCodec = GetCodecBase(name, nameIsType);  //创建ACodec
    if (mCodec == NULL) {
        return NAME_NOT_FOUND;
    }
    ……

详解查看 GetCodecBase 函数:

sp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) {
    // at this time only ACodec specifies a mime type.
    if (nameIsType || name.startsWithIgnoreCase("omx.")) {
        return new ACodec;
    } else if (name.startsWithIgnoreCase("android.filter.")) {
        return new MediaFilter;
    } else {
        return NULL;
    }
}

我们使用MediaCodec主要是创建编解码的Codec,
目前很少用到滤波器 filter,故我们着重分析MediaCodec -> ACodec及ACodec向下的流程,不分析 MediaFilter的流程。

查看ACodec 构造函数

ACodec::ACodec()
    : mSampleRate(0),
      mNodeGeneration(0),
      mUsingNativeWindow(false),
      mNativeWindowUsageBits(0),
      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
      mIsVideo(false),
      mIsEncoder(false),
      mFatalError(false),
      mShutdownInProgress(false),
      mExplicitShutdown(false),
      
  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值