Android Multimedia框架总结(二十二)MediaCodec中C++中创建到start过程及状态变换

上一章介绍MediaCodec中创建到start过程(到jni部分),从今天开始,将深入源码中看看其c++过程,看下Agenda如下:

  • mediacodec.h
  • CreateByType
  • initMediaCodec中BufferInfo内部类:
  • configure过程
  • start

BufferInfo在MediaCodec.h中对应是一个结构体

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. struct BufferInfo {
  4. uint32_t mBufferID;
  5. sp<ABuffer> mData;
  6. sp<ABuffer> mEncryptedData;
  7. sp<IMemory> mSharedEncryptedBuffer;
  8. sp<AMessage> mNotify;
  9. sp<AMessage> mFormat;
  10. bool mOwnedByClient;
  11. };

mediacodec.h的方法的声明,位于\frameworks\av\include\media\stagefright下

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. namespace android {
  4. struct ABuffer;
  5. struct AMessage;
  6. struct AReplyToken;
  7. struct AString;
  8. struct CodecBase;
  9. struct IBatteryStats;
  10. struct ICrypto;
  11. class IMemory;
  12. struct MemoryDealer;
  13. class IResourceManagerClient;
  14. class IResourceManagerService;
  15. struct PersistentSurface;
  16. struct SoftwareRenderer;
  17. struct Surface;
  18. struct MediaCodec : public AHandler {
  19. enum ConfigureFlags {
  20. CONFIGURE_FLAG_ENCODE = 1,
  21. };
  22. enum BufferFlags {
  23. BUFFER_FLAG_SYNCFRAME = 1,
  24. BUFFER_FLAG_CODECCONFIG = 2,
  25. BUFFER_FLAG_EOS = 4,
  26. };
  27. enum {
  28. CB_INPUT_AVAILABLE = 1,
  29. CB_OUTPUT_AVAILABLE = 2,
  30. CB_ERROR = 3,
  31. CB_OUTPUT_FORMAT_CHANGED = 4,
  32. CB_RESOURCE_RECLAIMED = 5,
  33. };
  34. static const pid_t kNoPid = -1;
  35. static sp<MediaCodec> CreateByType(
  36. const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL,
  37. pid_t pid = kNoPid);
  38. static sp<MediaCodec> CreateByComponentName(
  39. const sp<ALooper> &looper, const char *name, status_t *err = NULL,
  40. pid_t pid = kNoPid);
  41. static sp<PersistentSurface> CreatePersistentInputSurface();
  42. status_t configure(
  43. const sp<AMessage> &format,
  44. const sp<Surface> &nativeWindow,
  45. const sp<ICrypto> &crypto,
  46. uint32_t flags);
  47. status_t setCallback(const sp<AMessage> &callback);
  48. status_t setOnFrameRenderedNotification(const sp<AMessage> &notify);
  49. status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
  50. status_t setInputSurface(const sp<PersistentSurface> &surface);
  51. status_t start();
  52. // Returns to a state in which the component remains allocated but
  53. // unconfigured.
  54. status_t stop();
  55. // Resets the codec to the INITIALIZED state. Can be called after an error
  56. // has occured to make the codec usable.
  57. status_t reset();
  58. // Client MUST call release before releasing final reference to this
  59. // object.
  60. status_t release();
  61. status_t flush();
  62. status_t queueInputBuffer(
  63. size_t index,
  64. size_t offset,
  65. size_t size,
  66. int64_t presentationTimeUs,
  67. uint32_t flags,
  68. AString *errorDetailMsg = NULL);
  69. status_t queueSecureInputBuffer(
  70. size_t index,
  71. size_t offset,
  72. const CryptoPlugin::SubSample *subSamples,
  73. size_t numSubSamples,
  74. const uint8_t key[16],
  75. const uint8_t iv[16],
  76. CryptoPlugin::Mode mode,
  77. int64_t presentationTimeUs,
  78. uint32_t flags,
  79. AString *errorDetailMsg = NULL);
  80. status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
  81. status_t dequeueOutputBuffer(
  82. size_t *index,
  83. size_t *offset,
  84. size_t *size,
  85. int64_t *presentationTimeUs,
  86. uint32_t *flags,
  87. int64_t timeoutUs = 0ll);
  88. status_t renderOutputBufferAndRelease(size_t index, int64_t timestampNs);
  89. status_t renderOutputBufferAndRelease(size_t index);
  90. status_t releaseOutputBuffer(size_t index);
  91. status_t signalEndOfInputStream();
  92. status_t getOutputFormat(sp<AMessage> *format) const;
  93. status_t getInputFormat(sp<AMessage> *format) const;
  94. status_t getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const;
  95. status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;
  96. status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const;
  97. status_t getOutputBuffer(size_t index, sp<ABuffer> *buffer);
  98. status_t getOutputFormat(size_t index, sp<AMessage> *format);
  99. status_t getInputBuffer(size_t index, sp<ABuffer> *buffer);
  100. status_t setSurface(const sp<Surface> &nativeWindow);
  101. status_t requestIDRFrame();
  102. // Notification will be posted once there "is something to do", i.e.
  103. // an input/output buffer has become available, a format change is
  104. // pending, an error is pending.
  105. void requestActivityNotification(const sp<AMessage> &notify);
  106. status_t getName(AString *componentName) const;
  107. status_t setParameters(const sp<AMessage> &params);
  108. // Create a MediaCodec notification message from a list of rendered or dropped render infos
  109. // by adding rendered frame information to a base notification message. Returns the number
  110. // of frames that were rendered.
  111. static size_t CreateFramesRenderedMessage(
  112. std::list<FrameRenderTracker::Info> done, sp<AMessage> &msg);
  113. protected:
  114. virtual ~MediaCodec();
  115. virtual void onMessageReceived(const sp<AMessage> &msg);
  116. private:
  117. // used by ResourceManagerClient
  118. status_t reclaim(bool force = false);
  119. friend struct ResourceManagerClient;
  120. private:
  121. enum State {
  122. UNINITIALIZED,
  123. INITIALIZING,
  124. INITIALIZED,
  125. CONFIGURING,
  126. CONFIGURED,
  127. STARTING,
  128. STARTED,
  129. FLUSHING,
  130. FLUSHED,
  131. STOPPING,
  132. RELEASING,
  133. };
  134. enum {
  135. kPortIndexInput = 0,
  136. kPortIndexOutput = 1,
  137. };
  138. enum {
  139. kWhatInit = 'init',
  140. kWhatConfigure = 'conf',
  141. kWhatSetSurface = 'sSur',
  142. kWhatCreateInputSurface = 'cisf',
  143. kWhatSetInputSurface = 'sisf',
  144. kWhatStart = 'strt',
  145. kWhatStop = 'stop',
  146. kWhatRelease = 'rele',
  147. kWhatDequeueInputBuffer = 'deqI',
  148. kWhatQueueInputBuffer = 'queI',
  149. kWhatDequeueOutputBuffer = 'deqO',
  150. kWhatReleaseOutputBuffer = 'relO',
  151. kWhatSignalEndOfInputStream = 'eois',
  152. kWhatGetBuffers = 'getB',
  153. kWhatFlush = 'flus',
  154. kWhatGetOutputFormat = 'getO',
  155. kWhatGetInputFormat = 'getI',
  156. kWhatDequeueInputTimedOut = 'dITO',
  157. kWhatDequeueOutputTimedOut = 'dOTO',
  158. kWhatCodecNotify = 'codc',
  159. kWhatRequestIDRFrame = 'ridr',
  160. kWhatRequestActivityNotification = 'racN',
  161. kWhatGetName = 'getN',
  162. kWhatSetParameters = 'setP',
  163. kWhatSetCallback = 'setC',
  164. kWhatSetNotification = 'setN',
  165. };
  166. enum {
  167. kFlagUsesSoftwareRenderer = 1,
  168. kFlagOutputFormatChanged = 2,
  169. kFlagOutputBuffersChanged = 4,
  170. kFlagStickyError = 8,
  171. kFlagDequeueInputPending = 16,
  172. kFlagDequeueOutputPending = 32,
  173. kFlagIsSecure = 64,
  174. kFlagSawMediaServerDie = 128,
  175. kFlagIsEncoder = 256,
  176. kFlagGatherCodecSpecificData = 512,
  177. kFlagIsAsync = 1024,
  178. kFlagIsComponentAllocated = 2048,
  179. kFlagPushBlankBuffersOnShutdown = 4096,
  180. };
  181. struct BufferInfo {
  182. uint32_t mBufferID;
  183. sp<ABuffer> mData;
  184. sp<ABuffer> mEncryptedData;
  185. sp<IMemory> mSharedEncryptedBuffer;
  186. sp<AMessage> mNotify;
  187. sp<AMessage> mFormat;
  188. bool mOwnedByClient;
  189. };
  190. struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
  191. ResourceManagerServiceProxy(pid_t pid);
  192. ~ResourceManagerServiceProxy();
  193. void init();
  194. // implements DeathRecipient
  195. virtual void binderDied(const wp<IBinder>& /*who*/);
  196. void addResource(
  197. int64_t clientId,
  198. const sp<IResourceManagerClient> client,
  199. const Vector<MediaResource> &resources);
  200. void removeResource(int64_t clientId);
  201. bool reclaimResource(const Vector<MediaResource> &resources);
  202. private:
  203. Mutex mLock;
  204. sp<IResourceManagerService> mService;
  205. pid_t mPid;
  206. };
  207. State mState;
  208. bool mReleasedByResourceManager;
  209. sp<ALooper> mLooper;
  210. sp<ALooper> mCodecLooper;
  211. sp<CodecBase> mCodec;
  212. AString mComponentName;
  213. sp<AReplyToken> mReplyID;
  214. uint32_t mFlags;
  215. status_t mStickyError;
  216. sp<Surface> mSurface;
  217. SoftwareRenderer *mSoftRenderer;
  218. sp<AMessage> mOutputFormat;
  219. sp<AMessage> mInputFormat;
  220. sp<AMessage> mCallback;
  221. sp<AMessage> mOnFrameRenderedNotification;
  222. sp<MemoryDealer> mDealer;
  223. sp<IResourceManagerClient> mResourceManagerClient;
  224. sp<ResourceManagerServiceProxy> mResourceManagerService;
  225. bool mBatteryStatNotified;
  226. bool mIsVideo;
  227. int32_t mVideoWidth;
  228. int32_t mVideoHeight;
  229. int32_t mRotationDegrees;
  230. // initial create parameters
  231. AString mInitName;
  232. bool mInitNameIsType;
  233. bool mInitIsEncoder;
  234. // configure parameter
  235. sp<AMessage> mConfigureMsg;
  236. // Used only to synchronize asynchronous getBufferAndFormat
  237. // across all the other (synchronous) buffer state change
  238. // operations, such as de/queueIn/OutputBuffer, start and
  239. // stop/flush/reset/release.
  240. Mutex mBufferLock;
  241. List<size_t> mAvailPortBuffers[2];
  242. Vector<BufferInfo> mPortBuffers[2];
  243. int32_t mDequeueInputTimeoutGeneration;
  244. sp<AReplyToken> mDequeueInputReplyID;
  245. int32_t mDequeueOutputTimeoutGeneration;
  246. sp<AReplyToken> mDequeueOutputReplyID;
  247. sp<ICrypto> mCrypto;
  248. List<sp<ABuffer> > mCSD;
  249. sp<AMessage> mActivityNotify;
  250. bool mHaveInputSurface;
  251. bool mHavePendingInputBuffers;
  252. MediaCodec(const sp<ALooper> &looper, pid_t pid);
  253. static status_t PostAndAwaitResponse(
  254. const sp<AMessage> &msg, sp<AMessage> *response);
  255. void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
  256. status_t init(const AString &name, bool nameIsType, bool encoder);
  257. void setState(State newState);
  258. void returnBuffersToCodec();
  259. void returnBuffersToCodecOnPort(int32_t portIndex);
  260. size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
  261. status_t onQueueInputBuffer(const sp<AMessage> &msg);
  262. status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
  263. ssize_t dequeuePortBuffer(int32_t portIndex);
  264. status_t getBufferAndFormat(
  265. size_t portIndex, size_t index,
  266. sp<ABuffer> *buffer, sp<AMessage> *format);
  267. bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
  268. bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
  269. void cancelPendingDequeueOperations();
  270. void extractCSD(const sp<AMessage> &format);
  271. status_t queueCSDInputBuffer(size_t bufferIndex);
  272. status_t handleSetSurface(const sp<Surface> &surface);
  273. status_t connectToSurface(const sp<Surface> &surface);
  274. status_t disconnectFromSurface();
  275. void postActivityNotificationIfPossible();
  276. void onInputBufferAvailable();
  277. void onOutputBufferAvailable();
  278. void onError(status_t err, int32_t actionCode, const char *detail = NULL);
  279. void onOutputFormatChanged();
  280. status_t onSetParameters(const sp<AMessage> &params);
  281. status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
  282. void updateBatteryStat();
  283. bool isExecuting() const;
  284. uint64_t getGraphicBufferSize();
  285. void addResource(const String8 &type, const String8 &subtype, uint64_t value);
  286. bool hasPendingBuffer(int portIndex);
  287. bool hasPendingBuffer();
  288. /* called to get the last codec error when the sticky flag is set.
  289. * if no such codec error is found, returns UNKNOWN_ERROR.
  290. */
  291. inline status_t getStickyError() const {
  292. return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR;
  293. }
  294. inline void setStickyError(status_t err) {
  295. mFlags |= kFlagStickyError;
  296. mStickyError = err;
  297. }
  298. DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
  299. };
  300. } // namespace android

CreateByType

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. // static
  4. sp<MediaCodec> MediaCodec::CreateByType(
  5. const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err, pid_t pid) {
  6. sp<MediaCodec> codec = new MediaCodec(looper, pid);//这果实际上new出MediaCodec对象
  7. const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
  8. if (err != NULL) {
  9. *err = ret;
  10. }
  11. return ret == OK ? codec : NULL; // NULL deallocates codec.
  12. }

接着到init过程

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
  4. mResourceManagerService->init();
  5. // 保存 初始参数,到时用于reset
  6. mInitName = name;
  7. mInitNameIsType = nameIsType;
  8. mInitIsEncoder = encoder;
  9. // 目前视频解码器不能马上从OMX_FillThisBuffer返回,违反OpenMAX规格,直到提醒我们需要入驻另一个第三方的looper释放在事件队列中。
  10. if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {//omx.匹配
  11. mCodec = new ACodec;//实例化ACodec
  12. } else if (!nameIsType
  13. && !strncasecmp(name.c_str(), "android.filter.", 15)) {
  14. mCodec = new MediaFilter;// 实例化MediaFilter
  15. } else {
  16. return NAME_NOT_FOUND;
  17. }
  18. bool secureCodec = false;
  19. if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
  20. mIsVideo = true;
  21. } else {
  22. AString tmp = name;
  23. if (tmp.endsWith(".secure")) {
  24. secureCodec = true;
  25. tmp.erase(tmp.size() - 7, 7);
  26. }
  27. const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
  28. if (mcl == NULL) {
  29. mCodec = NULL; // remove the codec.
  30. return NO_INIT; // if called from Java should raise IOException
  31. }
  32. ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
  33. if (codecIdx >= 0) {
  34. const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
  35. Vector<AString> mimes;
  36. info->getSupportedMimes(&mimes);
  37. for (size_t i = 0; i < mimes.size(); i++) {
  38. if (mimes[i].startsWith("video/")) {
  39. mIsVideo = true;
  40. break;
  41. }
  42. }
  43. }
  44. }
  45. if (mIsVideo) {
  46. // video codec needs dedicated looper
  47. if (mCodecLooper == NULL) {
  48. mCodecLooper = new ALooper;
  49. mCodecLooper->setName("CodecLooper");//设置名字为CodecLooper
  50. mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
  51. }
  52. mCodecLooper->registerHandler(mCodec);
  53. } else {
  54. mLooper->registerHandler(mCodec);
  55. }
  56. mLooper->registerHandler(this);
  57. mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
  58. sp<AMessage> msg = new AMessage(kWhatInit, this);
  59. msg->setString("name", name);
  60. msg->setInt32("nameIsType", nameIsType);
  61. if (nameIsType) {
  62. msg->setInt32("encoder", encoder);
  63. }
  64. status_t err;
  65. Vector<MediaResource> resources;
  66. const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
  67. const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
  68. resources.push_back(MediaResource(String8(type), String8(subtype), 1));
  69. for (int i = 0; i <= kMaxRetry; ++i) {
  70. if (i > 0) {
  71. // Don't try to reclaim resource for the first time.
  72. if (!mResourceManagerService->reclaimResource(resources)) {
  73. break;
  74. }
  75. }
  76. sp<AMessage> response;
  77. err = PostAndAwaitResponse(msg, &response);
  78. if (!isResourceError(err)) {
  79. break;
  80. }
  81. }
  82. return err;
  83. }

configure过程

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. status_t MediaCodec::configure(
  4. const sp<AMessage> &format,
  5. const sp<Surface> &surface,
  6. const sp<ICrypto> &crypto,
  7. uint32_t flags) {
  8. sp<AMessage> msg = new AMessage(kWhatConfigure, this);
  9. if (mIsVideo) {
  10. format->findInt32("width", &mVideoWidth);
  11. format->findInt32("height", &mVideoHeight);
  12. if (!format->findInt32("rotation-degrees", &mRotationDegrees)) {
  13. mRotationDegrees = 0;
  14. }
  15. }
  16. msg->setMessage("format", format);
  17. msg->setInt32("flags", flags);
  18. msg->setObject("surface", surface);
  19. if (crypto != NULL) {
  20. msg->setPointer("crypto", crypto.get());
  21. }
  22. // save msg for reset
  23. mConfigureMsg = msg;
  24. status_t err;
  25. Vector<MediaResource> resources;
  26. const char *type = (mFlags & kFlagIsSecure) ?
  27. kResourceSecureCodec : kResourceNonSecureCodec;
  28. const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
  29. resources.push_back(MediaResource(String8(type), String8(subtype), 1));
  30. // Don't know the buffer size at this point, but it's fine to use 1 because
  31. // the reclaimResource call doesn't consider the requester's buffer size for now.
  32. resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
  33. for (int i = 0; i <= kMaxRetry; ++i) {
  34. if (i > 0) {
  35. // Don't try to reclaim resource for the first time.
  36. if (!mResourceManagerService->reclaimResource(resources)) {
  37. break;
  38. }
  39. }
  40. sp<AMessage> response;
  41. err = PostAndAwaitResponse(msg, &response);
  42. if (err != OK && err != INVALID_OPERATION) {
  43. // MediaCodec now set state to UNINITIALIZED upon any fatal error.
  44. // To maintain backward-compatibility, do a reset() to put codec
  45. // back into INITIALIZED state.
  46. // But don't reset if the err is INVALID_OPERATION, which means
  47. // the configure failure is due to wrong state.
  48. ALOGE("configure failed with err 0x%08x, resetting...", err);
  49. reset();
  50. }
  51. if (!isResourceError(err)) {
  52. break;
  53. }
  54. }
  55. return err;
  56. }

start过程

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. status_t MediaCodec::start() {
  4. sp<AMessage> msg = new AMessage(kWhatStart, this);
  5. status_t err;
  6. Vector<MediaResource> resources;
  7. const char *type = (mFlags & kFlagIsSecure) ?
  8. kResourceSecureCodec : kResourceNonSecureCodec;
  9. const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
  10. resources.push_back(MediaResource(String8(type), String8(subtype), 1));
  11. // Don't know the buffer size at this point, but it's fine to use 1 because
  12. // the reclaimResource call doesn't consider the requester's buffer size for now.
  13. resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
  14. for (int i = 0; i <= kMaxRetry; ++i) {
  15. if (i > 0) {
  16. // Don't try to reclaim resource for the first time.
  17. if (!mResourceManagerService->reclaimResource(resources)) {
  18. break;
  19. }
  20. // Recover codec from previous error before retry start.
  21. err = reset();
  22. if (err != OK) {
  23. ALOGE("retrying start: failed to reset codec");
  24. break;
  25. }
  26. sp<AMessage> response;
  27. err = PostAndAwaitResponse(mConfigureMsg, &response);
  28. if (err != OK) {
  29. ALOGE("retrying start: failed to configure codec");
  30. break;
  31. }
  32. }
  33. sp<AMessage> response;
  34. err = PostAndAwaitResponse(msg, &response);
  35. if (!isResourceError(err)) {
  36. break;
  37. }
  38. }
  39. return err;
  40. }

stop过程

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. status_t MediaCodec::stop() {
  4. sp<AMessage> msg = new AMessage(kWhatStop, this);
  5. sp<AMessage> response;
  6. return PostAndAwaitResponse(msg, &response);
  7. }

找到对应的AMessage.cpp,对应同样有一套AHandler.cpp,及ALooper.cpp,这此组成了在c++中一套机制,接口 方法的名字和Java层保持一致。 
所有message都在onMessageReceived方法中处理,MediaCodec的各个状态的相关切换。

 
  1. //create by 逆流的鱼yuiop on 2016/12/11
  2. //blog地址:http://blog.csdn.net/hejjunlin
  3. void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
  4. switch (mState) {
  5. case INITIALIZING://初始化中
  6. {
  7. setState(UNINITIALIZED);
  8. break;
  9. }
  10. case CONFIGURING://配置中
  11. {
  12. setState(actionCode == ACTION_CODE_FATAL ?
  13. UNINITIALIZED : INITIALIZED);
  14. break;
  15. }
  16. case STARTING://start中
  17. {
  18. setState(actionCode == ACTION_CODE_FATAL ?
  19. UNINITIALIZED : CONFIGURED);
  20. break;
  21. }
  22. case STOPPING://停止中
  23. case RELEASING://释放中
  24. {
  25. // Ignore the error, assuming we'll still get
  26. // the shutdown complete notification.
  27. sendErrorResponse = false;
  28. if (mFlags & kFlagSawMediaServerDie) {
  29. // MediaServer died, there definitely won't
  30. // be a shutdown complete notification after
  31. // all.
  32. // note that we're directly going from
  33. // STOPPING->UNINITIALIZED, instead of the
  34. // usual STOPPING->INITIALIZED state.
  35. setState(UNINITIALIZED);
  36. if (mState == RELEASING) {
  37. mComponentName.clear();
  38. }
  39. (new AMessage)->postReply(mReplyID);
  40. }
  41. break;
  42. }
  43. case FLUSHING://刷新中
  44. {
  45. if (actionCode == ACTION_CODE_FATAL) {
  46. setState(UNINITIALIZED);
  47. } else {
  48. setState(
  49. (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
  50. }
  51. break;
  52. }
  53. case FLUSHED:
  54. case STARTED:
  55. {
  56. sendErrorResponse = false;
  57. setStickyError(err);
  58. postActivityNotificationIfPossible();
  59. cancelPendingDequeueOperations();
  60. if (mFlags & kFlagIsAsync) {
  61. onError(err, actionCode);
  62. }
  63. switch (actionCode) {
  64. case ACTION_CODE_TRANSIENT:
  65. break;
  66. case ACTION_CODE_RECOVERABLE:
  67. setState(INITIALIZED);
  68. break;
  69. default:
  70. setState(UNINITIALIZED);
  71. break;
  72. }
  73. break;
  74. }
  75. default:
  76. {
  77. sendErrorResponse = false;
  78. setStickyError(err);
  79. postActivityNotificationIfPossible();
  80. // actionCode in an uninitialized state is always fatal.
  81. if (mState == UNINITIALIZED) {
  82. actionCode = ACTION_CODE_FATAL;
  83. }
  84. if (mFlags & kFlagIsAsync) {
  85. onError(err, actionCode);
  86. }
  87. switch (actionCode) {
  88. case ACTION_CODE_TRANSIENT:
  89. break;
  90. case ACTION_CODE_RECOVERABLE:
  91. setState(INITIALIZED);
  92. break;
  93. default:
  94. setState(UNINITIALIZED);
  95. break;
  96. }
  97. break;
  98. }
  99. }
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页