接着 《MediaCodec(四) 从MediaCodec到Codec2之create Competent(1)》 来看:
codec->init(componentName) 的实现还是比较多的,把主要的步骤分步来看:
/frameworks/av/media/libstagefright/MediaCodec.cpp
1886 status_t MediaCodec::init(const AString &name) {
1887 status_t err = mResourceManagerProxy->init(); //Setp 1
1894
1895 // save init parameters for reset
1896 mInitName = name;
1902
1903 mCodecInfo.clear(); //清空 mCodecInfo
1904
1905 bool secureCodec = false;
1906 const char *owner = "";
1907 if (!name.startsWith("android.filter.")) {
1908 err = mGetCodecInfo(name, &mCodecInfo); //Step2 调用mGetCodecInfo 函数
1920 secureCodec = name.endsWith(".secure"); //判断是否是加密的组件
1921 Vector<AString> mediaTypes;
1922 mCodecInfo->getSupportedMediaTypes(&mediaTypes); //获取MediaTypes
1923 for (size_t i = 0; i < mediaTypes.size(); ++i) { //根据MediaTypes 区分mDomain Video or audio or image(image是什么不是很清楚)
1924 if (mediaTypes[i].startsWith("video/")) {
1925 mDomain = DOMAIN_VIDEO;
1926 break;
1927 } else if (mediaTypes[i].startsWith("audio/")) {
1928 mDomain = DOMAIN_AUDIO;
1929 break;
1930 } else if (mediaTypes[i].startsWith("image/")) {
1931 mDomain = DOMAIN_IMAGE;
1932 break;
1933 }
1934 }
1935 owner = mCodecInfo->getOwnerName();
1936 }
1937
1938 mCodec = mGetCodecBase(name, owner); //Step3
1944
1945 if (mDomain == DOMAIN_VIDEO) { //Video 单独新创建一个 Looper
1946 // video codec needs dedicated looper
1947 if (mCodecLooper == NULL) {
1948 status_t err = OK;
1949 mCodecLooper = new ALooper;
1950 mCodecLooper->setName("CodecLooper");
1951 err = mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1956 }
1957
1958 mCodecLooper->registerHandler(mCodec);
1959 } else {
1960 mLooper->registerHandler(mCodec);
1961 }
1964
1965 mCodec->setCallback( // Setp4 设置 Codec的 回调函数
1966 std::unique_ptr<CodecBase::CodecCallback>(
1967 new CodecCallback(new AMessage(kWhatCodecNotify, this))));
1968 mBufferChannel = mCodec->getBufferChannel(); //Step5 获取 BufferChannel
1969 mBufferChannel->setCallback( //设置 BufferChannel 的回调函数
1970 std::unique_ptr<CodecBase::BufferCallback>(
1971 new BufferCallback(new AMessage(kWhatCodecNotify, this))));
1972 sp<AMessage> msg = new AMessage(kWhatInit, this); // Step6 发送 kWhatInit
1973 if (mCodecInfo) {
1974 msg->setObject("codecInfo", mCodecInfo);
1977 }
1978 msg->setString("name", name); //设置msg 参数
1980 // initial naming setup covers the period before the first call to ::configure().
1981 // after that, we manage this through ::configure() and the setup message.
1982 if (mMetricsHandle != 0) {
1983 mediametrics_setCString(mMetricsHandle, kCodecCodec, name.c_str());
1984 mediametrics_setCString(mMetricsHandle, kCodecMode, toCodecMode(mDomain));
1985 }
1986
1987 if (mDomain == DOMAIN_VIDEO) { //video 创建 BatteryChecker?
1988 mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this));
1989 }
1990
1991 std::vector<MediaResourceParcel> resources;
1992 resources.push_back(MediaResource::CodecResource(secureCodec, toMediaResourceSubType(mDomain)));
1993
1994 // If the ComponentName is not set yet, use the name passed by the user.
1995 if (mComponentName.empty()) {
1996 mResourceManagerProxy->setCodecName(name.c_str()); //Step 7
1997 }
1998 for (int i = 0; i <= kMaxRetry; ++i) {
1999 if (i > 0) {
2000 // Don't try to reclaim resource for the first time.
2001 if (!mResourceManagerProxy->reclaimResource(resources)) {
2002 break;
2003 }
2004 }
2005
2006 sp<AMessage> response;
2007 err = PostAndAwaitResponse(msg, &response);
2008 if (!isResourceError(err)) {
2009 break;
2010 }
2011 }
2012
2013 if (OK == err) {
2014 // Notify the ResourceManager that, this codec has been created
2015 // (initialized) successfully.
2016 mResourceManagerProxy->notifyClientCreated();
2017 }
2018 return err;
2019 }
Step1:先看下 mResourceManagerProxy->init()
看起来主要是为了获取 "media.resource_manager" 这个service 像是资源管理的,目前还不知做什么用的
/frameworks/av/media/libstagefright/MediaCodec.cpp
360 struct MediaCodec::ResourceManagerServiceProxy : public RefBase {
------------
//初始化
399 MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
400 pid_t pid, uid_t uid, const std::shared_ptr<IResourceManagerClient> &client)
401 : mPid(pid), mUid(uid), mClient(client),
402 mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {
403 if (mUid == MediaCodec::kNoUid) {
404 mUid = AIBinder_getCallingUid();
405 }
406 if (mPid == MediaCodec::kNoPid) {
407 mPid = AIBinder_getCallingPid();
408 }
409 }
-------------
424 status_t MediaCodec::ResourceManagerServiceProxy::init() {
425 ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.resource_manager"));
426 mService = IResourceManagerService::fromBinder(binder);
431
432 int callerPid = AIBinder_getCallingPid();
433 int callerUid = AIBinder_getCallingUid();
434 if (mPid != callerPid || mUid != callerUid) {
435 // Media processes don't need special permissions to act on behalf of other processes.
436 if (callerUid != AID_MEDIA) {
437 char const * permission = "android.permission.MEDIA_RESOURCE_OVERRIDE_PID";
438 if (!checkCallingPermission(String16(permission))) {
439 ALOGW("%s is required to override the caller's PID for media resource management.",
440 permission);
441 return PERMISSION_DENIED;
442 }
443 }
444 }
445
446 // Kill clients pending removal.
447 mService->reclaimResourcesFromClientsPendingRemoval(mPid);
448
449 // so our handler will process the death notifications
450 addCookie(this);
451
452 // after this, require mLock whenever using mService
453 AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
454 return OK;
455 }
Step2:err = mGetCodecInfo(name, &mCodecInfo)
这边就用到了上一篇 MediaCodec::MediaCodec的匿名函数:
1058 if (!mGetCodecInfo) {
1059 mGetCodecInfo = [&log = mErrorLog](const AString &name,
1060 sp<MediaCodecInfo> *info) -> status_t {
1061 *info = nullptr;
1062 const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
1067 AString tmp = name;
1068 if (tmp.endsWith(".secure")) { //如果是name 是 .secure 结束的,那么就移除.secure 储存在 tmp 中
1069 tmp.erase(tmp.size() - 7, 7);
1070 }
1071 for (const AString &codecName : { name, tmp }) { //首先寻找secure的,如果没有就找non_secure的 codec,比如 {"c2.android.amrnb.decoder.secure", "c2.android.amrnb.decoder"}
1072 ssize_t codecIdx = mcl->findCodecByName(codecName.c_str()); //在 MediaCodecList 寻找 findCodecByName
1073 if (codecIdx < 0) {
1074 continue;
1075 }
1076 *info = mcl->getCodecInfo(codecIdx);
1077 return OK;
1078 }
1079 log.log(LOG_TAG, base::StringPrintf("Codec with name '%s' is not found on the device.",
1080 name.c_str()));
1081 return NAME_NOT_FOUND;
1082 };
1083 }
- 首先是获取 MediaCodecList::getInstance();这边主要就是为了获取 sp<IMediaCodecList> MediaCodecList::sRemoteList; 具体的获取方法在下一篇有讲,这边就不展开了;
/frameworks/av/media/libstagefright/MediaCodecList.cpp
183 sp<IMediaCodecList> MediaCodecList::getInstance() {
184 Mutex::Autolock _l(sRemoteInitMutex);
185 if (sRemoteList == nullptr) {
186 sMediaPlayer = defaultServiceManager()->getService(String16("media.player"));
187 sp<IMediaPlayerService> service = //获取"media.player" service
188 interface_cast<IMediaPlayerService>(sMediaPlayer);
189 if (service.get() != nullptr) {
190 sRemoteList = service->getCodecList();
191 if (sRemoteList != nullptr) {
192 sBinderDeathObserver = new BinderDeathObserver();
193 sMediaPlayer->linkToDeath(sBinderDeathObserver.get());
194 }
195 }
196 if (sRemoteList == nullptr) {
197 // if failed to get remote list, create local list
198 sRemoteList = getLocalInstance();
199 }
200 }
201 return sRemoteList;
202 }
- 然后 mcl->findCodecByName(codecName.c_str()) 寻找 codecInx,如果没有找到就返回 ENOENT
Decoder "c2.android.amrnb.decoder" supports
aliases: [
"OMX.google.amrnb.decoder" ]
/frameworks/av/media/libstagefright/MediaCodecList.cpp
294 ssize_t MediaCodecList::findCodecByName(const char *name) const {
295 Vector<AString> aliases;
296 for (size_t i = 0; i < mCodecInfos.size(); ++i) {
297 if (strcmp(mCodecInfos[i]->getCodecName(), name) == 0) { //如果在 mCodecInfos中找到 name 的codec 就返回 i
298 return i;
299 }
300 mCodecInfos[i]->getAliases(&aliases); //不然就再用 mCodecInfos 的别名中查找 name 的codec
301 for (const AString &alias : aliases) {
302 if (alias == name) {
303 return i;
304 }
305 }
306 }
307
308 return -ENOENT; //没有找到的话就会返回 ENOENT
309 }
- 最后看一下 mcl->getCodecInfo(codecIdx); 主要是为了获取到 index 对应的 MediaCodecInfo 信息,里面主要储存了 ProfileLevel、Attributes、Capabilities、CapabilitiesWriter
/frameworks/av/media/libstagefright/include/media/stagefright/MediaCodecList.h
51 virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const {
52 if (index >= mCodecInfos.size()) {
53 ALOGE("b/24445127");
54 return NULL;
55 }
56 return mCodecInfos[index];
57 }
std::vector<sp<MediaCodecInfo> > mCodecInfos;
========================
/frameworks/av/media/libmedia/include/media/MediaCodecInfo.h
45 struct MediaCodecInfo : public RefBase {
46 struct ProfileLevel {
47 uint32_t mProfile;
48 uint32_t mLevel;
49 bool operator <(const ProfileLevel &o) const {
50 return mProfile < o.mProfile || (mProfile == o.mProfile && mLevel < o.mLevel);
51 }
52 };
55
56 enum Attributes : int32_t {
57 // attribute flags
58 kFlagIsEncoder = 1 << 0,
59 kFlagIsVendor = 1 << 1,
60 kFlagIsSoftwareOnly = 1 << 2,
61 kFlagIsHardwareAccelerated = 1 << 3,
62 };
63
64 struct Capabilities : public RefBase {
65 constexpr static char FEATURE_ADAPTIVE_PLAYBACK[] = "feature-adaptive-playback";
66 constexpr static char FEATURE_DYNAMIC_TIMESTAMP[] = "feature-dynamic-timestamp";
67 constexpr static char FEATURE_FRAME_PARSING[] = "feature-frame-parsing";
68 constexpr static char FEATURE_INTRA_REFRESH[] = "feature-frame-parsing";
69 constexpr static char FEATURE_MULTIPLE_FRAMES[] = "feature-multiple-frames";
70 constexpr static char FEATURE_SECURE_PLAYBACK[] = "feature-secure-playback";
71 constexpr static char FEATURE_TUNNELED_PLAYBACK[] = "feature-tunneled-playback";
.......
118 };
119
120 /**
121 * This class is used for modifying information inside a `Capabilities`
122 * object. An object of type `CapabilitiesWriter` can be obtained by calling
123 * `MediaCodecInfoWriter::addMediaType()`.
124 */
125 struct CapabilitiesWriter {
......
186 };
253 };
Step 3:mCodec = mGetCodecBase(name, owner); 这边主要是为了获取 ACodec 或者 Codec2 的对象;
/frameworks/av/media/libstagefright/MediaCodec.cpp
1054 mGetCodecBase = [](const AString &name, const char *owner) {
1055 return GetCodecBase(name, owner);
1056 };
-----------------
1845 sp<CodecBase> MediaCodec::GetCodecBase(const AString &name, const char *owner) {
1846 if (owner) {
1847 if (strcmp(owner, "default") == 0) {
1848 return new ACodec; //创建 ACodec
1849 } else if (strncmp(owner, "codec2", 6) == 0) {
1850 return CreateCCodec(); //创建 CCodec
1851 }
1852 }
1853
1854 if (name.startsWithIgnoreCase("c2.")) {
1855 return CreateCCodec();
1856 } else if (name.startsWithIgnoreCase("omx.")) {
1857 // at this time only ACodec specifies a mime type.
1858 return new ACodec;
1859 } else {
1860 return NULL;
1861 }
1862 }
继续来看 CreateCCodec创建 Codec2 的对象,其中主要是为了创建 CCodecBufferChannel(buffer 相关的) 和 CCodecConfig 这两个比较重要,在后面单独去看!
/frameworks/av/media/libstagefright/MediaCodec.cpp
1840 static CodecBase *CreateCCodec() {
1841 return new CCodec;
1842 }
==============
//这边开始进入 CCodec 了,主要是为了创建 CCodecBufferChannel 和 CCodecConfig
/frameworks/av/media/codec2/sfplugin/CCodec.cpp
693 CCodec::CCodec()
694 : mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))),
695 mConfig(new CCodecConfig) {
696 }
Step 4: mCodec->setCallback(std::unique_ptr<CodecBase::CodecCallback>(new CodecCallback(new AMessage(kWhatCodecNotify, this)))); 这边就是设置 codec 的回调函数,最终都会call kWhatCodecNotify 中去
new AMessage(kWhatCodecNotify, this) //创建 AMessage 对象,把 kWhatCodecNotify 的实现赋给 mWhat,这样回调的话,就会call 到 kWhatCodecNotify 中去
60 AMessage::AMessage(uint32_t what, const sp<const AHandler> &handler)
61 : mWhat(what) {
62 setTarget(handler);
63 }
======================
new CodecCallback(new AMessage(kWhatCodecNotify, this) // 再把Amessage作为参数赋值给CodecCallback 的 mNotify
735 class CodecCallback : public CodecBase::CodecCallback {
766 CodecCallback::CodecCallback(const sp<AMessage> ¬ify) : mNotify(notify) {}
Step5:mBufferChannel = mCodec->getBufferChannel(); 调用Acodec/Codec2 的 getBufferChannel函数 获取 CCodecBufferChannel 对象,CCodecBufferChannel 部分在 《Codec2(1) CCodecBufferChannel》学习。
/frameworks/av/media/codec2/sfplugin/
H A D CCodec.cpp 701 std::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() {
/frameworks/av/media/libstagefright/
H A D ACodec.cpp 631 std::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
======================
//看下Codec2 的,很简单 就是返回 mChannel,而mChannel 是在上面创建 Codec2 对像的时候 new 的
701 std::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() {
702 return mChannel;
703 }
mBufferChannel->setCallback(std::unique_ptr<CodecBase::BufferCallback>(new BufferCallback(new AMessage(kWhatCodecNotify, this)))); 这一句为 mBufferChannel 设置回调函数和Setp 4一样,最终返回值在 kWhatCodecNotify 中处理;
Step6:sp<AMessage> msg = new AMessage(kWhatInit, this);
kWhatInit 的处理 主要是根据传送的 codecinfo 和name 去调用 CCodec/Acodec 的 initiateAllocateComponent 创建组件,同时设置状态为 INITIALIZING
/frameworks/av/media/libstagefright/MediaCodec.cpp
4353 case kWhatInit:
4354 {
4360 if (mReplyID) {
4361 mDeferredMessages.push_back(msg);
4362 break;
4363 }
4364 sp<AReplyToken> replyID;
4365 CHECK(msg->senderAwaitsResponse(&replyID));
4366
4367 mReplyID = replyID;
4368 setState(INITIALIZING); //设置状态 INITIALIZING
4369
4370 sp<RefBase> codecInfo;
4371 (void)msg->findObject("codecInfo", &codecInfo);
4372 AString name;
4373 CHECK(msg->findString("name", &name));
4374
4375 sp<AMessage> format = new AMessage;
4376 if (codecInfo) {
4377 format->setObject("codecInfo", codecInfo);
4378 }
4379 format->setString("componentName", name);
4380
4381 mCodec->initiateAllocateComponent(format); //根据传送过来的codecInfo 和 name 创建 Component
4382 break;
4383 }
initiateAllocateComponent 的实现看下篇