1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "ACodec"
19 
20 #ifdef __LP64__
21 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22 #endif
23 
24 #include <android_media_codec.h>
25 
26 #include <inttypes.h>
27 #include <utils/Trace.h>
28 
29 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
30 
31 #include <gui/Surface.h>
32 
33 #include <media/stagefright/ACodec.h>
34 
35 #include <media/stagefright/foundation/avc_utils.h>
36 #include <media/stagefright/foundation/hexdump.h>
37 #include <media/stagefright/foundation/ABuffer.h>
38 #include <media/stagefright/foundation/ADebug.h>
39 #include <media/stagefright/foundation/AMessage.h>
40 #include <media/stagefright/foundation/AUtils.h>
41 
42 #include <media/stagefright/BufferProducerWrapper.h>
43 #include <media/stagefright/MediaCodec.h>
44 #include <media/stagefright/MediaCodecConstants.h>
45 #include <media/stagefright/MediaDefs.h>
46 #include <media/stagefright/OMXClient.h>
47 #include <media/stagefright/PersistentSurface.h>
48 #include <media/stagefright/RenderedFrameInfo.h>
49 #include <media/stagefright/SurfaceUtils.h>
50 #include <media/hardware/HardwareAPI.h>
51 #include <media/MediaBufferHolder.h>
52 #include <media/OMXBuffer.h>
53 #include <media/omx/1.0/Conversion.h>
54 #include <media/omx/1.0/WOmxNode.h>
55 
56 #include <hidlmemory/mapping.h>
57 
58 #include <media/openmax/OMX_AudioExt.h>
59 #include <media/openmax/OMX_VideoExt.h>
60 #include <media/openmax/OMX_Component.h>
61 #include <media/openmax/OMX_IndexExt.h>
62 #include <media/openmax/OMX_AsString.h>
63 
64 #include "include/ACodecBufferChannel.h"
65 #include "include/DataConverter.h"
66 #include "include/SecureBuffer.h"
67 #include "include/SharedMemoryBuffer.h"
68 #include <media/stagefright/omx/OMXUtils.h>
69 
70 #include <server_configurable_flags/get_flags.h>
71 
72 namespace android {
73 
74 typedef hardware::media::omx::V1_0::IGraphicBufferSource HGraphicBufferSource;
75 
76 using hardware::media::omx::V1_0::Status;
77 using server_configurable_flags::GetServerConfigurableFlag;
78 
79 enum {
80     kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
81 };
82 
83 namespace {
84 
85 constexpr char TUNNEL_PEEK_KEY[] = "android._trigger-tunnel-peek";
86 constexpr char TUNNEL_PEEK_SET_LEGACY_KEY[] = "android._tunnel-peek-set-legacy";
87 
88 }
89 
areRenderMetricsEnabled()90 static bool areRenderMetricsEnabled() {
91     std::string v = GetServerConfigurableFlag("media_native", "render_metrics_enabled", "false");
92     return v == "true";
93 }
94 
95 // OMX errors are directly mapped into status_t range if
96 // there is no corresponding MediaError status code.
97 // Use the statusFromOMXError(int32_t omxError) function.
98 //
99 // Currently this is a direct map.
100 // See frameworks/native/include/media/openmax/OMX_Core.h
101 //
102 // Vendor OMX errors     from 0x90000000 - 0x9000FFFF
103 // Extension OMX errors  from 0x8F000000 - 0x90000000
104 // Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
105 //
106 
107 // returns true if err is a recognized OMX error code.
108 // as OMX error is OMX_S32, this is an int32_t type
isOMXError(int32_t err)109 static inline bool isOMXError(int32_t err) {
110     return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
111 }
112 
113 // converts an OMX error to a status_t
statusFromOMXError(int32_t omxError)114 static inline status_t statusFromOMXError(int32_t omxError) {
115     switch (omxError) {
116     case OMX_ErrorInvalidComponentName:
117     case OMX_ErrorComponentNotFound:
118         return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
119     default:
120         return isOMXError(omxError) ? omxError : 0; // no translation required
121     }
122 }
123 
statusFromBinderStatus(hardware::Return<Status> && status)124 static inline status_t statusFromBinderStatus(hardware::Return<Status> &&status) {
125     if (status.isOk()) {
126         return static_cast<status_t>(status.withDefault(Status::UNKNOWN_ERROR));
127     } else if (status.isDeadObject()) {
128         return DEAD_OBJECT;
129     }
130     // Other exception
131     return UNKNOWN_ERROR;
132 }
133 
134 // checks and converts status_t to a non-side-effect status_t
makeNoSideEffectStatus(status_t err)135 static inline status_t makeNoSideEffectStatus(status_t err) {
136     switch (err) {
137     // the following errors have side effects and may come
138     // from other code modules. Remap for safety reasons.
139     case INVALID_OPERATION:
140     case DEAD_OBJECT:
141         return UNKNOWN_ERROR;
142     default:
143         return err;
144     }
145 }
146 
getVideoBitrateMode(const sp<AMessage> & msg)147 static OMX_VIDEO_CONTROLRATETYPE getVideoBitrateMode(const sp<AMessage> &msg) {
148     int32_t tmp;
149     if (msg->findInt32("bitrate-mode", &tmp)) {
150         // explicitly translate from MediaCodecInfo.EncoderCapabilities.
151         // BITRATE_MODE_* into OMX bitrate mode.
152         switch (tmp) {
153             //BITRATE_MODE_CQ
154             case 0: return OMX_Video_ControlRateConstantQuality;
155             //BITRATE_MODE_VBR
156             case 1: return OMX_Video_ControlRateVariable;
157             //BITRATE_MODE_CBR
158             case 2: return OMX_Video_ControlRateConstant;
159             default: break;
160         }
161     }
162     return OMX_Video_ControlRateVariable;
163 }
164 
findVideoBitrateControlInfo(const sp<AMessage> & msg,OMX_VIDEO_CONTROLRATETYPE * mode,int32_t * bitrate,int32_t * quality)165 static bool findVideoBitrateControlInfo(const sp<AMessage> &msg,
166         OMX_VIDEO_CONTROLRATETYPE *mode, int32_t *bitrate, int32_t *quality) {
167     *mode = getVideoBitrateMode(msg);
168     bool isCQ = (*mode == OMX_Video_ControlRateConstantQuality);
169     return (!isCQ && msg->findInt32("bitrate", bitrate))
170          || (isCQ && msg->findInt32("quality", quality));
171 }
172 
173 struct MessageList : public RefBase {
MessageListandroid::MessageList174     MessageList() {
175     }
~MessageListandroid::MessageList176     virtual ~MessageList() {
177     }
getListandroid::MessageList178     std::list<sp<AMessage> > &getList() { return mList; }
179 private:
180     std::list<sp<AMessage> > mList;
181 
182     DISALLOW_EVIL_CONSTRUCTORS(MessageList);
183 };
184 
getCopyConverter()185 static sp<DataConverter> getCopyConverter() {
186     static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
187     static sp<DataConverter> sCopyConverter;        // zero-inited
188     pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
189     return sCopyConverter;
190 }
191 
192 struct CodecObserver : public BnOMXObserver {
CodecObserverandroid::CodecObserver193     explicit CodecObserver(const sp<AMessage> &msg) : mNotify(msg) {}
194 
195     // from IOMXObserver
onMessagesandroid::CodecObserver196     virtual void onMessages(const std::list<omx_message> &messages) {
197         if (messages.empty()) {
198             return;
199         }
200 
201         sp<AMessage> notify = mNotify->dup();
202         sp<MessageList> msgList = new MessageList();
203         for (std::list<omx_message>::const_iterator it = messages.cbegin();
204               it != messages.cend(); ++it) {
205             const omx_message &omx_msg = *it;
206 
207             sp<AMessage> msg = new AMessage;
208             msg->setInt32("type", omx_msg.type);
209             switch (omx_msg.type) {
210                 case omx_message::EVENT:
211                 {
212                     msg->setInt32("event", omx_msg.u.event_data.event);
213                     msg->setInt32("data1", omx_msg.u.event_data.data1);
214                     msg->setInt32("data2", omx_msg.u.event_data.data2);
215                     break;
216                 }
217 
218                 case omx_message::EMPTY_BUFFER_DONE:
219                 {
220                     msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
221                     msg->setInt32("fence_fd", omx_msg.fenceFd);
222                     break;
223                 }
224 
225                 case omx_message::FILL_BUFFER_DONE:
226                 {
227                     msg->setInt32(
228                             "buffer", omx_msg.u.extended_buffer_data.buffer);
229                     msg->setInt32(
230                             "range_offset",
231                             omx_msg.u.extended_buffer_data.range_offset);
232                     msg->setInt32(
233                             "range_length",
234                             omx_msg.u.extended_buffer_data.range_length);
235                     msg->setInt32(
236                             "flags",
237                             omx_msg.u.extended_buffer_data.flags);
238                     msg->setInt64(
239                             "timestamp",
240                             omx_msg.u.extended_buffer_data.timestamp);
241                     msg->setInt32(
242                             "fence_fd", omx_msg.fenceFd);
243                     break;
244                 }
245 
246                 case omx_message::FRAME_RENDERED:
247                 {
248                     msg->setInt64(
249                             "media_time_us", omx_msg.u.render_data.timestamp);
250                     msg->setInt64(
251                             "system_nano", omx_msg.u.render_data.nanoTime);
252                     break;
253                 }
254 
255                 default:
256                     ALOGE("Unrecognized message type: %d", omx_msg.type);
257                     break;
258             }
259             msgList->getList().push_back(msg);
260         }
261         notify->setObject("messages", msgList);
262         notify->post();
263     }
264 
265 protected:
~CodecObserverandroid::CodecObserver266     virtual ~CodecObserver() {}
267 
268 private:
269     const sp<AMessage> mNotify;
270 
271     DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
272 };
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 
276 struct ACodec::BaseState : public AState {
277     explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
278 
279 protected:
280     enum PortMode {
281         KEEP_BUFFERS,
282         RESUBMIT_BUFFERS,
283         FREE_BUFFERS,
284     };
285 
286     ACodec *mCodec;
287 
288     virtual PortMode getPortMode(OMX_U32 portIndex);
289 
290     virtual void stateExited();
291     virtual bool onMessageReceived(const sp<AMessage> &msg);
292 
293     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
294 
295     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
296     virtual void onInputBufferFilled(const sp<AMessage> &msg);
297 
298     void postFillThisBuffer(BufferInfo *info);
299 
maybePostExtraOutputMetadataBufferRequestandroid::ACodec::BaseState300     void maybePostExtraOutputMetadataBufferRequest() {
301         if (!mPendingExtraOutputMetadataBufferRequest) {
302             (new AMessage(kWhatSubmitExtraOutputMetadataBuffer, mCodec))->post();
303             mPendingExtraOutputMetadataBufferRequest = true;
304         }
305     }
306 
307     void setSurfaceParameters(const sp<AMessage> &msg);
308 
309 private:
310     // Handles an OMX message. Returns true iff message was handled.
311     bool onOMXMessage(const sp<AMessage> &msg);
312 
313     // Handles a list of messages. Returns true iff messages were handled.
314     bool onOMXMessageList(const sp<AMessage> &msg);
315 
316     // returns true iff this message is for this component and the component is alive
317     bool checkOMXMessage(const sp<AMessage> &msg);
318 
319     bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
320 
321     bool onOMXFillBufferDone(
322             IOMX::buffer_id bufferID,
323             size_t rangeOffset, size_t rangeLength,
324             OMX_U32 flags,
325             int64_t timeUs,
326             int fenceFd);
327 
328     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
329 
330     void getMoreInputDataIfPossible();
331 
332     bool mPendingExtraOutputMetadataBufferRequest;
333 
334     DISALLOW_EVIL_CONSTRUCTORS(BaseState);
335 };
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 
339 struct ACodec::DeathNotifier :
340         public IBinder::DeathRecipient,
341         public ::android::hardware::hidl_death_recipient {
DeathNotifierandroid::ACodec::DeathNotifier342     explicit DeathNotifier(const sp<AMessage> &notify)
343         : mNotify(notify) {
344     }
345 
binderDiedandroid::ACodec::DeathNotifier346     virtual void binderDied(const wp<IBinder> &) {
347         mNotify->post();
348     }
349 
serviceDiedandroid::ACodec::DeathNotifier350     virtual void serviceDied(
351             uint64_t /* cookie */,
352             const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
353         mNotify->post();
354     }
355 
356 protected:
~DeathNotifierandroid::ACodec::DeathNotifier357     virtual ~DeathNotifier() {}
358 
359 private:
360     sp<AMessage> mNotify;
361 
362     DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
363 };
364 
365 struct ACodec::UninitializedState : public ACodec::BaseState {
366     explicit UninitializedState(ACodec *codec);
367 
368 protected:
369     virtual bool onMessageReceived(const sp<AMessage> &msg);
370     virtual void stateEntered();
371 
372 private:
373     void onSetup(const sp<AMessage> &msg);
374     bool onAllocateComponent(const sp<AMessage> &msg);
375 
376     sp<DeathNotifier> mDeathNotifier;
377 
378     DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
379 };
380 
381 ////////////////////////////////////////////////////////////////////////////////
382 
383 struct ACodec::LoadedState : public ACodec::BaseState {
384     explicit LoadedState(ACodec *codec);
385 
386 protected:
387     virtual bool onMessageReceived(const sp<AMessage> &msg);
388     virtual void stateEntered();
389 
390 private:
391     friend struct ACodec::UninitializedState;
392 
393     bool onConfigureComponent(const sp<AMessage> &msg);
394     void onCreateInputSurface(const sp<AMessage> &msg);
395     void onSetInputSurface(const sp<AMessage> &msg);
396     void onStart();
397     void onShutdown(bool keepComponentAllocated);
398 
399     status_t setupInputSurface();
400 
401     DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
402 };
403 
404 ////////////////////////////////////////////////////////////////////////////////
405 
406 struct ACodec::LoadedToIdleState : public ACodec::BaseState {
407     explicit LoadedToIdleState(ACodec *codec);
408 
409 protected:
410     virtual bool onMessageReceived(const sp<AMessage> &msg);
411     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
412     virtual void stateEntered();
413 
414 private:
415     status_t allocateBuffers();
416 
417     DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
418 };
419 
420 ////////////////////////////////////////////////////////////////////////////////
421 
422 struct ACodec::IdleToExecutingState : public ACodec::BaseState {
423     explicit IdleToExecutingState(ACodec *codec);
424 
425 protected:
426     virtual bool onMessageReceived(const sp<AMessage> &msg);
427     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
428     virtual void stateEntered();
429 
430 private:
431     DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
432 };
433 
434 ////////////////////////////////////////////////////////////////////////////////
435 
436 struct ACodec::ExecutingState : public ACodec::BaseState {
437     explicit ExecutingState(ACodec *codec);
438 
439     void submitRegularOutputBuffers();
440     void submitOutputMetaBuffers();
441     void submitOutputBuffers();
442 
443     // Submit output buffers to the decoder, submit input buffers to client
444     // to fill with data.
445     void resume();
446 
447     // Returns true iff input and output buffers are in play.
activeandroid::ACodec::ExecutingState448     bool active() const { return mActive; }
449 
450 protected:
451     virtual PortMode getPortMode(OMX_U32 portIndex);
452     virtual bool onMessageReceived(const sp<AMessage> &msg);
453     virtual void stateEntered();
454 
455     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
456     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
457 
458 private:
459     bool mActive;
460 
461     DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
462 };
463 
464 ////////////////////////////////////////////////////////////////////////////////
465 
466 struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
467     explicit OutputPortSettingsChangedState(ACodec *codec);
468 
469 protected:
470     virtual PortMode getPortMode(OMX_U32 portIndex);
471     virtual bool onMessageReceived(const sp<AMessage> &msg);
472     virtual void stateEntered();
473 
474     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
475     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
476 
477 private:
478     DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
479 };
480 
481 ////////////////////////////////////////////////////////////////////////////////
482 
483 struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
484     explicit ExecutingToIdleState(ACodec *codec);
485 
486 protected:
487     virtual bool onMessageReceived(const sp<AMessage> &msg);
488     virtual void stateEntered();
489 
490     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
491 
492     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
493     virtual void onInputBufferFilled(const sp<AMessage> &msg);
494 
495 private:
496     void changeStateIfWeOwnAllBuffers();
497 
498     bool mComponentNowIdle;
499 
500     DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
501 };
502 
503 ////////////////////////////////////////////////////////////////////////////////
504 
505 struct ACodec::IdleToLoadedState : public ACodec::BaseState {
506     explicit IdleToLoadedState(ACodec *codec);
507 
508 protected:
509     virtual bool onMessageReceived(const sp<AMessage> &msg);
510     virtual void stateEntered();
511 
512     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
513 
514 private:
515     DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
516 };
517 
518 ////////////////////////////////////////////////////////////////////////////////
519 
520 struct ACodec::FlushingState : public ACodec::BaseState {
521     explicit FlushingState(ACodec *codec);
522 
523 protected:
524     virtual bool onMessageReceived(const sp<AMessage> &msg);
525     virtual void stateEntered();
526 
527     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
528 
529     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
530     virtual void onInputBufferFilled(const sp<AMessage> &msg);
531 
532 private:
533     bool mFlushComplete[2];
534 
535     void changeStateIfWeOwnAllBuffers();
536 
537     DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
538 };
539 
540 ////////////////////////////////////////////////////////////////////////////////
541 
setWriteFence(int fenceFd,const char * dbg)542 void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
543     if (mFenceFd >= 0) {
544         ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
545                 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
546     }
547     mFenceFd = fenceFd;
548     mIsReadFence = false;
549 }
550 
setReadFence(int fenceFd,const char * dbg)551 void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
552     if (mFenceFd >= 0) {
553         ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
554                 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
555     }
556     mFenceFd = fenceFd;
557     mIsReadFence = true;
558 }
559 
checkWriteFence(const char * dbg)560 void ACodec::BufferInfo::checkWriteFence(const char *dbg) {
561     if (mFenceFd >= 0 && mIsReadFence) {
562         ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
563     }
564 }
565 
checkReadFence(const char * dbg)566 void ACodec::BufferInfo::checkReadFence(const char *dbg) {
567     if (mFenceFd >= 0 && !mIsReadFence) {
568         ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
569     }
570 }
571 
572 ////////////////////////////////////////////////////////////////////////////////
573 
ACodec()574 ACodec::ACodec()
575     : mSampleRate(0),
576       mNodeGeneration(0),
577       mAreRenderMetricsEnabled(areRenderMetricsEnabled()),
578       mIsWindowToDisplay(false),
579       mHasPresentFenceTimes(false),
580       mUsingNativeWindow(false),
581       mNativeWindowUsageBits(0),
582       mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
583       mIsVideo(false),
584       mIsImage(false),
585       mIsEncoder(false),
586       mFatalError(false),
587       mShutdownInProgress(false),
588       mExplicitShutdown(false),
589       mIsLegacyVP9Decoder(false),
590       mIsStreamCorruptFree(false),
591       mIsLowLatency(false),
592       mEncoderDelay(0),
593       mEncoderPadding(0),
594       mRotationDegrees(0),
595       mChannelMaskPresent(false),
596       mChannelMask(0),
597       mDequeueCounter(0),
598       mMetadataBuffersToSubmit(0),
599       mNumUndequeuedBuffers(0),
600       mRepeatFrameDelayUs(-1LL),
601       mMaxPtsGapUs(0LL),
602       mMaxFps(-1),
603       mFps(-1.0),
604       mCaptureFps(-1.0),
605       mCreateInputBuffersSuspended(false),
606       mTunneled(false),
607       mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
608       mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
609       mDescribeHDR10PlusInfoIndex((OMX_INDEXTYPE)0),
610       mStateGeneration(0),
611       mVendorExtensionsStatus(kExtensionsUnchecked) {
612     memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));
613 
614     mUninitializedState = new UninitializedState(this);
615     mLoadedState = new LoadedState(this);
616     mLoadedToIdleState = new LoadedToIdleState(this);
617     mIdleToExecutingState = new IdleToExecutingState(this);
618     mExecutingState = new ExecutingState(this);
619 
620     mOutputPortSettingsChangedState =
621         new OutputPortSettingsChangedState(this);
622 
623     mExecutingToIdleState = new ExecutingToIdleState(this);
624     mIdleToLoadedState = new IdleToLoadedState(this);
625     mFlushingState = new FlushingState(this);
626 
627     mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
628     mInputEOSResult = OK;
629 
630     mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
631     mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
632 
633     memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
634 
635     changeState(mUninitializedState);
636 }
637 
~ACodec()638 ACodec::~ACodec() {
639 }
640 
initiateSetup(const sp<AMessage> & msg)641 void ACodec::initiateSetup(const sp<AMessage> &msg) {
642     msg->setWhat(kWhatSetup);
643     msg->setTarget(this);
644     msg->post();
645 }
646 
getBufferChannel()647 std::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
648     if (!mBufferChannel) {
649         mBufferChannel = std::make_shared<ACodecBufferChannel>(
650                 new AMessage(kWhatInputBufferFilled, this),
651                 new AMessage(kWhatOutputBufferDrained, this),
652                 new AMessage(kWhatPollForRenderedBuffers, this));
653     }
654     return mBufferChannel;
655 }
656 
signalSetParameters(const sp<AMessage> & params)657 void ACodec::signalSetParameters(const sp<AMessage> &params) {
658     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
659     msg->setMessage("params", params);
660     msg->post();
661 }
662 
initiateAllocateComponent(const sp<AMessage> & msg)663 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
664     msg->setWhat(kWhatAllocateComponent);
665     msg->setTarget(this);
666     msg->post();
667 }
668 
initiateConfigureComponent(const sp<AMessage> & msg)669 void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
670     msg->setWhat(kWhatConfigureComponent);
671     msg->setTarget(this);
672     msg->post();
673 }
674 
setSurface(const sp<Surface> & surface,uint32_t)675 status_t ACodec::setSurface(const sp<Surface> &surface, uint32_t /*generation*/) {
676     sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
677     msg->setObject("surface", surface);
678 
679     sp<AMessage> response;
680     status_t err = msg->postAndAwaitResponse(&response);
681 
682     if (err == OK) {
683         (void)response->findInt32("err", &err);
684     }
685     return err;
686 }
687 
initiateCreateInputSurface()688 void ACodec::initiateCreateInputSurface() {
689     (new AMessage(kWhatCreateInputSurface, this))->post();
690 }
691 
initiateSetInputSurface(const sp<PersistentSurface> & surface)692 void ACodec::initiateSetInputSurface(
693         const sp<PersistentSurface> &surface) {
694     sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
695     msg->setObject("input-surface", surface);
696     msg->post();
697 }
698 
signalEndOfInputStream()699 void ACodec::signalEndOfInputStream() {
700     (new AMessage(kWhatSignalEndOfInputStream, this))->post();
701 }
702 
initiateStart()703 void ACodec::initiateStart() {
704     (new AMessage(kWhatStart, this))->post();
705 }
706 
signalFlush()707 void ACodec::signalFlush() {
708     ALOGV("[%s] signalFlush", mComponentName.c_str());
709     (new AMessage(kWhatFlush, this))->post();
710 }
711 
signalResume()712 void ACodec::signalResume() {
713     (new AMessage(kWhatResume, this))->post();
714 }
715 
initiateShutdown(bool keepComponentAllocated)716 void ACodec::initiateShutdown(bool keepComponentAllocated) {
717     sp<AMessage> msg = new AMessage(kWhatShutdown, this);
718     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
719     msg->post();
720     if (!keepComponentAllocated) {
721         // ensure shutdown completes in 3 seconds
722         (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
723     }
724 }
725 
signalRequestIDRFrame()726 void ACodec::signalRequestIDRFrame() {
727     (new AMessage(kWhatRequestIDRFrame, this))->post();
728 }
729 
730 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
731 // Some codecs may return input buffers before having them processed.
732 // This causes a halt if we already signaled an EOS on the input
733 // port.  For now keep submitting an output buffer if there was an
734 // EOS on the input port, but not yet on the output port.
signalSubmitOutputMetadataBufferIfEOS_workaround()735 void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
736     if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
737             mMetadataBuffersToSubmit > 0) {
738         (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
739     }
740 }
741 
handleSetSurface(const sp<Surface> & surface)742 status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
743     // allow keeping unset surface
744     if (surface == NULL) {
745         if (mNativeWindow != NULL) {
746             ALOGW("cannot unset a surface");
747             return INVALID_OPERATION;
748         }
749         return OK;
750     }
751 
752     // cannot switch from bytebuffers to surface
753     if (mNativeWindow == NULL) {
754         ALOGW("component was not configured with a surface");
755         return INVALID_OPERATION;
756     }
757 
758     ANativeWindow *nativeWindow = surface.get();
759     // if we have not yet started the codec, we can simply set the native window
760     if (mBuffers[kPortIndexInput].size() == 0) {
761         mNativeWindow = surface;
762         initializeFrameTracking();
763         return OK;
764     }
765 
766     // we do not support changing a tunneled surface after start
767     if (mTunneled) {
768         ALOGW("cannot change tunneled surface");
769         return INVALID_OPERATION;
770     }
771 
772     int usageBits = 0;
773     // no need to reconnect as we will not dequeue all buffers
774     status_t err = setupNativeWindowSizeFormatAndUsage(
775             nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
776     if (err != OK) {
777         return err;
778     }
779 
780     int ignoredFlags = kVideoGrallocUsage;
781     // New output surface is not allowed to add new usage flag except ignored ones.
782     if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
783         ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
784         return BAD_VALUE;
785     }
786 
787     // get min undequeued count. We cannot switch to a surface that has a higher
788     // undequeued count than we allocated.
789     int minUndequeuedBuffers = 0;
790     err = nativeWindow->query(
791             nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
792             &minUndequeuedBuffers);
793     if (err != 0) {
794         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
795                 strerror(-err), -err);
796         return err;
797     }
798     if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
799         ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
800                 minUndequeuedBuffers, mNumUndequeuedBuffers);
801         return BAD_VALUE;
802     }
803 
804     // we cannot change the number of output buffers while OMX is running
805     // set up surface to the same count
806     std::vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
807     ALOGV("setting up surface for %zu buffers", buffers.size());
808 
809     err = native_window_set_buffer_count(nativeWindow, buffers.size());
810     if (err != 0) {
811         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
812                 -err);
813         return err;
814     }
815 
816     // need to enable allocation when attaching
817     surface->getIGraphicBufferProducer()->allowAllocation(true);
818 
819     // dequeueBuffer cannot time out
820     surface->setDequeueTimeout(-1);
821 
822     // for meta data mode, we move dequeud buffers to the new surface.
823     // for non-meta mode, we must move all registered buffers
824     for (size_t i = 0; i < buffers.size(); ++i) {
825         const BufferInfo &info = buffers[i];
826         // skip undequeued buffers for meta data mode
827         if (storingMetadataInDecodedBuffers()
828                 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
829             ALOGV("skipping buffer");
830             continue;
831         }
832         ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
833 
834         err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
835         if (err != OK) {
836             ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
837                     info.mGraphicBuffer->getNativeBuffer(),
838                     strerror(-err), -err);
839             return err;
840         }
841     }
842 
843     // cancel undequeued buffers to new surface
844     if (!storingMetadataInDecodedBuffers()) {
845         for (size_t i = 0; i < buffers.size(); ++i) {
846             BufferInfo &info = buffers[i];
847             if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
848                 ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
849                 err = nativeWindow->cancelBuffer(
850                         nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
851                 info.mFenceFd = -1;
852                 if (err != OK) {
853                     ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
854                             info.mGraphicBuffer->getNativeBuffer(),
855                             strerror(-err), -err);
856                     return err;
857                 }
858             }
859         }
860         // disallow further allocation
861         (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
862     }
863 
864     // push blank buffers to previous window if requested
865     if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
866         pushBlankBuffersToNativeWindow(mNativeWindow.get());
867     }
868 
869     mNativeWindow = nativeWindow;
870     mNativeWindowUsageBits = usageBits;
871     initializeFrameTracking();
872     return OK;
873 }
874 
setPortMode(int32_t portIndex,IOMX::PortMode mode)875 status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
876     status_t err = mOMXNode->setPortMode(portIndex, mode);
877     if (err != OK) {
878         ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
879                 mComponentName.c_str(),
880                 portIndex == kPortIndexInput ? "input" : "output",
881                 asString(mode),
882                 err);
883         return err;
884     }
885 
886     mPortMode[portIndex] = mode;
887     return OK;
888 }
889 
allocateBuffersOnPort(OMX_U32 portIndex)890 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
891     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
892 
893     CHECK(mAllocator[portIndex] == NULL);
894     CHECK(mBuffers[portIndex].empty());
895 
896     status_t err;
897     if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
898         if (storingMetadataInDecodedBuffers()) {
899             err = allocateOutputMetadataBuffers();
900         } else {
901             err = allocateOutputBuffersFromNativeWindow();
902         }
903     } else {
904         OMX_PARAM_PORTDEFINITIONTYPE def;
905         InitOMXParams(&def);
906         def.nPortIndex = portIndex;
907 
908         err = mOMXNode->getParameter(
909                 OMX_IndexParamPortDefinition, &def, sizeof(def));
910 
911         if (err == OK) {
912             const IOMX::PortMode &mode = mPortMode[portIndex];
913             size_t bufSize = def.nBufferSize;
914             // Always allocate VideoNativeMetadata if using ANWBuffer.
915             // OMX might use gralloc source internally, but we don't share
916             // metadata buffer with OMX, OMX has its own headers.
917             if (mode == IOMX::kPortModeDynamicANWBuffer) {
918                 bufSize = sizeof(VideoNativeMetadata);
919             } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
920                 bufSize = sizeof(VideoNativeHandleMetadata);
921             }
922 
923             size_t conversionBufferSize = 0;
924 
925             sp<DataConverter> converter = mConverter[portIndex];
926             if (converter != NULL) {
927                 // here we assume conversions of max 4:1, so result fits in int32
928                 if (portIndex == kPortIndexInput) {
929                     conversionBufferSize = converter->sourceSize(bufSize);
930                 } else {
931                     conversionBufferSize = converter->targetSize(bufSize);
932                 }
933             }
934 
935             size_t alignment = 32; // This is the value currently returned by
936                                    // MemoryDealer::getAllocationAlignment().
937                                    // TODO: Fix this when Treble has
938                                    // MemoryHeap/MemoryDealer.
939 
940             ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
941                     mComponentName.c_str(),
942                     def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
943                     portIndex == kPortIndexInput ? "input" : "output");
944 
945             // verify buffer sizes to avoid overflow in align()
946             if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
947                 ALOGE("b/22885421");
948                 return NO_MEMORY;
949             }
950 
951             // don't modify bufSize as OMX may not expect it to increase after negotiation
952             size_t alignedSize = align(bufSize, alignment);
953             size_t alignedConvSize = align(conversionBufferSize, alignment);
954             if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
955                 ALOGE("b/22885421");
956                 return NO_MEMORY;
957             }
958 
959             if (mode != IOMX::kPortModePresetSecureBuffer) {
960                 mAllocator[portIndex] = TAllocator::getService("ashmem");
961                 if (mAllocator[portIndex] == nullptr) {
962                     ALOGE("hidl allocator on port %d is null",
963                             (int)portIndex);
964                     return NO_MEMORY;
965                 }
966                 // TODO: When Treble has MemoryHeap/MemoryDealer, we should
967                 // specify the heap size to be
968                 // def.nBufferCountActual * (alignedSize + alignedConvSize).
969             }
970 
971             const sp<AMessage> &format =
972                     portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
973             mBuffers[portIndex].reserve(def.nBufferCountActual);
974             for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
975                 hidl_memory hidlMemToken;
976                 sp<TMemory> hidlMem;
977                 sp<IMemory> mem;
978 
979                 BufferInfo info;
980                 info.mStatus = BufferInfo::OWNED_BY_US;
981                 info.mFenceFd = -1;
982                 info.mGraphicBuffer = NULL;
983                 info.mNewGraphicBuffer = false;
984 
985                 if (mode == IOMX::kPortModePresetSecureBuffer) {
986                     void *ptr = NULL;
987                     sp<NativeHandle> native_handle;
988                     err = mOMXNode->allocateSecureBuffer(
989                             portIndex, bufSize, &info.mBufferID,
990                             &ptr, &native_handle);
991 
992                     info.mData = (native_handle == NULL)
993                             ? new SecureBuffer(format, ptr, bufSize)
994                             : new SecureBuffer(format, native_handle, bufSize);
995                     info.mCodecData = info.mData;
996                 } else {
997                     bool success;
998                     auto transStatus = mAllocator[portIndex]->allocate(
999                             bufSize,
1000                             [&success, &hidlMemToken](
1001                                     bool s,
1002                                     hidl_memory const& m) {
1003                                 success = s;
1004                                 hidlMemToken = m;
1005                             });
1006 
1007                     if (!transStatus.isOk()) {
1008                         ALOGE("hidl's AshmemAllocator failed at the "
1009                                 "transport: %s",
1010                                 transStatus.description().c_str());
1011                         return NO_MEMORY;
1012                     }
1013                     if (!success) {
1014                         return NO_MEMORY;
1015                     }
1016                     hidlMem = mapMemory(hidlMemToken);
1017                     if (hidlMem == nullptr) {
1018                         return NO_MEMORY;
1019                     }
1020                     err = mOMXNode->useBuffer(
1021                             portIndex, hidlMemToken, &info.mBufferID);
1022 
1023                     if (mode == IOMX::kPortModeDynamicANWBuffer) {
1024                         VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
1025                                 (void*)hidlMem->getPointer());
1026                         metaData->nFenceFd = -1;
1027                     }
1028 
1029                     info.mCodecData = new SharedMemoryBuffer(
1030                             format, hidlMem);
1031                     info.mCodecRef = hidlMem;
1032 
1033                     // if we require conversion, allocate conversion buffer for client use;
1034                     // otherwise, reuse codec buffer
1035                     if (mConverter[portIndex] != NULL) {
1036                         CHECK_GT(conversionBufferSize, (size_t)0);
1037                         bool success;
1038                         mAllocator[portIndex]->allocate(
1039                                 conversionBufferSize,
1040                                 [&success, &hidlMemToken](
1041                                         bool s,
1042                                         hidl_memory const& m) {
1043                                     success = s;
1044                                     hidlMemToken = m;
1045                                 });
1046                         if (!success) {
1047                             return NO_MEMORY;
1048                         }
1049                         hidlMem = mapMemory(hidlMemToken);
1050                         if (hidlMem == nullptr) {
1051                             return NO_MEMORY;
1052                         }
1053                         info.mData = new SharedMemoryBuffer(format, hidlMem);
1054                         info.mMemRef = hidlMem;
1055                     } else {
1056                         info.mData = info.mCodecData;
1057                         info.mMemRef = info.mCodecRef;
1058                     }
1059                 }
1060 
1061                 mBuffers[portIndex].push_back(info);
1062             }
1063         }
1064     }
1065 
1066     if (err != OK) {
1067         return err;
1068     }
1069 
1070     std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
1071     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1072         array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
1073     }
1074     if (portIndex == kPortIndexInput) {
1075         mBufferChannel->setInputBufferArray(array);
1076     } else if (portIndex == kPortIndexOutput) {
1077         mBufferChannel->setOutputBufferArray(array);
1078     } else {
1079         TRESPASS();
1080     }
1081 
1082     return OK;
1083 }
1084 
setupNativeWindowSizeFormatAndUsage(ANativeWindow * nativeWindow,int * finalUsage,bool reconnect)1085 status_t ACodec::setupNativeWindowSizeFormatAndUsage(
1086         ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
1087         bool reconnect) {
1088     OMX_PARAM_PORTDEFINITIONTYPE def;
1089     InitOMXParams(&def);
1090     def.nPortIndex = kPortIndexOutput;
1091 
1092     status_t err = mOMXNode->getParameter(
1093             OMX_IndexParamPortDefinition, &def, sizeof(def));
1094 
1095     if (err != OK) {
1096         return err;
1097     }
1098 
1099     OMX_INDEXTYPE index;
1100     err = mOMXNode->getExtensionIndex(
1101             "OMX.google.android.index.AndroidNativeBufferConsumerUsage",
1102             &index);
1103 
1104     if (err != OK) {
1105         // allow failure
1106         err = OK;
1107     } else {
1108         int usageBits = 0;
1109         if (nativeWindow->query(
1110                 nativeWindow,
1111                 NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1112                 &usageBits) == OK) {
1113             OMX_PARAM_U32TYPE params;
1114             InitOMXParams(&params);
1115             params.nPortIndex = kPortIndexOutput;
1116             params.nU32 = (OMX_U32)usageBits;
1117 
1118             err = mOMXNode->setParameter(index, &params, sizeof(params));
1119 
1120             if (err != OK) {
1121                 ALOGE("Fail to set AndroidNativeBufferConsumerUsage: %d", err);
1122                 return err;
1123             }
1124         }
1125     }
1126 
1127     OMX_U32 usage = 0;
1128     err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
1129     if (err != 0) {
1130         ALOGW("querying usage flags from OMX IL component failed: %d", err);
1131         // XXX: Currently this error is logged, but not fatal.
1132         usage = 0;
1133     }
1134     int omxUsage = usage;
1135 
1136     if (mFlags & kFlagIsGrallocUsageProtected) {
1137         usage |= GRALLOC_USAGE_PROTECTED;
1138     }
1139 
1140     usage |= kVideoGrallocUsage;
1141     *finalUsage = usage;
1142 
1143     memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
1144     mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
1145 
1146     ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
1147     return setNativeWindowSizeFormatAndUsage(
1148             nativeWindow,
1149             def.format.video.nFrameWidth,
1150             def.format.video.nFrameHeight,
1151             def.format.video.eColorFormat,
1152             mRotationDegrees,
1153             usage,
1154             reconnect);
1155 }
1156 
configureOutputBuffersFromNativeWindow(OMX_U32 * bufferCount,OMX_U32 * bufferSize,OMX_U32 * minUndequeuedBuffers,bool preregister)1157 status_t ACodec::configureOutputBuffersFromNativeWindow(
1158         OMX_U32 *bufferCount, OMX_U32 *bufferSize,
1159         OMX_U32 *minUndequeuedBuffers, bool preregister) {
1160 
1161     OMX_PARAM_PORTDEFINITIONTYPE def;
1162     InitOMXParams(&def);
1163     def.nPortIndex = kPortIndexOutput;
1164 
1165     status_t err = mOMXNode->getParameter(
1166             OMX_IndexParamPortDefinition, &def, sizeof(def));
1167 
1168     if (err == OK) {
1169         err = setupNativeWindowSizeFormatAndUsage(
1170                 mNativeWindow.get(), &mNativeWindowUsageBits,
1171                 preregister && !mTunneled /* reconnect */);
1172     }
1173     if (err != OK) {
1174         mNativeWindowUsageBits = 0;
1175         return err;
1176     }
1177 
1178     static_cast<Surface *>(mNativeWindow.get())->setDequeueTimeout(-1);
1179 
1180     // Exits here for tunneled video playback codecs -- i.e. skips native window
1181     // buffer allocation step as this is managed by the tunneled OMX omponent
1182     // itself and explicitly sets def.nBufferCountActual to 0.
1183     if (mTunneled) {
1184         ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1185         def.nBufferCountActual = 0;
1186         err = mOMXNode->setParameter(
1187                 OMX_IndexParamPortDefinition, &def, sizeof(def));
1188 
1189         *minUndequeuedBuffers = 0;
1190         *bufferCount = 0;
1191         *bufferSize = 0;
1192         return err;
1193     }
1194 
1195     *minUndequeuedBuffers = 0;
1196     err = mNativeWindow->query(
1197             mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1198             (int *)minUndequeuedBuffers);
1199 
1200     if (err != 0) {
1201         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1202                 strerror(-err), -err);
1203         return err;
1204     }
1205 
1206     // FIXME: assume that surface is controlled by app (native window
1207     // returns the number for the case when surface is not controlled by app)
1208     // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
1209     // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1210 
1211     // Use conservative allocation while also trying to reduce starvation
1212     //
1213     // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1214     //    minimum needed for the consumer to be able to work
1215     // 2. try to allocate two (2) additional buffers to reduce starvation from
1216     //    the consumer
1217     //    plus an extra buffer to account for incorrect minUndequeuedBufs
1218     for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1219         OMX_U32 newBufferCount =
1220             def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1221         def.nBufferCountActual = newBufferCount;
1222         err = mOMXNode->setParameter(
1223                 OMX_IndexParamPortDefinition, &def, sizeof(def));
1224 
1225         if (err == OK) {
1226             *minUndequeuedBuffers += extraBuffers;
1227             break;
1228         }
1229 
1230         ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1231                 mComponentName.c_str(), newBufferCount, err);
1232         /* exit condition */
1233         if (extraBuffers == 0) {
1234             return err;
1235         }
1236     }
1237 
1238     err = native_window_set_buffer_count(
1239             mNativeWindow.get(), def.nBufferCountActual);
1240 
1241     if (err != 0) {
1242         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1243                 -err);
1244         return err;
1245     }
1246 
1247     *bufferCount = def.nBufferCountActual;
1248     *bufferSize =  def.nBufferSize;
1249     initializeFrameTracking();
1250     return err;
1251 }
1252 
allocateOutputBuffersFromNativeWindow()1253 status_t ACodec::allocateOutputBuffersFromNativeWindow() {
1254     // This method only handles the non-metadata mode (or simulating legacy
1255     // mode with metadata, which is transparent to ACodec).
1256     CHECK(!storingMetadataInDecodedBuffers());
1257 
1258     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1259     status_t err = configureOutputBuffersFromNativeWindow(
1260             &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1261     if (err != 0)
1262         return err;
1263     mNumUndequeuedBuffers = minUndequeuedBuffers;
1264 
1265     static_cast<Surface*>(mNativeWindow.get())
1266             ->getIGraphicBufferProducer()->allowAllocation(true);
1267 
1268     ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1269          "output port",
1270          mComponentName.c_str(), bufferCount, bufferSize);
1271 
1272     // Dequeue buffers and send them to OMX
1273     mBuffers[kPortIndexOutput].reserve(bufferCount);
1274     for (OMX_U32 i = 0; i < bufferCount; i++) {
1275         ANativeWindowBuffer *buf;
1276         int fenceFd;
1277         err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1278         if (err != 0) {
1279             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1280             break;
1281         }
1282 
1283         sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf));
1284         BufferInfo info;
1285         info.mStatus = BufferInfo::OWNED_BY_US;
1286         info.mFenceFd = fenceFd;
1287         info.mIsReadFence = false;
1288         info.mGraphicBuffer = graphicBuffer;
1289         info.mNewGraphicBuffer = false;
1290         info.mDequeuedAt = mDequeueCounter;
1291 
1292         // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
1293         //       OMX doesn't use the shared memory buffer, but some code still
1294         //       access info.mData. Create an ABuffer as a placeholder.
1295         info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1296         info.mCodecData = info.mData;
1297 
1298         mBuffers[kPortIndexOutput].push_back(info);
1299 
1300         IOMX::buffer_id bufferId;
1301         err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
1302         if (err != 0) {
1303             ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
1304                  "%d", i, err);
1305             break;
1306         }
1307 
1308         mBuffers[kPortIndexOutput][i].mBufferID = bufferId;
1309 
1310         ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1311              mComponentName.c_str(),
1312              bufferId, graphicBuffer.get());
1313     }
1314 
1315     OMX_U32 cancelStart;
1316     OMX_U32 cancelEnd;
1317 
1318     if (err != OK) {
1319         // If an error occurred while dequeuing we need to cancel any buffers
1320         // that were dequeued. Also cancel all if we're in legacy metadata mode.
1321         cancelStart = 0;
1322         cancelEnd = mBuffers[kPortIndexOutput].size();
1323     } else {
1324         // Return the required minimum undequeued buffers to the native window.
1325         cancelStart = bufferCount - minUndequeuedBuffers;
1326         cancelEnd = bufferCount;
1327     }
1328 
1329     for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1330         BufferInfo *info = &mBuffers[kPortIndexOutput][i];
1331         if (info->mStatus == BufferInfo::OWNED_BY_US) {
1332             status_t error = cancelBufferToNativeWindow(info);
1333             if (err == 0) {
1334                 err = error;
1335             }
1336         }
1337     }
1338 
1339     static_cast<Surface*>(mNativeWindow.get())
1340             ->getIGraphicBufferProducer()->allowAllocation(false);
1341 
1342     return err;
1343 }
1344 
allocateOutputMetadataBuffers()1345 status_t ACodec::allocateOutputMetadataBuffers() {
1346     CHECK(storingMetadataInDecodedBuffers());
1347 
1348     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1349     status_t err = configureOutputBuffersFromNativeWindow(
1350             &bufferCount, &bufferSize, &minUndequeuedBuffers,
1351             mFlags & kFlagPreregisterMetadataBuffers /* preregister */);
1352     if (err != OK)
1353         return err;
1354     mNumUndequeuedBuffers = minUndequeuedBuffers;
1355 
1356     ALOGV("[%s] Allocating %u meta buffers on output port",
1357          mComponentName.c_str(), bufferCount);
1358 
1359     mBuffers[kPortIndexOutput].reserve(bufferCount);
1360     for (OMX_U32 i = 0; i < bufferCount; i++) {
1361         BufferInfo info;
1362         info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1363         info.mFenceFd = -1;
1364         info.mGraphicBuffer = NULL;
1365         info.mNewGraphicBuffer = false;
1366         info.mDequeuedAt = mDequeueCounter;
1367 
1368         info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1369 
1370         // Initialize fence fd to -1 to avoid warning in freeBuffer().
1371         ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1;
1372 
1373         info.mCodecData = info.mData;
1374 
1375         err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
1376         mBuffers[kPortIndexOutput].push_back(info);
1377 
1378         ALOGV("[%s] allocated meta buffer with ID %u",
1379                 mComponentName.c_str(), info.mBufferID);
1380     }
1381 
1382     mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1383     return err;
1384 }
1385 
submitOutputMetadataBuffer()1386 status_t ACodec::submitOutputMetadataBuffer() {
1387     CHECK(storingMetadataInDecodedBuffers());
1388     if (mMetadataBuffersToSubmit == 0)
1389         return OK;
1390 
1391     BufferInfo *info = dequeueBufferFromNativeWindow();
1392     if (info == NULL) {
1393         return ERROR_IO;
1394     }
1395 
1396     ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1397           mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer->handle);
1398 
1399     --mMetadataBuffersToSubmit;
1400     info->checkWriteFence("submitOutputMetadataBuffer");
1401     return fillBuffer(info);
1402 }
1403 
waitForFence(int fd,const char * dbg)1404 status_t ACodec::waitForFence(int fd, const char *dbg ) {
1405     status_t res = OK;
1406     if (fd >= 0) {
1407         sp<Fence> fence = new Fence(fd);
1408         res = fence->wait(IOMX::kFenceTimeoutMs);
1409         ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
1410     }
1411     return res;
1412 }
1413 
1414 // static
_asString(BufferInfo::Status s)1415 const char *ACodec::_asString(BufferInfo::Status s) {
1416     switch (s) {
1417         case BufferInfo::OWNED_BY_US:            return "OUR";
1418         case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
1419         case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
1420         case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
1421         case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
1422         case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
1423         default:                                 return "?";
1424     }
1425 }
1426 
dumpBuffers(OMX_U32 portIndex)1427 void ACodec::dumpBuffers(OMX_U32 portIndex) {
1428     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1429     ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
1430             portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
1431     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1432         const BufferInfo &info = mBuffers[portIndex][i];
1433         ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
1434                 i, info.mBufferID, info.mGraphicBuffer.get(),
1435                 info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
1436                 _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
1437     }
1438 }
1439 
cancelBufferToNativeWindow(BufferInfo * info)1440 status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1441     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1442 
1443     ALOGV("[%s] Calling cancelBuffer on buffer %u",
1444          mComponentName.c_str(), info->mBufferID);
1445 
1446     info->checkWriteFence("cancelBufferToNativeWindow");
1447     int err = mNativeWindow->cancelBuffer(
1448         mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
1449     info->mFenceFd = -1;
1450 
1451     ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
1452             mComponentName.c_str(), info->mBufferID);
1453     // change ownership even if cancelBuffer fails
1454     info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1455 
1456     return err;
1457 }
1458 
onFirstTunnelFrameReady()1459 void ACodec::onFirstTunnelFrameReady() {
1460     mCallback->onFirstTunnelFrameReady();
1461 }
1462 
dequeueBufferFromNativeWindow()1463 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
1464     ANativeWindowBuffer *buf;
1465     CHECK(mNativeWindow.get() != NULL);
1466 
1467     if (mTunneled) {
1468         ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1469               " video playback mode mode!");
1470         return NULL;
1471     }
1472 
1473     if (mFatalError) {
1474         ALOGW("not dequeuing from native window due to fatal error");
1475         return NULL;
1476     }
1477 
1478     int fenceFd = -1;
1479     do {
1480         status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1481         if (err != 0) {
1482             ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1483             return NULL;
1484         }
1485 
1486         bool stale = false;
1487         for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1488             i--;
1489             BufferInfo *info = &mBuffers[kPortIndexOutput][i];
1490 
1491             if (info->mGraphicBuffer != NULL &&
1492                     info->mGraphicBuffer->handle == buf->handle) {
1493                 // Since consumers can attach buffers to BufferQueues, it is possible
1494                 // that a known yet stale buffer can return from a surface that we
1495                 // once used.  We can simply ignore this as we have already dequeued
1496                 // this buffer properly.  NOTE: this does not eliminate all cases,
1497                 // e.g. it is possible that we have queued the valid buffer to the
1498                 // NW, and a stale copy of the same buffer gets dequeued - which will
1499                 // be treated as the valid buffer by ACodec.
1500                 if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1501                     ALOGI("dequeued stale buffer %p. discarding", buf);
1502                     stale = true;
1503                     break;
1504                 }
1505 
1506                 ALOGV("dequeued buffer #%u with age %u, graphicBuffer %p",
1507                         (unsigned)(info - &mBuffers[kPortIndexOutput][0]),
1508                         mDequeueCounter - info->mDequeuedAt,
1509                         info->mGraphicBuffer->handle);
1510 
1511                 info->mStatus = BufferInfo::OWNED_BY_US;
1512                 info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
1513                 return info;
1514             }
1515         }
1516 
1517         // It is also possible to receive a previously unregistered buffer
1518         // in non-meta mode. These should be treated as stale buffers. The
1519         // same is possible in meta mode, in which case, it will be treated
1520         // as a normal buffer, which is not desirable.
1521         // TODO: fix this.
1522         if (!stale && !storingMetadataInDecodedBuffers()) {
1523             ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1524             stale = true;
1525         }
1526         if (stale) {
1527             // TODO: detach stale buffer, but there is no API yet to do it.
1528             buf = NULL;
1529         }
1530     } while (buf == NULL);
1531 
1532     // get oldest undequeued buffer
1533     BufferInfo *oldest = NULL;
1534     for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1535         i--;
1536         BufferInfo *info = &mBuffers[kPortIndexOutput][i];
1537         if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1538             (oldest == NULL ||
1539              // avoid potential issues from counter rolling over
1540              mDequeueCounter - info->mDequeuedAt >
1541                     mDequeueCounter - oldest->mDequeuedAt)) {
1542             oldest = info;
1543         }
1544     }
1545 
1546     // it is impossible dequeue a buffer when there are no buffers with ANW
1547     CHECK(oldest != NULL);
1548     // it is impossible to dequeue an unknown buffer in non-meta mode, as the
1549     // while loop above does not complete
1550     CHECK(storingMetadataInDecodedBuffers());
1551 
1552     // discard buffer in LRU info and replace with new buffer
1553     oldest->mGraphicBuffer = GraphicBuffer::from(buf);
1554     oldest->mNewGraphicBuffer = true;
1555     oldest->mStatus = BufferInfo::OWNED_BY_US;
1556     oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
1557 
1558     ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
1559             (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1560             mDequeueCounter - oldest->mDequeuedAt,
1561             oldest->mGraphicBuffer->handle);
1562     return oldest;
1563 }
1564 
initializeFrameTracking()1565 void ACodec::initializeFrameTracking() {
1566     mTrackedFrames.clear();
1567 
1568     int isWindowToDisplay = 0;
1569     mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1570             &isWindowToDisplay);
1571     mIsWindowToDisplay = isWindowToDisplay == 1;
1572     // No frame tracking is needed if we're not sending frames to the display
1573     if (!mIsWindowToDisplay) {
1574         // Return early so we don't call into SurfaceFlinger (requiring permissions)
1575         return;
1576     }
1577 
1578     int hasPresentFenceTimes = 0;
1579     mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT,
1580             &hasPresentFenceTimes);
1581     mHasPresentFenceTimes = hasPresentFenceTimes == 1;
1582     if (!mHasPresentFenceTimes) {
1583         ALOGI("Using latch times for frame rendered signals - present fences not supported");
1584     }
1585 
1586     status_t err = native_window_enable_frame_timestamps(mNativeWindow.get(), true);
1587     if (err) {
1588         ALOGE("Failed to enable frame timestamps (%d)", err);
1589     }
1590 }
1591 
trackReleasedFrame(int64_t frameId,int64_t mediaTimeUs,int64_t desiredRenderTimeNs)1592 void ACodec::trackReleasedFrame(int64_t frameId, int64_t mediaTimeUs, int64_t desiredRenderTimeNs) {
1593     // If the render time is earlier than now, then we're suggesting it should be rendered ASAP,
1594     // so track the frame as if the desired render time is now.
1595     int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
1596     if (desiredRenderTimeNs < nowNs) {
1597         desiredRenderTimeNs = nowNs;
1598     }
1599 
1600     // If the render time is more than a second from now, then pretend the frame is supposed to be
1601     // rendered immediately, because that's what SurfaceFlinger heuristics will do. This is a tight
1602     // coupling, but is really the only way to optimize away unnecessary present fence checks in
1603     // processRenderedFrames.
1604     if (desiredRenderTimeNs > nowNs + 1*1000*1000*1000LL) {
1605         desiredRenderTimeNs = nowNs;
1606     }
1607 
1608     // We've just queued a frame to the surface, so keep track of it and later check to see if it is
1609     // actually rendered.
1610     TrackedFrame frame;
1611     frame.id = frameId;
1612     frame.mediaTimeUs = mediaTimeUs;
1613     frame.desiredRenderTimeNs = desiredRenderTimeNs;
1614     mTrackedFrames.push_back(frame);
1615 }
1616 
pollForRenderedFrames()1617 void ACodec::pollForRenderedFrames() {
1618     std::list<RenderedFrameInfo> renderedFrameInfos;
1619     // Scan all frames and check to see if the frames that SHOULD have been rendered by now, have,
1620     // in fact, been rendered.
1621     int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
1622     while (!mTrackedFrames.empty()) {
1623         TrackedFrame & frame = mTrackedFrames.front();
1624         // Frames that should have been rendered at least 100ms in the past are checked
1625         if (frame.desiredRenderTimeNs > nowNs - 100*1000*1000LL) {
1626             break;
1627         }
1628 
1629         status_t err;
1630         nsecs_t latchOrPresentTimeNs = NATIVE_WINDOW_TIMESTAMP_INVALID;
1631         err = native_window_get_frame_timestamps(mNativeWindow.get(), frame.id,
1632                 /* outRequestedPresentTime */ nullptr, /* outAcquireTime */ nullptr,
1633                 mHasPresentFenceTimes ? nullptr : &latchOrPresentTimeNs, // latch time
1634                 /* outFirstRefreshStartTime */ nullptr, /* outLastRefreshStartTime */ nullptr,
1635                 /* outGpuCompositionDoneTime */ nullptr,
1636                 mHasPresentFenceTimes ? &latchOrPresentTimeNs : nullptr, // display present time,
1637                 /* outDequeueReadyTime */ nullptr, /* outReleaseTime */ nullptr);
1638         if (err) {
1639             ALOGE("Failed to get frame timestamps for %lld: %d", (long long) frame.id, err);
1640         }
1641         // If we don't have a render time by now, then consider the frame as dropped
1642         if (latchOrPresentTimeNs != NATIVE_WINDOW_TIMESTAMP_PENDING &&
1643             latchOrPresentTimeNs != NATIVE_WINDOW_TIMESTAMP_INVALID) {
1644             renderedFrameInfos.push_back(RenderedFrameInfo(frame.mediaTimeUs,
1645                                                            latchOrPresentTimeNs));
1646         }
1647 
1648         mTrackedFrames.pop_front();
1649     }
1650 
1651     if (!renderedFrameInfos.empty()) {
1652         mCallback->onOutputFramesRendered(renderedFrameInfos);
1653     }
1654 }
1655 
freeBuffersOnPort(OMX_U32 portIndex)1656 status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1657     if (portIndex == kPortIndexInput) {
1658         mBufferChannel->setInputBufferArray({});
1659     } else {
1660         mBufferChannel->setOutputBufferArray({});
1661     }
1662 
1663     status_t err = OK;
1664     for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1665         i--;
1666         status_t err2 = freeBuffer(portIndex, i);
1667         if (err == OK) {
1668             err = err2;
1669         }
1670     }
1671 
1672     mAllocator[portIndex].clear();
1673     return err;
1674 }
1675 
freeOutputBuffersNotOwnedByComponent()1676 status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1677     status_t err = OK;
1678     for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1679         i--;
1680         BufferInfo *info = &mBuffers[kPortIndexOutput][i];
1681 
1682         // At this time some buffers may still be with the component
1683         // or being drained.
1684         if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
1685             info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1686             status_t err2 = freeBuffer(kPortIndexOutput, i);
1687             if (err == OK) {
1688                 err = err2;
1689             }
1690         }
1691     }
1692 
1693     return err;
1694 }
1695 
freeBuffer(OMX_U32 portIndex,size_t i)1696 status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1697     BufferInfo *info = &mBuffers[portIndex][i];
1698     status_t err = OK;
1699 
1700     // there should not be any fences in the metadata
1701     if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
1702             && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
1703         int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
1704         if (fenceFd >= 0) {
1705             ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
1706                     fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
1707         }
1708     }
1709 
1710     switch (info->mStatus) {
1711         case BufferInfo::OWNED_BY_US:
1712             if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
1713                 (void)cancelBufferToNativeWindow(info);
1714             }
1715             FALLTHROUGH_INTENDED;
1716 
1717         case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1718             err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
1719             break;
1720 
1721         default:
1722             ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
1723             err = FAILED_TRANSACTION;
1724             break;
1725     }
1726 
1727     if (info->mFenceFd >= 0) {
1728         ::close(info->mFenceFd);
1729     }
1730 
1731     // remove buffer even if mOMXNode->freeBuffer fails
1732     mBuffers[portIndex].erase(mBuffers[portIndex].begin() + i);
1733     return err;
1734 }
1735 
findBufferByID(uint32_t portIndex,IOMX::buffer_id bufferID,ssize_t * index)1736 ACodec::BufferInfo *ACodec::findBufferByID(
1737         uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1738     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1739         BufferInfo *info = &mBuffers[portIndex][i];
1740 
1741         if (info->mBufferID == bufferID) {
1742             if (index != NULL) {
1743                 *index = i;
1744             }
1745             return info;
1746         }
1747     }
1748 
1749     ALOGE("Could not find buffer with ID %u", bufferID);
1750     return NULL;
1751 }
1752 
fillBuffer(BufferInfo * info)1753 status_t ACodec::fillBuffer(BufferInfo *info) {
1754     status_t err;
1755     // Even in dynamic ANW buffer mode, if the graphic buffer is not changing,
1756     // send sPreset instead of the same graphic buffer, so that OMX server
1757     // side doesn't update the meta. In theory it should make no difference,
1758     // however when the same buffer is parcelled again, a new handle could be
1759     // created on server side, and some decoder doesn't recognize the handle
1760     // even if it's the same buffer.
1761     if (!storingMetadataInDecodedBuffers() || !info->mNewGraphicBuffer) {
1762         err = mOMXNode->fillBuffer(
1763             info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
1764     } else {
1765         err = mOMXNode->fillBuffer(
1766             info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
1767     }
1768 
1769     info->mNewGraphicBuffer = false;
1770     info->mFenceFd = -1;
1771     if (err == OK) {
1772         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1773     }
1774     return err;
1775 }
1776 
setComponentRole(bool isEncoder,const char * mime)1777 status_t ACodec::setComponentRole(
1778         bool isEncoder, const char *mime) {
1779     const char *role = GetComponentRole(isEncoder, mime);
1780     if (role == NULL) {
1781         return BAD_VALUE;
1782     }
1783     status_t err = SetComponentRole(mOMXNode, role);
1784     if (err != OK) {
1785         ALOGW("[%s] Failed to set standard component role '%s'.",
1786              mComponentName.c_str(), role);
1787     }
1788     return err;
1789 }
1790 
configureCodec(const char * mime,const sp<AMessage> & msg)1791 status_t ACodec::configureCodec(
1792         const char *mime, const sp<AMessage> &msg) {
1793     int32_t encoder;
1794     if (!msg->findInt32("encoder", &encoder)) {
1795         encoder = false;
1796     }
1797 
1798     sp<AMessage> inputFormat = new AMessage;
1799     sp<AMessage> outputFormat = new AMessage;
1800     mConfigFormat = msg;
1801 
1802     mIsEncoder = encoder;
1803     mIsVideo = !strncasecmp(mime, "video/", 6);
1804     mIsImage = !strncasecmp(mime, "image/", 6);
1805 
1806     mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
1807     mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
1808 
1809     status_t err = setComponentRole(encoder /* isEncoder */, mime);
1810 
1811     if (err != OK) {
1812         return err;
1813     }
1814 
1815     OMX_VIDEO_CONTROLRATETYPE bitrateMode;
1816     int32_t bitrate = 0, quality;
1817     // FLAC encoder or video encoder in constant quality mode doesn't need a
1818     // bitrate, other encoders do.
1819     if (encoder) {
1820         if (mIsVideo || mIsImage) {
1821             if (!findVideoBitrateControlInfo(msg, &bitrateMode, &bitrate, &quality)) {
1822                 return INVALID_OPERATION;
1823             }
1824         } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1825             && !msg->findInt32("bitrate", &bitrate)) {
1826             return INVALID_OPERATION;
1827         }
1828     }
1829 
1830     // propagate bitrate to the output so that the muxer has it
1831     if (encoder && msg->findInt32("bitrate", &bitrate)) {
1832         // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
1833         // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
1834         outputFormat->setInt32("bitrate", bitrate);
1835         outputFormat->setInt32("max-bitrate", bitrate);
1836     }
1837 
1838     int32_t storeMeta;
1839     if (encoder) {
1840         IOMX::PortMode mode = IOMX::kPortModePresetByteBuffer;
1841         if (msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
1842                 && storeMeta != kMetadataBufferTypeInvalid) {
1843             if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
1844                 mode = IOMX::kPortModeDynamicNativeHandle;
1845             } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
1846                     storeMeta == kMetadataBufferTypeGrallocSource) {
1847                 mode = IOMX::kPortModeDynamicANWBuffer;
1848             } else {
1849                 return BAD_VALUE;
1850             }
1851         }
1852         err = setPortMode(kPortIndexInput, mode);
1853         if (err != OK) {
1854             return err;
1855         }
1856 
1857         if (mode != IOMX::kPortModePresetByteBuffer) {
1858             uint32_t usageBits;
1859             if (mOMXNode->getParameter(
1860                     (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1861                     &usageBits, sizeof(usageBits)) == OK) {
1862                 inputFormat->setInt32(
1863                         "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1864             }
1865         }
1866     }
1867 
1868     int32_t lowLatency = 0;
1869     if (msg->findInt32("low-latency", &lowLatency)) {
1870         err = setLowLatency(lowLatency);
1871         if (err != OK) {
1872             return err;
1873         }
1874     }
1875 
1876     int32_t prependSPSPPS = 0;
1877     if (encoder && mIsVideo
1878             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
1879             && prependSPSPPS != 0) {
1880         OMX_INDEXTYPE index;
1881         err = mOMXNode->getExtensionIndex(
1882                 "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
1883 
1884         if (err == OK) {
1885             PrependSPSPPSToIDRFramesParams params;
1886             InitOMXParams(&params);
1887             params.bEnable = OMX_TRUE;
1888 
1889             err = mOMXNode->setParameter(index, &params, sizeof(params));
1890         }
1891 
1892         if (err != OK) {
1893             ALOGE("Encoder could not be configured to emit SPS/PPS before "
1894                   "IDR frames. (err %d)", err);
1895 
1896             return err;
1897         }
1898     }
1899 
1900     // Only enable metadata mode on encoder output if encoder can prepend
1901     // sps/pps to idr frames, since in metadata mode the bitstream is in an
1902     // opaque handle, to which we don't have access.
1903     if (encoder && mIsVideo) {
1904         OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1905             && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1906             && storeMeta != 0);
1907         if (mFlags & kFlagIsSecure) {
1908             enable = OMX_TRUE;
1909         }
1910 
1911         err = setPortMode(kPortIndexOutput, enable ?
1912                 IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
1913         if (err != OK) {
1914             return err;
1915         }
1916 
1917         if (!msg->findInt64(
1918                 KEY_REPEAT_PREVIOUS_FRAME_AFTER, &mRepeatFrameDelayUs)) {
1919             mRepeatFrameDelayUs = -1LL;
1920         }
1921 
1922         if (!msg->findDouble("time-lapse-fps", &mCaptureFps)) {
1923             float captureRate;
1924             if (msg->findAsFloat(KEY_CAPTURE_RATE, &captureRate)) {
1925                 mCaptureFps = captureRate;
1926             } else {
1927                 mCaptureFps = -1.0;
1928             }
1929         }
1930 
1931         if (!msg->findInt32(
1932                 KEY_CREATE_INPUT_SURFACE_SUSPENDED,
1933                 (int32_t*)&mCreateInputBuffersSuspended)) {
1934             mCreateInputBuffersSuspended = false;
1935         }
1936     }
1937 
1938     if (encoder && (mIsVideo || mIsImage)) {
1939         // only allow 32-bit value, since we pass it as U32 to OMX.
1940         if (!msg->findInt64(KEY_MAX_PTS_GAP_TO_ENCODER, &mMaxPtsGapUs)) {
1941             mMaxPtsGapUs = 0LL;
1942         } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < INT32_MIN) {
1943             ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
1944             mMaxPtsGapUs = 0LL;
1945         }
1946 
1947         if (!msg->findFloat(KEY_MAX_FPS_TO_ENCODER, &mMaxFps)) {
1948             mMaxFps = -1;
1949         }
1950 
1951         // notify GraphicBufferSource to allow backward frames
1952         if (mMaxPtsGapUs < 0LL) {
1953             mMaxFps = -1;
1954         }
1955     }
1956 
1957     // NOTE: we only use native window for video decoders
1958     sp<RefBase> obj;
1959     bool haveNativeWindow = msg->findObject("native-window", &obj)
1960             && obj != NULL && mIsVideo && !encoder;
1961     mUsingNativeWindow = haveNativeWindow;
1962     if (mIsVideo && !encoder) {
1963         inputFormat->setInt32("adaptive-playback", false);
1964 
1965         int32_t usageProtected;
1966         if (msg->findInt32("protected", &usageProtected) && usageProtected) {
1967             if (!haveNativeWindow) {
1968                 ALOGE("protected output buffers must be sent to an ANativeWindow");
1969                 return PERMISSION_DENIED;
1970             }
1971             mFlags |= kFlagIsGrallocUsageProtected;
1972             mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1973         }
1974     }
1975     if (mFlags & kFlagIsSecure) {
1976         // use native_handles for secure input buffers
1977         err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
1978 
1979         if (err != OK) {
1980             ALOGI("falling back to non-native_handles");
1981             setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
1982             err = OK; // ignore error for now
1983         }
1984 
1985         OMX_INDEXTYPE index;
1986         if (mOMXNode->getExtensionIndex(
1987                 "OMX.google.android.index.preregisterMetadataBuffers", &index) == OK) {
1988             OMX_CONFIG_BOOLEANTYPE param;
1989             InitOMXParams(&param);
1990             param.bEnabled = OMX_FALSE;
1991             if (mOMXNode->getParameter(index, &param, sizeof(param)) == OK) {
1992                 if (param.bEnabled == OMX_TRUE) {
1993                     mFlags |= kFlagPreregisterMetadataBuffers;
1994                 }
1995             }
1996         }
1997     }
1998     if (haveNativeWindow) {
1999         sp<ANativeWindow> nativeWindow =
2000             static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
2001 
2002         // START of temporary support for automatic FRC - THIS WILL BE REMOVED
2003         int32_t autoFrc;
2004         if (msg->findInt32("auto-frc", &autoFrc)) {
2005             bool enabled = autoFrc;
2006             OMX_CONFIG_BOOLEANTYPE config;
2007             InitOMXParams(&config);
2008             config.bEnabled = (OMX_BOOL)enabled;
2009             status_t temp = mOMXNode->setConfig(
2010                     (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
2011                     &config, sizeof(config));
2012             if (temp == OK) {
2013                 outputFormat->setInt32("auto-frc", enabled);
2014             } else if (enabled) {
2015                 ALOGI("codec does not support requested auto-frc (err %d)", temp);
2016             }
2017         }
2018         // END of temporary support for automatic FRC
2019 
2020         int32_t tunneled;
2021         if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
2022             tunneled != 0) {
2023             ALOGI("Configuring TUNNELED video playback.");
2024             mTunneled = true;
2025 
2026             int32_t audioHwSync = 0;
2027             if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
2028                 ALOGW("No Audio HW Sync provided for video tunnel");
2029             }
2030             err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
2031             if (err != OK) {
2032                 ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
2033                         audioHwSync, nativeWindow.get());
2034                 return err;
2035             }
2036 
2037             int32_t maxWidth = 0, maxHeight = 0;
2038             if (msg->findInt32("max-width", &maxWidth) &&
2039                     msg->findInt32("max-height", &maxHeight)) {
2040 
2041                 err = mOMXNode->prepareForAdaptivePlayback(
2042                         kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
2043                 if (err != OK) {
2044                     ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
2045                             mComponentName.c_str(), err);
2046                     // allow failure
2047                     err = OK;
2048                 } else {
2049                     inputFormat->setInt32("max-width", maxWidth);
2050                     inputFormat->setInt32("max-height", maxHeight);
2051                     inputFormat->setInt32("adaptive-playback", true);
2052                 }
2053             }
2054         } else {
2055             ALOGV("Configuring CPU controlled video playback.");
2056             mTunneled = false;
2057 
2058             // Explicity reset the sideband handle of the window for
2059             // non-tunneled video in case the window was previously used
2060             // for a tunneled video playback.
2061             err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
2062             if (err != OK) {
2063                 ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
2064                 return err;
2065             }
2066 
2067             err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
2068             if (err != OK) {
2069                 // if adaptive playback has been requested, try JB fallback
2070                 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
2071                 // LARGE MEMORY REQUIREMENT
2072 
2073                 // we will not do adaptive playback on software accessed
2074                 // surfaces as they never had to respond to changes in the
2075                 // crop window, and we don't trust that they will be able to.
2076                 int usageBits = 0;
2077                 bool canDoAdaptivePlayback;
2078 
2079                 if (nativeWindow->query(
2080                         nativeWindow.get(),
2081                         NATIVE_WINDOW_CONSUMER_USAGE_BITS,
2082                         &usageBits) != OK) {
2083                     canDoAdaptivePlayback = false;
2084                 } else {
2085                     canDoAdaptivePlayback =
2086                         (usageBits &
2087                                 (GRALLOC_USAGE_SW_READ_MASK |
2088                                  GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
2089                 }
2090 
2091                 int32_t maxWidth = 0, maxHeight = 0;
2092                 if (canDoAdaptivePlayback &&
2093                         msg->findInt32("max-width", &maxWidth) &&
2094                         msg->findInt32("max-height", &maxHeight)) {
2095                     ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
2096                             mComponentName.c_str(), maxWidth, maxHeight);
2097 
2098                     err = mOMXNode->prepareForAdaptivePlayback(
2099                             kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
2100                     ALOGW_IF(err != OK,
2101                             "[%s] prepareForAdaptivePlayback failed w/ err %d",
2102                             mComponentName.c_str(), err);
2103 
2104                     if (err == OK) {
2105                         inputFormat->setInt32("max-width", maxWidth);
2106                         inputFormat->setInt32("max-height", maxHeight);
2107                         inputFormat->setInt32("adaptive-playback", true);
2108                     }
2109                 }
2110                 // allow failure
2111                 err = OK;
2112             } else {
2113                 ALOGV("[%s] setPortMode on output to %s succeeded",
2114                         mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
2115                 CHECK(storingMetadataInDecodedBuffers());
2116                 inputFormat->setInt32("adaptive-playback", true);
2117             }
2118 
2119             int32_t push;
2120             if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
2121                     && push != 0) {
2122                 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
2123             }
2124         }
2125 
2126         int32_t rotationDegrees;
2127         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
2128             mRotationDegrees = rotationDegrees;
2129         } else {
2130             mRotationDegrees = 0;
2131         }
2132     }
2133 
2134     AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
2135     (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
2136     // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
2137 
2138     if (mIsVideo || mIsImage) {
2139         // determine need for software renderer
2140         bool usingSwRenderer = false;
2141         if (haveNativeWindow) {
2142             bool requiresSwRenderer = false;
2143             OMX_PARAM_U32TYPE param;
2144             InitOMXParams(&param);
2145             param.nPortIndex = kPortIndexOutput;
2146 
2147             status_t err = mOMXNode->getParameter(
2148                     (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidRequiresSwRenderer,
2149                     &param, sizeof(param));
2150 
2151             if (err == OK && param.nU32 == 1) {
2152                 requiresSwRenderer = true;
2153             }
2154 
2155             if (mComponentName.startsWith("OMX.google.") || requiresSwRenderer) {
2156                 usingSwRenderer = true;
2157                 haveNativeWindow = false;
2158                 (void)setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2159             } else if (!storingMetadataInDecodedBuffers()) {
2160                 err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
2161                 if (err != OK) {
2162                     return err;
2163                 }
2164             }
2165 
2166         }
2167 
2168 
2169         if (encoder) {
2170             err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
2171         } else {
2172             err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
2173         }
2174 
2175         if (err != OK) {
2176             return err;
2177         }
2178 
2179         if (haveNativeWindow) {
2180             mNativeWindow = static_cast<Surface *>(obj.get());
2181 
2182             // fallback for devices that do not handle flex-YUV for native buffers
2183             int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
2184             if (msg->findInt32("color-format", &requestedColorFormat) &&
2185                     requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
2186                 status_t err = getPortFormat(kPortIndexOutput, outputFormat);
2187                 if (err != OK) {
2188                     return err;
2189                 }
2190                 int32_t colorFormat = OMX_COLOR_FormatUnused;
2191                 OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
2192                 if (!outputFormat->findInt32("color-format", &colorFormat)) {
2193                     ALOGE("output port did not have a color format (wrong domain?)");
2194                     return BAD_VALUE;
2195                 }
2196                 ALOGD("[%s] Requested output format %#x and got %#x.",
2197                         mComponentName.c_str(), requestedColorFormat, colorFormat);
2198                 if (!IsFlexibleColorFormat(
2199                         mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
2200                         || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
2201                     // device did not handle flex-YUV request for native window, fall back
2202                     // to SW renderer
2203                     ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
2204                     mNativeWindow.clear();
2205                     mNativeWindowUsageBits = 0;
2206                     haveNativeWindow = false;
2207                     usingSwRenderer = true;
2208                     // TODO: implement adaptive-playback support for bytebuffer mode.
2209                     // This is done by SW codecs, but most HW codecs don't support it.
2210                     err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2211                     inputFormat->setInt32("adaptive-playback", false);
2212                     if (mFlags & kFlagIsGrallocUsageProtected) {
2213                         // fallback is not supported for protected playback
2214                         err = PERMISSION_DENIED;
2215                     } else if (err == OK) {
2216                         err = setupVideoDecoder(
2217                                 mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
2218                     }
2219                 }
2220             }
2221         }
2222 
2223         if (usingSwRenderer) {
2224             outputFormat->setInt32("using-sw-renderer", 1);
2225         }
2226     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) ||
2227         !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II)) {
2228         int32_t numChannels, sampleRate;
2229         if (!msg->findInt32("channel-count", &numChannels)
2230                 || !msg->findInt32("sample-rate", &sampleRate)) {
2231             // Since we did not always check for these, leave them optional
2232             // and have the decoder figure it all out.
2233             err = OK;
2234         } else {
2235             err = setupRawAudioFormat(
2236                     encoder ? kPortIndexInput : kPortIndexOutput,
2237                     sampleRate,
2238                     numChannels);
2239         }
2240     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2241         int32_t numChannels, sampleRate;
2242         if (!msg->findInt32("channel-count", &numChannels)
2243                 || !msg->findInt32("sample-rate", &sampleRate)) {
2244             err = INVALID_OPERATION;
2245         } else {
2246             int32_t isADTS, aacProfile;
2247             int32_t sbrMode;
2248             int32_t maxOutputChannelCount;
2249             int32_t pcmLimiterEnable;
2250             drcParams_t drc;
2251             if (!msg->findInt32("is-adts", &isADTS)) {
2252                 isADTS = 0;
2253             }
2254             if (!msg->findInt32("aac-profile", &aacProfile)) {
2255                 aacProfile = OMX_AUDIO_AACObjectNull;
2256             }
2257             if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2258                 sbrMode = -1;
2259             }
2260 
2261             if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
2262                 // check non AAC-specific key
2263                 if (!msg->findInt32("max-output-channel-count", &maxOutputChannelCount)) {
2264                     maxOutputChannelCount = -1;
2265                 }
2266             }
2267             if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
2268                 // value is unknown
2269                 pcmLimiterEnable = -1;
2270             }
2271             if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
2272                 // value is unknown
2273                 drc.encodedTargetLevel = -1;
2274             }
2275             if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
2276                 // value is unknown
2277                 drc.drcCut = -1;
2278             }
2279             if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
2280                 // value is unknown
2281                 drc.drcBoost = -1;
2282             }
2283             if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
2284                 // value is unknown
2285                 drc.heavyCompression = -1;
2286             }
2287             if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
2288                 // value is unknown
2289                 drc.targetRefLevel = -2;
2290             }
2291             if (!msg->findInt32("aac-drc-effect-type", &drc.effectType)) {
2292                 // value is unknown
2293                 drc.effectType = -2; // valid values are -1 and over
2294             }
2295             if (!msg->findInt32("aac-drc-album-mode", &drc.albumMode)) {
2296                 // value is unknown
2297                 drc.albumMode = -1; // valid values are 0 and 1
2298             }
2299             if (!msg->findInt32("aac-drc-output-loudness", &drc.outputLoudness)) {
2300                 // value is unknown
2301                 drc.outputLoudness = -1;
2302             }
2303 
2304             err = setupAACCodec(
2305                     encoder, numChannels, sampleRate, bitrate, aacProfile,
2306                     isADTS != 0, sbrMode, maxOutputChannelCount, drc,
2307                     pcmLimiterEnable);
2308         }
2309     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
2310         err = setupAMRCodec(encoder, false /* isWAMR */, bitrate);
2311     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
2312         err = setupAMRCodec(encoder, true /* isWAMR */, bitrate);
2313     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2314             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2315         // These are PCM-like formats with a fixed sample rate but
2316         // a variable number of channels.
2317 
2318         int32_t numChannels;
2319         if (!msg->findInt32("channel-count", &numChannels)) {
2320             err = INVALID_OPERATION;
2321         } else {
2322             int32_t sampleRate;
2323             if (!msg->findInt32("sample-rate", &sampleRate)) {
2324                 sampleRate = 8000;
2325             }
2326             err = setupG711Codec(encoder, sampleRate, numChannels);
2327         }
2328     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_OPUS)) {
2329         int32_t numChannels = 1, sampleRate = 48000;
2330         if (msg->findInt32("channel-count", &numChannels) &&
2331             msg->findInt32("sample-rate", &sampleRate)) {
2332             err = setupOpusCodec(encoder, sampleRate, numChannels);
2333         }
2334     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2335         // numChannels needs to be set to properly communicate PCM values.
2336         int32_t numChannels = 2, sampleRate = 44100, compressionLevel = -1;
2337         if (encoder &&
2338                 (!msg->findInt32("channel-count", &numChannels)
2339                         || !msg->findInt32("sample-rate", &sampleRate))) {
2340             ALOGE("missing channel count or sample rate for FLAC encoder");
2341             err = INVALID_OPERATION;
2342         } else {
2343             if (encoder) {
2344                 if (!msg->findInt32(
2345                             "complexity", &compressionLevel) &&
2346                     !msg->findInt32(
2347                             "flac-compression-level", &compressionLevel)) {
2348                     compressionLevel = 5; // default FLAC compression level
2349                 } else if (compressionLevel < 0) {
2350                     ALOGW("compression level %d outside [0..8] range, "
2351                           "using 0",
2352                           compressionLevel);
2353                     compressionLevel = 0;
2354                 } else if (compressionLevel > 8) {
2355                     ALOGW("compression level %d outside [0..8] range, "
2356                           "using 8",
2357                           compressionLevel);
2358                     compressionLevel = 8;
2359                 }
2360             }
2361             err = setupFlacCodec(
2362                     encoder, numChannels, sampleRate, compressionLevel, pcmEncoding);
2363         }
2364     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2365         int32_t numChannels, sampleRate;
2366         if (encoder
2367                 || !msg->findInt32("channel-count", &numChannels)
2368                 || !msg->findInt32("sample-rate", &sampleRate)) {
2369             err = INVALID_OPERATION;
2370         } else {
2371             err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2372         }
2373     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
2374         int32_t numChannels;
2375         int32_t sampleRate;
2376         if (!msg->findInt32("channel-count", &numChannels)
2377                 || !msg->findInt32("sample-rate", &sampleRate)) {
2378             err = INVALID_OPERATION;
2379         } else {
2380             err = setupAC3Codec(encoder, numChannels, sampleRate);
2381         }
2382     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
2383         int32_t numChannels;
2384         int32_t sampleRate;
2385         if (!msg->findInt32("channel-count", &numChannels)
2386                 || !msg->findInt32("sample-rate", &sampleRate)) {
2387             err = INVALID_OPERATION;
2388         } else {
2389             err = setupEAC3Codec(encoder, numChannels, sampleRate);
2390         }
2391      } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC4)) {
2392         int32_t numChannels;
2393         int32_t sampleRate;
2394         if (!msg->findInt32("channel-count", &numChannels)
2395                 || !msg->findInt32("sample-rate", &sampleRate)) {
2396             err = INVALID_OPERATION;
2397         } else {
2398             err = setupAC4Codec(encoder, numChannels, sampleRate);
2399         }
2400     }
2401 
2402     if (err != OK) {
2403         return err;
2404     }
2405 
2406     if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
2407         mEncoderDelay = 0;
2408     }
2409 
2410     if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
2411         mEncoderPadding = 0;
2412     }
2413 
2414     if (msg->findInt32("channel-mask", &mChannelMask)) {
2415         mChannelMaskPresent = true;
2416     } else {
2417         mChannelMaskPresent = false;
2418     }
2419 
2420     int32_t isCorruptFree = 0;
2421     if (msg->findInt32("corrupt-free", &isCorruptFree)) {
2422         mIsStreamCorruptFree = isCorruptFree == 1 ? true : false;
2423         ALOGV("corrupt-free=[%d]", mIsStreamCorruptFree);
2424     }
2425 
2426     int32_t maxInputSize;
2427     if (msg->findInt32("max-input-size", &maxInputSize)) {
2428         err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2429         err = OK; // ignore error
2430     } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
2431         err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2432         err = OK; // ignore error
2433     }
2434 
2435     int32_t priority;
2436     if (msg->findInt32("priority", &priority)) {
2437         err = setPriority(priority);
2438         err = OK; // ignore error
2439     }
2440 
2441     int32_t rateInt = -1;
2442     float rateFloat = -1;
2443     if (!msg->findFloat("operating-rate", &rateFloat)) {
2444         msg->findInt32("operating-rate", &rateInt);
2445         rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2446     }
2447     if (rateFloat > 0) {
2448         err = setOperatingRate(rateFloat, mIsVideo);
2449         err = OK; // ignore errors
2450     }
2451 
2452     if (err == OK) {
2453         err = setVendorParameters(msg);
2454         if (err != OK) {
2455             return err;
2456         }
2457     }
2458 
2459     // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
2460     mBaseOutputFormat = outputFormat;
2461     mLastOutputFormat.clear();
2462 
2463     err = getPortFormat(kPortIndexInput, inputFormat);
2464     if (err == OK) {
2465         err = getPortFormat(kPortIndexOutput, outputFormat);
2466         if (err == OK) {
2467             mInputFormat = inputFormat;
2468             mOutputFormat = outputFormat;
2469         }
2470     }
2471 
2472     // create data converters if needed
2473     if (!mIsVideo && !mIsImage && err == OK) {
2474         AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
2475         if (encoder) {
2476             (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
2477             mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
2478             if (mConverter[kPortIndexInput] != NULL) {
2479                 ALOGD("%s: encoder %s input format pcm encoding converter from %d to %d",
2480                         __func__, mComponentName.c_str(), pcmEncoding, codecPcmEncoding);
2481                 mInputFormat->setInt32("pcm-encoding", pcmEncoding);
2482             }
2483         } else {
2484             (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
2485             mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
2486             if (mConverter[kPortIndexOutput] != NULL) {
2487                 ALOGD("%s: decoder %s output format pcm encoding converter from %d to %d",
2488                         __func__, mComponentName.c_str(), codecPcmEncoding, pcmEncoding);
2489                 mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
2490             }
2491         }
2492     }
2493 
2494     return err;
2495 }
2496 
setLowLatency(int32_t lowLatency)2497 status_t ACodec::setLowLatency(int32_t lowLatency) {
2498     if (mIsEncoder) {
2499         ALOGE("encoder does not support low-latency");
2500         return BAD_VALUE;
2501     }
2502 
2503     OMX_CONFIG_BOOLEANTYPE config;
2504     InitOMXParams(&config);
2505     config.bEnabled = (OMX_BOOL)(lowLatency != 0);
2506     status_t err = mOMXNode->setConfig(
2507             (OMX_INDEXTYPE)OMX_IndexConfigLowLatency,
2508             &config, sizeof(config));
2509     if (err != OK) {
2510         ALOGE("decoder can not set low-latency to %d (err %d)", lowLatency, err);
2511     }
2512     mIsLowLatency = (lowLatency && err == OK);
2513     return err;
2514 }
2515 
setLatency(uint32_t latency)2516 status_t ACodec::setLatency(uint32_t latency) {
2517     OMX_PARAM_U32TYPE config;
2518     InitOMXParams(&config);
2519     config.nPortIndex = kPortIndexInput;
2520     config.nU32 = (OMX_U32)latency;
2521     status_t err = mOMXNode->setConfig(
2522             (OMX_INDEXTYPE)OMX_IndexConfigLatency,
2523             &config, sizeof(config));
2524     return err;
2525 }
2526 
getLatency(uint32_t * latency)2527 status_t ACodec::getLatency(uint32_t *latency) {
2528     OMX_PARAM_U32TYPE config;
2529     InitOMXParams(&config);
2530     config.nPortIndex = kPortIndexInput;
2531     status_t err = mOMXNode->getConfig(
2532             (OMX_INDEXTYPE)OMX_IndexConfigLatency,
2533             &config, sizeof(config));
2534     if (err == OK) {
2535         *latency = config.nU32;
2536     }
2537     return err;
2538 }
2539 
setTunnelPeek(int32_t tunnelPeek)2540 status_t ACodec::setTunnelPeek(int32_t tunnelPeek) {
2541     if (mIsEncoder) {
2542         ALOGE("encoder does not support %s", TUNNEL_PEEK_KEY);
2543         return BAD_VALUE;
2544     }
2545     if (!mTunneled) {
2546         ALOGE("%s is only supported in tunnel mode", TUNNEL_PEEK_KEY);
2547         return BAD_VALUE;
2548     }
2549 
2550     OMX_CONFIG_BOOLEANTYPE tunnelPeekConfig;
2551     InitOMXParams(&tunnelPeekConfig);
2552     tunnelPeekConfig.bEnabled = (OMX_BOOL)(tunnelPeek != 0);
2553     status_t err = mOMXNode->setConfig(
2554             (OMX_INDEXTYPE)OMX_IndexConfigAndroidTunnelPeek,
2555             &tunnelPeekConfig, sizeof(tunnelPeekConfig));
2556     if (err != OK) {
2557         ALOGE("decoder cannot set %s to %d (err %d)",
2558                 TUNNEL_PEEK_KEY, tunnelPeek, err);
2559     }
2560     return err;
2561 }
2562 
setTunnelPeekLegacy(int32_t isLegacy)2563 status_t ACodec::setTunnelPeekLegacy(int32_t isLegacy) {
2564     if (mIsEncoder) {
2565         ALOGE("encoder does not support %s", TUNNEL_PEEK_SET_LEGACY_KEY);
2566         return BAD_VALUE;
2567     }
2568     if (!mTunneled) {
2569         ALOGE("%s is only supported in tunnel mode", TUNNEL_PEEK_SET_LEGACY_KEY);
2570         return BAD_VALUE;
2571     }
2572 
2573     OMX_CONFIG_BOOLEANTYPE tunnelPeekLegacyModeConfig;
2574     InitOMXParams(&tunnelPeekLegacyModeConfig);
2575     tunnelPeekLegacyModeConfig.bEnabled = (OMX_BOOL)(isLegacy != 0);
2576     status_t err = mOMXNode->setConfig(
2577             (OMX_INDEXTYPE)OMX_IndexConfigAndroidTunnelPeekLegacyMode,
2578             &tunnelPeekLegacyModeConfig, sizeof(tunnelPeekLegacyModeConfig));
2579     if (err != OK) {
2580         ALOGE("decoder cannot set video peek legacy mode to %d (err %d)",
2581                 isLegacy,  err);
2582     }
2583     return err;
2584 }
2585 
setAudioPresentation(int32_t presentationId,int32_t programId)2586 status_t ACodec::setAudioPresentation(int32_t presentationId, int32_t programId) {
2587     OMX_AUDIO_CONFIG_ANDROID_AUDIOPRESENTATION config;
2588     InitOMXParams(&config);
2589     config.nPresentationId = (OMX_S32)presentationId;
2590     config.nProgramId = (OMX_S32)programId;
2591     status_t err = mOMXNode->setConfig(
2592             (OMX_INDEXTYPE)OMX_IndexConfigAudioPresentation,
2593             &config, sizeof(config));
2594     return err;
2595 }
2596 
setPriority(int32_t priority)2597 status_t ACodec::setPriority(int32_t priority) {
2598     if (priority < 0) {
2599         return BAD_VALUE;
2600     }
2601     OMX_PARAM_U32TYPE config;
2602     InitOMXParams(&config);
2603     config.nU32 = (OMX_U32)priority;
2604     status_t temp = mOMXNode->setConfig(
2605             (OMX_INDEXTYPE)OMX_IndexConfigPriority,
2606             &config, sizeof(config));
2607     if (temp != OK) {
2608         ALOGI("codec does not support config priority (err %d)", temp);
2609     }
2610     return OK;
2611 }
2612 
setOperatingRate(float rateFloat,bool isVideo)2613 status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2614     if (rateFloat < 0) {
2615         return BAD_VALUE;
2616     }
2617     OMX_U32 rate;
2618     if (isVideo) {
2619         if (rateFloat > 65535) {
2620             return BAD_VALUE;
2621         }
2622         rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2623     } else {
2624         if (rateFloat > (float)UINT_MAX) {
2625             return BAD_VALUE;
2626         }
2627         rate = (OMX_U32)(rateFloat);
2628     }
2629     OMX_PARAM_U32TYPE config;
2630     InitOMXParams(&config);
2631     config.nU32 = rate;
2632     status_t err = mOMXNode->setConfig(
2633             (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2634             &config, sizeof(config));
2635     if (err != OK) {
2636         ALOGI("codec does not support config operating rate (err %d)", err);
2637     }
2638     return OK;
2639 }
2640 
getIntraRefreshPeriod(uint32_t * intraRefreshPeriod)2641 status_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2642     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2643     InitOMXParams(&params);
2644     params.nPortIndex = kPortIndexOutput;
2645     status_t err = mOMXNode->getConfig(
2646             (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2647     if (err == OK) {
2648         *intraRefreshPeriod = params.nRefreshPeriod;
2649         return OK;
2650     }
2651 
2652     // Fallback to query through standard OMX index.
2653     OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2654     InitOMXParams(&refreshParams);
2655     refreshParams.nPortIndex = kPortIndexOutput;
2656     refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2657     err = mOMXNode->getParameter(
2658             OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2659     if (err != OK || refreshParams.nCirMBs == 0) {
2660         *intraRefreshPeriod = 0;
2661         return OK;
2662     }
2663 
2664     // Calculate period based on width and height
2665     uint32_t width, height;
2666     OMX_PARAM_PORTDEFINITIONTYPE def;
2667     InitOMXParams(&def);
2668     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2669     def.nPortIndex = kPortIndexOutput;
2670     err = mOMXNode->getParameter(
2671             OMX_IndexParamPortDefinition, &def, sizeof(def));
2672     if (err != OK) {
2673         *intraRefreshPeriod = 0;
2674         return err;
2675     }
2676     width = video_def->nFrameWidth;
2677     height = video_def->nFrameHeight;
2678     // Use H.264/AVC MacroBlock size 16x16
2679     *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2680 
2681     return OK;
2682 }
2683 
setIntraRefreshPeriod(uint32_t intraRefreshPeriod,bool inConfigure)2684 status_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2685     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2686     InitOMXParams(&params);
2687     params.nPortIndex = kPortIndexOutput;
2688     params.nRefreshPeriod = intraRefreshPeriod;
2689     status_t err = mOMXNode->setConfig(
2690             (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2691     if (err == OK) {
2692         return OK;
2693     }
2694 
2695     // Only in configure state, a component could invoke setParameter.
2696     if (!inConfigure) {
2697         return INVALID_OPERATION;
2698     } else {
2699         ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2700     }
2701 
2702     OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2703     InitOMXParams(&refreshParams);
2704     refreshParams.nPortIndex = kPortIndexOutput;
2705     refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2706 
2707     if (intraRefreshPeriod == 0) {
2708         // 0 means disable intra refresh.
2709         refreshParams.nCirMBs = 0;
2710     } else {
2711         // Calculate macroblocks that need to be intra coded base on width and height
2712         uint32_t width, height;
2713         OMX_PARAM_PORTDEFINITIONTYPE def;
2714         InitOMXParams(&def);
2715         OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2716         def.nPortIndex = kPortIndexOutput;
2717         err = mOMXNode->getParameter(
2718                 OMX_IndexParamPortDefinition, &def, sizeof(def));
2719         if (err != OK) {
2720             return err;
2721         }
2722         width = video_def->nFrameWidth;
2723         height = video_def->nFrameHeight;
2724         // Use H.264/AVC MacroBlock size 16x16
2725         refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2726     }
2727 
2728     err = mOMXNode->setParameter(
2729             OMX_IndexParamVideoIntraRefresh,
2730             &refreshParams, sizeof(refreshParams));
2731     if (err != OK) {
2732         return err;
2733     }
2734 
2735     return OK;
2736 }
2737 
configureTemporalLayers(const sp<AMessage> & msg,bool inConfigure,sp<AMessage> & outputFormat)2738 status_t ACodec::configureTemporalLayers(
2739         const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
2740     if (!mIsVideo || !mIsEncoder) {
2741         return INVALID_OPERATION;
2742     }
2743 
2744     AString tsSchema;
2745     if (!msg->findString("ts-schema", &tsSchema)) {
2746         return OK;
2747     }
2748 
2749     unsigned int numLayers = 0;
2750     unsigned int numBLayers = 0;
2751     int tags;
2752     char tmp;
2753     OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
2754         OMX_VIDEO_AndroidTemporalLayeringPatternNone;
2755     if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &tmp) == 1
2756             && numLayers > 0) {
2757         pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
2758     } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
2759                     &numLayers, &tmp, &numBLayers, &tmp))
2760             && (tags == 1 || (tags == 3 && tmp == '+'))
2761             && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
2762         numLayers += numBLayers;
2763         pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
2764     } else {
2765         ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
2766         return BAD_VALUE;
2767     }
2768 
2769     OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
2770     InitOMXParams(&layerParams);
2771     layerParams.nPortIndex = kPortIndexOutput;
2772 
2773     status_t err = mOMXNode->getParameter(
2774             (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2775             &layerParams, sizeof(layerParams));
2776 
2777     if (err != OK) {
2778         return err;
2779     } else if (!(layerParams.eSupportedPatterns & pattern)) {
2780         return BAD_VALUE;
2781     }
2782 
2783     numLayers = min(numLayers, layerParams.nLayerCountMax);
2784     numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
2785 
2786     if (!inConfigure) {
2787         OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
2788         InitOMXParams(&layerConfig);
2789         layerConfig.nPortIndex = kPortIndexOutput;
2790         layerConfig.ePattern = pattern;
2791         layerConfig.nPLayerCountActual = numLayers - numBLayers;
2792         layerConfig.nBLayerCountActual = numBLayers;
2793         layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
2794 
2795         err = mOMXNode->setConfig(
2796                 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
2797                 &layerConfig, sizeof(layerConfig));
2798     } else {
2799         layerParams.ePattern = pattern;
2800         layerParams.nPLayerCountActual = numLayers - numBLayers;
2801         layerParams.nBLayerCountActual = numBLayers;
2802         layerParams.bBitrateRatiosSpecified = OMX_FALSE;
2803         layerParams.nLayerCountMax = numLayers;
2804         layerParams.nBLayerCountMax = numBLayers;
2805 
2806         err = mOMXNode->setParameter(
2807                 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2808                 &layerParams, sizeof(layerParams));
2809     }
2810 
2811     AString configSchema;
2812     if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
2813         configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
2814     } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
2815         configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
2816     }
2817 
2818     if (err != OK) {
2819         ALOGW("Failed to set temporal layers to %s (requested %s)",
2820                 configSchema.c_str(), tsSchema.c_str());
2821         return err;
2822     }
2823 
2824     err = mOMXNode->getParameter(
2825             (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2826             &layerParams, sizeof(layerParams));
2827 
2828     if (err == OK) {
2829         ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
2830                 tsSchema.c_str(), configSchema.c_str(),
2831                 asString(layerParams.ePattern), layerParams.ePattern,
2832                 layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
2833 
2834         if (outputFormat.get() == mOutputFormat.get()) {
2835             mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
2836         }
2837         // assume we got what we configured
2838         outputFormat->setString("ts-schema", configSchema);
2839     }
2840     return err;
2841 }
2842 
setMinBufferSize(OMX_U32 portIndex,size_t size)2843 status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2844     OMX_PARAM_PORTDEFINITIONTYPE def;
2845     InitOMXParams(&def);
2846     def.nPortIndex = portIndex;
2847 
2848     status_t err = mOMXNode->getParameter(
2849             OMX_IndexParamPortDefinition, &def, sizeof(def));
2850 
2851     if (err != OK) {
2852         return err;
2853     }
2854 
2855     if (def.nBufferSize >= size) {
2856         return OK;
2857     }
2858 
2859     def.nBufferSize = size;
2860 
2861     err = mOMXNode->setParameter(
2862             OMX_IndexParamPortDefinition, &def, sizeof(def));
2863 
2864     if (err != OK) {
2865         return err;
2866     }
2867 
2868     err = mOMXNode->getParameter(
2869             OMX_IndexParamPortDefinition, &def, sizeof(def));
2870 
2871     if (err != OK) {
2872         return err;
2873     }
2874 
2875     if (def.nBufferSize < size) {
2876         ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2877         return FAILED_TRANSACTION;
2878     }
2879 
2880     return OK;
2881 }
2882 
selectAudioPortFormat(OMX_U32 portIndex,OMX_AUDIO_CODINGTYPE desiredFormat)2883 status_t ACodec::selectAudioPortFormat(
2884         OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
2885     OMX_AUDIO_PARAM_PORTFORMATTYPE format;
2886     InitOMXParams(&format);
2887 
2888     format.nPortIndex = portIndex;
2889     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2890         format.nIndex = index;
2891         status_t err = mOMXNode->getParameter(
2892                 OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2893 
2894         if (err != OK) {
2895             return err;
2896         }
2897 
2898         if (format.eEncoding == desiredFormat) {
2899             break;
2900         }
2901 
2902         if (index == kMaxIndicesToCheck) {
2903             ALOGW("[%s] stopping checking formats after %u: %s(%x)",
2904                     mComponentName.c_str(), index,
2905                     asString(format.eEncoding), format.eEncoding);
2906             return ERROR_UNSUPPORTED;
2907         }
2908     }
2909 
2910     return mOMXNode->setParameter(
2911             OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2912 }
2913 
setupAACCodec(bool encoder,int32_t numChannels,int32_t sampleRate,int32_t bitRate,int32_t aacProfile,bool isADTS,int32_t sbrMode,int32_t maxOutputChannelCount,const drcParams_t & drc,int32_t pcmLimiterEnable)2914 status_t ACodec::setupAACCodec(
2915         bool encoder, int32_t numChannels, int32_t sampleRate,
2916         int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
2917         int32_t maxOutputChannelCount, const drcParams_t& drc,
2918         int32_t pcmLimiterEnable) {
2919     if (encoder && isADTS) {
2920         return -EINVAL;
2921     }
2922 
2923     status_t err = setupRawAudioFormat(
2924             encoder ? kPortIndexInput : kPortIndexOutput,
2925             sampleRate,
2926             numChannels);
2927 
2928     if (err != OK) {
2929         return err;
2930     }
2931 
2932     if (encoder) {
2933         err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
2934 
2935         if (err != OK) {
2936             return err;
2937         }
2938 
2939         OMX_PARAM_PORTDEFINITIONTYPE def;
2940         InitOMXParams(&def);
2941         def.nPortIndex = kPortIndexOutput;
2942 
2943         err = mOMXNode->getParameter(
2944                 OMX_IndexParamPortDefinition, &def, sizeof(def));
2945 
2946         if (err != OK) {
2947             return err;
2948         }
2949 
2950         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
2951         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
2952 
2953         err = mOMXNode->setParameter(
2954                 OMX_IndexParamPortDefinition, &def, sizeof(def));
2955 
2956         if (err != OK) {
2957             return err;
2958         }
2959 
2960         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2961         InitOMXParams(&profile);
2962         profile.nPortIndex = kPortIndexOutput;
2963 
2964         err = mOMXNode->getParameter(
2965                 OMX_IndexParamAudioAac, &profile, sizeof(profile));
2966 
2967         if (err != OK) {
2968             return err;
2969         }
2970 
2971         profile.nChannels = numChannels;
2972 
2973         profile.eChannelMode =
2974             (numChannels == 1)
2975                 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
2976 
2977         profile.nSampleRate = sampleRate;
2978         profile.nBitRate = bitRate;
2979         profile.nAudioBandWidth = 0;
2980         profile.nFrameLength = 0;
2981         profile.nAACtools = OMX_AUDIO_AACToolAll;
2982         profile.nAACERtools = OMX_AUDIO_AACERNone;
2983         profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
2984         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2985         switch (sbrMode) {
2986         case 0:
2987             // disable sbr
2988             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2989             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2990             break;
2991         case 1:
2992             // enable single-rate sbr
2993             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2994             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2995             break;
2996         case 2:
2997             // enable dual-rate sbr
2998             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2999             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
3000             break;
3001         case -1:
3002             // enable both modes -> the codec will decide which mode should be used
3003             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
3004             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
3005             break;
3006         default:
3007             // unsupported sbr mode
3008             return BAD_VALUE;
3009         }
3010 
3011 
3012         err = mOMXNode->setParameter(
3013                 OMX_IndexParamAudioAac, &profile, sizeof(profile));
3014 
3015         if (err != OK) {
3016             return err;
3017         }
3018 
3019         return err;
3020     }
3021 
3022     OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3023     InitOMXParams(&profile);
3024     profile.nPortIndex = kPortIndexInput;
3025 
3026     err = mOMXNode->getParameter(
3027             OMX_IndexParamAudioAac, &profile, sizeof(profile));
3028 
3029     if (err != OK) {
3030         return err;
3031     }
3032 
3033     profile.nChannels = numChannels;
3034     profile.nSampleRate = sampleRate;
3035 
3036     profile.eAACStreamFormat =
3037         isADTS
3038             ? OMX_AUDIO_AACStreamFormatMP4ADTS
3039             : OMX_AUDIO_AACStreamFormatMP4FF;
3040 
3041     OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
3042     InitOMXParams(&presentation);
3043     presentation.nMaxOutputChannels = maxOutputChannelCount;
3044     presentation.nDrcCut = drc.drcCut;
3045     presentation.nDrcBoost = drc.drcBoost;
3046     presentation.nHeavyCompression = drc.heavyCompression;
3047     presentation.nTargetReferenceLevel = drc.targetRefLevel;
3048     presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
3049     presentation.nPCMLimiterEnable = pcmLimiterEnable;
3050     presentation.nDrcEffectType = drc.effectType;
3051     presentation.nDrcAlbumMode = drc.albumMode;
3052     presentation.nDrcOutputLoudness = drc.outputLoudness;
3053 
3054     status_t res = mOMXNode->setParameter(
3055             OMX_IndexParamAudioAac, &profile, sizeof(profile));
3056     if (res == OK) {
3057         // optional parameters, will not cause configuration failure
3058         if (mOMXNode->setParameter(
3059                 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
3060                 &presentation, sizeof(presentation)) == ERROR_UNSUPPORTED) {
3061             // prior to 9.0 we used a different config structure and index
3062             OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation8;
3063             InitOMXParams(&presentation8);
3064             presentation8.nMaxOutputChannels = presentation.nMaxOutputChannels;
3065             presentation8.nDrcCut = presentation.nDrcCut;
3066             presentation8.nDrcBoost = presentation.nDrcBoost;
3067             presentation8.nHeavyCompression = presentation.nHeavyCompression;
3068             presentation8.nTargetReferenceLevel = presentation.nTargetReferenceLevel;
3069             presentation8.nEncodedTargetLevel = presentation.nEncodedTargetLevel;
3070             presentation8.nPCMLimiterEnable = presentation.nPCMLimiterEnable;
3071             (void)mOMXNode->setParameter(
3072                 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
3073                 &presentation8, sizeof(presentation8));
3074         }
3075     } else {
3076         ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
3077     }
3078     mSampleRate = sampleRate;
3079     return res;
3080 }
3081 
setupAC3Codec(bool encoder,int32_t numChannels,int32_t sampleRate)3082 status_t ACodec::setupAC3Codec(
3083         bool encoder, int32_t numChannels, int32_t sampleRate) {
3084     status_t err = setupRawAudioFormat(
3085             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
3086 
3087     if (err != OK) {
3088         return err;
3089     }
3090 
3091     if (encoder) {
3092         ALOGW("AC3 encoding is not supported.");
3093         return INVALID_OPERATION;
3094     }
3095 
3096     OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
3097     InitOMXParams(&def);
3098     def.nPortIndex = kPortIndexInput;
3099 
3100     err = mOMXNode->getParameter(
3101             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
3102 
3103     if (err != OK) {
3104         return err;
3105     }
3106 
3107     def.nChannels = numChannels;
3108     def.nSampleRate = sampleRate;
3109 
3110     return mOMXNode->setParameter(
3111             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
3112 }
3113 
setupEAC3Codec(bool encoder,int32_t numChannels,int32_t sampleRate)3114 status_t ACodec::setupEAC3Codec(
3115         bool encoder, int32_t numChannels, int32_t sampleRate) {
3116     status_t err = setupRawAudioFormat(
3117             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
3118 
3119     if (err != OK) {
3120         return err;
3121     }
3122 
3123     if (encoder) {
3124         ALOGW("EAC3 encoding is not supported.");
3125         return INVALID_OPERATION;
3126     }
3127 
3128     OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
3129     InitOMXParams(&def);
3130     def.nPortIndex = kPortIndexInput;
3131 
3132     err = mOMXNode->getParameter(
3133             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
3134 
3135     if (err != OK) {
3136         return err;
3137     }
3138 
3139     def.nChannels = numChannels;
3140     def.nSampleRate = sampleRate;
3141 
3142     return mOMXNode->setParameter(
3143             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
3144 }
3145 
setupAC4Codec(bool encoder,int32_t numChannels,int32_t sampleRate)3146 status_t ACodec::setupAC4Codec(
3147         bool encoder, int32_t numChannels, int32_t sampleRate) {
3148     status_t err = setupRawAudioFormat(
3149             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
3150 
3151     if (err != OK) {
3152         return err;
3153     }
3154 
3155     if (encoder) {
3156         ALOGW("AC4 encoding is not supported.");
3157         return INVALID_OPERATION;
3158     }
3159 
3160     OMX_AUDIO_PARAM_ANDROID_AC4TYPE def;
3161     InitOMXParams(&def);
3162     def.nPortIndex = kPortIndexInput;
3163 
3164     err = mOMXNode->getParameter(
3165             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc4, &def, sizeof(def));
3166 
3167     if (err != OK) {
3168         return err;
3169     }
3170 
3171     def.nChannels = numChannels;
3172     def.nSampleRate = sampleRate;
3173 
3174     return mOMXNode->setParameter(
3175             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc4, &def, sizeof(def));
3176 }
3177 
pickModeFromBitRate(bool isAMRWB,int32_t bps)3178 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
3179         bool isAMRWB, int32_t bps) {
3180     if (isAMRWB) {
3181         if (bps <= 6600) {
3182             return OMX_AUDIO_AMRBandModeWB0;
3183         } else if (bps <= 8850) {
3184             return OMX_AUDIO_AMRBandModeWB1;
3185         } else if (bps <= 12650) {
3186             return OMX_AUDIO_AMRBandModeWB2;
3187         } else if (bps <= 14250) {
3188             return OMX_AUDIO_AMRBandModeWB3;
3189         } else if (bps <= 15850) {
3190             return OMX_AUDIO_AMRBandModeWB4;
3191         } else if (bps <= 18250) {
3192             return OMX_AUDIO_AMRBandModeWB5;
3193         } else if (bps <= 19850) {
3194             return OMX_AUDIO_AMRBandModeWB6;
3195         } else if (bps <= 23050) {
3196             return OMX_AUDIO_AMRBandModeWB7;
3197         }
3198 
3199         // 23850 bps
3200         return OMX_AUDIO_AMRBandModeWB8;
3201     } else {  // AMRNB
3202         if (bps <= 4750) {
3203             return OMX_AUDIO_AMRBandModeNB0;
3204         } else if (bps <= 5150) {
3205             return OMX_AUDIO_AMRBandModeNB1;
3206         } else if (bps <= 5900) {
3207             return OMX_AUDIO_AMRBandModeNB2;
3208         } else if (bps <= 6700) {
3209             return OMX_AUDIO_AMRBandModeNB3;
3210         } else if (bps <= 7400) {
3211             return OMX_AUDIO_AMRBandModeNB4;
3212         } else if (bps <= 7950) {
3213             return OMX_AUDIO_AMRBandModeNB5;
3214         } else if (bps <= 10200) {
3215             return OMX_AUDIO_AMRBandModeNB6;
3216         }
3217 
3218         // 12200 bps
3219         return OMX_AUDIO_AMRBandModeNB7;
3220     }
3221 }
3222 
setupAMRCodec(bool encoder,bool isWAMR,int32_t bitrate)3223 status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
3224     OMX_AUDIO_PARAM_AMRTYPE def;
3225     InitOMXParams(&def);
3226     def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
3227 
3228     status_t err = mOMXNode->getParameter(
3229             OMX_IndexParamAudioAmr, &def, sizeof(def));
3230 
3231     if (err != OK) {
3232         return err;
3233     }
3234 
3235     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
3236     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
3237 
3238     err = mOMXNode->setParameter(
3239             OMX_IndexParamAudioAmr, &def, sizeof(def));
3240 
3241     if (err != OK) {
3242         return err;
3243     }
3244 
3245     return setupRawAudioFormat(
3246             encoder ? kPortIndexInput : kPortIndexOutput,
3247             isWAMR ? 16000 : 8000 /* sampleRate */,
3248             1 /* numChannels */);
3249 }
3250 
setupG711Codec(bool encoder,int32_t sampleRate,int32_t numChannels)3251 status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
3252     if (encoder) {
3253         return INVALID_OPERATION;
3254     }
3255 
3256     return setupRawAudioFormat(
3257             kPortIndexInput, sampleRate, numChannels);
3258 }
3259 
setupOpusCodec(bool encoder,int32_t sampleRate,int32_t numChannels)3260 status_t ACodec::setupOpusCodec(bool encoder, int32_t sampleRate, int32_t numChannels) {
3261     if (encoder) {
3262         return INVALID_OPERATION;
3263     }
3264     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE def;
3265     InitOMXParams(&def);
3266     def.nPortIndex = kPortIndexInput;
3267     status_t err = mOMXNode->getParameter(
3268             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def));
3269     if (err != OK) {
3270         ALOGE("setupOpusCodec(): Error %d getting OMX_IndexParamAudioAndroidOpus parameter", err);
3271         return err;
3272     }
3273     def.nSampleRate = sampleRate;
3274     def.nChannels = numChannels;
3275     err = mOMXNode->setParameter(
3276            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus, &def, sizeof(def));
3277     return err;
3278 }
3279 
setupFlacCodec(bool encoder,int32_t numChannels,int32_t sampleRate,int32_t compressionLevel,AudioEncoding encoding)3280 status_t ACodec::setupFlacCodec(
3281         bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
3282         AudioEncoding encoding) {
3283     if (encoder) {
3284         OMX_AUDIO_PARAM_FLACTYPE def;
3285         InitOMXParams(&def);
3286         def.nPortIndex = kPortIndexOutput;
3287 
3288         // configure compression level
3289         status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
3290         if (err != OK) {
3291             ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
3292             return err;
3293         }
3294         def.nCompressionLevel = compressionLevel;
3295         err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
3296         if (err != OK) {
3297             ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
3298             return err;
3299         }
3300     }
3301 
3302     return setupRawAudioFormat(
3303             encoder ? kPortIndexInput : kPortIndexOutput,
3304             sampleRate,
3305             numChannels,
3306             encoding);
3307 }
3308 
setupRawAudioFormat(OMX_U32 portIndex,int32_t sampleRate,int32_t numChannels,AudioEncoding encoding)3309 status_t ACodec::setupRawAudioFormat(
3310         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
3311     OMX_PARAM_PORTDEFINITIONTYPE def;
3312     InitOMXParams(&def);
3313     def.nPortIndex = portIndex;
3314 
3315     status_t err = mOMXNode->getParameter(
3316             OMX_IndexParamPortDefinition, &def, sizeof(def));
3317 
3318     if (err != OK) {
3319         return err;
3320     }
3321 
3322     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
3323 
3324     err = mOMXNode->setParameter(
3325             OMX_IndexParamPortDefinition, &def, sizeof(def));
3326 
3327     if (err != OK) {
3328         return err;
3329     }
3330 
3331     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
3332     InitOMXParams(&pcmParams);
3333     pcmParams.nPortIndex = portIndex;
3334 
3335     err = mOMXNode->getParameter(
3336             OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3337 
3338     if (err != OK) {
3339         return err;
3340     }
3341 
3342     pcmParams.nChannels = numChannels;
3343     switch (encoding) {
3344         case kAudioEncodingPcm8bit:
3345             pcmParams.eNumData = OMX_NumericalDataUnsigned;
3346             pcmParams.nBitPerSample = 8;
3347             break;
3348         case kAudioEncodingPcmFloat:
3349             pcmParams.eNumData = OMX_NumericalDataFloat;
3350             pcmParams.nBitPerSample = 32;
3351             break;
3352         case kAudioEncodingPcm16bit:
3353             pcmParams.eNumData = OMX_NumericalDataSigned;
3354             pcmParams.nBitPerSample = 16;
3355             break;
3356         default:
3357             return BAD_VALUE;
3358     }
3359     pcmParams.bInterleaved = OMX_TRUE;
3360     pcmParams.nSamplingRate = sampleRate;
3361     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3362 
3363     if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
3364         ALOGE("%s: incorrect numChannels: %d", __func__, numChannels);
3365         return OMX_ErrorNone;
3366     }
3367 
3368     err = mOMXNode->setParameter(
3369             OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3370     // if we could not set up raw format to non-16-bit, try with 16-bit
3371     // NOTE: we will also verify this via readback, in case codec ignores these fields
3372     if (err != OK && encoding != kAudioEncodingPcm16bit) {
3373         pcmParams.eNumData = OMX_NumericalDataSigned;
3374         pcmParams.nBitPerSample = 16;
3375         err = mOMXNode->setParameter(
3376                 OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3377     }
3378     return err;
3379 }
3380 
configureTunneledVideoPlayback(int32_t audioHwSync,const sp<ANativeWindow> & nativeWindow)3381 status_t ACodec::configureTunneledVideoPlayback(
3382         int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
3383     native_handle_t* sidebandHandle;
3384 
3385     status_t err = mOMXNode->configureVideoTunnelMode(
3386             kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
3387     if (err != OK) {
3388         ALOGE("configureVideoTunnelMode failed! (err %d).", err);
3389         return err;
3390     }
3391 
3392     err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
3393     if (err != OK) {
3394         ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
3395                 sidebandHandle, err);
3396     }
3397 
3398     native_handle_close(sidebandHandle);
3399     native_handle_delete(sidebandHandle);
3400 
3401     return err;
3402 }
3403 
setVideoPortFormatType(OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE compressionFormat,OMX_COLOR_FORMATTYPE colorFormat,bool usingNativeBuffers)3404 status_t ACodec::setVideoPortFormatType(
3405         OMX_U32 portIndex,
3406         OMX_VIDEO_CODINGTYPE compressionFormat,
3407         OMX_COLOR_FORMATTYPE colorFormat,
3408         bool usingNativeBuffers) {
3409     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
3410     InitOMXParams(&format);
3411     format.nPortIndex = portIndex;
3412     format.nIndex = 0;
3413     bool found = false;
3414 
3415     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
3416         format.nIndex = index;
3417         status_t err = mOMXNode->getParameter(
3418                 OMX_IndexParamVideoPortFormat,
3419                 &format, sizeof(format));
3420 
3421         if (err != OK) {
3422             return err;
3423         }
3424 
3425         // substitute back flexible color format to codec supported format
3426         OMX_U32 flexibleEquivalent;
3427         if (compressionFormat == OMX_VIDEO_CodingUnused
3428                 && IsFlexibleColorFormat(
3429                         mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
3430                 && colorFormat == flexibleEquivalent) {
3431             ALOGI("[%s] using color format %#x in place of %#x",
3432                     mComponentName.c_str(), format.eColorFormat, colorFormat);
3433             colorFormat = format.eColorFormat;
3434         }
3435 
3436         // The following assertion is violated by TI's video decoder.
3437         // CHECK_EQ(format.nIndex, index);
3438 
3439         if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
3440             if (portIndex == kPortIndexInput
3441                     && colorFormat == format.eColorFormat) {
3442                 // eCompressionFormat does not seem right.
3443                 found = true;
3444                 break;
3445             }
3446             if (portIndex == kPortIndexOutput
3447                     && compressionFormat == format.eCompressionFormat) {
3448                 // eColorFormat does not seem right.
3449                 found = true;
3450                 break;
3451             }
3452         }
3453 
3454         if (format.eCompressionFormat == compressionFormat
3455             && format.eColorFormat == colorFormat) {
3456             found = true;
3457             break;
3458         }
3459 
3460         if (index == kMaxIndicesToCheck) {
3461             ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
3462                     mComponentName.c_str(), index,
3463                     asString(format.eCompressionFormat), format.eCompressionFormat,
3464                     asString(format.eColorFormat), format.eColorFormat);
3465         }
3466     }
3467 
3468     if (!found) {
3469         return UNKNOWN_ERROR;
3470     }
3471 
3472     status_t err = mOMXNode->setParameter(
3473             OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3474 
3475     return err;
3476 }
3477 
3478 // Set optimal output format. OMX component lists output formats in the order
3479 // of preference, but this got more complicated since the introduction of flexible
3480 // YUV formats. We support a legacy behavior for applications that do not use
3481 // surface output, do not specify an output format, but expect a "usable" standard
3482 // OMX format. SW readable and standard formats must be flex-YUV.
3483 //
3484 // Suggested preference order:
3485 // - optimal format for texture rendering (mediaplayer behavior)
3486 // - optimal SW readable & texture renderable format (flex-YUV support)
3487 // - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
3488 // - legacy "usable" standard formats
3489 //
3490 // For legacy support, we prefer a standard format, but will settle for a SW readable
3491 // flex-YUV format.
setSupportedOutputFormat(bool getLegacyFlexibleFormat)3492 status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
3493     OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3494     InitOMXParams(&format);
3495     format.nPortIndex = kPortIndexOutput;
3496 
3497     InitOMXParams(&legacyFormat);
3498     // this field will change when we find a suitable legacy format
3499     legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3500 
3501     for (OMX_U32 index = 0; ; ++index) {
3502         format.nIndex = index;
3503         status_t err = mOMXNode->getParameter(
3504                 OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3505         if (err != OK) {
3506             // no more formats, pick legacy format if found
3507             if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
3508                  memcpy(&format, &legacyFormat, sizeof(format));
3509                  break;
3510             }
3511             return err;
3512         }
3513         if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
3514             return OMX_ErrorBadParameter;
3515         }
3516         if (!getLegacyFlexibleFormat) {
3517             break;
3518         }
3519         // standard formats that were exposed to users before
3520         if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
3521                 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
3522                 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
3523                 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
3524                 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
3525             break;
3526         }
3527         // find best legacy non-standard format
3528         OMX_U32 flexibleEquivalent;
3529         if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
3530                 && IsFlexibleColorFormat(
3531                         mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
3532                         &flexibleEquivalent)
3533                 && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
3534             memcpy(&legacyFormat, &format, sizeof(format));
3535         }
3536     }
3537     return mOMXNode->setParameter(
3538             OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3539 }
3540 
3541 static const struct VideoCodingMapEntry {
3542     const char *mMime;
3543     OMX_VIDEO_CODINGTYPE mVideoCodingType;
3544 } kVideoCodingMapEntry[] = {
3545     { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
3546     { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3547     { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3548     { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3549     { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
3550     { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
3551     { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3552     { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3553     { MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, OMX_VIDEO_CodingImageHEIC },
3554     { MEDIA_MIMETYPE_VIDEO_AV1, OMX_VIDEO_CodingAV1 },
3555 };
3556 
GetVideoCodingTypeFromMime(const char * mime,OMX_VIDEO_CODINGTYPE * codingType)3557 static status_t GetVideoCodingTypeFromMime(
3558         const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3559     for (size_t i = 0;
3560          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3561          ++i) {
3562         if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3563             *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3564             return OK;
3565         }
3566     }
3567 
3568     *codingType = OMX_VIDEO_CodingUnused;
3569 
3570     return ERROR_UNSUPPORTED;
3571 }
3572 
GetMimeTypeForVideoCoding(OMX_VIDEO_CODINGTYPE codingType,AString * mime)3573 static status_t GetMimeTypeForVideoCoding(
3574         OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3575     for (size_t i = 0;
3576          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3577          ++i) {
3578         if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3579             *mime = kVideoCodingMapEntry[i].mMime;
3580             return OK;
3581         }
3582     }
3583 
3584     mime->clear();
3585 
3586     return ERROR_UNSUPPORTED;
3587 }
3588 
setPortBufferNum(OMX_U32 portIndex,int bufferNum)3589 status_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3590     OMX_PARAM_PORTDEFINITIONTYPE def;
3591     InitOMXParams(&def);
3592     def.nPortIndex = portIndex;
3593     status_t err;
3594     ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3595             portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3596     err = mOMXNode->getParameter(
3597         OMX_IndexParamPortDefinition, &def, sizeof(def));
3598     if (err != OK) {
3599         return err;
3600     }
3601     def.nBufferCountActual = bufferNum;
3602     err = mOMXNode->setParameter(
3603         OMX_IndexParamPortDefinition, &def, sizeof(def));
3604     if (err != OK) {
3605         // Component could reject this request.
3606         ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3607             portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3608     }
3609     return OK;
3610 }
3611 
setupVideoDecoder(const char * mime,const sp<AMessage> & msg,bool haveNativeWindow,bool usingSwRenderer,sp<AMessage> & outputFormat)3612 status_t ACodec::setupVideoDecoder(
3613         const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3614         bool usingSwRenderer, sp<AMessage> &outputFormat) {
3615     int32_t width, height;
3616     if (!msg->findInt32("width", &width)
3617             || !msg->findInt32("height", &height)) {
3618         return INVALID_OPERATION;
3619     }
3620 
3621     OMX_VIDEO_CODINGTYPE compressionFormat;
3622     status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
3623 
3624     if (err != OK) {
3625         return err;
3626     }
3627 
3628     if (compressionFormat == OMX_VIDEO_CodingHEVC) {
3629         int32_t profile;
3630         if (msg->findInt32("profile", &profile)) {
3631             // verify if Main10 profile is supported at all, and fail
3632             // immediately if it's not supported.
3633             if (profile == OMX_VIDEO_HEVCProfileMain10 ||
3634                 profile == OMX_VIDEO_HEVCProfileMain10HDR10) {
3635                 err = verifySupportForProfileAndLevel(
3636                         kPortIndexInput, profile, 0);
3637                 if (err != OK) {
3638                     return err;
3639                 }
3640             }
3641         }
3642     }
3643 
3644     if (compressionFormat == OMX_VIDEO_CodingVP9) {
3645         OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3646         InitOMXParams(&params);
3647         params.nPortIndex = kPortIndexInput;
3648         // Check if VP9 decoder advertises supported profiles.
3649         params.nProfileIndex = 0;
3650         status_t err = mOMXNode->getParameter(
3651                 OMX_IndexParamVideoProfileLevelQuerySupported,
3652                 &params, sizeof(params));
3653         mIsLegacyVP9Decoder = err != OK;
3654     }
3655 
3656     err = setVideoPortFormatType(
3657             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3658 
3659     if (err != OK) {
3660         return err;
3661     }
3662 
3663     int32_t tmp;
3664     if (msg->findInt32("color-format", &tmp)) {
3665         OMX_COLOR_FORMATTYPE colorFormat =
3666             static_cast<OMX_COLOR_FORMATTYPE>(tmp);
3667         err = setVideoPortFormatType(
3668                 kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
3669         if (err != OK) {
3670             ALOGW("[%s] does not support color format %d",
3671                   mComponentName.c_str(), colorFormat);
3672             err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
3673         }
3674     } else {
3675         err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
3676     }
3677 
3678     if (err != OK) {
3679         return err;
3680     }
3681 
3682     // Set the component input buffer number to be |tmp|. If succeed,
3683     // component will set input port buffer number to be |tmp|. If fail,
3684     // component will keep the same buffer number as before.
3685     if (msg->findInt32("android._num-input-buffers", &tmp)) {
3686         err = setPortBufferNum(kPortIndexInput, tmp);
3687         if (err != OK)
3688             return err;
3689     }
3690 
3691     // Set the component output buffer number to be |tmp|. If succeed,
3692     // component will set output port buffer number to be |tmp|. If fail,
3693     // component will keep the same buffer number as before.
3694     if (msg->findInt32("android._num-output-buffers", &tmp)) {
3695         err = setPortBufferNum(kPortIndexOutput, tmp);
3696         if (err != OK)
3697             return err;
3698     }
3699 
3700     int32_t frameRateInt;
3701     float frameRateFloat;
3702     if (!msg->findFloat("frame-rate", &frameRateFloat)) {
3703         if (!msg->findInt32("frame-rate", &frameRateInt)) {
3704             frameRateInt = -1;
3705         }
3706         frameRateFloat = (float)frameRateInt;
3707     }
3708 
3709     err = setVideoFormatOnPort(
3710             kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3711 
3712     if (err != OK) {
3713         return err;
3714     }
3715 
3716     err = setVideoFormatOnPort(
3717             kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3718 
3719     if (err != OK) {
3720         return err;
3721     }
3722 
3723     err = setColorAspectsForVideoDecoder(
3724             width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3725     if (err == ERROR_UNSUPPORTED) { // support is optional
3726         err = OK;
3727     }
3728 
3729     if (err != OK) {
3730         return err;
3731     }
3732 
3733     err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3734     if (err == ERROR_UNSUPPORTED) { // support is optional
3735         err = OK;
3736     }
3737     return err;
3738 }
3739 
initDescribeColorAspectsIndex()3740 status_t ACodec::initDescribeColorAspectsIndex() {
3741     status_t err = mOMXNode->getExtensionIndex(
3742             "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3743     if (err != OK) {
3744         mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3745     }
3746     return err;
3747 }
3748 
setCodecColorAspects(DescribeColorAspectsParams & params,bool verify)3749 status_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3750     status_t err = ERROR_UNSUPPORTED;
3751     if (mDescribeColorAspectsIndex) {
3752         err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3753     }
3754     ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3755             mComponentName.c_str(),
3756             params.sAspects.mRange, asString(params.sAspects.mRange),
3757             params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3758             params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3759             params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3760             err, asString(err));
3761 
3762     if (verify && err == OK) {
3763         err = getCodecColorAspects(params);
3764     }
3765 
3766     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3767             "[%s] setting color aspects failed even though codec advertises support",
3768             mComponentName.c_str());
3769     return err;
3770 }
3771 
setColorAspectsForVideoDecoder(int32_t width,int32_t height,bool usingNativeWindow,const sp<AMessage> & configFormat,sp<AMessage> & outputFormat)3772 status_t ACodec::setColorAspectsForVideoDecoder(
3773         int32_t width, int32_t height, bool usingNativeWindow,
3774         const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
3775     DescribeColorAspectsParams params;
3776     InitOMXParams(&params);
3777     params.nPortIndex = kPortIndexOutput;
3778 
3779     getColorAspectsFromFormat(configFormat, params.sAspects);
3780     if (usingNativeWindow) {
3781         setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3782         // The default aspects will be set back to the output format during the
3783         // getFormat phase of configure(). Set non-Unspecified values back into the
3784         // format, in case component does not support this enumeration.
3785         setColorAspectsIntoFormat(params.sAspects, outputFormat);
3786     }
3787 
3788     (void)initDescribeColorAspectsIndex();
3789 
3790     // communicate color aspects to codec
3791     return setCodecColorAspects(params);
3792 }
3793 
getCodecColorAspects(DescribeColorAspectsParams & params)3794 status_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3795     status_t err = ERROR_UNSUPPORTED;
3796     if (mDescribeColorAspectsIndex) {
3797         err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3798     }
3799     ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3800             mComponentName.c_str(),
3801             params.sAspects.mRange, asString(params.sAspects.mRange),
3802             params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3803             params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3804             params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3805             err, asString(err));
3806     if (params.bRequestingDataSpace) {
3807         ALOGV("for dataspace %#x", params.nDataSpace);
3808     }
3809     if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3810             && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3811         ALOGW("[%s] getting color aspects failed even though codec advertises support",
3812                 mComponentName.c_str());
3813     }
3814     return err;
3815 }
3816 
getInputColorAspectsForVideoEncoder(sp<AMessage> & format)3817 status_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3818     DescribeColorAspectsParams params;
3819     InitOMXParams(&params);
3820     params.nPortIndex = kPortIndexInput;
3821     status_t err = getCodecColorAspects(params);
3822     if (err == OK) {
3823         // we only set encoder input aspects if codec supports them
3824         setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
3825     }
3826     return err;
3827 }
3828 
getDataSpace(DescribeColorAspectsParams & params,android_dataspace * dataSpace,bool tryCodec)3829 status_t ACodec::getDataSpace(
3830         DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3831         bool tryCodec) {
3832     status_t err = OK;
3833     if (tryCodec) {
3834         // request dataspace guidance from codec.
3835         params.bRequestingDataSpace = OMX_TRUE;
3836         err = getCodecColorAspects(params);
3837         params.bRequestingDataSpace = OMX_FALSE;
3838         if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3839             *dataSpace = (android_dataspace)params.nDataSpace;
3840             return err;
3841         } else if (err == ERROR_UNSUPPORTED) {
3842             // ignore not-implemented error for dataspace requests
3843             err = OK;
3844         }
3845     }
3846 
3847     // this returns legacy versions if available
3848     *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3849     ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3850           "and dataspace %#x",
3851             mComponentName.c_str(),
3852             params.sAspects.mRange, asString(params.sAspects.mRange),
3853             params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3854             params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3855             params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3856             *dataSpace);
3857     return err;
3858 }
3859 
3860 
getColorAspectsAndDataSpaceForVideoDecoder(int32_t width,int32_t height,const sp<AMessage> & configFormat,sp<AMessage> & outputFormat,android_dataspace * dataSpace)3861 status_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3862         int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3863         android_dataspace *dataSpace) {
3864     DescribeColorAspectsParams params;
3865     InitOMXParams(&params);
3866     params.nPortIndex = kPortIndexOutput;
3867 
3868     // reset default format and get resulting format
3869     getColorAspectsFromFormat(configFormat, params.sAspects);
3870     if (dataSpace != NULL) {
3871         setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3872     }
3873     status_t err = setCodecColorAspects(params, true /* readBack */);
3874 
3875     // we always set specified aspects for decoders
3876     setColorAspectsIntoFormat(params.sAspects, outputFormat);
3877 
3878     if (dataSpace != NULL) {
3879         status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3880         if (err == OK) {
3881             err = res;
3882         }
3883     }
3884 
3885     return err;
3886 }
3887 
3888 // initial video encoder setup for bytebuffer mode
setColorAspectsForVideoEncoder(const sp<AMessage> & configFormat,sp<AMessage> & outputFormat,sp<AMessage> & inputFormat)3889 status_t ACodec::setColorAspectsForVideoEncoder(
3890         const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3891     // copy config to output format as this is not exposed via getFormat
3892     copyColorConfig(configFormat, outputFormat);
3893 
3894     DescribeColorAspectsParams params;
3895     InitOMXParams(&params);
3896     params.nPortIndex = kPortIndexInput;
3897     getColorAspectsFromFormat(configFormat, params.sAspects);
3898 
3899     (void)initDescribeColorAspectsIndex();
3900 
3901     int32_t usingRecorder;
3902     if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3903         android_dataspace dataSpace = HAL_DATASPACE_BT709;
3904         int32_t width, height;
3905         if (configFormat->findInt32("width", &width)
3906                 && configFormat->findInt32("height", &height)) {
3907             setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3908             status_t err = getDataSpace(
3909                     params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3910             if (err != OK) {
3911                 return err;
3912             }
3913             setColorAspectsIntoFormat(params.sAspects, outputFormat);
3914         }
3915         inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
3916     }
3917 
3918     // communicate color aspects to codec, but do not allow change of the platform aspects
3919     ColorAspects origAspects = params.sAspects;
3920     for (int triesLeft = 2; --triesLeft >= 0; ) {
3921         status_t err = setCodecColorAspects(params, true /* readBack */);
3922         if (err != OK
3923                 || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3924                         params.sAspects, origAspects, true /* usePlatformAspects */)) {
3925             return err;
3926         }
3927         ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3928                 mComponentName.c_str());
3929     }
3930     return OK;
3931 }
3932 
setHDRStaticInfoForVideoCodec(OMX_U32 portIndex,const sp<AMessage> & configFormat,sp<AMessage> & outputFormat)3933 status_t ACodec::setHDRStaticInfoForVideoCodec(
3934         OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
3935     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3936 
3937     DescribeHDRStaticInfoParams params;
3938     InitOMXParams(&params);
3939     params.nPortIndex = portIndex;
3940 
3941     HDRStaticInfo *info = &params.sInfo;
3942     if (getHDRStaticInfoFromFormat(configFormat, info)) {
3943         setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
3944     }
3945 
3946     (void)initDescribeHDRStaticInfoIndex();
3947 
3948     // communicate HDR static Info to codec
3949     return setHDRStaticInfo(params);
3950 }
3951 
3952 // subsequent initial video encoder setup for surface mode
setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(android_dataspace * dataSpace)3953 status_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3954         android_dataspace *dataSpace /* nonnull */) {
3955     DescribeColorAspectsParams params;
3956     InitOMXParams(&params);
3957     params.nPortIndex = kPortIndexInput;
3958     ColorAspects &aspects = params.sAspects;
3959 
3960     // reset default format and store resulting format into both input and output formats
3961     getColorAspectsFromFormat(mConfigFormat, aspects);
3962     int32_t width, height;
3963     if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3964         setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
3965     }
3966     setColorAspectsIntoFormat(aspects, mInputFormat);
3967     setColorAspectsIntoFormat(aspects, mOutputFormat);
3968 
3969     // communicate color aspects to codec, but do not allow any change
3970     ColorAspects origAspects = aspects;
3971     status_t err = OK;
3972     for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3973         status_t err = setCodecColorAspects(params, true /* readBack */);
3974         if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3975             break;
3976         }
3977         ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3978                 mComponentName.c_str());
3979     }
3980 
3981     *dataSpace = HAL_DATASPACE_BT709;
3982     aspects = origAspects; // restore desired color aspects
3983     status_t res = getDataSpace(
3984             params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3985     if (err == OK) {
3986         err = res;
3987     }
3988     mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3989     mInputFormat->setBuffer(
3990             "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3991 
3992     // update input format with codec supported color aspects (basically set unsupported
3993     // aspects to Unspecified)
3994     if (err == OK) {
3995         (void)getInputColorAspectsForVideoEncoder(mInputFormat);
3996     }
3997 
3998     ALOGV("set default color aspects, updated input format to %s, output format to %s",
3999             mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
4000 
4001     return err;
4002 }
4003 
getHDRStaticInfoForVideoCodec(OMX_U32 portIndex,sp<AMessage> & format)4004 status_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
4005     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
4006     DescribeHDRStaticInfoParams params;
4007     InitOMXParams(&params);
4008     params.nPortIndex = portIndex;
4009 
4010     status_t err = getHDRStaticInfo(params);
4011     if (err == OK) {
4012         // we only set decodec output HDRStaticInfo if codec supports them
4013         setHDRStaticInfoIntoFormat(params.sInfo, format);
4014     }
4015     return err;
4016 }
4017 
initDescribeHDRStaticInfoIndex()4018 status_t ACodec::initDescribeHDRStaticInfoIndex() {
4019     status_t err = mOMXNode->getExtensionIndex(
4020             "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
4021     if (err != OK) {
4022         mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
4023         return err;
4024     }
4025 
4026     err = mOMXNode->getExtensionIndex(
4027                 "OMX.google.android.index.describeHDR10PlusInfo", &mDescribeHDR10PlusInfoIndex);
4028     if (err != OK) {
4029         mDescribeHDR10PlusInfoIndex = (OMX_INDEXTYPE)0;
4030         return err;
4031     }
4032 
4033     return OK;
4034 }
4035 
setHDRStaticInfo(const DescribeHDRStaticInfoParams & params)4036 status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
4037     status_t err = ERROR_UNSUPPORTED;
4038     if (mDescribeHDRStaticInfoIndex) {
4039         err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
4040     }
4041 
4042     const HDRStaticInfo *info = &params.sInfo;
4043     ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
4044             "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
4045             mComponentName.c_str(),
4046             info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
4047             info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
4048             info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
4049             info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
4050 
4051     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
4052             "[%s] setting HDRStaticInfo failed even though codec advertises support",
4053             mComponentName.c_str());
4054     return err;
4055 }
4056 
getHDRStaticInfo(DescribeHDRStaticInfoParams & params)4057 status_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
4058     status_t err = ERROR_UNSUPPORTED;
4059     if (mDescribeHDRStaticInfoIndex) {
4060         err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
4061     }
4062 
4063     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
4064             "[%s] getting HDRStaticInfo failed even though codec advertises support",
4065             mComponentName.c_str());
4066     return err;
4067 }
4068 
setupVideoEncoder(const char * mime,const sp<AMessage> & msg,sp<AMessage> & outputFormat,sp<AMessage> & inputFormat)4069 status_t ACodec::setupVideoEncoder(
4070         const char *mime, const sp<AMessage> &msg,
4071         sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
4072     int32_t tmp;
4073     if (!msg->findInt32("color-format", &tmp)) {
4074         return INVALID_OPERATION;
4075     }
4076 
4077     OMX_COLOR_FORMATTYPE colorFormat =
4078         static_cast<OMX_COLOR_FORMATTYPE>(tmp);
4079 
4080     status_t err = setVideoPortFormatType(
4081             kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
4082 
4083     if (err != OK) {
4084         ALOGE("[%s] does not support color format %d",
4085               mComponentName.c_str(), colorFormat);
4086 
4087         return err;
4088     }
4089 
4090     /* Input port configuration */
4091 
4092     OMX_PARAM_PORTDEFINITIONTYPE def;
4093     InitOMXParams(&def);
4094 
4095     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4096 
4097     def.nPortIndex = kPortIndexInput;
4098 
4099     err = mOMXNode->getParameter(
4100             OMX_IndexParamPortDefinition, &def, sizeof(def));
4101 
4102     if (err != OK) {
4103         return err;
4104     }
4105 
4106     OMX_VIDEO_CONTROLRATETYPE bitrateMode;
4107     int32_t width, height, bitrate = 0, quality;
4108     if (!msg->findInt32("width", &width)
4109             || !msg->findInt32("height", &height)
4110             || !findVideoBitrateControlInfo(
4111                     msg, &bitrateMode, &bitrate, &quality)) {
4112         return INVALID_OPERATION;
4113     }
4114 
4115     video_def->nFrameWidth = width;
4116     video_def->nFrameHeight = height;
4117 
4118     int32_t stride;
4119     if (!msg->findInt32("stride", &stride)) {
4120         stride = width;
4121     }
4122 
4123     video_def->nStride = stride;
4124 
4125     int32_t sliceHeight;
4126     if (!msg->findInt32("slice-height", &sliceHeight)) {
4127         sliceHeight = height;
4128     }
4129 
4130     video_def->nSliceHeight = sliceHeight;
4131 
4132     def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
4133 
4134     float framerate;
4135     if (!msg->findFloat("frame-rate", &framerate)) {
4136         int32_t tmp;
4137         if (!msg->findInt32("frame-rate", &tmp)) {
4138             return INVALID_OPERATION;
4139         }
4140         mFps = (double)tmp;
4141     } else {
4142         mFps = (double)framerate;
4143     }
4144     // propagate framerate to the output so that the muxer has it
4145     outputFormat->setInt32("frame-rate", (int32_t)mFps);
4146 
4147     video_def->xFramerate = (OMX_U32)(mFps * 65536);
4148     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
4149     // this is redundant as it was already set up in setVideoPortFormatType
4150     // FIXME for now skip this only for flexible YUV formats
4151     if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
4152         video_def->eColorFormat = colorFormat;
4153     }
4154 
4155     err = mOMXNode->setParameter(
4156             OMX_IndexParamPortDefinition, &def, sizeof(def));
4157 
4158     if (err != OK) {
4159         ALOGE("[%s] failed to set input port definition parameters.",
4160               mComponentName.c_str());
4161 
4162         return err;
4163     }
4164 
4165     /* Output port configuration */
4166 
4167     OMX_VIDEO_CODINGTYPE compressionFormat;
4168     err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
4169 
4170     if (err != OK) {
4171         return err;
4172     }
4173 
4174     err = setVideoPortFormatType(
4175             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
4176 
4177     if (err != OK) {
4178         ALOGE("[%s] does not support compression format %d",
4179              mComponentName.c_str(), compressionFormat);
4180 
4181         return err;
4182     }
4183 
4184     def.nPortIndex = kPortIndexOutput;
4185 
4186     err = mOMXNode->getParameter(
4187             OMX_IndexParamPortDefinition, &def, sizeof(def));
4188 
4189     if (err != OK) {
4190         return err;
4191     }
4192 
4193     video_def->nFrameWidth = width;
4194     video_def->nFrameHeight = height;
4195     video_def->xFramerate = 0;
4196     video_def->nBitrate = bitrate;
4197     video_def->eCompressionFormat = compressionFormat;
4198     video_def->eColorFormat = OMX_COLOR_FormatUnused;
4199 
4200     err = mOMXNode->setParameter(
4201             OMX_IndexParamPortDefinition, &def, sizeof(def));
4202 
4203     if (err != OK) {
4204         ALOGE("[%s] failed to set output port definition parameters.",
4205               mComponentName.c_str());
4206 
4207         return err;
4208     }
4209 
4210     int32_t intraRefreshPeriod = 0;
4211     if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
4212             && intraRefreshPeriod >= 0) {
4213         err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
4214         if (err != OK) {
4215             ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
4216                     mComponentName.c_str());
4217             err = OK;
4218         }
4219     }
4220 
4221     configureEncoderLatency(msg);
4222 
4223     switch (compressionFormat) {
4224         case OMX_VIDEO_CodingMPEG4:
4225             err = setupMPEG4EncoderParameters(msg);
4226             break;
4227 
4228         case OMX_VIDEO_CodingH263:
4229             err = setupH263EncoderParameters(msg);
4230             break;
4231 
4232         case OMX_VIDEO_CodingAVC:
4233             err = setupAVCEncoderParameters(msg);
4234             break;
4235 
4236         case OMX_VIDEO_CodingHEVC:
4237         case OMX_VIDEO_CodingImageHEIC:
4238             err = setupHEVCEncoderParameters(msg, outputFormat);
4239             break;
4240 
4241         case OMX_VIDEO_CodingVP8:
4242         case OMX_VIDEO_CodingVP9:
4243             err = setupVPXEncoderParameters(msg, outputFormat);
4244             break;
4245 
4246         default:
4247             break;
4248     }
4249 
4250     if (err != OK) {
4251         return err;
4252     }
4253 
4254     // Set up color aspects on input, but propagate them to the output format, as they will
4255     // not be read back from encoder.
4256     err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
4257     if (err == ERROR_UNSUPPORTED) {
4258         ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
4259         err = OK;
4260     }
4261 
4262     if (err != OK) {
4263         return err;
4264     }
4265 
4266     err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
4267     if (err == ERROR_UNSUPPORTED) { // support is optional
4268         ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
4269         err = OK;
4270     }
4271 
4272     if (err != OK) {
4273         return err;
4274     }
4275 
4276     switch (compressionFormat) {
4277         case OMX_VIDEO_CodingAVC:
4278         case OMX_VIDEO_CodingHEVC:
4279             err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
4280             if (err != OK) {
4281                 err = OK; // ignore failure
4282             }
4283             break;
4284 
4285         case OMX_VIDEO_CodingVP8:
4286         case OMX_VIDEO_CodingVP9:
4287             // TODO: do we need to support android.generic layering? webrtc layering is
4288             // already set up in setupVPXEncoderParameters.
4289             break;
4290 
4291         default:
4292             break;
4293     }
4294 
4295     if (err == OK) {
4296         ALOGI("setupVideoEncoder succeeded");
4297     }
4298 
4299     // Video should be encoded as stand straight because RTP protocol
4300     // can provide rotation information only if CVO is supported.
4301     // This needs to be added to support non-CVO case for video streaming scenario.
4302     int32_t rotation = 0;
4303     if (msg->findInt32("rotation-degrees", &rotation)) {
4304         OMX_CONFIG_ROTATIONTYPE config;
4305         InitOMXParams(&config);
4306         config.nPortIndex = kPortIndexOutput;
4307         status_t err = mOMXNode->getConfig(
4308                 (OMX_INDEXTYPE)OMX_IndexConfigCommonRotate, &config, sizeof(config));
4309         if (err != OK) {
4310             ALOGW("Failed to getConfig of OMX_IndexConfigCommonRotate(err %d)", err);
4311         }
4312         config.nRotation = rotation;
4313         err = mOMXNode->setConfig(
4314                 (OMX_INDEXTYPE)OMX_IndexConfigCommonRotate, &config, sizeof(config));
4315 
4316         ALOGD("Applying encoder-rotation=[%d] to video encoder.", config.nRotation);
4317         if (err != OK) {
4318             ALOGW("Failed to setConfig of OMX_IndexConfigCommonRotate(err %d)", err);
4319         }
4320     }
4321 
4322     return err;
4323 }
4324 
setCyclicIntraMacroblockRefresh(const sp<AMessage> & msg,int32_t mode)4325 status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
4326     OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
4327     InitOMXParams(&params);
4328     params.nPortIndex = kPortIndexOutput;
4329 
4330     params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
4331 
4332     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
4333             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
4334         int32_t mbs;
4335         if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
4336             return INVALID_OPERATION;
4337         }
4338         params.nCirMBs = mbs;
4339     }
4340 
4341     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
4342             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
4343         int32_t mbs;
4344         if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
4345             return INVALID_OPERATION;
4346         }
4347         params.nAirMBs = mbs;
4348 
4349         int32_t ref;
4350         if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
4351             return INVALID_OPERATION;
4352         }
4353         params.nAirRef = ref;
4354     }
4355 
4356     status_t err = mOMXNode->setParameter(
4357             OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
4358     return err;
4359 }
4360 
setPFramesSpacing(float iFramesInterval,int32_t frameRate,uint32_t BFramesSpacing=0)4361 static OMX_U32 setPFramesSpacing(
4362         float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
4363     // BFramesSpacing is the number of B frames between I/P frames
4364     // PFramesSpacing (the value to be returned) is the number of P frames between I frames
4365     //
4366     // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
4367     //                                     ^^^                            ^^^        ^^^
4368     //                              number of B frames                number of P    I frame
4369     //
4370     //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
4371     //
4372     // E.g.
4373     //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
4374     //       BBB BBB
4375 
4376     if (iFramesInterval < 0) { // just 1 key frame
4377         return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
4378     } else if (iFramesInterval == 0) { // just key frames
4379         return 0;
4380     }
4381 
4382     // round down as key-frame-interval is an upper limit
4383     uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
4384     OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
4385     return ret > 0 ? ret - 1 : 0;
4386 }
4387 
setupMPEG4EncoderParameters(const sp<AMessage> & msg)4388 status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
4389     int32_t bitrate;
4390     float iFrameInterval;
4391     if (!msg->findInt32("bitrate", &bitrate)
4392             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4393         return INVALID_OPERATION;
4394     }
4395 
4396     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4397 
4398     float frameRate;
4399     if (!msg->findFloat("frame-rate", &frameRate)) {
4400         int32_t tmp;
4401         if (!msg->findInt32("frame-rate", &tmp)) {
4402             return INVALID_OPERATION;
4403         }
4404         frameRate = (float)tmp;
4405     }
4406 
4407     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
4408     InitOMXParams(&mpeg4type);
4409     mpeg4type.nPortIndex = kPortIndexOutput;
4410 
4411     status_t err = mOMXNode->getParameter(
4412             OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
4413 
4414     if (err != OK) {
4415         return err;
4416     }
4417 
4418     mpeg4type.nSliceHeaderSpacing = 0;
4419     mpeg4type.bSVH = OMX_FALSE;
4420     mpeg4type.bGov = OMX_FALSE;
4421 
4422     mpeg4type.nAllowedPictureTypes =
4423         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4424 
4425     mpeg4type.nBFrames = 0;
4426     mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
4427     if (mpeg4type.nPFrames == 0) {
4428         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
4429     }
4430     mpeg4type.nIDCVLCThreshold = 0;
4431     mpeg4type.bACPred = OMX_TRUE;
4432     mpeg4type.nMaxPacketSize = 256;
4433     mpeg4type.nTimeIncRes = 1000;
4434     mpeg4type.nHeaderExtension = 0;
4435     mpeg4type.bReversibleVLC = OMX_FALSE;
4436 
4437     int32_t profile;
4438     if (msg->findInt32("profile", &profile)) {
4439         int32_t level;
4440         if (!msg->findInt32("level", &level)) {
4441             return INVALID_OPERATION;
4442         }
4443 
4444         err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
4445 
4446         if (err != OK) {
4447             return err;
4448         }
4449 
4450         mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
4451         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
4452     }
4453 
4454     err = mOMXNode->setParameter(
4455             OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
4456 
4457     if (err != OK) {
4458         return err;
4459     }
4460 
4461     err = configureBitrate(bitrateMode, bitrate);
4462 
4463     if (err != OK) {
4464         return err;
4465     }
4466 
4467     return setupErrorCorrectionParameters();
4468 }
4469 
setupH263EncoderParameters(const sp<AMessage> & msg)4470 status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
4471     int32_t bitrate;
4472     float iFrameInterval;
4473     if (!msg->findInt32("bitrate", &bitrate)
4474             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4475         return INVALID_OPERATION;
4476     }
4477 
4478     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4479 
4480     float frameRate;
4481     if (!msg->findFloat("frame-rate", &frameRate)) {
4482         int32_t tmp;
4483         if (!msg->findInt32("frame-rate", &tmp)) {
4484             return INVALID_OPERATION;
4485         }
4486         frameRate = (float)tmp;
4487     }
4488 
4489     OMX_VIDEO_PARAM_H263TYPE h263type;
4490     InitOMXParams(&h263type);
4491     h263type.nPortIndex = kPortIndexOutput;
4492 
4493     status_t err = mOMXNode->getParameter(
4494             OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
4495 
4496     if (err != OK) {
4497         return err;
4498     }
4499 
4500     h263type.nAllowedPictureTypes =
4501         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4502 
4503     h263type.nBFrames = 0;
4504     h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
4505     if (h263type.nPFrames == 0) {
4506         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
4507     }
4508 
4509     int32_t profile;
4510     if (msg->findInt32("profile", &profile)) {
4511         int32_t level;
4512         if (!msg->findInt32("level", &level)) {
4513             return INVALID_OPERATION;
4514         }
4515 
4516         err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
4517 
4518         if (err != OK) {
4519             return err;
4520         }
4521 
4522         h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
4523         h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
4524     }
4525 
4526     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
4527     h263type.bForceRoundingTypeToZero = OMX_FALSE;
4528     h263type.nPictureHeaderRepetition = 0;
4529     h263type.nGOBHeaderInterval = 0;
4530 
4531     err = mOMXNode->setParameter(
4532             OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
4533 
4534     if (err != OK) {
4535         return err;
4536     }
4537 
4538     err = configureBitrate(bitrateMode, bitrate);
4539 
4540     if (err != OK) {
4541         return err;
4542     }
4543 
4544     return setupErrorCorrectionParameters();
4545 }
4546 
4547 // static
getAVCLevelFor(int width,int height,int rate,int bitrate,OMX_VIDEO_AVCPROFILEEXTTYPE profile)4548 int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
4549         int width, int height, int rate, int bitrate,
4550         OMX_VIDEO_AVCPROFILEEXTTYPE profile) {
4551     // convert bitrate to main/baseline profile kbps equivalent
4552     switch ((uint32_t)profile) {
4553         case OMX_VIDEO_AVCProfileHigh10:
4554             bitrate = divUp(bitrate, 3000); break;
4555         case OMX_VIDEO_AVCProfileConstrainedHigh:
4556         case OMX_VIDEO_AVCProfileHigh:
4557             bitrate = divUp(bitrate, 1250); break;
4558         default:
4559             bitrate = divUp(bitrate, 1000); break;
4560     }
4561 
4562     // convert size and rate to MBs
4563     width = divUp(width, 16);
4564     height = divUp(height, 16);
4565     int mbs = width * height;
4566     rate *= mbs;
4567     int maxDimension = max(width, height);
4568 
4569     static const int limits[][5] = {
4570         /*    MBps      MB   dim  bitrate        level */
4571         {     1485,     99,   28,     64, OMX_VIDEO_AVCLevel1  },
4572         {     1485,     99,   28,    128, OMX_VIDEO_AVCLevel1b },
4573         {     3000,    396,   56,    192, OMX_VIDEO_AVCLevel11 },
4574         {     6000,    396,   56,    384, OMX_VIDEO_AVCLevel12 },
4575         {    11880,    396,   56,    768, OMX_VIDEO_AVCLevel13 },
4576         {    11880,    396,   56,   2000, OMX_VIDEO_AVCLevel2  },
4577         {    19800,    792,   79,   4000, OMX_VIDEO_AVCLevel21 },
4578         {    20250,   1620,  113,   4000, OMX_VIDEO_AVCLevel22 },
4579         {    40500,   1620,  113,  10000, OMX_VIDEO_AVCLevel3  },
4580         {   108000,   3600,  169,  14000, OMX_VIDEO_AVCLevel31 },
4581         {   216000,   5120,  202,  20000, OMX_VIDEO_AVCLevel32 },
4582         {   245760,   8192,  256,  20000, OMX_VIDEO_AVCLevel4  },
4583         {   245760,   8192,  256,  50000, OMX_VIDEO_AVCLevel41 },
4584         {   522240,   8704,  263,  50000, OMX_VIDEO_AVCLevel42 },
4585         {   589824,  22080,  420, 135000, OMX_VIDEO_AVCLevel5  },
4586         {   983040,  36864,  543, 240000, OMX_VIDEO_AVCLevel51 },
4587         {  2073600,  36864,  543, 240000, OMX_VIDEO_AVCLevel52 },
4588         {  4177920, 139264, 1055, 240000, OMX_VIDEO_AVCLevel6  },
4589         {  8355840, 139264, 1055, 480000, OMX_VIDEO_AVCLevel61 },
4590         { 16711680, 139264, 1055, 800000, OMX_VIDEO_AVCLevel62 },
4591     };
4592 
4593     for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4594         const int (&limit)[5] = limits[i];
4595         if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4596                 && bitrate <= limit[3]) {
4597             return limit[4];
4598         }
4599     }
4600     return 0;
4601 }
4602 
setupAVCEncoderParameters(const sp<AMessage> & msg)4603 status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
4604     int32_t bitrate;
4605     float iFrameInterval;
4606     if (!msg->findInt32("bitrate", &bitrate)
4607             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4608         return INVALID_OPERATION;
4609     }
4610 
4611     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4612 
4613     float frameRate;
4614     if (!msg->findFloat("frame-rate", &frameRate)) {
4615         int32_t tmp;
4616         if (!msg->findInt32("frame-rate", &tmp)) {
4617             return INVALID_OPERATION;
4618         }
4619         frameRate = (float)tmp;
4620     }
4621 
4622     status_t err = OK;
4623     int32_t intraRefreshMode = 0;
4624     if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
4625         err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
4626         if (err != OK) {
4627             ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
4628                     err, intraRefreshMode);
4629             return err;
4630         }
4631     }
4632 
4633     OMX_VIDEO_PARAM_AVCTYPE h264type;
4634     InitOMXParams(&h264type);
4635     h264type.nPortIndex = kPortIndexOutput;
4636 
4637     err = mOMXNode->getParameter(
4638             OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4639 
4640     if (err != OK) {
4641         return err;
4642     }
4643 
4644     h264type.nAllowedPictureTypes =
4645         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4646 
4647     int32_t profile;
4648     if (msg->findInt32("profile", &profile)) {
4649         int32_t level;
4650         if (!msg->findInt32("level", &level)) {
4651             return INVALID_OPERATION;
4652         }
4653 
4654         err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
4655 
4656         if (err != OK) {
4657             return err;
4658         }
4659 
4660         h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
4661         h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4662     } else {
4663         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
4664 #if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
4665         // Use largest supported profile for AVC recording if profile is not specified.
4666         for (OMX_VIDEO_AVCPROFILETYPE profile : {
4667                 OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4668             if (verifySupportForProfileAndLevel(kPortIndexOutput, profile, 0) == OK) {
4669                 h264type.eProfile = profile;
4670                 break;
4671             }
4672         }
4673 #endif
4674     }
4675 
4676     ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4677             asString(h264type.eProfile), asString(h264type.eLevel));
4678 
4679     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
4680         h264type.nSliceHeaderSpacing = 0;
4681         h264type.bUseHadamard = OMX_TRUE;
4682         h264type.nRefFrames = 1;
4683         h264type.nBFrames = 0;
4684         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4685         if (h264type.nPFrames == 0) {
4686             h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
4687         }
4688         h264type.nRefIdx10ActiveMinus1 = 0;
4689         h264type.nRefIdx11ActiveMinus1 = 0;
4690         h264type.bEntropyCodingCABAC = OMX_FALSE;
4691         h264type.bWeightedPPrediction = OMX_FALSE;
4692         h264type.bconstIpred = OMX_FALSE;
4693         h264type.bDirect8x8Inference = OMX_FALSE;
4694         h264type.bDirectSpatialTemporal = OMX_FALSE;
4695         h264type.nCabacInitIdc = 0;
4696     } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4697             h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4698         h264type.nSliceHeaderSpacing = 0;
4699         h264type.bUseHadamard = OMX_TRUE;
4700         int32_t maxBframes = 0;
4701         (void)msg->findInt32(KEY_MAX_B_FRAMES, &maxBframes);
4702         h264type.nBFrames = uint32_t(maxBframes);
4703         if (mLatency && h264type.nBFrames > *mLatency) {
4704             h264type.nBFrames = *mLatency;
4705         }
4706         h264type.nRefFrames = h264type.nBFrames == 0 ? 1 : 2;
4707 
4708         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4709         h264type.nAllowedPictureTypes =
4710             OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4711         h264type.nRefIdx10ActiveMinus1 = 0;
4712         h264type.nRefIdx11ActiveMinus1 = 0;
4713         h264type.bEntropyCodingCABAC = OMX_TRUE;
4714         h264type.bWeightedPPrediction = OMX_TRUE;
4715         h264type.bconstIpred = OMX_TRUE;
4716         h264type.bDirect8x8Inference = OMX_TRUE;
4717         h264type.bDirectSpatialTemporal = OMX_TRUE;
4718         h264type.nCabacInitIdc = 1;
4719     }
4720 
4721     if (h264type.nBFrames != 0) {
4722         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
4723     }
4724 
4725     h264type.bEnableUEP = OMX_FALSE;
4726     h264type.bEnableFMO = OMX_FALSE;
4727     h264type.bEnableASO = OMX_FALSE;
4728     h264type.bEnableRS = OMX_FALSE;
4729     h264type.bFrameMBsOnly = OMX_TRUE;
4730     h264type.bMBAFF = OMX_FALSE;
4731     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
4732 
4733     err = mOMXNode->setParameter(
4734             OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4735 
4736     if (err != OK) {
4737         return err;
4738     }
4739 
4740     // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4741     // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4742     // is preferred.
4743     AString tsSchema;
4744     int32_t preferBFrames = (int32_t)false;
4745     if (msg->findString("ts-schema", &tsSchema)
4746             && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4747         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4748         InitOMXParams(&layering);
4749         layering.nPortIndex = kPortIndexOutput;
4750         if (mOMXNode->getParameter(
4751                         (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4752                         &layering, sizeof(layering)) == OK
4753                 && layering.eSupportedPatterns
4754                 && layering.nBLayerCountMax == 0) {
4755             h264type.nBFrames = 0;
4756             h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4757             h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4758             ALOGI("disabling B-frames");
4759             err = mOMXNode->setParameter(
4760                     OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4761 
4762             if (err != OK) {
4763                 return err;
4764             }
4765         }
4766     }
4767 
4768     return configureBitrate(bitrateMode, bitrate);
4769 }
4770 
configureImageGrid(const sp<AMessage> & msg,sp<AMessage> & outputFormat)4771 status_t ACodec::configureImageGrid(
4772         const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
4773     int32_t tileWidth, tileHeight, gridRows, gridCols;
4774     OMX_BOOL useGrid = OMX_FALSE;
4775     if (msg->findInt32("tile-width", &tileWidth) &&
4776         msg->findInt32("tile-height", &tileHeight) &&
4777         msg->findInt32("grid-rows", &gridRows) &&
4778         msg->findInt32("grid-cols", &gridCols)) {
4779         useGrid = OMX_TRUE;
4780     } else {
4781         // when bEnabled is false, the tile info is not used,
4782         // but clear out these too.
4783         tileWidth = tileHeight = gridRows = gridCols = 0;
4784     }
4785 
4786     if (!mIsImage && !useGrid) {
4787         return OK;
4788     }
4789 
4790     OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE gridType;
4791     InitOMXParams(&gridType);
4792     gridType.nPortIndex = kPortIndexOutput;
4793     gridType.bEnabled = useGrid;
4794     gridType.nTileWidth = tileWidth;
4795     gridType.nTileHeight = tileHeight;
4796     gridType.nGridRows = gridRows;
4797     gridType.nGridCols = gridCols;
4798 
4799     ALOGV("sending image grid info to component: bEnabled %d, tile %dx%d, grid %dx%d",
4800             gridType.bEnabled,
4801             gridType.nTileWidth,
4802             gridType.nTileHeight,
4803             gridType.nGridRows,
4804             gridType.nGridCols);
4805 
4806     status_t err = mOMXNode->setParameter(
4807             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid,
4808             &gridType, sizeof(gridType));
4809 
4810     // for video encoders, grid config is only a hint.
4811     if (!mIsImage) {
4812         return OK;
4813     }
4814 
4815     // image encoders must support grid config.
4816     if (err != OK) {
4817         return err;
4818     }
4819 
4820     // query to get the image encoder's real grid config as it might be
4821     // different from the requested, and transfer that to the output.
4822     err = mOMXNode->getParameter(
4823             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid,
4824             &gridType, sizeof(gridType));
4825 
4826     ALOGV("received image grid info from component: bEnabled %d, tile %dx%d, grid %dx%d",
4827             gridType.bEnabled,
4828             gridType.nTileWidth,
4829             gridType.nTileHeight,
4830             gridType.nGridRows,
4831             gridType.nGridCols);
4832 
4833     if (err == OK && gridType.bEnabled) {
4834         outputFormat->setInt32("tile-width", gridType.nTileWidth);
4835         outputFormat->setInt32("tile-height", gridType.nTileHeight);
4836         outputFormat->setInt32("grid-rows", gridType.nGridRows);
4837         outputFormat->setInt32("grid-cols", gridType.nGridCols);
4838     }
4839 
4840     return err;
4841 }
4842 
setupHEVCEncoderParameters(const sp<AMessage> & msg,sp<AMessage> & outputFormat)4843 status_t ACodec::setupHEVCEncoderParameters(
4844         const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
4845     OMX_VIDEO_CONTROLRATETYPE bitrateMode;
4846     int32_t bitrate, quality;
4847     if (!findVideoBitrateControlInfo(msg, &bitrateMode, &bitrate, &quality)) {
4848         return INVALID_OPERATION;
4849     }
4850 
4851     OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4852     InitOMXParams(&hevcType);
4853     hevcType.nPortIndex = kPortIndexOutput;
4854 
4855     status_t err = OK;
4856     err = mOMXNode->getParameter(
4857             (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4858     if (err != OK) {
4859         return err;
4860     }
4861 
4862     int32_t profile;
4863     if (msg->findInt32("profile", &profile)) {
4864         int32_t level;
4865         if (!msg->findInt32("level", &level)) {
4866             return INVALID_OPERATION;
4867         }
4868 
4869         err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
4870         if (err != OK) {
4871             return err;
4872         }
4873 
4874         hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4875         hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4876     }
4877     // TODO: finer control?
4878     if (mIsImage) {
4879         hevcType.nKeyFrameInterval = 1;
4880     } else {
4881         float iFrameInterval;
4882         if (!msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4883             return INVALID_OPERATION;
4884         }
4885 
4886         float frameRate;
4887         if (!msg->findFloat("frame-rate", &frameRate)) {
4888             int32_t tmp;
4889             if (!msg->findInt32("frame-rate", &tmp)) {
4890                 return INVALID_OPERATION;
4891             }
4892             frameRate = (float)tmp;
4893         }
4894 
4895         hevcType.nKeyFrameInterval =
4896                 setPFramesSpacing(iFrameInterval, frameRate) + 1;
4897     }
4898 
4899 
4900     err = mOMXNode->setParameter(
4901             (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4902     if (err != OK) {
4903         return err;
4904     }
4905 
4906     err = configureImageGrid(msg, outputFormat);
4907 
4908     if (err != OK) {
4909         return err;
4910     }
4911 
4912     return configureBitrate(bitrateMode, bitrate, quality);
4913 }
4914 
setupVPXEncoderParameters(const sp<AMessage> & msg,sp<AMessage> & outputFormat)4915 status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
4916     int32_t bitrate;
4917     float iFrameInterval = 0;
4918     size_t tsLayers = 0;
4919     OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
4920         OMX_VIDEO_VPXTemporalLayerPatternNone;
4921     static const uint32_t kVp8LayerRateAlloction
4922         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
4923         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
4924         {100, 100, 100},  // 1 layer
4925         { 60, 100, 100},  // 2 layers {60%, 40%}
4926         { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
4927     };
4928     if (!msg->findInt32("bitrate", &bitrate)) {
4929         return INVALID_OPERATION;
4930     }
4931     msg->findAsFloat("i-frame-interval", &iFrameInterval);
4932 
4933     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
4934 
4935     float frameRate;
4936     if (!msg->findFloat("frame-rate", &frameRate)) {
4937         int32_t tmp;
4938         if (!msg->findInt32("frame-rate", &tmp)) {
4939             return INVALID_OPERATION;
4940         }
4941         frameRate = (float)tmp;
4942     }
4943 
4944     AString tsSchema;
4945     OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
4946         OMX_VIDEO_AndroidTemporalLayeringPatternNone;
4947 
4948     if (msg->findString("ts-schema", &tsSchema)) {
4949         unsigned int numLayers = 0;
4950         unsigned int numBLayers = 0;
4951         int tags;
4952         char tmp;
4953         if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &tmp) == 1
4954                 && numLayers > 0) {
4955             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4956             tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4957             tsLayers = numLayers;
4958         } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4959                         &numLayers, &tmp, &numBLayers, &tmp))
4960                 && (tags == 1 || (tags == 3 && tmp == '+'))
4961                 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
4962             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4963             // VPX does not have a concept of B-frames, so just count all layers
4964             tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4965             tsLayers = numLayers + numBLayers;
4966         } else {
4967             ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
4968         }
4969         tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
4970     }
4971 
4972     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
4973     InitOMXParams(&vp8type);
4974     vp8type.nPortIndex = kPortIndexOutput;
4975     status_t err = mOMXNode->getParameter(
4976             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4977             &vp8type, sizeof(vp8type));
4978 
4979     if (err == OK) {
4980         if (iFrameInterval > 0) {
4981             vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4982         }
4983         vp8type.eTemporalPattern = pattern;
4984         vp8type.nTemporalLayerCount = tsLayers;
4985         if (tsLayers > 0) {
4986             for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
4987                 vp8type.nTemporalLayerBitrateRatio[i] =
4988                     kVp8LayerRateAlloction[tsLayers - 1][i];
4989             }
4990         }
4991         if (bitrateMode == OMX_Video_ControlRateConstant) {
4992             vp8type.nMinQuantizer = 2;
4993             vp8type.nMaxQuantizer = 63;
4994         }
4995 
4996         err = mOMXNode->setParameter(
4997                 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4998                 &vp8type, sizeof(vp8type));
4999         if (err != OK) {
5000             ALOGW("Extended VP8 parameters set failed: %d", err);
5001         } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
5002             // advertise even single layer WebRTC layering, as it is defined
5003             outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
5004         } else if (tsLayers > 0) {
5005             // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
5006             outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
5007         }
5008     }
5009 
5010     return configureBitrate(bitrateMode, bitrate);
5011 }
5012 
verifySupportForProfileAndLevel(OMX_U32 portIndex,int32_t profile,int32_t level)5013 status_t ACodec::verifySupportForProfileAndLevel(
5014         OMX_U32 portIndex, int32_t profile, int32_t level) {
5015     OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
5016     InitOMXParams(&params);
5017     params.nPortIndex = portIndex;
5018 
5019     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
5020         params.nProfileIndex = index;
5021         status_t err = mOMXNode->getParameter(
5022                 OMX_IndexParamVideoProfileLevelQuerySupported,
5023                 &params, sizeof(params));
5024 
5025         if (err != OK) {
5026             return err;
5027         }
5028 
5029         int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
5030         int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
5031 
5032         if (profile == supportedProfile && level <= supportedLevel) {
5033             return OK;
5034         }
5035 
5036         if (index == kMaxIndicesToCheck) {
5037             ALOGW("[%s] stopping checking profiles after %u: %x/%x",
5038                     mComponentName.c_str(), index,
5039                     params.eProfile, params.eLevel);
5040         }
5041     }
5042     return ERROR_UNSUPPORTED;
5043 }
5044 
configureBitrate(OMX_VIDEO_CONTROLRATETYPE bitrateMode,int32_t bitrate,int32_t quality)5045 status_t ACodec::configureBitrate(
5046         OMX_VIDEO_CONTROLRATETYPE bitrateMode, int32_t bitrate, int32_t quality) {
5047     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
5048     InitOMXParams(&bitrateType);
5049     bitrateType.nPortIndex = kPortIndexOutput;
5050 
5051     status_t err = mOMXNode->getParameter(
5052             OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
5053 
5054     if (err != OK) {
5055         return err;
5056     }
5057 
5058     bitrateType.eControlRate = bitrateMode;
5059 
5060     // write it out explicitly even if it's a union
5061     if (bitrateMode == OMX_Video_ControlRateConstantQuality) {
5062         bitrateType.nQualityFactor = quality;
5063     } else {
5064         bitrateType.nTargetBitrate = bitrate;
5065     }
5066 
5067     return mOMXNode->setParameter(
5068             OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
5069 }
5070 
configureEncoderLatency(const sp<AMessage> & msg)5071 void ACodec::configureEncoderLatency(const sp<AMessage> &msg) {
5072     if (!mIsEncoder || !mIsVideo) {
5073         return;
5074     }
5075 
5076     int32_t latency = 0, bitrateMode;
5077     if (msg->findInt32("latency", &latency) && latency > 0) {
5078         status_t err = setLatency(latency);
5079         if (err != OK) {
5080             ALOGW("[%s] failed setLatency. Failure is fine since this key is optional",
5081                     mComponentName.c_str());
5082             err = OK;
5083         } else {
5084             mLatency = latency;
5085         }
5086     } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) &&
5087             bitrateMode == OMX_Video_ControlRateConstant)) {
5088         // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode
5089         // is CBR.
5090         mLatency = 1;
5091     }
5092 }
5093 
setupErrorCorrectionParameters()5094 status_t ACodec::setupErrorCorrectionParameters() {
5095     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
5096     InitOMXParams(&errorCorrectionType);
5097     errorCorrectionType.nPortIndex = kPortIndexOutput;
5098 
5099     status_t err = mOMXNode->getParameter(
5100             OMX_IndexParamVideoErrorCorrection,
5101             &errorCorrectionType, sizeof(errorCorrectionType));
5102 
5103     if (err != OK) {
5104         return OK;  // Optional feature. Ignore this failure
5105     }
5106 
5107     errorCorrectionType.bEnableHEC = OMX_FALSE;
5108     errorCorrectionType.bEnableResync = OMX_TRUE;
5109     errorCorrectionType.nResynchMarkerSpacing = 256;
5110     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
5111     errorCorrectionType.bEnableRVLC = OMX_FALSE;
5112 
5113     return mOMXNode->setParameter(
5114             OMX_IndexParamVideoErrorCorrection,
5115             &errorCorrectionType, sizeof(errorCorrectionType));
5116 }
5117 
setVideoFormatOnPort(OMX_U32 portIndex,int32_t width,int32_t height,OMX_VIDEO_CODINGTYPE compressionFormat,float frameRate)5118 status_t ACodec::setVideoFormatOnPort(
5119         OMX_U32 portIndex,
5120         int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
5121         float frameRate) {
5122     OMX_PARAM_PORTDEFINITIONTYPE def;
5123     InitOMXParams(&def);
5124     def.nPortIndex = portIndex;
5125 
5126     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
5127 
5128     status_t err = mOMXNode->getParameter(
5129             OMX_IndexParamPortDefinition, &def, sizeof(def));
5130     if (err != OK) {
5131         return err;
5132     }
5133 
5134     if (portIndex == kPortIndexInput) {
5135         // XXX Need a (much) better heuristic to compute input buffer sizes.
5136         const size_t X = 64 * 1024;
5137         if (def.nBufferSize < X) {
5138             def.nBufferSize = X;
5139         }
5140     }
5141 
5142     if (def.eDomain != OMX_PortDomainVideo) {
5143         ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
5144         return FAILED_TRANSACTION;
5145     }
5146 
5147     video_def->nFrameWidth = width;
5148     video_def->nFrameHeight = height;
5149 
5150     if (portIndex == kPortIndexInput) {
5151         video_def->eCompressionFormat = compressionFormat;
5152         video_def->eColorFormat = OMX_COLOR_FormatUnused;
5153         if (frameRate >= 0) {
5154             video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
5155         }
5156     }
5157 
5158     err = mOMXNode->setParameter(
5159             OMX_IndexParamPortDefinition, &def, sizeof(def));
5160 
5161     return err;
5162 }
5163 
countBuffersOwnedByComponent(OMX_U32 portIndex) const5164 size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
5165     size_t n = 0;
5166 
5167     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
5168         const BufferInfo &info = mBuffers[portIndex][i];
5169 
5170         if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5171             ++n;
5172         }
5173     }
5174 
5175     return n;
5176 }
5177 
countBuffersOwnedByNativeWindow() const5178 size_t ACodec::countBuffersOwnedByNativeWindow() const {
5179     size_t n = 0;
5180 
5181     for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
5182         const BufferInfo &info = mBuffers[kPortIndexOutput][i];
5183 
5184         if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5185             ++n;
5186         }
5187     }
5188 
5189     return n;
5190 }
5191 
waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs()5192 void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
5193     if (mNativeWindow == NULL) {
5194         return;
5195     }
5196 
5197     while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
5198             && dequeueBufferFromNativeWindow() != NULL) {
5199         // these buffers will be submitted as regular buffers; account for this
5200         if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
5201             --mMetadataBuffersToSubmit;
5202         }
5203     }
5204 }
5205 
allYourBuffersAreBelongToUs(OMX_U32 portIndex)5206 bool ACodec::allYourBuffersAreBelongToUs(
5207         OMX_U32 portIndex) {
5208     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
5209         BufferInfo *info = &mBuffers[portIndex][i];
5210 
5211         if (info->mStatus != BufferInfo::OWNED_BY_US
5212                 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5213             ALOGV("[%s] Buffer %u on port %u still has status %d",
5214                     mComponentName.c_str(),
5215                     info->mBufferID, portIndex, info->mStatus);
5216             return false;
5217         }
5218     }
5219 
5220     return true;
5221 }
5222 
allYourBuffersAreBelongToUs()5223 bool ACodec::allYourBuffersAreBelongToUs() {
5224     return allYourBuffersAreBelongToUs(kPortIndexInput)
5225         && allYourBuffersAreBelongToUs(kPortIndexOutput);
5226 }
5227 
deferMessage(const sp<AMessage> & msg)5228 void ACodec::deferMessage(const sp<AMessage> &msg) {
5229     mDeferredQueue.push_back(msg);
5230 }
5231 
processDeferredMessages()5232 void ACodec::processDeferredMessages() {
5233     std::list<sp<AMessage>> queue = mDeferredQueue;
5234     mDeferredQueue.clear();
5235 
5236     for(const sp<AMessage> &msg : queue) {
5237         onMessageReceived(msg);
5238     }
5239 }
5240 
getPortFormat(OMX_U32 portIndex,sp<AMessage> & notify)5241 status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
5242     const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
5243     OMX_PARAM_PORTDEFINITIONTYPE def;
5244     InitOMXParams(&def);
5245     def.nPortIndex = portIndex;
5246 
5247     status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
5248     if (err != OK) {
5249         return err;
5250     }
5251 
5252     if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
5253         ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
5254         return BAD_VALUE;
5255     }
5256 
5257     switch (def.eDomain) {
5258         case OMX_PortDomainVideo:
5259         {
5260             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
5261             switch ((int)videoDef->eCompressionFormat) {
5262                 case OMX_VIDEO_CodingUnused:
5263                 {
5264                     CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
5265                     notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
5266 
5267                     notify->setInt32("stride", videoDef->nStride);
5268                     notify->setInt32("slice-height", videoDef->nSliceHeight);
5269                     notify->setInt32("color-format", videoDef->eColorFormat);
5270 
5271                     if (mNativeWindow == NULL) {
5272                         DescribeColorFormat2Params describeParams;
5273                         InitOMXParams(&describeParams);
5274                         describeParams.eColorFormat = videoDef->eColorFormat;
5275                         describeParams.nFrameWidth = videoDef->nFrameWidth;
5276                         describeParams.nFrameHeight = videoDef->nFrameHeight;
5277                         describeParams.nStride = videoDef->nStride;
5278                         describeParams.nSliceHeight = videoDef->nSliceHeight;
5279                         describeParams.bUsingNativeBuffers = OMX_FALSE;
5280 
5281                         if (DescribeColorFormat(mOMXNode, describeParams)) {
5282                             notify->setBuffer(
5283                                     "image-data",
5284                                     ABuffer::CreateAsCopy(
5285                                             &describeParams.sMediaImage,
5286                                             sizeof(describeParams.sMediaImage)));
5287 
5288                             MediaImage2 &img = describeParams.sMediaImage;
5289                             MediaImage2::PlaneInfo *plane = img.mPlane;
5290                             ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
5291                                     mComponentName.c_str(), img.mWidth, img.mHeight,
5292                                     plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
5293                                     plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
5294                                     plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
5295                         }
5296                     }
5297 
5298                     int32_t width = (int32_t)videoDef->nFrameWidth;
5299                     int32_t height = (int32_t)videoDef->nFrameHeight;
5300 
5301                     if (portIndex == kPortIndexOutput) {
5302                         OMX_CONFIG_RECTTYPE rect;
5303                         InitOMXParams(&rect);
5304                         rect.nPortIndex = portIndex;
5305 
5306                         if (mOMXNode->getConfig(
5307                                     (portIndex == kPortIndexOutput ?
5308                                             OMX_IndexConfigCommonOutputCrop :
5309                                             OMX_IndexConfigCommonInputCrop),
5310                                     &rect, sizeof(rect)) != OK) {
5311                             rect.nLeft = 0;
5312                             rect.nTop = 0;
5313                             rect.nWidth = videoDef->nFrameWidth;
5314                             rect.nHeight = videoDef->nFrameHeight;
5315                         }
5316 
5317                         if (rect.nLeft < 0 || rect.nTop < 0 ||
5318                             rect.nWidth == 0 || rect.nHeight == 0 ||
5319                             rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
5320                             rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
5321                             ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)",
5322                                     rect.nLeft, rect.nTop,
5323                                     rect.nWidth, rect.nHeight,
5324                                     videoDef->nFrameWidth, videoDef->nFrameHeight);
5325                             return BAD_VALUE;
5326                         }
5327 
5328                         notify->setRect(
5329                                 "crop",
5330                                 rect.nLeft,
5331                                 rect.nTop,
5332                                 rect.nLeft + rect.nWidth - 1,
5333                                 rect.nTop + rect.nHeight - 1);
5334 
5335                         width = rect.nWidth;
5336                         height = rect.nHeight;
5337 
5338                         android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
5339                         (void)getColorAspectsAndDataSpaceForVideoDecoder(
5340                                 width, height, mConfigFormat, notify,
5341                                 mUsingNativeWindow ? &dataSpace : NULL);
5342                         if (mUsingNativeWindow) {
5343                             notify->setInt32("android._dataspace", dataSpace);
5344                         }
5345                         (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
5346                     } else {
5347                         (void)getInputColorAspectsForVideoEncoder(notify);
5348                         if (mConfigFormat->contains("hdr-static-info")) {
5349                             (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
5350                         }
5351                         uint32_t latency = 0;
5352                         if (mIsEncoder && !mIsImage &&
5353                                 getLatency(&latency) == OK && latency > 0) {
5354                             notify->setInt32("latency", latency);
5355                         }
5356                     }
5357 
5358                     break;
5359                 }
5360 
5361                 case OMX_VIDEO_CodingVP8:
5362                 case OMX_VIDEO_CodingVP9:
5363                 {
5364                     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
5365                     InitOMXParams(&vp8type);
5366                     vp8type.nPortIndex = kPortIndexOutput;
5367                     status_t err = mOMXNode->getParameter(
5368                             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
5369                             &vp8type,
5370                             sizeof(vp8type));
5371 
5372                     if (err == OK) {
5373                         if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
5374                                 && vp8type.nTemporalLayerCount > 0
5375                                 && vp8type.nTemporalLayerCount
5376                                         <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
5377                             // advertise as android.generic if we configured for android.generic
5378                             AString origSchema;
5379                             if (notify->findString("ts-schema", &origSchema)
5380                                     && origSchema.startsWith("android.generic")) {
5381                                 notify->setString("ts-schema", AStringPrintf(
5382                                         "android.generic.%u", vp8type.nTemporalLayerCount));
5383                             } else {
5384                                 notify->setString("ts-schema", AStringPrintf(
5385                                         "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
5386                             }
5387                         }
5388                     }
5389                     // Fall through to set up mime.
5390                     FALLTHROUGH_INTENDED;
5391                 }
5392 
5393                 default:
5394                 {
5395                     if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
5396                         // should be CodingUnused
5397                         ALOGE("Raw port video compression format is %s(%d)",
5398                                 asString(videoDef->eCompressionFormat),
5399                                 videoDef->eCompressionFormat);
5400                         return BAD_VALUE;
5401                     }
5402                     AString mime;
5403                     if (GetMimeTypeForVideoCoding(
5404                         videoDef->eCompressionFormat, &mime) != OK) {
5405                         notify->setString("mime", "application/octet-stream");
5406                     } else {
5407                         notify->setString("mime", mime.c_str());
5408                     }
5409                     uint32_t intraRefreshPeriod = 0;
5410                     if (mIsEncoder && !mIsImage &&
5411                             getIntraRefreshPeriod(&intraRefreshPeriod) == OK
5412                             && intraRefreshPeriod > 0) {
5413                         notify->setInt32("intra-refresh-period", intraRefreshPeriod);
5414                     }
5415                     break;
5416                 }
5417             }
5418             notify->setInt32("width", videoDef->nFrameWidth);
5419             notify->setInt32("height", videoDef->nFrameHeight);
5420             ALOGV("[%s] %s format is %s", mComponentName.c_str(),
5421                     portIndex == kPortIndexInput ? "input" : "output",
5422                     notify->debugString().c_str());
5423 
5424             break;
5425         }
5426 
5427         case OMX_PortDomainAudio:
5428         {
5429             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
5430 
5431             switch ((int)audioDef->eEncoding) {
5432                 case OMX_AUDIO_CodingPCM:
5433                 {
5434                     OMX_AUDIO_PARAM_PCMMODETYPE params;
5435                     InitOMXParams(&params);
5436                     params.nPortIndex = portIndex;
5437 
5438                     err = mOMXNode->getParameter(
5439                             OMX_IndexParamAudioPcm, &params, sizeof(params));
5440                     if (err != OK) {
5441                         return err;
5442                     }
5443 
5444                     if (params.nChannels <= 0
5445                             || (params.nChannels != 1 && !params.bInterleaved)
5446                             || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
5447                         ALOGE("unsupported PCM port: %u channels%s, %u-bit",
5448                                 params.nChannels,
5449                                 params.bInterleaved ? " interleaved" : "",
5450                                 params.nBitPerSample);
5451                         return FAILED_TRANSACTION;
5452                     }
5453 
5454                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
5455                     notify->setInt32("channel-count", params.nChannels);
5456                     notify->setInt32("sample-rate", params.nSamplingRate);
5457 
5458                     AudioEncoding encoding = kAudioEncodingPcm16bit;
5459                     if (params.eNumData == OMX_NumericalDataUnsigned
5460                             && params.nBitPerSample == 8u) {
5461                         encoding = kAudioEncodingPcm8bit;
5462                     } else if (params.eNumData == OMX_NumericalDataFloat
5463                             && params.nBitPerSample == 32u) {
5464                         encoding = kAudioEncodingPcmFloat;
5465                     } else if (params.nBitPerSample != 16u
5466                             || params.eNumData != OMX_NumericalDataSigned) {
5467                         ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
5468                                 asString(params.eNumData), params.eNumData,
5469                                 asString(params.ePCMMode), params.ePCMMode);
5470                         return FAILED_TRANSACTION;
5471                     }
5472                     notify->setInt32("pcm-encoding", encoding);
5473 
5474                     if (mChannelMaskPresent) {
5475                         notify->setInt32("channel-mask", mChannelMask);
5476                     }
5477 
5478                     if (!mIsEncoder && portIndex == kPortIndexOutput) {
5479                         AString mime;
5480                         if (mConfigFormat->findString("mime", &mime)
5481                                 && !strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime.c_str())) {
5482 
5483                             OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
5484                             InitOMXParams(&presentation);
5485                             err = mOMXNode->getParameter(
5486                                     (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
5487                                     &presentation, sizeof(presentation));
5488                             if (err == OK) {
5489                                 notify->setInt32("aac-encoded-target-level",
5490                                                  presentation.nEncodedTargetLevel);
5491                                 notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
5492                                 notify->setInt32("aac-drc-boost-level", presentation.nDrcBoost);
5493                                 notify->setInt32("aac-drc-heavy-compression",
5494                                                  presentation.nHeavyCompression);
5495                                 notify->setInt32("aac-target-ref-level",
5496                                                  presentation.nTargetReferenceLevel);
5497                                 notify->setInt32("aac-drc-effect-type",
5498                                                  presentation.nDrcEffectType);
5499                                 notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
5500                                 notify->setInt32("aac-drc-output-loudness",
5501                                                  presentation.nDrcOutputLoudness);
5502                             }
5503                         }
5504                     }
5505                     break;
5506                 }
5507 
5508                 case OMX_AUDIO_CodingAAC:
5509                 {
5510                     OMX_AUDIO_PARAM_AACPROFILETYPE params;
5511                     InitOMXParams(&params);
5512                     params.nPortIndex = portIndex;
5513 
5514                     err = mOMXNode->getParameter(
5515                             OMX_IndexParamAudioAac, &params, sizeof(params));
5516                     if (err != OK) {
5517                         return err;
5518                     }
5519 
5520                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
5521                     notify->setInt32("channel-count", params.nChannels);
5522                     notify->setInt32("sample-rate", params.nSampleRate);
5523                     notify->setInt32("bitrate", params.nBitRate);
5524                     notify->setInt32("aac-profile", params.eAACProfile);
5525                     break;
5526                 }
5527 
5528                 case OMX_AUDIO_CodingAMR:
5529                 {
5530                     OMX_AUDIO_PARAM_AMRTYPE params;
5531                     InitOMXParams(&params);
5532                     params.nPortIndex = portIndex;
5533 
5534                     err = mOMXNode->getParameter(
5535                             OMX_IndexParamAudioAmr, &params, sizeof(params));
5536                     if (err != OK) {
5537                         return err;
5538                     }
5539 
5540                     notify->setInt32("channel-count", 1);
5541                     if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
5542                         notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
5543                         notify->setInt32("sample-rate", 16000);
5544                     } else {
5545                         notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
5546                         notify->setInt32("sample-rate", 8000);
5547                     }
5548                     break;
5549                 }
5550 
5551                 case OMX_AUDIO_CodingFLAC:
5552                 {
5553                     OMX_AUDIO_PARAM_FLACTYPE params;
5554                     InitOMXParams(&params);
5555                     params.nPortIndex = portIndex;
5556 
5557                     err = mOMXNode->getParameter(
5558                             OMX_IndexParamAudioFlac, &params, sizeof(params));
5559                     if (err != OK) {
5560                         return err;
5561                     }
5562 
5563                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
5564                     notify->setInt32("channel-count", params.nChannels);
5565                     notify->setInt32("sample-rate", params.nSampleRate);
5566                     break;
5567                 }
5568 
5569                 case OMX_AUDIO_CodingMP3:
5570                 {
5571                     OMX_AUDIO_PARAM_MP3TYPE params;
5572                     InitOMXParams(&params);
5573                     params.nPortIndex = portIndex;
5574 
5575                     err = mOMXNode->getParameter(
5576                             OMX_IndexParamAudioMp3, &params, sizeof(params));
5577                     if (err != OK) {
5578                         return err;
5579                     }
5580 
5581                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
5582                     notify->setInt32("channel-count", params.nChannels);
5583                     notify->setInt32("sample-rate", params.nSampleRate);
5584                     break;
5585                 }
5586 
5587                 case OMX_AUDIO_CodingVORBIS:
5588                 {
5589                     OMX_AUDIO_PARAM_VORBISTYPE params;
5590                     InitOMXParams(&params);
5591                     params.nPortIndex = portIndex;
5592 
5593                     err = mOMXNode->getParameter(
5594                             OMX_IndexParamAudioVorbis, &params, sizeof(params));
5595                     if (err != OK) {
5596                         return err;
5597                     }
5598 
5599                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
5600                     notify->setInt32("channel-count", params.nChannels);
5601                     notify->setInt32("sample-rate", params.nSampleRate);
5602                     break;
5603                 }
5604 
5605                 case OMX_AUDIO_CodingAndroidAC3:
5606                 {
5607                     OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
5608                     InitOMXParams(&params);
5609                     params.nPortIndex = portIndex;
5610 
5611                     err = mOMXNode->getParameter(
5612                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
5613                             &params, sizeof(params));
5614                     if (err != OK) {
5615                         return err;
5616                     }
5617 
5618                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
5619                     notify->setInt32("channel-count", params.nChannels);
5620                     notify->setInt32("sample-rate", params.nSampleRate);
5621                     break;
5622                 }
5623 
5624                 case OMX_AUDIO_CodingAndroidEAC3:
5625                 {
5626                     OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
5627                     InitOMXParams(&params);
5628                     params.nPortIndex = portIndex;
5629 
5630                     err = mOMXNode->getParameter(
5631                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
5632                             &params, sizeof(params));
5633                     if (err != OK) {
5634                         return err;
5635                     }
5636 
5637                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
5638                     notify->setInt32("channel-count", params.nChannels);
5639                     notify->setInt32("sample-rate", params.nSampleRate);
5640                     break;
5641                 }
5642 
5643                 case OMX_AUDIO_CodingAndroidAC4:
5644                 {
5645                     OMX_AUDIO_PARAM_ANDROID_AC4TYPE params;
5646                     InitOMXParams(&params);
5647                     params.nPortIndex = portIndex;
5648 
5649                     err = mOMXNode->getParameter(
5650                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc4,
5651                             &params, sizeof(params));
5652                     if (err != OK) {
5653                         return err;
5654                     }
5655 
5656                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC4);
5657                     notify->setInt32("channel-count", params.nChannels);
5658                     notify->setInt32("sample-rate", params.nSampleRate);
5659                     break;
5660                 }
5661 
5662                 case OMX_AUDIO_CodingAndroidOPUS:
5663                 {
5664                     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
5665                     InitOMXParams(&params);
5666                     params.nPortIndex = portIndex;
5667 
5668                     err = mOMXNode->getParameter(
5669                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
5670                             &params, sizeof(params));
5671                     if (err != OK) {
5672                         return err;
5673                     }
5674 
5675                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
5676                     notify->setInt32("channel-count", params.nChannels);
5677                     notify->setInt32("sample-rate", params.nSampleRate);
5678                     break;
5679                 }
5680 
5681                 case OMX_AUDIO_CodingG711:
5682                 {
5683                     OMX_AUDIO_PARAM_PCMMODETYPE params;
5684                     InitOMXParams(&params);
5685                     params.nPortIndex = portIndex;
5686 
5687                     err = mOMXNode->getParameter(
5688                             (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
5689                     if (err != OK) {
5690                         return err;
5691                     }
5692 
5693                     const char *mime = NULL;
5694                     if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
5695                         mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
5696                     } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
5697                         mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
5698                     } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
5699                         mime = MEDIA_MIMETYPE_AUDIO_RAW;
5700                     }
5701                     notify->setString("mime", mime);
5702                     notify->setInt32("channel-count", params.nChannels);
5703                     notify->setInt32("sample-rate", params.nSamplingRate);
5704                     notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
5705                     break;
5706                 }
5707 
5708                 case OMX_AUDIO_CodingGSMFR:
5709                 {
5710                     OMX_AUDIO_PARAM_PCMMODETYPE params;
5711                     InitOMXParams(&params);
5712                     params.nPortIndex = portIndex;
5713 
5714                     err = mOMXNode->getParameter(
5715                                 OMX_IndexParamAudioPcm, &params, sizeof(params));
5716                     if (err != OK) {
5717                         return err;
5718                     }
5719 
5720                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
5721                     notify->setInt32("channel-count", params.nChannels);
5722                     notify->setInt32("sample-rate", params.nSamplingRate);
5723                     break;
5724                 }
5725 
5726                 default:
5727                     ALOGE("Unsupported audio coding: %s(%d)\n",
5728                             asString(audioDef->eEncoding), audioDef->eEncoding);
5729                     return BAD_TYPE;
5730             }
5731             break;
5732         }
5733 
5734         default:
5735             ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
5736             return BAD_TYPE;
5737     }
5738 
5739     return getVendorParameters(portIndex, notify);
5740 }
5741 
getHDR10PlusInfo(size_t paramSizeUsed)5742 DescribeHDR10PlusInfoParams* ACodec::getHDR10PlusInfo(size_t paramSizeUsed) {
5743     if (mDescribeHDR10PlusInfoIndex == 0) {
5744         ALOGE("getHDR10PlusInfo: does not support DescribeHDR10PlusInfoParams");
5745         return nullptr;
5746     }
5747 
5748     size_t newSize = sizeof(DescribeHDR10PlusInfoParams) - 1 +
5749             ((paramSizeUsed > 0) ? paramSizeUsed : 512);
5750     if (mHdr10PlusScratchBuffer == nullptr
5751             || newSize > mHdr10PlusScratchBuffer->size()) {
5752         mHdr10PlusScratchBuffer = new ABuffer(newSize);
5753     }
5754     DescribeHDR10PlusInfoParams *config =
5755             (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
5756     InitOMXParams(config);
5757     config->nSize = mHdr10PlusScratchBuffer->size();
5758     config->nPortIndex = 1;
5759     size_t paramSize = config->nSize - sizeof(DescribeHDR10PlusInfoParams) + 1;
5760     config->nParamSize = paramSize;
5761     config->nParamSizeUsed = 0;
5762     status_t err = mOMXNode->getConfig(
5763             (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
5764             config, config->nSize);
5765     if (err != OK) {
5766         ALOGE("failed to get DescribeHDR10PlusInfoParams (err %d)", err);
5767         return nullptr;
5768     }
5769     if (config->nParamSize != paramSize) {
5770         ALOGE("DescribeHDR10PlusInfoParams alters nParamSize: %u vs %zu",
5771                 config->nParamSize, paramSize);
5772         return nullptr;
5773     }
5774     if (paramSizeUsed > 0 && config->nParamSizeUsed != paramSizeUsed) {
5775         ALOGE("DescribeHDR10PlusInfoParams returns wrong nParamSizeUsed: %u vs %zu",
5776                 config->nParamSizeUsed, paramSizeUsed);
5777         return nullptr;
5778     }
5779     return config;
5780 }
5781 
onConfigUpdate(OMX_INDEXTYPE configIndex)5782 void ACodec::onConfigUpdate(OMX_INDEXTYPE configIndex) {
5783     if (mDescribeHDR10PlusInfoIndex == 0
5784             || configIndex != mDescribeHDR10PlusInfoIndex) {
5785         // mDescribeHDR10PlusInfoIndex is the only update we recognize now
5786         return;
5787     }
5788 
5789     DescribeHDR10PlusInfoParams *config = getHDR10PlusInfo();
5790     if (config == nullptr) {
5791         return;
5792     }
5793     if (config->nParamSizeUsed > config->nParamSize) {
5794         // try again with the size specified
5795         config = getHDR10PlusInfo(config->nParamSizeUsed);
5796         if (config == nullptr) {
5797             return;
5798         }
5799     }
5800 
5801     mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5802     mOutputFormat->setBuffer("hdr10-plus-info",
5803             ABuffer::CreateAsCopy(config->nValue, config->nParamSizeUsed));
5804 }
5805 
onDataSpaceChanged(android_dataspace dataSpace,const ColorAspects & aspects)5806 void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5807     // aspects are normally communicated in ColorAspects
5808     int32_t range, standard, transfer;
5809     convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5810 
5811     int32_t dsRange, dsStandard, dsTransfer;
5812     getColorConfigFromDataSpace(dataSpace, &dsRange, &dsStandard, &dsTransfer);
5813 
5814     // if some aspects are unspecified, use dataspace fields
5815     if (range == 0) {
5816         range = dsRange;
5817     }
5818     if (standard == 0) {
5819         standard = dsStandard;
5820     }
5821     if (transfer == 0) {
5822         transfer = dsTransfer;
5823     }
5824 
5825     mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5826     if (range != 0) {
5827         mOutputFormat->setInt32("color-range", range);
5828     }
5829     if (standard != 0) {
5830         mOutputFormat->setInt32("color-standard", standard);
5831     }
5832     if (transfer != 0) {
5833         mOutputFormat->setInt32("color-transfer", transfer);
5834     }
5835 
5836     ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5837           "(R:%d(%s), S:%d(%s), T:%d(%s))",
5838             dataSpace,
5839             aspects.mRange, asString(aspects.mRange),
5840             aspects.mPrimaries, asString(aspects.mPrimaries),
5841             aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5842             aspects.mTransfer, asString(aspects.mTransfer),
5843             range, asString((ColorRange)range),
5844             standard, asString((ColorStandard)standard),
5845             transfer, asString((ColorTransfer)transfer));
5846 }
5847 
onOutputFormatChanged(sp<const AMessage> expectedFormat)5848 void ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5849     // store new output format, at the same time mark that this is no longer the first frame
5850     mOutputFormat = mBaseOutputFormat->dup();
5851 
5852     if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5853         ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5854         return;
5855     }
5856 
5857     if (expectedFormat != NULL) {
5858         sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
5859         sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
5860         if (changes->countEntries() != 0 || to->countEntries() != 0) {
5861             ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
5862                     mComponentName.c_str(),
5863                     changes->debugString(4).c_str(), to->debugString(4).c_str());
5864         }
5865     }
5866 
5867     if (!mIsVideo && !mIsEncoder) {
5868         AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
5869         (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
5870         AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
5871         (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
5872 
5873         mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
5874         if (mConverter[kPortIndexOutput] != NULL) {
5875             mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
5876         }
5877     }
5878 
5879     if (mTunneled) {
5880         sendFormatChange();
5881     }
5882 }
5883 
sendFormatChange()5884 void ACodec::sendFormatChange() {
5885     AString mime;
5886     CHECK(mOutputFormat->findString("mime", &mime));
5887 
5888     if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5889         int32_t channelCount, sampleRate;
5890         CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5891         CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5892         if (mSampleRate != 0 && sampleRate != 0) {
5893             // avoiding 32-bit overflows in intermediate values
5894             mEncoderDelay = (int32_t)((((int64_t)mEncoderDelay) * sampleRate) / mSampleRate);
5895             mEncoderPadding = (int32_t)((((int64_t)mEncoderPadding) * sampleRate) / mSampleRate);
5896             mSampleRate = sampleRate;
5897         }
5898         if (mSkipCutBuffer != NULL) {
5899             size_t prevbufsize = mSkipCutBuffer->size();
5900             if (prevbufsize != 0) {
5901                 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5902             }
5903         }
5904         mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5905     }
5906 
5907     // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5908     mLastOutputFormat = mOutputFormat;
5909 }
5910 
signalError(OMX_ERRORTYPE error,status_t internalError)5911 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5912     ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5913 
5914     if (internalError == UNKNOWN_ERROR) { // find better error code
5915         const status_t omxStatus = statusFromOMXError(error);
5916         if (omxStatus != 0) {
5917             internalError = omxStatus;
5918         } else {
5919             ALOGW("Invalid OMX error %#x", error);
5920         }
5921     }
5922 
5923     mFatalError = true;
5924     mCallback->onError(internalError, ACTION_CODE_FATAL);
5925 }
5926 
requestIDRFrame()5927 status_t ACodec::requestIDRFrame() {
5928     if (!mIsEncoder) {
5929         return ERROR_UNSUPPORTED;
5930     }
5931 
5932     OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5933     InitOMXParams(&params);
5934 
5935     params.nPortIndex = kPortIndexOutput;
5936     params.IntraRefreshVOP = OMX_TRUE;
5937 
5938     return mOMXNode->setConfig(
5939             OMX_IndexConfigVideoIntraVOPRefresh,
5940             &params,
5941             sizeof(params));
5942 }
5943 
5944 ////////////////////////////////////////////////////////////////////////////////
5945 
BaseState(ACodec * codec,const sp<AState> & parentState)5946 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5947     : AState(parentState),
5948       mCodec(codec),
5949       mPendingExtraOutputMetadataBufferRequest(false) {
5950 }
5951 
getPortMode(OMX_U32)5952 ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5953         OMX_U32 /* portIndex */) {
5954     return KEEP_BUFFERS;
5955 }
5956 
stateExited()5957 void ACodec::BaseState::stateExited() {
5958     ++mCodec->mStateGeneration;
5959 }
5960 
onMessageReceived(const sp<AMessage> & msg)5961 bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5962     switch (msg->what()) {
5963         case kWhatInputBufferFilled:
5964         {
5965             onInputBufferFilled(msg);
5966             break;
5967         }
5968 
5969         case kWhatOutputBufferDrained:
5970         {
5971             onOutputBufferDrained(msg);
5972             break;
5973         }
5974 
5975         case ACodec::kWhatOMXMessageList:
5976         {
5977             return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
5978         }
5979 
5980         case ACodec::kWhatOMXMessageItem:
5981         {
5982             // no need to check as we already did it for kWhatOMXMessageList
5983             return onOMXMessage(msg);
5984         }
5985 
5986         case ACodec::kWhatOMXMessage:
5987         {
5988             return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5989         }
5990 
5991         case ACodec::kWhatSetSurface:
5992         {
5993             sp<AReplyToken> replyID;
5994             CHECK(msg->senderAwaitsResponse(&replyID));
5995 
5996             sp<RefBase> obj;
5997             CHECK(msg->findObject("surface", &obj));
5998 
5999             status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
6000 
6001             sp<AMessage> response = new AMessage;
6002             response->setInt32("err", err);
6003             response->postReply(replyID);
6004             break;
6005         }
6006 
6007         case ACodec::kWhatCreateInputSurface:
6008         case ACodec::kWhatSetInputSurface:
6009         case ACodec::kWhatSignalEndOfInputStream:
6010         {
6011             // This may result in an app illegal state exception.
6012             ALOGE("Message 0x%x was not handled", msg->what());
6013             mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
6014             return true;
6015         }
6016 
6017         case ACodec::kWhatOMXDied:
6018         {
6019             // This will result in kFlagSawMediaServerDie handling in MediaCodec.
6020             ALOGE("OMX/mediaserver died, signalling error!");
6021             mCodec->mGraphicBufferSource.clear();
6022             mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
6023             break;
6024         }
6025 
6026         case ACodec::kWhatReleaseCodecInstance:
6027         {
6028             ALOGI("[%s] forcing the release of codec",
6029                     mCodec->mComponentName.c_str());
6030             status_t err = mCodec->mOMXNode->freeNode();
6031             ALOGE_IF("[%s] failed to release codec instance: err=%d",
6032                        mCodec->mComponentName.c_str(), err);
6033             mCodec->mCallback->onReleaseCompleted();
6034 
6035             mCodec->changeState(mCodec->mUninitializedState);
6036             break;
6037         }
6038 
6039         case ACodec::kWhatForceStateTransition:
6040         {
6041             ALOGV("Already transitioned --- ignore");
6042             break;
6043         }
6044 
6045         case kWhatCheckIfStuck: {
6046             ALOGV("No-op by default");
6047             break;
6048         }
6049 
6050         case kWhatSubmitExtraOutputMetadataBuffer: {
6051             mPendingExtraOutputMetadataBufferRequest = false;
6052             if (getPortMode(kPortIndexOutput) == RESUBMIT_BUFFERS && mCodec->mIsLowLatency) {
6053                 // Decoders often need more than one output buffer to be
6054                 // submitted before processing a single input buffer.
6055                 // For low latency codecs, we don't want to wait for more input
6056                 // to be queued to get those output buffers submitted.
6057                 if (mCodec->submitOutputMetadataBuffer() == OK
6058                         && mCodec->mMetadataBuffersToSubmit > 0) {
6059                     maybePostExtraOutputMetadataBufferRequest();
6060                 }
6061             }
6062             break;
6063         }
6064 
6065         default:
6066             return false;
6067     }
6068 
6069     return true;
6070 }
6071 
checkOMXMessage(const sp<AMessage> & msg)6072 bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
6073     // there is a possibility that this is an outstanding message for a
6074     // codec that we have already destroyed
6075     if (mCodec->mOMXNode == NULL) {
6076         ALOGI("ignoring message as already freed component: %s",
6077                 msg->debugString().c_str());
6078         return false;
6079     }
6080 
6081     int32_t generation;
6082     CHECK(msg->findInt32("generation", (int32_t*)&generation));
6083     if (generation != mCodec->mNodeGeneration) {
6084         ALOGW("Unexpected message for component: %s, gen %u, cur %u",
6085                 msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
6086         return false;
6087     }
6088     return true;
6089 }
6090 
onOMXMessageList(const sp<AMessage> & msg)6091 bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
6092     sp<RefBase> obj;
6093     CHECK(msg->findObject("messages", &obj));
6094     sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
6095     for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
6096           it != msgList->getList().cend(); ++it) {
6097         (*it)->setWhat(ACodec::kWhatOMXMessageItem);
6098         mCodec->handleMessage(*it);
6099     }
6100     return true;
6101 }
6102 
onOMXMessage(const sp<AMessage> & msg)6103 bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
6104     int32_t type;
6105     CHECK(msg->findInt32("type", &type));
6106 
6107     switch (type) {
6108         case omx_message::EVENT:
6109         {
6110             int32_t event, data1, data2;
6111             CHECK(msg->findInt32("event", &event));
6112             CHECK(msg->findInt32("data1", &data1));
6113             CHECK(msg->findInt32("data2", &data2));
6114 
6115             if (event == OMX_EventCmdComplete
6116                     && data1 == OMX_CommandFlush
6117                     && data2 == (int32_t)OMX_ALL) {
6118                 // Use of this notification is not consistent across
6119                 // implementations. We'll drop this notification and rely
6120                 // on flush-complete notifications on the individual port
6121                 // indices instead.
6122 
6123                 return true;
6124             }
6125 
6126             return onOMXEvent(
6127                     static_cast<OMX_EVENTTYPE>(event),
6128                     static_cast<OMX_U32>(data1),
6129                     static_cast<OMX_U32>(data2));
6130         }
6131 
6132         case omx_message::EMPTY_BUFFER_DONE:
6133         {
6134             IOMX::buffer_id bufferID;
6135             int32_t fenceFd;
6136 
6137             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
6138             CHECK(msg->findInt32("fence_fd", &fenceFd));
6139 
6140             return onOMXEmptyBufferDone(bufferID, fenceFd);
6141         }
6142 
6143         case omx_message::FILL_BUFFER_DONE:
6144         {
6145             IOMX::buffer_id bufferID;
6146             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
6147 
6148             int32_t rangeOffset, rangeLength, flags, fenceFd;
6149             int64_t timeUs;
6150 
6151             CHECK(msg->findInt32("range_offset", &rangeOffset));
6152             CHECK(msg->findInt32("range_length", &rangeLength));
6153             CHECK(msg->findInt32("flags", &flags));
6154             CHECK(msg->findInt64("timestamp", &timeUs));
6155             CHECK(msg->findInt32("fence_fd", &fenceFd));
6156 
6157             return onOMXFillBufferDone(
6158                     bufferID,
6159                     (size_t)rangeOffset, (size_t)rangeLength,
6160                     (OMX_U32)flags,
6161                     timeUs,
6162                     fenceFd);
6163         }
6164 
6165         case omx_message::FRAME_RENDERED:
6166         {
6167             int64_t mediaTimeUs, systemNano;
6168 
6169             CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
6170             CHECK(msg->findInt64("system_nano", &systemNano));
6171 
6172             return onOMXFrameRendered(
6173                     mediaTimeUs, systemNano);
6174         }
6175 
6176         default:
6177             ALOGE("Unexpected message type: %d", type);
6178             return false;
6179     }
6180 }
6181 
onOMXFrameRendered(int64_t mediaTimeUs __unused,nsecs_t systemNano __unused)6182 bool ACodec::BaseState::onOMXFrameRendered(
6183         int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
6184     // ignore outside of Executing and PortSettingsChanged states
6185     return true;
6186 }
6187 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6188 bool ACodec::BaseState::onOMXEvent(
6189         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6190     if (event == OMX_EventDataSpaceChanged) {
6191         ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
6192 
6193         mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
6194         return true;
6195     }
6196 
6197     if (event != OMX_EventError) {
6198         ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
6199              mCodec->mComponentName.c_str(), event, data1, data2);
6200 
6201         return false;
6202     }
6203 
6204     if (mCodec->mIsStreamCorruptFree && data1 == (OMX_U32)OMX_ErrorStreamCorrupt) {
6205         ALOGV("[%s] handle OMX_ErrorStreamCorrupt as a normal operation",
6206                 mCodec->mComponentName.c_str());
6207         return true;
6208     }
6209 
6210     ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
6211 
6212     // verify OMX component sends back an error we expect.
6213     OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
6214     if (!isOMXError(omxError)) {
6215         ALOGW("Invalid OMX error %#x", omxError);
6216         omxError = OMX_ErrorUndefined;
6217     }
6218     mCodec->signalError(omxError);
6219 
6220     return true;
6221 }
6222 
onOMXEmptyBufferDone(IOMX::buffer_id bufferID,int fenceFd)6223 bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
6224     ALOGV("[%s] onOMXEmptyBufferDone %u",
6225          mCodec->mComponentName.c_str(), bufferID);
6226 
6227     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
6228     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
6229     if (status != BufferInfo::OWNED_BY_COMPONENT) {
6230         ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
6231         mCodec->dumpBuffers(kPortIndexInput);
6232         if (fenceFd >= 0) {
6233             ::close(fenceFd);
6234         }
6235         return false;
6236     }
6237     info->mStatus = BufferInfo::OWNED_BY_US;
6238 
6239     // input buffers cannot take fences, so wait for any fence now
6240     (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
6241     fenceFd = -1;
6242 
6243     // still save fence for completeness
6244     info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
6245 
6246     // We're in "store-metadata-in-buffers" mode, the underlying
6247     // OMX component had access to data that's implicitly refcounted
6248     // by this "MediaBuffer" object. Now that the OMX component has
6249     // told us that it's done with the input buffer, we can decrement
6250     // the mediaBuffer's reference count.
6251     info->mData->meta()->setObject("mediaBufferHolder", sp<MediaBufferHolder>(nullptr));
6252 
6253     PortMode mode = getPortMode(kPortIndexInput);
6254 
6255     switch (mode) {
6256         case KEEP_BUFFERS:
6257             break;
6258 
6259         case RESUBMIT_BUFFERS:
6260             postFillThisBuffer(info);
6261             break;
6262 
6263         case FREE_BUFFERS:
6264         default:
6265             ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
6266             return false;
6267     }
6268 
6269     return true;
6270 }
6271 
postFillThisBuffer(BufferInfo * info)6272 void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
6273     if (mCodec->mPortEOS[kPortIndexInput]) {
6274         return;
6275     }
6276 
6277     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
6278 
6279     info->mData->setFormat(mCodec->mInputFormat);
6280     mCodec->mBufferChannel->fillThisBuffer(info->mBufferID);
6281     info->mData.clear();
6282     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
6283 }
6284 
onInputBufferFilled(const sp<AMessage> & msg)6285 void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
6286     IOMX::buffer_id bufferID;
6287     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
6288     sp<MediaCodecBuffer> buffer;
6289     int32_t err = OK;
6290     bool eos = false;
6291     PortMode mode = getPortMode(kPortIndexInput);
6292     int32_t discarded = 0;
6293     if (msg->findInt32("discarded", &discarded) && discarded) {
6294         // these are unfilled buffers returned by client
6295         // buffers are returned on MediaCodec.flush
6296         mode = KEEP_BUFFERS;
6297     }
6298     sp<RefBase> obj;
6299     CHECK(msg->findObject("buffer", &obj));
6300     buffer = static_cast<MediaCodecBuffer *>(obj.get());
6301 
6302     int32_t tmp;
6303     if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
6304         eos = true;
6305         err = ERROR_END_OF_STREAM;
6306     }
6307 
6308     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
6309     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
6310     if (status != BufferInfo::OWNED_BY_UPSTREAM) {
6311         ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
6312         mCodec->dumpBuffers(kPortIndexInput);
6313         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6314         return;
6315     }
6316 
6317     int32_t cvo;
6318     if (mCodec->mNativeWindow != NULL && buffer != NULL &&
6319             buffer->meta()->findInt32("cvo", &cvo)) {
6320         ALOGV("cvo(%d) found in buffer #%u", cvo, bufferID);
6321         setNativeWindowRotation(mCodec->mNativeWindow.get(), cvo);
6322     }
6323 
6324     info->mStatus = BufferInfo::OWNED_BY_US;
6325     info->mData = buffer;
6326 
6327     switch (mode) {
6328         case KEEP_BUFFERS:
6329         {
6330             if (eos) {
6331                 if (!mCodec->mPortEOS[kPortIndexInput]) {
6332                     mCodec->mPortEOS[kPortIndexInput] = true;
6333                     mCodec->mInputEOSResult = err;
6334                 }
6335             }
6336             break;
6337         }
6338 
6339         case RESUBMIT_BUFFERS:
6340         {
6341             if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
6342                 // Do not send empty input buffer w/o EOS to the component.
6343                 if (buffer->size() == 0 && !eos) {
6344                     postFillThisBuffer(info);
6345                     break;
6346                 }
6347 
6348                 int64_t timeUs;
6349                 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
6350 
6351                 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
6352 
6353                 int32_t isCSD = 0;
6354                 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
6355                     if (mCodec->mIsLegacyVP9Decoder) {
6356                         ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
6357                             mCodec->mComponentName.c_str(), bufferID);
6358                         postFillThisBuffer(info);
6359                         break;
6360                     }
6361                     flags |= OMX_BUFFERFLAG_CODECCONFIG;
6362                 }
6363 
6364                 if (eos) {
6365                     flags |= OMX_BUFFERFLAG_EOS;
6366                 }
6367 
6368                 int32_t isDecodeOnly = 0;
6369                 if (buffer->meta()->findInt32("decode-only", &isDecodeOnly) && isDecodeOnly != 0) {
6370                     flags |= OMX_BUFFERFLAG_DECODEONLY;
6371                     mCodec->mDecodeOnlyTimesUs.emplace(timeUs);
6372                 }
6373                 size_t size = buffer->size();
6374                 size_t offset = buffer->offset();
6375                 if (buffer->base() != info->mCodecData->base()) {
6376                     ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
6377                          mCodec->mComponentName.c_str(),
6378                          bufferID,
6379                          buffer->base(), info->mCodecData->base());
6380 
6381                     sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
6382                     if (converter == NULL || isCSD) {
6383                         converter = getCopyConverter();
6384                     }
6385                     status_t err = converter->convert(buffer, info->mCodecData);
6386                     if (err != OK) {
6387                         mCodec->signalError(OMX_ErrorUndefined, err);
6388                         return;
6389                     }
6390                     size = info->mCodecData->size();
6391                 } else {
6392                     info->mCodecData->setRange(offset, size);
6393                 }
6394 
6395                 if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
6396                     ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
6397                          mCodec->mComponentName.c_str(), bufferID);
6398                 } else if (flags & OMX_BUFFERFLAG_EOS) {
6399                     ALOGV("[%s] calling emptyBuffer %u w/ EOS",
6400                          mCodec->mComponentName.c_str(), bufferID);
6401                 } else {
6402                     if (flags & OMX_BUFFERFLAG_DECODEONLY) {
6403                         ALOGV("[%s] calling emptyBuffer %u w/ decode only flag",
6404                             mCodec->mComponentName.c_str(), bufferID);
6405                     }
6406 #if TRACK_BUFFER_TIMING
6407                     ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
6408                          mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
6409 #else
6410                     ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
6411                          mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
6412 #endif
6413                 }
6414 
6415 #if TRACK_BUFFER_TIMING
6416                 ACodec::BufferStats stats;
6417                 stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
6418                 stats.mFillBufferDoneTimeUs = -1ll;
6419                 mCodec->mBufferStats.add(timeUs, stats);
6420 #endif
6421 
6422                 if (mCodec->storingMetadataInDecodedBuffers()) {
6423                     // try to submit an output buffer for each input buffer
6424                     PortMode outputMode = getPortMode(kPortIndexOutput);
6425 
6426                     ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
6427                             mCodec->mMetadataBuffersToSubmit,
6428                             (outputMode == FREE_BUFFERS ? "FREE" :
6429                              outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
6430                     if (outputMode == RESUBMIT_BUFFERS) {
6431                         status_t err = mCodec->submitOutputMetadataBuffer();
6432                         if (mCodec->mIsLowLatency
6433                                 && err == OK
6434                                 && mCodec->mMetadataBuffersToSubmit > 0) {
6435                             maybePostExtraOutputMetadataBufferRequest();
6436                         }
6437                     }
6438                 }
6439                 info->checkReadFence("onInputBufferFilled");
6440 
6441                 status_t err2 = OK;
6442                 switch (mCodec->mPortMode[kPortIndexInput]) {
6443                 case IOMX::kPortModePresetByteBuffer:
6444                 case IOMX::kPortModePresetANWBuffer:
6445                 case IOMX::kPortModePresetSecureBuffer:
6446                     {
6447                         err2 = mCodec->mOMXNode->emptyBuffer(
6448                             bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
6449                     }
6450                     break;
6451 #ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
6452                 case IOMX::kPortModeDynamicNativeHandle:
6453                     if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
6454                         VideoNativeHandleMetadata *vnhmd =
6455                             (VideoNativeHandleMetadata*)info->mCodecData->base();
6456                         sp<NativeHandle> handle = NativeHandle::create(
6457                                 vnhmd->pHandle, false /* ownsHandle */);
6458                         err2 = mCodec->mOMXNode->emptyBuffer(
6459                             bufferID, handle, flags, timeUs, info->mFenceFd);
6460                     }
6461                     break;
6462                 case IOMX::kPortModeDynamicANWBuffer:
6463                     if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
6464                         VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
6465                         sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer);
6466                         err2 = mCodec->mOMXNode->emptyBuffer(
6467                             bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
6468                     }
6469                     break;
6470 #endif
6471                 default:
6472                     ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
6473                             asString(mCodec->mPortMode[kPortIndexInput]),
6474                             info->mCodecData->size(),
6475                             sizeof(buffer_handle_t) * 8);
6476                     err2 = ERROR_UNSUPPORTED;
6477                     break;
6478                 }
6479 
6480                 info->mFenceFd = -1;
6481                 if (err2 != OK) {
6482                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
6483                     return;
6484                 }
6485                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6486                 // Hold the reference while component is using the buffer.
6487                 info->mData = buffer;
6488 
6489                 if (!eos && err == OK) {
6490                     getMoreInputDataIfPossible();
6491                 } else {
6492                     ALOGV("[%s] Signalled EOS (%d) on the input port",
6493                          mCodec->mComponentName.c_str(), err);
6494 
6495                     mCodec->mPortEOS[kPortIndexInput] = true;
6496                     mCodec->mInputEOSResult = err;
6497                 }
6498             } else if (!mCodec->mPortEOS[kPortIndexInput]) {
6499                 if (err != OK && err != ERROR_END_OF_STREAM) {
6500                     ALOGV("[%s] Signalling EOS on the input port due to error %d",
6501                          mCodec->mComponentName.c_str(), err);
6502                 } else {
6503                     ALOGV("[%s] Signalling EOS on the input port",
6504                          mCodec->mComponentName.c_str());
6505                 }
6506 
6507                 ALOGV("[%s] calling emptyBuffer %u signalling EOS",
6508                      mCodec->mComponentName.c_str(), bufferID);
6509 
6510                 info->checkReadFence("onInputBufferFilled");
6511                 status_t err2 = mCodec->mOMXNode->emptyBuffer(
6512                         bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
6513                 info->mFenceFd = -1;
6514                 if (err2 != OK) {
6515                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
6516                     return;
6517                 }
6518                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6519 
6520                 mCodec->mPortEOS[kPortIndexInput] = true;
6521                 mCodec->mInputEOSResult = err;
6522             }
6523             break;
6524         }
6525 
6526         case FREE_BUFFERS:
6527             break;
6528 
6529         default:
6530             ALOGE("invalid port mode: %d", mode);
6531             break;
6532     }
6533 }
6534 
getMoreInputDataIfPossible()6535 void ACodec::BaseState::getMoreInputDataIfPossible() {
6536     if (mCodec->mPortEOS[kPortIndexInput]) {
6537         return;
6538     }
6539 
6540     BufferInfo *eligible = NULL;
6541 
6542     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6543         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput][i];
6544 
6545 #if 0
6546         if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
6547             // There's already a "read" pending.
6548             return;
6549         }
6550 #endif
6551 
6552         if (info->mStatus == BufferInfo::OWNED_BY_US) {
6553             eligible = info;
6554         }
6555     }
6556 
6557     if (eligible == NULL) {
6558         return;
6559     }
6560 
6561     postFillThisBuffer(eligible);
6562 }
6563 
setSurfaceParameters(const sp<AMessage> & msg)6564 void ACodec::BaseState::setSurfaceParameters(const sp<AMessage> &msg) {
6565     sp<AMessage> params;
6566     CHECK(msg->findMessage("params", &params));
6567 
6568     status_t err = mCodec->setSurfaceParameters(params);
6569     if (err != OK) {
6570         ALOGE("[%s] Unable to set input surface parameters (err %d)",
6571                 mCodec->mComponentName.c_str(),
6572                 err);
6573         return;
6574     }
6575 
6576     int64_t timeOffsetUs;
6577     if (params->findInt64(PARAMETER_KEY_OFFSET_TIME, &timeOffsetUs)) {
6578         params->removeEntryAt(params->findEntryByName(PARAMETER_KEY_OFFSET_TIME));
6579 
6580         if (params->countEntries() == 0) {
6581             msg->removeEntryAt(msg->findEntryByName("params"));
6582             return;
6583         }
6584     }
6585 
6586     int64_t skipFramesBeforeUs;
6587     if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
6588         params->removeEntryAt(params->findEntryByName("skip-frames-before"));
6589 
6590         if (params->countEntries() == 0) {
6591             msg->removeEntryAt(msg->findEntryByName("params"));
6592             return;
6593         }
6594     }
6595 
6596     int32_t dropInputFrames;
6597     if (params->findInt32(PARAMETER_KEY_SUSPEND, &dropInputFrames)) {
6598         params->removeEntryAt(params->findEntryByName(PARAMETER_KEY_SUSPEND));
6599 
6600         if (params->countEntries() == 0) {
6601             msg->removeEntryAt(msg->findEntryByName("params"));
6602             return;
6603         }
6604     }
6605 
6606     int64_t stopTimeUs;
6607     if (params->findInt64("stop-time-us", &stopTimeUs)) {
6608         params->removeEntryAt(params->findEntryByName("stop-time-us"));
6609 
6610         if (params->countEntries() == 0) {
6611             msg->removeEntryAt(msg->findEntryByName("params"));
6612             return;
6613         }
6614     }
6615 }
6616 
onOMXFillBufferDone(IOMX::buffer_id bufferID,size_t rangeOffset,size_t rangeLength,OMX_U32 flags,int64_t timeUs,int fenceFd)6617 bool ACodec::BaseState::onOMXFillBufferDone(
6618         IOMX::buffer_id bufferID,
6619         size_t rangeOffset, size_t rangeLength,
6620         OMX_U32 flags,
6621         int64_t timeUs,
6622         int fenceFd) {
6623     ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
6624          mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
6625 
6626     ssize_t index;
6627     status_t err= OK;
6628 
6629 #if TRACK_BUFFER_TIMING
6630     index = mCodec->mBufferStats.indexOfKey(timeUs);
6631     if (index >= 0) {
6632         ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
6633         stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
6634 
6635         ALOGI("frame PTS %lld: %lld",
6636                 timeUs,
6637                 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
6638 
6639         mCodec->mBufferStats.removeItemsAt(index);
6640         stats = NULL;
6641     }
6642 #endif
6643 
6644     BufferInfo *info =
6645         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
6646     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
6647     if (status != BufferInfo::OWNED_BY_COMPONENT) {
6648         ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
6649         mCodec->dumpBuffers(kPortIndexOutput);
6650         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6651         if (fenceFd >= 0) {
6652             ::close(fenceFd);
6653         }
6654         return true;
6655     }
6656 
6657     info->mDequeuedAt = ++mCodec->mDequeueCounter;
6658     info->mStatus = BufferInfo::OWNED_BY_US;
6659 
6660     // byte buffers cannot take fences, so wait for any fence now
6661     if (mCodec->mNativeWindow == NULL) {
6662         (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
6663         fenceFd = -1;
6664     }
6665     info->setReadFence(fenceFd, "onOMXFillBufferDone");
6666 
6667     PortMode mode = getPortMode(kPortIndexOutput);
6668 
6669     switch (mode) {
6670         case KEEP_BUFFERS:
6671             break;
6672 
6673         case RESUBMIT_BUFFERS:
6674         {
6675             if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
6676                     || mCodec->mPortEOS[kPortIndexOutput])) {
6677                 ALOGV("[%s] calling fillBuffer %u",
6678                      mCodec->mComponentName.c_str(), info->mBufferID);
6679 
6680                 err = mCodec->fillBuffer(info);
6681                 if (err != OK) {
6682                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6683                     return true;
6684                 }
6685                 break;
6686             }
6687 
6688             sp<MediaCodecBuffer> buffer = info->mData;
6689 
6690             if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
6691                 // pretend that output format has changed on the first frame (we used to do this)
6692                 if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
6693                     mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
6694                 }
6695                 mCodec->sendFormatChange();
6696             }
6697             buffer->setFormat(mCodec->mOutputFormat);
6698 
6699             if (mCodec->usingSecureBufferOnEncoderOutput()) {
6700                 native_handle_t *handle = NULL;
6701                 sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
6702                 if (secureBuffer != NULL) {
6703 #ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
6704                     // handle is only valid on 32-bit/mediaserver process
6705                     handle = NULL;
6706 #else
6707                     handle = (native_handle_t *)secureBuffer->getDestinationPointer();
6708 #endif
6709                 }
6710                 buffer->meta()->setPointer("handle", handle);
6711                 buffer->meta()->setInt32("rangeOffset", rangeOffset);
6712                 buffer->meta()->setInt32("rangeLength", rangeLength);
6713             } else if (buffer->base() == info->mCodecData->base()) {
6714                 buffer->setRange(rangeOffset, rangeLength);
6715             } else {
6716                 info->mCodecData->setRange(rangeOffset, rangeLength);
6717                 // in this case we know that mConverter is not null
6718                 status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
6719                         info->mCodecData, buffer);
6720                 if (err != OK) {
6721                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6722                     return true;
6723                 }
6724             }
6725 #if 0
6726             if (mCodec->mNativeWindow == NULL) {
6727                 if (IsIDR(info->mData->data(), info->mData->size())) {
6728                     ALOGI("IDR frame");
6729                 }
6730             }
6731 #endif
6732 
6733             if (mCodec->mSkipCutBuffer != NULL) {
6734                 mCodec->mSkipCutBuffer->submit(buffer);
6735             }
6736             buffer->meta()->setInt64("timeUs", timeUs);
6737 
6738             info->mData.clear();
6739 
6740             // Workaround: if OMX_BUFFERFLAG_DECODEONLY is not implemented in
6741             // HAL, the flag is then removed in the corresponding output buffer.
6742 
6743             // for all buffers that were marked as DECODE_ONLY, remove their timestamp
6744             // if it is smaller than the timestamp of the buffer that was
6745             // just received
6746             while (!mCodec->mDecodeOnlyTimesUs.empty() &&
6747                    *mCodec->mDecodeOnlyTimesUs.begin() < timeUs) {
6748                     mCodec->mDecodeOnlyTimesUs.erase(mCodec->mDecodeOnlyTimesUs.begin());
6749             }
6750             // if OMX_BUFFERFLAG_DECODEONLY is not implemented in HAL, we need to restore the
6751             // OMX_BUFFERFLAG_DECODEONLY flag to the frames we had saved in the set, the set
6752             // contains the timestamps of buffers that were marked as DECODE_ONLY by the app
6753             if (!mCodec->mDecodeOnlyTimesUs.empty() &&
6754                 *mCodec->mDecodeOnlyTimesUs.begin() == timeUs) {
6755                 mCodec->mDecodeOnlyTimesUs.erase(timeUs);
6756                 // If the app queued the last valid buffer as DECODE_ONLY and queued an additional
6757                 // empty buffer as EOS, it's possible that HAL sets the last valid frame as EOS
6758                 // instead and drops the empty buffer. In such a case, we should not add back
6759                 // the OMX_BUFFERFLAG_DECODEONLY flag to it, as doing so will make it so that the
6760                 // app does not receive the EOS buffer, which breaks the contract of EOS buffers
6761                 if (flags & OMX_BUFFERFLAG_EOS) {
6762                     // Set buffer size to 0, as described by
6763                     // https://developer.android.com/reference/android/media/MediaCodec.BufferInfo?hl=en#size
6764                     // a buffer of size 0 should only be used to carry the EOS flag and should
6765                     // be discarded by the app as it has no data
6766                     buffer->setRange(0, 0);
6767                 } else {
6768                     // re-add the OMX_BUFFERFLAG_DECODEONLY flag to the buffer in case it is
6769                     // not the end of stream buffer
6770                     flags |= OMX_BUFFERFLAG_DECODEONLY;
6771                 }
6772             }
6773             mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);
6774 
6775             info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6776 
6777             if (flags & OMX_BUFFERFLAG_EOS) {
6778                 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
6779 
6780                 mCodec->mCallback->onEos(mCodec->mInputEOSResult);
6781                 mCodec->mPortEOS[kPortIndexOutput] = true;
6782             }
6783             break;
6784         }
6785 
6786         case FREE_BUFFERS:
6787             err = mCodec->freeBuffer(kPortIndexOutput, index);
6788             if (err != OK) {
6789                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6790                 return true;
6791             }
6792             break;
6793 
6794         default:
6795             ALOGE("Invalid port mode: %d", mode);
6796             return false;
6797     }
6798 
6799     return true;
6800 }
6801 
onOutputBufferDrained(const sp<AMessage> & msg)6802 void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6803     IOMX::buffer_id bufferID;
6804     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
6805     sp<RefBase> obj;
6806     CHECK(msg->findObject("buffer", &obj));
6807     sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
6808     int32_t discarded = 0;
6809     msg->findInt32("discarded", &discarded);
6810 
6811     ssize_t index;
6812     BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
6813     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
6814     if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
6815         ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
6816         mCodec->dumpBuffers(kPortIndexOutput);
6817         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6818         return;
6819     }
6820     info->mData = buffer;
6821     int32_t render;
6822     if (mCodec->mNativeWindow != NULL
6823             && msg->findInt32("render", &render) && render != 0
6824             && !discarded && buffer->size() != 0) {
6825         ATRACE_NAME("render");
6826         // The client wants this buffer to be rendered.
6827 
6828         android_native_rect_t crop;
6829         if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
6830             // NOTE: native window uses extended right-bottom coordinate
6831             ++crop.right;
6832             ++crop.bottom;
6833             if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6834                 mCodec->mLastNativeWindowCrop = crop;
6835                 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6836                 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6837             }
6838         }
6839 
6840         int32_t dataSpace;
6841         if (buffer->format()->findInt32("android._dataspace", &dataSpace)
6842                 && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6843             status_t err = native_window_set_buffers_data_space(
6844                     mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6845             mCodec->mLastNativeWindowDataSpace = dataSpace;
6846             ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6847         }
6848         if (buffer->format()->contains("hdr-static-info")) {
6849             HDRStaticInfo info;
6850             if (ColorUtils::getHDRStaticInfoFromFormat(buffer->format(), &info)
6851                 && memcmp(&mCodec->mLastHDRStaticInfo, &info, sizeof(info))) {
6852                 setNativeWindowHdrMetadata(mCodec->mNativeWindow.get(), &info);
6853                 mCodec->mLastHDRStaticInfo = info;
6854             }
6855         }
6856 
6857         sp<ABuffer> hdr10PlusInfo;
6858         if (buffer->format()->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
6859                 && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0
6860                 && hdr10PlusInfo != mCodec->mLastHdr10PlusBuffer) {
6861             native_window_set_buffers_hdr10_plus_metadata(mCodec->mNativeWindow.get(),
6862                     hdr10PlusInfo->size(), hdr10PlusInfo->data());
6863             mCodec->mLastHdr10PlusBuffer = hdr10PlusInfo;
6864         }
6865 
6866         int64_t timestampNs = 0;
6867         if (!msg->findInt64("timestampNs", &timestampNs)) {
6868             // use media timestamp if client did not request a specific render timestamp
6869             if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6870                 ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6871                 timestampNs *= 1000;
6872             }
6873         }
6874 
6875         status_t err;
6876         err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
6877         ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6878 
6879         uint64_t frameId;
6880         err = native_window_get_next_frame_id(mCodec->mNativeWindow.get(), &frameId);
6881 
6882         info->checkReadFence("onOutputBufferDrained before queueBuffer");
6883         err = mCodec->mNativeWindow->queueBuffer(
6884                     mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
6885 
6886         int64_t mediaTimeUs = -1;
6887         buffer->meta()->findInt64("timeUs", &mediaTimeUs);
6888         if (mCodec->mAreRenderMetricsEnabled && mCodec->mIsWindowToDisplay) {
6889             mCodec->trackReleasedFrame(frameId, mediaTimeUs, timestampNs);
6890             mCodec->pollForRenderedFrames();
6891         } else {
6892             // When the surface is an intermediate surface, onFrameRendered is triggered immediately
6893             // when the frame is queued to the non-display surface
6894             mCodec->mCallback->onOutputFramesRendered({RenderedFrameInfo(mediaTimeUs,
6895                                                                          timestampNs)});
6896         }
6897 
6898         info->mFenceFd = -1;
6899         if (err == OK) {
6900             info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6901         } else {
6902             ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6903             mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6904             info->mStatus = BufferInfo::OWNED_BY_US;
6905             // keeping read fence as write fence to avoid clobbering
6906             info->mIsReadFence = false;
6907         }
6908     } else {
6909         if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) {
6910             // move read fence into write fence to avoid clobbering
6911             info->mIsReadFence = false;
6912             ATRACE_NAME("frame-drop");
6913         }
6914         info->mStatus = BufferInfo::OWNED_BY_US;
6915     }
6916 
6917     PortMode mode = getPortMode(kPortIndexOutput);
6918 
6919     switch (mode) {
6920         case KEEP_BUFFERS:
6921         {
6922             // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6923 
6924             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6925                 // We cannot resubmit the buffer we just rendered, dequeue
6926                 // the spare instead.
6927 
6928                 info = mCodec->dequeueBufferFromNativeWindow();
6929             }
6930             break;
6931         }
6932 
6933         case RESUBMIT_BUFFERS:
6934         {
6935             if (!mCodec->mPortEOS[kPortIndexOutput]) {
6936                 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6937                     // We cannot resubmit the buffer we just rendered, dequeue
6938                     // the spare instead.
6939 
6940                     info = mCodec->dequeueBufferFromNativeWindow();
6941                 }
6942 
6943                 if (info != NULL) {
6944                     ALOGV("[%s] calling fillBuffer %u",
6945                          mCodec->mComponentName.c_str(), info->mBufferID);
6946                     info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
6947                     status_t err = mCodec->fillBuffer(info);
6948                     if (err != OK) {
6949                         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6950                     }
6951                 }
6952             }
6953             break;
6954         }
6955 
6956         case FREE_BUFFERS:
6957         {
6958             status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
6959             if (err != OK) {
6960                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6961             }
6962             break;
6963         }
6964 
6965         default:
6966             ALOGE("Invalid port mode: %d", mode);
6967             return;
6968     }
6969 }
6970 
6971 ////////////////////////////////////////////////////////////////////////////////
6972 
UninitializedState(ACodec * codec)6973 ACodec::UninitializedState::UninitializedState(ACodec *codec)
6974     : BaseState(codec) {
6975 }
6976 
stateEntered()6977 void ACodec::UninitializedState::stateEntered() {
6978     ALOGV("Now uninitialized");
6979 
6980     if (mDeathNotifier != NULL) {
6981         if (mCodec->mOMXNode != NULL) {
6982             auto tOmxNode = mCodec->mOMXNode->getHalInterface<IOmxNode>();
6983             if (tOmxNode) {
6984                 tOmxNode->unlinkToDeath(mDeathNotifier);
6985             }
6986         }
6987         mDeathNotifier.clear();
6988     }
6989 
6990     mCodec->mUsingNativeWindow = false;
6991     mCodec->mNativeWindow.clear();
6992     mCodec->mNativeWindowUsageBits = 0;
6993     mCodec->mOMX.clear();
6994     mCodec->mOMXNode.clear();
6995     mCodec->mFlags = 0;
6996     mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
6997     mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
6998     mCodec->mConverter[0].clear();
6999     mCodec->mConverter[1].clear();
7000     mCodec->mComponentName.clear();
7001     mCodec->mDecodeOnlyTimesUs.clear();
7002 }
7003 
onMessageReceived(const sp<AMessage> & msg)7004 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
7005     bool handled = false;
7006 
7007     switch (msg->what()) {
7008         case ACodec::kWhatSetup:
7009         {
7010             onSetup(msg);
7011 
7012             handled = true;
7013             break;
7014         }
7015 
7016         case ACodec::kWhatAllocateComponent:
7017         {
7018             onAllocateComponent(msg);
7019             handled = true;
7020             break;
7021         }
7022 
7023         case ACodec::kWhatShutdown:
7024         {
7025             int32_t keepComponentAllocated;
7026             CHECK(msg->findInt32(
7027                         "keepComponentAllocated", &keepComponentAllocated));
7028             ALOGW_IF(keepComponentAllocated,
7029                      "cannot keep component allocated on shutdown in Uninitialized state");
7030             if (keepComponentAllocated) {
7031                 mCodec->mCallback->onStopCompleted();
7032             } else {
7033                 mCodec->mCallback->onReleaseCompleted();
7034             }
7035             handled = true;
7036             break;
7037         }
7038 
7039         case ACodec::kWhatFlush:
7040         {
7041             mCodec->mCallback->onFlushCompleted();
7042             handled = true;
7043             break;
7044         }
7045 
7046         case ACodec::kWhatReleaseCodecInstance:
7047         {
7048             // nothing to do, as we have already signaled shutdown
7049             handled = true;
7050             break;
7051         }
7052 
7053         default:
7054             return BaseState::onMessageReceived(msg);
7055     }
7056 
7057     return handled;
7058 }
7059 
onSetup(const sp<AMessage> & msg)7060 void ACodec::UninitializedState::onSetup(
7061         const sp<AMessage> &msg) {
7062     if (onAllocateComponent(msg)
7063             && mCodec->mLoadedState->onConfigureComponent(msg)) {
7064         mCodec->mLoadedState->onStart();
7065     }
7066 }
7067 
onAllocateComponent(const sp<AMessage> & msg)7068 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
7069     ALOGV("onAllocateComponent");
7070 
7071     CHECK(mCodec->mOMXNode == NULL);
7072     mCodec->mFatalError = false;
7073 
7074     sp<AMessage> notify = new AMessage(kWhatOMXMessageList, mCodec);
7075     notify->setInt32("generation", mCodec->mNodeGeneration + 1);
7076 
7077     sp<RefBase> obj;
7078     CHECK(msg->findObject("codecInfo", &obj));
7079     sp<MediaCodecInfo> info = (MediaCodecInfo *)obj.get();
7080     if (info == nullptr) {
7081         ALOGE("Unexpected nullptr for codec information");
7082         mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);
7083         return false;
7084     }
7085     AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName();
7086 
7087     AString componentName;
7088     CHECK(msg->findString("componentName", &componentName));
7089 
7090     sp<CodecObserver> observer = new CodecObserver(notify);
7091     sp<IOMX> omx;
7092     sp<IOMXNode> omxNode;
7093 
7094     status_t err = NAME_NOT_FOUND;
7095     OMXClient client;
7096     if (client.connect(owner.c_str()) != OK) {
7097         mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
7098         return false;
7099     }
7100     omx = client.interface();
7101 
7102     pid_t tid = gettid();
7103     int prevPriority = androidGetThreadPriority(tid);
7104     androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
7105     err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
7106     androidSetThreadPriority(tid, prevPriority);
7107 
7108     if (err != OK) {
7109         ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
7110 
7111         mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
7112         return false;
7113     }
7114 
7115     mDeathNotifier = new DeathNotifier(new AMessage(kWhatOMXDied, mCodec));
7116     auto tOmxNode = omxNode->getHalInterface<IOmxNode>();
7117     if (tOmxNode && !tOmxNode->linkToDeath(mDeathNotifier, 0)) {
7118         mDeathNotifier.clear();
7119     }
7120 
7121     ++mCodec->mNodeGeneration;
7122 
7123     mCodec->mComponentName = componentName;
7124     mCodec->mFlags = 0;
7125 
7126     if (componentName.endsWith(".secure")) {
7127         mCodec->mFlags |= kFlagIsSecure;
7128         mCodec->mFlags |= kFlagIsGrallocUsageProtected;
7129         mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
7130     }
7131 
7132     mCodec->mOMX = omx;
7133     mCodec->mOMXNode = omxNode;
7134     mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str());
7135     mCodec->changeState(mCodec->mLoadedState);
7136 
7137     return true;
7138 }
7139 
7140 ////////////////////////////////////////////////////////////////////////////////
7141 
LoadedState(ACodec * codec)7142 ACodec::LoadedState::LoadedState(ACodec *codec)
7143     : BaseState(codec) {
7144 }
7145 
stateEntered()7146 void ACodec::LoadedState::stateEntered() {
7147     ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
7148 
7149     mCodec->mPortEOS[kPortIndexInput] =
7150         mCodec->mPortEOS[kPortIndexOutput] = false;
7151 
7152     mCodec->mInputEOSResult = OK;
7153 
7154     mCodec->mDequeueCounter = 0;
7155     mCodec->mMetadataBuffersToSubmit = 0;
7156     mCodec->mRepeatFrameDelayUs = -1LL;
7157     mCodec->mInputFormat.clear();
7158     mCodec->mOutputFormat.clear();
7159     mCodec->mBaseOutputFormat.clear();
7160     mCodec->mGraphicBufferSource.clear();
7161 
7162     if (mCodec->mShutdownInProgress) {
7163         bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
7164 
7165         mCodec->mShutdownInProgress = false;
7166         mCodec->mKeepComponentAllocated = false;
7167 
7168         onShutdown(keepComponentAllocated);
7169     }
7170     mCodec->mExplicitShutdown = false;
7171 
7172     mCodec->processDeferredMessages();
7173 }
7174 
onShutdown(bool keepComponentAllocated)7175 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
7176     if (!keepComponentAllocated) {
7177         (void)mCodec->mOMXNode->freeNode();
7178 
7179         mCodec->changeState(mCodec->mUninitializedState);
7180     }
7181 
7182     if (mCodec->mExplicitShutdown) {
7183         if (keepComponentAllocated) {
7184             mCodec->mCallback->onStopCompleted();
7185         } else {
7186             mCodec->mCallback->onReleaseCompleted();
7187         }
7188         mCodec->mExplicitShutdown = false;
7189     }
7190 }
7191 
onMessageReceived(const sp<AMessage> & msg)7192 bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
7193     bool handled = false;
7194 
7195     switch (msg->what()) {
7196         case ACodec::kWhatConfigureComponent:
7197         {
7198             onConfigureComponent(msg);
7199             handled = true;
7200             break;
7201         }
7202 
7203         case ACodec::kWhatCreateInputSurface:
7204         {
7205             onCreateInputSurface(msg);
7206             handled = true;
7207             break;
7208         }
7209 
7210         case ACodec::kWhatSetInputSurface:
7211         {
7212             onSetInputSurface(msg);
7213             handled = true;
7214             break;
7215         }
7216 
7217         case ACodec::kWhatStart:
7218         {
7219             onStart();
7220             handled = true;
7221             break;
7222         }
7223 
7224         case ACodec::kWhatShutdown:
7225         {
7226             int32_t keepComponentAllocated;
7227             CHECK(msg->findInt32(
7228                         "keepComponentAllocated", &keepComponentAllocated));
7229 
7230             mCodec->mExplicitShutdown = true;
7231             onShutdown(keepComponentAllocated);
7232 
7233             handled = true;
7234             break;
7235         }
7236 
7237         case ACodec::kWhatFlush:
7238         {
7239             mCodec->mCallback->onFlushCompleted();
7240             handled = true;
7241             break;
7242         }
7243 
7244         default:
7245             return BaseState::onMessageReceived(msg);
7246     }
7247 
7248     return handled;
7249 }
7250 
onConfigureComponent(const sp<AMessage> & msg)7251 bool ACodec::LoadedState::onConfigureComponent(
7252         const sp<AMessage> &msg) {
7253     ALOGV("onConfigureComponent");
7254 
7255     CHECK(mCodec->mOMXNode != NULL);
7256 
7257     status_t err = OK;
7258     AString mime;
7259     if (!msg->findString("mime", &mime)) {
7260         err = BAD_VALUE;
7261     } else {
7262         err = mCodec->configureCodec(mime.c_str(), msg);
7263     }
7264     if (err != OK) {
7265         ALOGE("[%s] configureCodec returning error %d",
7266               mCodec->mComponentName.c_str(), err);
7267 
7268         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7269         return false;
7270     }
7271 
7272     mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat);
7273 
7274     return true;
7275 }
7276 
setupInputSurface()7277 status_t ACodec::LoadedState::setupInputSurface() {
7278     if (mCodec->mGraphicBufferSource == NULL) {
7279         return BAD_VALUE;
7280     }
7281 
7282     android_dataspace dataSpace;
7283     status_t err =
7284         mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
7285     if (err != OK) {
7286         ALOGE("Failed to get default data space");
7287         return err;
7288     }
7289 
7290     err = statusFromBinderStatus(
7291             mCodec->mGraphicBufferSource->configure(
7292                     mCodec->mOMXNode->getHalInterface<IOmxNode>(),
7293                     static_cast<hardware::graphics::common::V1_0::Dataspace>(dataSpace)));
7294     if (err != OK) {
7295         ALOGE("[%s] Unable to configure for node (err %d)",
7296               mCodec->mComponentName.c_str(), err);
7297         return err;
7298     }
7299 
7300     if (mCodec->mRepeatFrameDelayUs > 0LL) {
7301         err = statusFromBinderStatus(
7302                 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
7303                         mCodec->mRepeatFrameDelayUs));
7304 
7305         if (err != OK) {
7306             ALOGE("[%s] Unable to configure option to repeat previous "
7307                   "frames (err %d)",
7308                   mCodec->mComponentName.c_str(), err);
7309             return err;
7310         }
7311     }
7312 
7313     if (mCodec->mIsVideo && mCodec->mMaxPtsGapUs != 0LL) {
7314         OMX_PARAM_U32TYPE maxPtsGapParams;
7315         InitOMXParams(&maxPtsGapParams);
7316         maxPtsGapParams.nPortIndex = kPortIndexInput;
7317         maxPtsGapParams.nU32 = (uint32_t)mCodec->mMaxPtsGapUs;
7318 
7319         err = mCodec->mOMXNode->setParameter(
7320                 (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
7321                 &maxPtsGapParams, sizeof(maxPtsGapParams));
7322 
7323         if (err != OK) {
7324             ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
7325                     mCodec->mComponentName.c_str(), err);
7326             return err;
7327         }
7328     }
7329 
7330     if (mCodec->mMaxFps > 0 || mCodec->mMaxPtsGapUs < 0) {
7331         err = statusFromBinderStatus(
7332                 mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
7333 
7334         if (err != OK) {
7335             ALOGE("[%s] Unable to configure max fps (err %d)",
7336                     mCodec->mComponentName.c_str(), err);
7337             return err;
7338         }
7339     }
7340 
7341     if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) {
7342         err = statusFromBinderStatus(
7343                 mCodec->mGraphicBufferSource->setTimeLapseConfig(
7344                         mCodec->mFps, mCodec->mCaptureFps));
7345 
7346         if (err != OK) {
7347             ALOGE("[%s] Unable to configure time lapse (err %d)",
7348                     mCodec->mComponentName.c_str(), err);
7349             return err;
7350         }
7351     }
7352 
7353     if (mCodec->mCreateInputBuffersSuspended) {
7354         err = statusFromBinderStatus(
7355                 mCodec->mGraphicBufferSource->setSuspend(true, -1));
7356 
7357         if (err != OK) {
7358             ALOGE("[%s] Unable to configure option to suspend (err %d)",
7359                   mCodec->mComponentName.c_str(), err);
7360             return err;
7361         }
7362     }
7363 
7364     uint32_t usageBits;
7365     if (mCodec->mOMXNode->getParameter(
7366             (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
7367             &usageBits, sizeof(usageBits)) == OK) {
7368         mCodec->mInputFormat->setInt32(
7369                 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
7370     }
7371 
7372     sp<ABuffer> colorAspectsBuffer;
7373     if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
7374         if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
7375             return INVALID_OPERATION;
7376         }
7377 
7378         err = statusFromBinderStatus(
7379                 mCodec->mGraphicBufferSource->setColorAspects(
7380                         hardware::media::omx::V1_0::utils::toHardwareColorAspects(
7381                                 *(ColorAspects *)colorAspectsBuffer->base())));
7382 
7383         if (err != OK) {
7384             ALOGE("[%s] Unable to configure color aspects (err %d)",
7385                   mCodec->mComponentName.c_str(), err);
7386             return err;
7387         }
7388     }
7389     return OK;
7390 }
7391 
onCreateInputSurface(const sp<AMessage> &)7392 void ACodec::LoadedState::onCreateInputSurface(
7393         const sp<AMessage> & /* msg */) {
7394     ALOGV("onCreateInputSurface");
7395 
7396     sp<IGraphicBufferProducer> bufferProducer;
7397     sp<HGraphicBufferSource> bufferSource;
7398     status_t err = mCodec->mOMX->createInputSurface(
7399             &bufferProducer, &bufferSource);
7400     mCodec->mGraphicBufferSource = bufferSource;
7401 
7402     if (err == OK) {
7403         err = setupInputSurface();
7404     }
7405 
7406     if (err == OK) {
7407         mCodec->mCallback->onInputSurfaceCreated(
7408                 mCodec->mInputFormat,
7409                 mCodec->mOutputFormat,
7410                 new BufferProducerWrapper(bufferProducer));
7411     } else {
7412         // Can't use mCodec->signalError() here -- MediaCodec won't forward
7413         // the error through because it's in the "configured" state.  We
7414         // send a kWhatInputSurfaceCreated with an error value instead.
7415         ALOGE("[%s] onCreateInputSurface returning error %d",
7416                 mCodec->mComponentName.c_str(), err);
7417         mCodec->mCallback->onInputSurfaceCreationFailed(err);
7418     }
7419 }
7420 
onSetInputSurface(const sp<AMessage> & msg)7421 void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) {
7422     ALOGV("onSetInputSurface");
7423 
7424     sp<RefBase> obj;
7425     CHECK(msg->findObject("input-surface", &obj));
7426     if (obj == NULL) {
7427         ALOGE("[%s] NULL input surface", mCodec->mComponentName.c_str());
7428         mCodec->mCallback->onInputSurfaceDeclined(BAD_VALUE);
7429         return;
7430     }
7431 
7432     sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
7433     sp<HGraphicBufferSource> hgbs = HGraphicBufferSource::castFrom(surface->getHidlTarget());
7434     status_t err = BAD_VALUE;
7435     if (hgbs) {
7436         mCodec->mGraphicBufferSource = hgbs;
7437         err = setupInputSurface();
7438     }
7439 
7440     if (err == OK) {
7441         mCodec->mCallback->onInputSurfaceAccepted(
7442                 mCodec->mInputFormat, mCodec->mOutputFormat);
7443     } else {
7444         // Can't use mCodec->signalError() here -- MediaCodec won't forward
7445         // the error through because it's in the "configured" state.  We
7446         // send a kWhatInputSurfaceAccepted with an error value instead.
7447         ALOGE("[%s] onSetInputSurface returning error %d",
7448                 mCodec->mComponentName.c_str(), err);
7449         mCodec->mCallback->onInputSurfaceDeclined(err);
7450     }
7451 }
7452 
onStart()7453 void ACodec::LoadedState::onStart() {
7454     ALOGV("onStart");
7455 
7456     status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
7457     if (err != OK) {
7458         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7459     } else {
7460         mCodec->changeState(mCodec->mLoadedToIdleState);
7461     }
7462 }
7463 
7464 ////////////////////////////////////////////////////////////////////////////////
7465 
LoadedToIdleState(ACodec * codec)7466 ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
7467     : BaseState(codec) {
7468 }
7469 
stateEntered()7470 void ACodec::LoadedToIdleState::stateEntered() {
7471     ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
7472 
7473     status_t err;
7474     if ((err = allocateBuffers()) != OK) {
7475         ALOGE("Failed to allocate buffers after transitioning to IDLE state "
7476              "(error 0x%08x)",
7477              err);
7478 
7479         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7480 
7481         mCodec->mOMXNode->sendCommand(
7482                 OMX_CommandStateSet, OMX_StateLoaded);
7483         if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
7484             mCodec->freeBuffersOnPort(kPortIndexInput);
7485         }
7486         if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
7487             mCodec->freeBuffersOnPort(kPortIndexOutput);
7488         }
7489 
7490         mCodec->changeState(mCodec->mLoadedState);
7491     }
7492 }
7493 
allocateBuffers()7494 status_t ACodec::LoadedToIdleState::allocateBuffers() {
7495     status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
7496     if (err != OK) {
7497         return err;
7498     }
7499 
7500     err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
7501     if (err != OK) {
7502         return err;
7503     }
7504 
7505     mCodec->mCallback->onStartCompleted();
7506 
7507     return OK;
7508 }
7509 
onMessageReceived(const sp<AMessage> & msg)7510 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7511     switch (msg->what()) {
7512         case kWhatSetParameters:
7513         {
7514             BaseState::setSurfaceParameters(msg);
7515             if (msg->countEntries() > 0) {
7516                 mCodec->deferMessage(msg);
7517             }
7518             return true;
7519         }
7520         case kWhatShutdown:
7521         {
7522             mCodec->deferMessage(msg);
7523             return true;
7524         }
7525 
7526         case kWhatSignalEndOfInputStream:
7527         {
7528             mCodec->onSignalEndOfInputStream();
7529             return true;
7530         }
7531 
7532         case kWhatResume:
7533         {
7534             // We'll be active soon enough.
7535             return true;
7536         }
7537 
7538         case kWhatFlush:
7539         {
7540             // We haven't even started yet, so we're flushed alright...
7541             mCodec->mCallback->onFlushCompleted();
7542             return true;
7543         }
7544 
7545         default:
7546             return BaseState::onMessageReceived(msg);
7547     }
7548 }
7549 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)7550 bool ACodec::LoadedToIdleState::onOMXEvent(
7551         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7552     switch (event) {
7553         case OMX_EventCmdComplete:
7554         {
7555             status_t err = OK;
7556             if (data1 != (OMX_U32)OMX_CommandStateSet
7557                     || data2 != (OMX_U32)OMX_StateIdle) {
7558                 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
7559                         asString((OMX_COMMANDTYPE)data1), data1,
7560                         asString((OMX_STATETYPE)data2), data2);
7561                 err = FAILED_TRANSACTION;
7562             }
7563 
7564             if (err == OK) {
7565                 err = mCodec->mOMXNode->sendCommand(
7566                     OMX_CommandStateSet, OMX_StateExecuting);
7567             }
7568 
7569             if (err != OK) {
7570                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7571             } else {
7572                 mCodec->changeState(mCodec->mIdleToExecutingState);
7573             }
7574 
7575             return true;
7576         }
7577 
7578         // When Acodec receive an error event at LoadedToIdleState, it will not release
7579         // allocated buffers, which will cause gralloc buffer leak issue. We need to first release
7580         // these buffers and then process the error event
7581         case OMX_EventError:
7582         {
7583             if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
7584                 mCodec->freeBuffersOnPort(kPortIndexInput);
7585             }
7586 
7587             if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
7588                 mCodec->freeBuffersOnPort(kPortIndexOutput);
7589             }
7590 
7591             return BaseState::onOMXEvent(event, data1, data2);
7592         }
7593 
7594         default:
7595             return BaseState::onOMXEvent(event, data1, data2);
7596     }
7597 }
7598 
7599 ////////////////////////////////////////////////////////////////////////////////
7600 
IdleToExecutingState(ACodec * codec)7601 ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
7602     : BaseState(codec) {
7603 }
7604 
stateEntered()7605 void ACodec::IdleToExecutingState::stateEntered() {
7606     ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
7607 }
7608 
onMessageReceived(const sp<AMessage> & msg)7609 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7610     switch (msg->what()) {
7611         case kWhatSetParameters:
7612         {
7613             BaseState::setSurfaceParameters(msg);
7614             if (msg->countEntries() > 0) {
7615                 mCodec->deferMessage(msg);
7616             }
7617             return true;
7618         }
7619         case kWhatShutdown:
7620         {
7621             mCodec->deferMessage(msg);
7622             return true;
7623         }
7624 
7625         case kWhatResume:
7626         {
7627             // We'll be active soon enough.
7628             return true;
7629         }
7630 
7631         case kWhatFlush:
7632         {
7633             // We haven't even started yet, so we're flushed alright...
7634             mCodec->mCallback->onFlushCompleted();
7635             return true;
7636         }
7637 
7638         case kWhatSignalEndOfInputStream:
7639         {
7640             mCodec->onSignalEndOfInputStream();
7641             return true;
7642         }
7643 
7644         default:
7645             return BaseState::onMessageReceived(msg);
7646     }
7647 }
7648 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)7649 bool ACodec::IdleToExecutingState::onOMXEvent(
7650         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7651     switch (event) {
7652         case OMX_EventCmdComplete:
7653         {
7654             if (data1 != (OMX_U32)OMX_CommandStateSet
7655                     || data2 != (OMX_U32)OMX_StateExecuting) {
7656                 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
7657                         asString((OMX_COMMANDTYPE)data1), data1,
7658                         asString((OMX_STATETYPE)data2), data2);
7659                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7660                 return true;
7661             }
7662 
7663             mCodec->mExecutingState->resume();
7664             mCodec->changeState(mCodec->mExecutingState);
7665 
7666             return true;
7667         }
7668 
7669         default:
7670             return BaseState::onOMXEvent(event, data1, data2);
7671     }
7672 }
7673 
7674 ////////////////////////////////////////////////////////////////////////////////
7675 
ExecutingState(ACodec * codec)7676 ACodec::ExecutingState::ExecutingState(ACodec *codec)
7677     : BaseState(codec),
7678       mActive(false) {
7679 }
7680 
getPortMode(OMX_U32)7681 ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
7682         OMX_U32 /* portIndex */) {
7683     return RESUBMIT_BUFFERS;
7684 }
7685 
submitOutputMetaBuffers()7686 void ACodec::ExecutingState::submitOutputMetaBuffers() {
7687     // submit as many buffers as there are input buffers with the codec
7688     // in case we are in port reconfiguring
7689     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
7690         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput][i];
7691 
7692         if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
7693             if (mCodec->submitOutputMetadataBuffer() != OK)
7694                 break;
7695         }
7696     }
7697     if (mCodec->mIsLowLatency) {
7698         maybePostExtraOutputMetadataBufferRequest();
7699     }
7700 
7701     // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7702     mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
7703 }
7704 
submitRegularOutputBuffers()7705 void ACodec::ExecutingState::submitRegularOutputBuffers() {
7706     bool failed = false;
7707     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
7708         BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput][i];
7709 
7710         if (mCodec->mNativeWindow != NULL) {
7711             if (info->mStatus != BufferInfo::OWNED_BY_US
7712                     && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7713                 ALOGE("buffers should be owned by us or the surface");
7714                 failed = true;
7715                 break;
7716             }
7717 
7718             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7719                 continue;
7720             }
7721         } else {
7722             if (info->mStatus != BufferInfo::OWNED_BY_US) {
7723                 ALOGE("buffers should be owned by us");
7724                 failed = true;
7725                 break;
7726             }
7727         }
7728 
7729         ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
7730 
7731         info->checkWriteFence("submitRegularOutputBuffers");
7732         status_t err = mCodec->fillBuffer(info);
7733         if (err != OK) {
7734             failed = true;
7735             break;
7736         }
7737     }
7738 
7739     if (failed) {
7740         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7741     }
7742 }
7743 
submitOutputBuffers()7744 void ACodec::ExecutingState::submitOutputBuffers() {
7745     submitRegularOutputBuffers();
7746     if (mCodec->storingMetadataInDecodedBuffers()) {
7747         submitOutputMetaBuffers();
7748     }
7749 }
7750 
resume()7751 void ACodec::ExecutingState::resume() {
7752     if (mActive) {
7753         ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
7754         return;
7755     }
7756 
7757     submitOutputBuffers();
7758 
7759     // Post all available input buffers
7760     if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
7761         ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
7762     }
7763 
7764     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
7765         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput][i];
7766         if (info->mStatus == BufferInfo::OWNED_BY_US) {
7767             postFillThisBuffer(info);
7768         }
7769     }
7770 
7771     mActive = true;
7772 }
7773 
stateEntered()7774 void ACodec::ExecutingState::stateEntered() {
7775     ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
7776     mCodec->processDeferredMessages();
7777 }
7778 
onMessageReceived(const sp<AMessage> & msg)7779 bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7780     bool handled = false;
7781 
7782     switch (msg->what()) {
7783         case kWhatShutdown:
7784         {
7785             int32_t keepComponentAllocated;
7786             CHECK(msg->findInt32(
7787                         "keepComponentAllocated", &keepComponentAllocated));
7788 
7789             mCodec->mShutdownInProgress = true;
7790             mCodec->mExplicitShutdown = true;
7791             mCodec->mKeepComponentAllocated = keepComponentAllocated;
7792 
7793             mActive = false;
7794 
7795             status_t err = mCodec->mOMXNode->sendCommand(
7796                     OMX_CommandStateSet, OMX_StateIdle);
7797             if (err != OK) {
7798                 if (keepComponentAllocated) {
7799                     mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7800                 }
7801                 // TODO: do some recovery here.
7802             } else {
7803                 mCodec->changeState(mCodec->mExecutingToIdleState);
7804             }
7805 
7806             handled = true;
7807             break;
7808         }
7809 
7810         case kWhatFlush:
7811         {
7812             ALOGV("[%s] ExecutingState flushing now "
7813                  "(codec owns %zu/%zu input, %zu/%zu output).",
7814                     mCodec->mComponentName.c_str(),
7815                     mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7816                     mCodec->mBuffers[kPortIndexInput].size(),
7817                     mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7818                     mCodec->mBuffers[kPortIndexOutput].size());
7819 
7820             mActive = false;
7821 
7822             status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
7823             if (err != OK) {
7824                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
7825             } else {
7826                 mCodec->changeState(mCodec->mFlushingState);
7827             }
7828 
7829             handled = true;
7830             break;
7831         }
7832 
7833         case kWhatResume:
7834         {
7835             resume();
7836 
7837             handled = true;
7838             break;
7839         }
7840 
7841         case kWhatRequestIDRFrame:
7842         {
7843             status_t err = mCodec->requestIDRFrame();
7844             if (err != OK) {
7845                 ALOGW("Requesting an IDR frame failed.");
7846             }
7847 
7848             handled = true;
7849             break;
7850         }
7851 
7852         case kWhatSetParameters:
7853         {
7854             sp<AMessage> params;
7855             CHECK(msg->findMessage("params", &params));
7856 
7857             status_t err = mCodec->setParameters(params);
7858 
7859             sp<AMessage> reply;
7860             if (msg->findMessage("reply", &reply)) {
7861                 reply->setInt32("err", err);
7862                 reply->post();
7863             }
7864 
7865             handled = true;
7866             break;
7867         }
7868 
7869         case ACodec::kWhatSignalEndOfInputStream:
7870         {
7871             mCodec->onSignalEndOfInputStream();
7872             handled = true;
7873             break;
7874         }
7875 
7876         // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7877         case kWhatSubmitOutputMetadataBufferIfEOS:
7878         {
7879             if (mCodec->mPortEOS[kPortIndexInput] &&
7880                     !mCodec->mPortEOS[kPortIndexOutput]) {
7881                 status_t err = mCodec->submitOutputMetadataBuffer();
7882                 if (err == OK) {
7883                     mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
7884                 }
7885             }
7886             handled = true;
7887             break;
7888         }
7889 
7890         case kWhatPollForRenderedBuffers:
7891         {
7892             mCodec->pollForRenderedFrames();
7893             handled = true;
7894             break;
7895         }
7896 
7897         default:
7898             handled = BaseState::onMessageReceived(msg);
7899             break;
7900     }
7901 
7902     return handled;
7903 }
7904 
setSurfaceParameters(const sp<AMessage> & params)7905 status_t ACodec::setSurfaceParameters(const sp<AMessage> &params) {
7906     int64_t timeOffsetUs;
7907     if (params->findInt64(PARAMETER_KEY_OFFSET_TIME, &timeOffsetUs)) {
7908         if (mGraphicBufferSource == NULL) {
7909             ALOGE("[%s] Invalid to set input buffer time offset without surface",
7910                     mComponentName.c_str());
7911             return INVALID_OPERATION;
7912         }
7913 
7914         status_t err = statusFromBinderStatus(
7915                 mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
7916 
7917         if (err != OK) {
7918             ALOGE("[%s] Unable to set input buffer time offset (err %d)",
7919                 mComponentName.c_str(),
7920                 err);
7921             return err;
7922         }
7923     }
7924 
7925     int64_t skipFramesBeforeUs;
7926     if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
7927         if (mGraphicBufferSource == NULL) {
7928             ALOGE("[%s] Invalid to set start time without surface",
7929                     mComponentName.c_str());
7930             return INVALID_OPERATION;
7931         }
7932 
7933         status_t err = statusFromBinderStatus(
7934                 mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
7935 
7936         if (err != OK) {
7937             ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
7938             return err;
7939         }
7940     }
7941 
7942     int32_t dropInputFrames;
7943     if (params->findInt32(PARAMETER_KEY_SUSPEND, &dropInputFrames)) {
7944         if (mGraphicBufferSource == NULL) {
7945             ALOGE("[%s] Invalid to set suspend without surface",
7946                     mComponentName.c_str());
7947             return INVALID_OPERATION;
7948         }
7949 
7950         int64_t suspendStartTimeUs = -1;
7951         (void) params->findInt64(PARAMETER_KEY_SUSPEND_TIME, &suspendStartTimeUs);
7952         status_t err = statusFromBinderStatus(
7953                 mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
7954 
7955         if (err != OK) {
7956             ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7957             return err;
7958         }
7959     }
7960 
7961     int64_t stopTimeUs;
7962     if (params->findInt64("stop-time-us", &stopTimeUs)) {
7963         if (mGraphicBufferSource == NULL) {
7964             ALOGE("[%s] Invalid to set stop time without surface",
7965                     mComponentName.c_str());
7966             return INVALID_OPERATION;
7967         }
7968         status_t err = statusFromBinderStatus(
7969                 mGraphicBufferSource->setStopTimeUs(stopTimeUs));
7970 
7971         if (err != OK) {
7972             ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
7973             return err;
7974         }
7975 
7976         int64_t stopTimeOffsetUs;
7977         hardware::Return<void> trans = mGraphicBufferSource->getStopTimeOffsetUs(
7978                 [&err, &stopTimeOffsetUs](auto status, auto result) {
7979                     err = static_cast<status_t>(status);
7980                     stopTimeOffsetUs = result;
7981                 });
7982         if (!trans.isOk()) {
7983             err = trans.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR;
7984         }
7985 
7986         if (err != OK) {
7987             ALOGE("Failed to get stop time offset (err %d)", err);
7988             return err;
7989         }
7990         mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
7991     }
7992 
7993     return OK;
7994 }
7995 
setParameters(const sp<AMessage> & params)7996 status_t ACodec::setParameters(const sp<AMessage> &params) {
7997     status_t err;
7998 
7999     int32_t videoBitrate;
8000     if (params->findInt32("video-bitrate", &videoBitrate)) {
8001         OMX_VIDEO_CONFIG_BITRATETYPE configParams;
8002         InitOMXParams(&configParams);
8003         configParams.nPortIndex = kPortIndexOutput;
8004         configParams.nEncodeBitrate = videoBitrate;
8005 
8006         err = mOMXNode->setConfig(
8007                 OMX_IndexConfigVideoBitrate,
8008                 &configParams,
8009                 sizeof(configParams));
8010 
8011         if (err != OK) {
8012             ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
8013                    videoBitrate, err);
8014 
8015             return err;
8016         }
8017     }
8018 
8019     err = setSurfaceParameters(params);
8020     if (err != OK) {
8021         ALOGE("Failed to set input surface parameters (err %d)", err);
8022         return err;
8023     }
8024 
8025     int32_t tmp;
8026     if (params->findInt32("request-sync", &tmp)) {
8027         err = requestIDRFrame();
8028 
8029         if (err != OK) {
8030             ALOGE("Requesting a sync frame failed w/ err %d", err);
8031             return err;
8032         }
8033     }
8034 
8035     int32_t rateInt = -1;
8036     float rateFloat = -1;
8037     if (!params->findFloat("operating-rate", &rateFloat)) {
8038         params->findInt32("operating-rate", &rateInt);
8039         rateFloat = (float) rateInt; // 16MHz (FLINTMAX) is OK for upper bound.
8040     }
8041     if (rateFloat > 0) {
8042         err = setOperatingRate(rateFloat, mIsVideo);
8043         if (err != OK) {
8044             ALOGI("Failed to set parameter 'operating-rate' (err %d)", err);
8045         }
8046     }
8047 
8048     int32_t intraRefreshPeriod = 0;
8049     if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
8050             && intraRefreshPeriod > 0) {
8051         err = setIntraRefreshPeriod(intraRefreshPeriod, false);
8052         if (err != OK) {
8053             ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
8054                     mComponentName.c_str());
8055             err = OK;
8056         }
8057     }
8058 
8059     int32_t lowLatency = 0;
8060     if (params->findInt32("low-latency", &lowLatency)) {
8061         err = setLowLatency(lowLatency);
8062         if (err != OK) {
8063             return err;
8064         }
8065     }
8066 
8067     int32_t latency = 0;
8068     if (params->findInt32("latency", &latency) && latency > 0) {
8069         err = setLatency(latency);
8070         if (err != OK) {
8071             ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
8072                     mComponentName.c_str());
8073             err = OK;
8074         }
8075     }
8076 
8077     int32_t presentationId = -1;
8078     if (params->findInt32("audio-presentation-presentation-id", &presentationId)) {
8079         int32_t programId = -1;
8080         params->findInt32("audio-presentation-program-id", &programId);
8081         err = setAudioPresentation(presentationId, programId);
8082         if (err != OK) {
8083             ALOGI("[%s] failed setAudioPresentation. Failure is fine since this key is optional",
8084                     mComponentName.c_str());
8085             err = OK;
8086         }
8087     }
8088 
8089     sp<ABuffer> hdr10PlusInfo;
8090     if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
8091             && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
8092         (void)setHdr10PlusInfo(hdr10PlusInfo);
8093     }
8094 
8095     // Ignore errors as failure is expected for codecs that aren't video encoders.
8096     (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
8097 
8098     AString mime;
8099     if (!mIsEncoder
8100             && (mConfigFormat->findString("mime", &mime))
8101             && !strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime.c_str())) {
8102         OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
8103         InitOMXParams(&presentation);
8104         mOMXNode->getParameter(
8105                     (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
8106                     &presentation, sizeof(presentation));
8107         int32_t value32 = 0;
8108         bool updated = false;
8109         if (params->findInt32("aac-pcm-limiter-enable", &value32)) {
8110             presentation.nPCMLimiterEnable = value32;
8111             updated = true;
8112         }
8113         if (params->findInt32("aac-encoded-target-level", &value32)) {
8114             presentation.nEncodedTargetLevel = value32;
8115             updated = true;
8116         }
8117         if (params->findInt32("aac-drc-cut-level", &value32)) {
8118             presentation.nDrcCut = value32;
8119             updated = true;
8120         }
8121         if (params->findInt32("aac-drc-boost-level", &value32)) {
8122             presentation.nDrcBoost = value32;
8123             updated = true;
8124         }
8125         if (params->findInt32("aac-drc-heavy-compression", &value32)) {
8126             presentation.nHeavyCompression = value32;
8127             updated = true;
8128         }
8129         if (params->findInt32("aac-target-ref-level", &value32)) {
8130             presentation.nTargetReferenceLevel = value32;
8131             updated = true;
8132         }
8133         if (params->findInt32("aac-drc-effect-type", &value32)) {
8134             presentation.nDrcEffectType = value32;
8135             updated = true;
8136         }
8137         if (params->findInt32("aac-drc-album-mode", &value32)) {
8138             presentation.nDrcAlbumMode = value32;
8139             updated = true;
8140         }
8141         if (!params->findInt32("aac-drc-output-loudness", &value32)) {
8142             presentation.nDrcOutputLoudness = value32;
8143             updated = true;
8144         }
8145         if (updated) {
8146             mOMXNode->setParameter((OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
8147                 &presentation, sizeof(presentation));
8148         }
8149     }
8150 
8151     {
8152         int32_t tunnelPeek = 0;
8153         if (params->findInt32(TUNNEL_PEEK_KEY, &tunnelPeek)) {
8154             err = setTunnelPeek(tunnelPeek);
8155             if (err != OK) {
8156                 return err;
8157             }
8158         }
8159     }
8160     {
8161         int32_t tunnelPeekSetLegacy = 0;
8162         if (params->findInt32(TUNNEL_PEEK_SET_LEGACY_KEY, &tunnelPeekSetLegacy)) {
8163             err = setTunnelPeekLegacy(tunnelPeekSetLegacy);
8164             if (err != OK) {
8165                 return err;
8166             }
8167         }
8168     }
8169 
8170     return setVendorParameters(params);
8171 }
8172 
setHdr10PlusInfo(const sp<ABuffer> & hdr10PlusInfo)8173 status_t ACodec::setHdr10PlusInfo(const sp<ABuffer> &hdr10PlusInfo) {
8174     if (mDescribeHDR10PlusInfoIndex == 0) {
8175         ALOGE("setHdr10PlusInfo: does not support DescribeHDR10PlusInfoParams");
8176         return ERROR_UNSUPPORTED;
8177     }
8178     size_t newSize = sizeof(DescribeHDR10PlusInfoParams) + hdr10PlusInfo->size() - 1;
8179     if (mHdr10PlusScratchBuffer == nullptr ||
8180             newSize > mHdr10PlusScratchBuffer->size()) {
8181         mHdr10PlusScratchBuffer = new ABuffer(newSize);
8182     }
8183     DescribeHDR10PlusInfoParams *config =
8184             (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
8185     InitOMXParams(config);
8186     config->nPortIndex = 0;
8187     config->nSize = newSize;
8188     config->nParamSize = hdr10PlusInfo->size();
8189     config->nParamSizeUsed = hdr10PlusInfo->size();
8190     memcpy(config->nValue, hdr10PlusInfo->data(), hdr10PlusInfo->size());
8191     status_t err = mOMXNode->setConfig(
8192             (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
8193             config, config->nSize);
8194     if (err != OK) {
8195         ALOGE("failed to set DescribeHDR10PlusInfoParams (err %d)", err);
8196     }
8197     return OK;
8198 }
8199 
8200 // Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
8201 // the minimum number of characters to keep in |key| (even if it has trailing tags).
8202 // (Used to remove trailing 'value' tags in settings names, e.g. to normalize
8203 // 'vendor.settingsX.value' to 'vendor.settingsX')
removeTrailingTags(char * key,size_t minLength,const char * tag)8204 static void removeTrailingTags(char *key, size_t minLength, const char *tag) {
8205     size_t length = strlen(key);
8206     size_t tagLength = strlen(tag);
8207     while (length > minLength + tagLength
8208             && !strcmp(key + length - tagLength, tag)
8209             && key[length - tagLength - 1] == '.') {
8210         length -= tagLength + 1;
8211         key[length] = '\0';
8212     }
8213 }
8214 
8215 /**
8216  * Struct encompassing a vendor extension config structure and a potential error status (in case
8217  * the structure is null). Used to iterate through vendor extensions.
8218  */
8219 struct VendorExtension {
8220     OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config;  // structure does not own config
8221     status_t status;
8222 
8223     // create based on an error status
VendorExtensionandroid::VendorExtension8224     VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { }
8225 
8226     // create based on a successfully retrieved config structure
VendorExtensionandroid::VendorExtension8227     VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { }
8228 };
8229 
8230 // class VendorExtensions;
8231 /**
8232  * Forward iterator to enumerate vendor extensions supported by an OMX component.
8233  */
8234 class VendorExtensionIterator {
8235 //private:
8236     static constexpr size_t kLastIndex = ~(size_t)0; // last index marker
8237 
8238     sp<IOMXNode> mNode;                   // component
8239     size_t mIndex;                        // current android extension index
8240     std::unique_ptr<uint8_t[]> mBacking;  // current extension's backing
8241     VendorExtension mCurrent;             // current extension
8242 
VendorExtensionIterator(const sp<IOMXNode> & node,size_t index)8243     VendorExtensionIterator(const sp<IOMXNode> &node, size_t index)
8244         : mNode(node),
8245           mIndex(index) {
8246         mCurrent = retrieve();
8247     }
8248 
8249     friend class VendorExtensions;
8250 
8251 public:
8252     // copy constructor
VendorExtensionIterator(const VendorExtensionIterator & it)8253     VendorExtensionIterator(const VendorExtensionIterator &it)
8254         : VendorExtensionIterator(it.mNode, it.mIndex) { }
8255 
8256     // retrieves the current extension pointed to by this iterator
retrieve()8257     VendorExtension retrieve() {
8258         if (mIndex == kLastIndex) {
8259             return NO_INIT;
8260         }
8261 
8262         // try with one param first, then retry if extension needs more than 1 param
8263         for (size_t paramSizeUsed = 1;; ) {
8264             if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) {
8265                 return BAD_VALUE; // this prevents overflow in the following formula
8266             }
8267 
8268             size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +
8269                 (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param);
8270             mBacking.reset(new uint8_t[size]);
8271             if (!mBacking) {
8272                 return NO_MEMORY;
8273             }
8274 
8275             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config =
8276                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get());
8277 
8278             InitOMXParams(config);
8279             config->nSize = size;
8280             config->nIndex = mIndex;
8281             config->nParamSizeUsed = paramSizeUsed;
8282             status_t err = mNode->getConfig(
8283                     (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size);
8284             if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) {
8285                 // reallocate if we need a bigger config
8286                 paramSizeUsed = config->nParamCount;
8287                 continue;
8288             } else if (err == NOT_ENOUGH_DATA
8289                    || (err != OK && mIndex == 0)) {
8290                 // stop iterator on no-more signal, or if index is not at all supported
8291                 mIndex = kLastIndex;
8292                 return NO_INIT;
8293             } else if (err != OK) {
8294                 return err;
8295             } else if (paramSizeUsed != config->nParamSizeUsed) {
8296                 return BAD_VALUE; // component shall not modify size of nParam
8297             }
8298 
8299             return config;
8300         }
8301     }
8302 
8303     // returns extension pointed to by this iterator
operator *()8304     VendorExtension operator*() {
8305         return mCurrent;
8306     }
8307 
8308     // prefix increment: move to next extension
operator ++()8309     VendorExtensionIterator &operator++() { // prefix
8310         if (mIndex != kLastIndex) {
8311             ++mIndex;
8312             mCurrent = retrieve();
8313         }
8314         return *this;
8315     }
8316 
8317     // iterator equality operators
operator ==(const VendorExtensionIterator & o)8318     bool operator==(const VendorExtensionIterator &o) {
8319         return mNode == o.mNode && mIndex == o.mIndex;
8320     }
8321 
operator !=(const VendorExtensionIterator & o)8322     bool operator!=(const VendorExtensionIterator &o) {
8323         return !(*this == o);
8324     }
8325 };
8326 
8327 /**
8328  * Iterable container for vendor extensions provided by a component
8329  */
8330 class VendorExtensions {
8331 //private:
8332     sp<IOMXNode> mNode;
8333 
8334 public:
VendorExtensions(const sp<IOMXNode> & node)8335     VendorExtensions(const sp<IOMXNode> &node)
8336         : mNode(node) {
8337     }
8338 
begin()8339     VendorExtensionIterator begin() {
8340         return VendorExtensionIterator(mNode, 0);
8341     }
8342 
end()8343     VendorExtensionIterator end() {
8344         return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex);
8345     }
8346 };
8347 
setVendorParameters(const sp<AMessage> & params)8348 status_t ACodec::setVendorParameters(const sp<AMessage> &params) {
8349     std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name
8350     constexpr char prefix[] = "vendor.";
8351     constexpr size_t prefixLength = sizeof(prefix) - 1;
8352     // longest possible vendor param name
8353     char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE];
8354 
8355     // identify all vendor keys to speed up search later and to detect vendor keys
8356     for (size_t i = params->countEntries(); i; --i) {
8357         AMessage::Type keyType;
8358         const char* key = params->getEntryNameAt(i - 1, &keyType);
8359         if (key != nullptr && !strncmp(key, prefix, prefixLength)
8360                 // it is safe to limit format keys to the max vendor param size as we only
8361                 // shorten parameter names by removing any trailing 'value' tags, and we
8362                 // already remove the vendor prefix.
8363                 && strlen(key + prefixLength) < sizeof(reducedKey)
8364                 && (keyType == AMessage::kTypeInt32
8365                         || keyType == AMessage::kTypeInt64
8366                         || keyType == AMessage::kTypeString)) {
8367             strcpy(reducedKey, key + prefixLength);
8368             removeTrailingTags(reducedKey, 0, "value");
8369             auto existingKey = vendorKeys.find(reducedKey);
8370             if (existingKey != vendorKeys.end()) {
8371                 ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'",
8372                         mComponentName.c_str(), key, existingKey->second.c_str());
8373                 // ignore for now
8374             }
8375             vendorKeys.emplace(reducedKey, key);
8376         }
8377     }
8378 
8379     // don't bother component if we don't have vendor extensions as they may not have implemented
8380     // the android vendor extension support, which will lead to unnecessary OMX failure logs.
8381     if (vendorKeys.empty()) {
8382         return OK;
8383     }
8384 
8385     char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
8386             sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)];
8387 
8388     status_t finalError = OK;
8389 
8390     // don't try again if component does not have vendor extensions
8391     if (mVendorExtensionsStatus == kExtensionsNone) {
8392         return OK;
8393     }
8394 
8395     for (VendorExtension ext : VendorExtensions(mOMXNode)) {
8396         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
8397         if (config == nullptr) {
8398             return ext.status;
8399         }
8400 
8401         mVendorExtensionsStatus = kExtensionsExist;
8402 
8403         config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
8404         strcpy(key, (const char *)config->cName);
8405         size_t nameLength = strlen(key);
8406         key[nameLength] = '.';
8407 
8408         // don't set vendor extension if client has not provided any of its parameters
8409         // or if client simply unsets parameters that are already unset
8410         bool needToSet = false;
8411         for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
8412             // null-terminate param key
8413             config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
8414             strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
8415             removeTrailingTags(key, nameLength, "value");
8416             auto existingKey = vendorKeys.find(key);
8417 
8418             // don't touch (e.g. change) parameters that are not specified by client
8419             if (existingKey == vendorKeys.end()) {
8420                 continue;
8421             }
8422 
8423             bool wasSet = config->param[paramIndex].bSet;
8424             switch (config->param[paramIndex].eValueType) {
8425             case OMX_AndroidVendorValueInt32:
8426             {
8427                 int32_t value;
8428                 config->param[paramIndex].bSet =
8429                     (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value);
8430                 if (config->param[paramIndex].bSet) {
8431                     config->param[paramIndex].nInt32 = value;
8432                 }
8433                 break;
8434             }
8435             case OMX_AndroidVendorValueInt64:
8436             {
8437                 int64_t value;
8438                 config->param[paramIndex].bSet =
8439                     (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value);
8440                 if (config->param[paramIndex].bSet) {
8441                     config->param[paramIndex].nInt64 = value;
8442                 }
8443                 break;
8444             }
8445             case OMX_AndroidVendorValueString:
8446             {
8447                 AString value;
8448                 config->param[paramIndex].bSet =
8449                     (OMX_BOOL)params->findString(existingKey->second.c_str(), &value);
8450                 if (config->param[paramIndex].bSet) {
8451                     size_t dstSize = sizeof(config->param[paramIndex].cString);
8452                     strncpy((char *)config->param[paramIndex].cString, value.c_str(), dstSize - 1);
8453                     // null terminate value
8454                     config->param[paramIndex].cString[dstSize - 1] = '\0';
8455                 }
8456                 break;
8457             }
8458             default:
8459                 ALOGW("[%s] vendor parameter '%s' is not a supported value",
8460                         mComponentName.c_str(), key);
8461                 continue;
8462             }
8463             if (config->param[paramIndex].bSet || wasSet) {
8464                 needToSet = true;
8465             }
8466         }
8467 
8468         if (needToSet) {
8469             status_t err = mOMXNode->setConfig(
8470                     (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension,
8471                     config, config->nSize);
8472             if (err != OK) {
8473                 key[nameLength] = '\0';
8474                 ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key);
8475                 // try to set each extension, and return first failure
8476                 if (finalError == OK) {
8477                     finalError = err;
8478                 }
8479             }
8480         }
8481     }
8482 
8483     if (mVendorExtensionsStatus == kExtensionsUnchecked) {
8484         mVendorExtensionsStatus = kExtensionsNone;
8485     }
8486 
8487     return finalError;
8488 }
8489 
getVendorParameters(OMX_U32 portIndex,sp<AMessage> & format)8490 status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) {
8491     constexpr char prefix[] = "vendor.";
8492     constexpr size_t prefixLength = sizeof(prefix) - 1;
8493     char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
8494             sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength];
8495     strcpy(key, prefix);
8496 
8497     // don't try again if component does not have vendor extensions
8498     if (mVendorExtensionsStatus == kExtensionsNone) {
8499         return OK;
8500     }
8501 
8502     for (VendorExtension ext : VendorExtensions(mOMXNode)) {
8503         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
8504         if (config == nullptr) {
8505             return ext.status;
8506         }
8507 
8508         mVendorExtensionsStatus = kExtensionsExist;
8509 
8510         if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) {
8511             continue;
8512         }
8513 
8514         config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
8515         strcpy(key + prefixLength, (const char *)config->cName);
8516         size_t nameLength = strlen(key);
8517         key[nameLength] = '.';
8518 
8519         for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
8520             // null-terminate param key
8521             config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
8522             strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
8523             removeTrailingTags(key, nameLength, "value");
8524             if (config->param[paramIndex].bSet) {
8525                 switch (config->param[paramIndex].eValueType) {
8526                 case OMX_AndroidVendorValueInt32:
8527                 {
8528                     format->setInt32(key, config->param[paramIndex].nInt32);
8529                     break;
8530                 }
8531                 case OMX_AndroidVendorValueInt64:
8532                 {
8533                     format->setInt64(key, config->param[paramIndex].nInt64);
8534                     break;
8535                 }
8536                 case OMX_AndroidVendorValueString:
8537                 {
8538                     config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0';
8539                     format->setString(key, (const char *)config->param[paramIndex].cString);
8540                     break;
8541                 }
8542                 default:
8543                     ALOGW("vendor parameter %s is not a supported value", key);
8544                     continue;
8545                 }
8546             }
8547         }
8548     }
8549 
8550     if (mVendorExtensionsStatus == kExtensionsUnchecked) {
8551         mVendorExtensionsStatus = kExtensionsNone;
8552     }
8553 
8554     return OK;
8555 }
8556 
onSignalEndOfInputStream()8557 void ACodec::onSignalEndOfInputStream() {
8558     status_t err = INVALID_OPERATION;
8559     if (mGraphicBufferSource != NULL) {
8560         err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
8561     }
8562     mCallback->onSignaledInputEOS(err);
8563 }
8564 
forceStateTransition(int generation)8565 void ACodec::forceStateTransition(int generation) {
8566     if (generation != mStateGeneration) {
8567         ALOGV("Ignoring stale force state transition message: #%d (now #%d)",
8568                 generation, mStateGeneration);
8569         return;
8570     }
8571     ALOGE("State machine stuck");
8572     // Error must have already been signalled to the client.
8573 
8574     // Deferred messages will be handled at LoadedState at the end of the
8575     // transition.
8576     mShutdownInProgress = true;
8577     // No shutdown complete callback at the end of the transition.
8578     mExplicitShutdown = false;
8579     mKeepComponentAllocated = true;
8580 
8581     status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
8582     if (err != OK) {
8583         // TODO: do some recovery here.
8584     } else {
8585         changeState(mExecutingToIdleState);
8586     }
8587 }
8588 
onOMXFrameRendered(int64_t mediaTimeUs,nsecs_t systemNano)8589 bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
8590     mCodec->mCallback->onOutputFramesRendered({RenderedFrameInfo(mediaTimeUs, systemNano)});
8591     return true;
8592 }
8593 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)8594 bool ACodec::ExecutingState::onOMXEvent(
8595         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8596     switch (event) {
8597         case OMX_EventPortSettingsChanged:
8598         {
8599             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
8600 
8601             mCodec->onOutputFormatChanged();
8602 
8603             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
8604                 mCodec->mMetadataBuffersToSubmit = 0;
8605                 CHECK_EQ(mCodec->mOMXNode->sendCommand(
8606                             OMX_CommandPortDisable, kPortIndexOutput),
8607                          (status_t)OK);
8608 
8609                 mCodec->freeOutputBuffersNotOwnedByComponent();
8610 
8611                 mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
8612             } else if (data2 != OMX_IndexConfigCommonOutputCrop
8613                     && data2 != OMX_IndexConfigAndroidIntraRefresh) {
8614                 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
8615                      mCodec->mComponentName.c_str(), data2);
8616             }
8617 
8618             return true;
8619         }
8620 
8621         case OMX_EventConfigUpdate:
8622         {
8623             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
8624 
8625             mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);
8626 
8627             return true;
8628         }
8629 
8630         case OMX_EventBufferFlag:
8631         {
8632             return true;
8633         }
8634 
8635         case OMX_EventOnFirstTunnelFrameReady:
8636         {
8637             mCodec->onFirstTunnelFrameReady();
8638             return true;
8639         }
8640 
8641         default:
8642             return BaseState::onOMXEvent(event, data1, data2);
8643     }
8644 }
8645 
8646 ////////////////////////////////////////////////////////////////////////////////
8647 
OutputPortSettingsChangedState(ACodec * codec)8648 ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
8649         ACodec *codec)
8650     : BaseState(codec) {
8651 }
8652 
getPortMode(OMX_U32 portIndex)8653 ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
8654         OMX_U32 portIndex) {
8655     if (portIndex == kPortIndexOutput) {
8656         return FREE_BUFFERS;
8657     }
8658 
8659     CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
8660 
8661     return RESUBMIT_BUFFERS;
8662 }
8663 
onMessageReceived(const sp<AMessage> & msg)8664 bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
8665         const sp<AMessage> &msg) {
8666     bool handled = false;
8667 
8668     switch (msg->what()) {
8669         case kWhatFlush:
8670         case kWhatShutdown: {
8671             if (mCodec->mFatalError) {
8672                 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
8673                 msg->setInt32("generation", mCodec->mStateGeneration);
8674                 msg->post(3000000);
8675             }
8676             FALLTHROUGH_INTENDED;
8677         }
8678         case kWhatResume:
8679         {
8680             ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
8681 
8682             mCodec->deferMessage(msg);
8683             handled = true;
8684             break;
8685         }
8686 
8687         case kWhatSetParameters:
8688         {
8689             sp<AMessage> params;
8690             CHECK(msg->findMessage("params", &params));
8691 
8692             sp<ABuffer> hdr10PlusInfo;
8693             if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
8694                 if (hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
8695                     (void)mCodec->setHdr10PlusInfo(hdr10PlusInfo);
8696                 }
8697                 params->removeEntryAt(params->findEntryByName("hdr10-plus-info"));
8698 
8699                 if (params->countEntries() == 0) {
8700                     msg->removeEntryAt(msg->findEntryByName("params"));
8701                 }
8702             }
8703 
8704             if (msg->countEntries() > 0) {
8705                 mCodec->deferMessage(msg);
8706             }
8707             handled = true;
8708             break;
8709         }
8710 
8711         case kWhatForceStateTransition:
8712         {
8713             int32_t generation = 0;
8714             CHECK(msg->findInt32("generation", &generation));
8715             mCodec->forceStateTransition(generation);
8716 
8717             handled = true;
8718             break;
8719         }
8720 
8721         case kWhatSetSurface:
8722         {
8723             ALOGD("[%s] Deferring setSurface from OutputPortSettingsChangedState",
8724                   mCodec->mComponentName.c_str());
8725 
8726             mCodec->deferMessage(msg);
8727 
8728             handled = true;
8729             break;
8730         }
8731 
8732         case kWhatCheckIfStuck:
8733         {
8734             int32_t generation = 0;
8735             CHECK(msg->findInt32("generation", &generation));
8736             if (generation == mCodec->mStateGeneration) {
8737                 mCodec->signalError(OMX_ErrorUndefined, TIMED_OUT);
8738             }
8739 
8740             handled = true;
8741             break;
8742         }
8743 
8744         default:
8745             handled = BaseState::onMessageReceived(msg);
8746             break;
8747     }
8748 
8749     return handled;
8750 }
8751 
stateEntered()8752 void ACodec::OutputPortSettingsChangedState::stateEntered() {
8753     ALOGV("[%s] Now handling output port settings change",
8754          mCodec->mComponentName.c_str());
8755 
8756     // If we haven't transitioned after 3 seconds, we're probably stuck.
8757     sp<AMessage> msg = new AMessage(ACodec::kWhatCheckIfStuck, mCodec);
8758     msg->setInt32("generation", mCodec->mStateGeneration);
8759     msg->post(3000000);
8760 }
8761 
onOMXFrameRendered(int64_t mediaTimeUs,nsecs_t systemNano)8762 bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
8763         int64_t mediaTimeUs, nsecs_t systemNano) {
8764     mCodec->mCallback->onOutputFramesRendered({RenderedFrameInfo(mediaTimeUs, systemNano)});
8765     return true;
8766 }
8767 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)8768 bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
8769         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8770     switch (event) {
8771         case OMX_EventCmdComplete:
8772         {
8773             if (data1 == (OMX_U32)OMX_CommandPortDisable) {
8774                 if (data2 != (OMX_U32)kPortIndexOutput) {
8775                     ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
8776                     return false;
8777                 }
8778 
8779                 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
8780 
8781                 status_t err = OK;
8782                 if (!mCodec->mBuffers[kPortIndexOutput].empty()) {
8783                     ALOGE("disabled port should be empty, but has %zu buffers",
8784                             mCodec->mBuffers[kPortIndexOutput].size());
8785                     err = FAILED_TRANSACTION;
8786                 } else {
8787                     mCodec->mAllocator[kPortIndexOutput].clear();
8788                 }
8789 
8790                 if (err == OK) {
8791                     err = mCodec->mOMXNode->sendCommand(
8792                             OMX_CommandPortEnable, kPortIndexOutput);
8793                 }
8794 
8795                 if (err == OK) {
8796                     err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
8797                     ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
8798                             "reconfiguration: (%d)", err);
8799                     mCodec->mCallback->onOutputBuffersChanged();
8800                 }
8801 
8802                 if (err != OK) {
8803                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
8804                     ALOGE("Error occurred while disabling the output port");
8805                 }
8806 
8807                 return true;
8808             } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
8809                 if (data2 != (OMX_U32)kPortIndexOutput) {
8810                     ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
8811                     return false;
8812                 }
8813 
8814                 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
8815 
8816                 if (mCodec->mExecutingState->active()) {
8817                     mCodec->mExecutingState->submitOutputBuffers();
8818                 }
8819 
8820                 mCodec->changeState(mCodec->mExecutingState);
8821 
8822                 return true;
8823             }
8824 
8825             return false;
8826         }
8827 
8828         case OMX_EventConfigUpdate:
8829         {
8830             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
8831 
8832             mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);
8833 
8834             return true;
8835         }
8836 
8837         default:
8838             return BaseState::onOMXEvent(event, data1, data2);
8839     }
8840 }
8841 
8842 ////////////////////////////////////////////////////////////////////////////////
8843 
ExecutingToIdleState(ACodec * codec)8844 ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
8845     : BaseState(codec),
8846       mComponentNowIdle(false) {
8847 }
8848 
onMessageReceived(const sp<AMessage> & msg)8849 bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
8850     bool handled = false;
8851 
8852     switch (msg->what()) {
8853         case kWhatFlush:
8854         {
8855             // Don't send me a flush request if you previously wanted me
8856             // to shutdown.
8857             ALOGW("Ignoring flush request in ExecutingToIdleState");
8858             break;
8859         }
8860 
8861         case kWhatShutdown:
8862         {
8863             mCodec->deferMessage(msg);
8864             handled = true;
8865             break;
8866         }
8867 
8868         default:
8869             handled = BaseState::onMessageReceived(msg);
8870             break;
8871     }
8872 
8873     return handled;
8874 }
8875 
stateEntered()8876 void ACodec::ExecutingToIdleState::stateEntered() {
8877     ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
8878 
8879     mComponentNowIdle = false;
8880     mCodec->mLastOutputFormat.clear();
8881 }
8882 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)8883 bool ACodec::ExecutingToIdleState::onOMXEvent(
8884         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8885     switch (event) {
8886         case OMX_EventCmdComplete:
8887         {
8888             if (data1 != (OMX_U32)OMX_CommandStateSet
8889                     || data2 != (OMX_U32)OMX_StateIdle) {
8890                 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
8891                         asString((OMX_COMMANDTYPE)data1), data1,
8892                         asString((OMX_STATETYPE)data2), data2);
8893                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8894                 return true;
8895             }
8896 
8897             mComponentNowIdle = true;
8898 
8899             changeStateIfWeOwnAllBuffers();
8900 
8901             return true;
8902         }
8903 
8904         case OMX_EventPortSettingsChanged:
8905         case OMX_EventBufferFlag:
8906         {
8907             // We're shutting down and don't care about this anymore.
8908             return true;
8909         }
8910 
8911         default:
8912             return BaseState::onOMXEvent(event, data1, data2);
8913     }
8914 }
8915 
changeStateIfWeOwnAllBuffers()8916 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
8917     if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
8918         status_t err = mCodec->mOMXNode->sendCommand(
8919                 OMX_CommandStateSet, OMX_StateLoaded);
8920         if (err == OK) {
8921             err = mCodec->freeBuffersOnPort(kPortIndexInput);
8922             status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
8923             if (err == OK) {
8924                 err = err2;
8925             }
8926         }
8927 
8928         if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
8929                 && mCodec->mNativeWindow != NULL) {
8930             // We push enough 1x1 blank buffers to ensure that one of
8931             // them has made it to the display.  This allows the OMX
8932             // component teardown to zero out any protected buffers
8933             // without the risk of scanning out one of those buffers.
8934             pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
8935         }
8936 
8937         if (err != OK) {
8938             mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
8939             return;
8940         }
8941 
8942         mCodec->changeState(mCodec->mIdleToLoadedState);
8943     }
8944 }
8945 
onInputBufferFilled(const sp<AMessage> & msg)8946 void ACodec::ExecutingToIdleState::onInputBufferFilled(
8947         const sp<AMessage> &msg) {
8948     BaseState::onInputBufferFilled(msg);
8949 
8950     changeStateIfWeOwnAllBuffers();
8951 }
8952 
onOutputBufferDrained(const sp<AMessage> & msg)8953 void ACodec::ExecutingToIdleState::onOutputBufferDrained(
8954         const sp<AMessage> &msg) {
8955     BaseState::onOutputBufferDrained(msg);
8956 
8957     changeStateIfWeOwnAllBuffers();
8958 }
8959 
8960 ////////////////////////////////////////////////////////////////////////////////
8961 
IdleToLoadedState(ACodec * codec)8962 ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
8963     : BaseState(codec) {
8964 }
8965 
onMessageReceived(const sp<AMessage> & msg)8966 bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
8967     bool handled = false;
8968 
8969     switch (msg->what()) {
8970         case kWhatShutdown:
8971         {
8972             mCodec->deferMessage(msg);
8973             handled = true;
8974             break;
8975         }
8976 
8977         case kWhatFlush:
8978         {
8979             // Don't send me a flush request if you previously wanted me
8980             // to shutdown.
8981             ALOGE("Got flush request in IdleToLoadedState");
8982             break;
8983         }
8984 
8985         default:
8986             handled = BaseState::onMessageReceived(msg);
8987             break;
8988     }
8989 
8990     return handled;
8991 }
8992 
stateEntered()8993 void ACodec::IdleToLoadedState::stateEntered() {
8994     ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
8995 }
8996 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)8997 bool ACodec::IdleToLoadedState::onOMXEvent(
8998         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8999     switch (event) {
9000         case OMX_EventCmdComplete:
9001         {
9002             if (data1 != (OMX_U32)OMX_CommandStateSet
9003                     || data2 != (OMX_U32)OMX_StateLoaded) {
9004                 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
9005                         asString((OMX_COMMANDTYPE)data1), data1,
9006                         asString((OMX_STATETYPE)data2), data2);
9007                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
9008                 return true;
9009             }
9010 
9011             mCodec->changeState(mCodec->mLoadedState);
9012 
9013             return true;
9014         }
9015 
9016         default:
9017             return BaseState::onOMXEvent(event, data1, data2);
9018     }
9019 }
9020 
9021 ////////////////////////////////////////////////////////////////////////////////
9022 
FlushingState(ACodec * codec)9023 ACodec::FlushingState::FlushingState(ACodec *codec)
9024     : BaseState(codec) {
9025 }
9026 
stateEntered()9027 void ACodec::FlushingState::stateEntered() {
9028     ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
9029 
9030     mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
9031     mCodec->mDecodeOnlyTimesUs.clear();
9032 
9033     // If we haven't transitioned after 3 seconds, we're probably stuck.
9034     sp<AMessage> msg = new AMessage(ACodec::kWhatCheckIfStuck, mCodec);
9035     msg->setInt32("generation", mCodec->mStateGeneration);
9036     msg->post(3000000);
9037 }
9038 
onMessageReceived(const sp<AMessage> & msg)9039 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
9040     bool handled = false;
9041 
9042     switch (msg->what()) {
9043         case kWhatShutdown:
9044         {
9045             mCodec->deferMessage(msg);
9046             if (mCodec->mFatalError) {
9047                 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
9048                 msg->setInt32("generation", mCodec->mStateGeneration);
9049                 msg->post(3000000);
9050             }
9051             handled = true;
9052             break;
9053         }
9054 
9055         case kWhatFlush:
9056         {
9057             // We're already doing this right now.
9058             handled = true;
9059             break;
9060         }
9061 
9062         case kWhatForceStateTransition:
9063         {
9064             int32_t generation = 0;
9065             CHECK(msg->findInt32("generation", &generation));
9066             mCodec->forceStateTransition(generation);
9067 
9068             handled = true;
9069             break;
9070         }
9071 
9072         case kWhatCheckIfStuck:
9073         {
9074             int32_t generation = 0;
9075             CHECK(msg->findInt32("generation", &generation));
9076             if (generation == mCodec->mStateGeneration) {
9077                 mCodec->signalError(OMX_ErrorUndefined, TIMED_OUT);
9078             }
9079 
9080             handled = true;
9081             break;
9082         }
9083 
9084         default:
9085             handled = BaseState::onMessageReceived(msg);
9086             break;
9087     }
9088 
9089     return handled;
9090 }
9091 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)9092 bool ACodec::FlushingState::onOMXEvent(
9093         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
9094     ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
9095             mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
9096 
9097     switch (event) {
9098         case OMX_EventCmdComplete:
9099         {
9100             if (data1 != (OMX_U32)OMX_CommandFlush) {
9101                 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
9102                         asString((OMX_COMMANDTYPE)data1), data1, data2);
9103                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
9104                 return true;
9105             }
9106 
9107             if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
9108                 if (mFlushComplete[data2]) {
9109                     ALOGW("Flush already completed for %s port",
9110                             data2 == kPortIndexInput ? "input" : "output");
9111                     return true;
9112                 }
9113                 mFlushComplete[data2] = true;
9114 
9115                 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
9116                     changeStateIfWeOwnAllBuffers();
9117                 }
9118             } else if (data2 == OMX_ALL) {
9119                 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
9120                     ALOGW("received flush complete event for OMX_ALL before ports have been"
9121                             "flushed (%d/%d)",
9122                             mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
9123                     return false;
9124                 }
9125 
9126                 changeStateIfWeOwnAllBuffers();
9127             } else {
9128                 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
9129             }
9130 
9131             return true;
9132         }
9133 
9134         case OMX_EventPortSettingsChanged:
9135         {
9136             sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
9137             msg->setInt32("type", omx_message::EVENT);
9138             msg->setInt32("generation", mCodec->mNodeGeneration);
9139             msg->setInt32("event", event);
9140             msg->setInt32("data1", data1);
9141             msg->setInt32("data2", data2);
9142 
9143             ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
9144                  mCodec->mComponentName.c_str());
9145 
9146             mCodec->deferMessage(msg);
9147 
9148             return true;
9149         }
9150 
9151         default:
9152             return BaseState::onOMXEvent(event, data1, data2);
9153     }
9154 
9155     return true;
9156 }
9157 
onOutputBufferDrained(const sp<AMessage> & msg)9158 void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
9159     BaseState::onOutputBufferDrained(msg);
9160 
9161     changeStateIfWeOwnAllBuffers();
9162 }
9163 
onInputBufferFilled(const sp<AMessage> & msg)9164 void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
9165     BaseState::onInputBufferFilled(msg);
9166 
9167     changeStateIfWeOwnAllBuffers();
9168 }
9169 
changeStateIfWeOwnAllBuffers()9170 void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
9171     if (mFlushComplete[kPortIndexInput]
9172             && mFlushComplete[kPortIndexOutput]
9173             && mCodec->allYourBuffersAreBelongToUs()) {
9174         // We now own all buffers except possibly those still queued with
9175         // the native window for rendering. Let's get those back as well.
9176         mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
9177 
9178         mCodec->mCallback->onFlushCompleted();
9179 
9180         mCodec->mPortEOS[kPortIndexInput] =
9181             mCodec->mPortEOS[kPortIndexOutput] = false;
9182 
9183         mCodec->mInputEOSResult = OK;
9184 
9185         if (mCodec->mSkipCutBuffer != NULL) {
9186             mCodec->mSkipCutBuffer->clear();
9187         }
9188 
9189         mCodec->changeState(mCodec->mExecutingState);
9190     }
9191 }
9192 
queryCapabilities(const char * owner,const char * name,const char * mime,bool isEncoder,MediaCodecInfo::CapabilitiesWriter * caps)9193 status_t ACodec::queryCapabilities(
9194         const char* owner, const char* name, const char* mime, bool isEncoder,
9195         MediaCodecInfo::CapabilitiesWriter* caps) {
9196     const char *role = GetComponentRole(isEncoder, mime);
9197     if (role == NULL) {
9198         return BAD_VALUE;
9199     }
9200 
9201     OMXClient client;
9202     status_t err = client.connect(owner);
9203     if (err != OK) {
9204         return err;
9205     }
9206 
9207     sp<IOMX> omx = client.interface();
9208     sp<CodecObserver> observer = new CodecObserver(new AMessage);
9209     sp<IOMXNode> omxNode;
9210 
9211     err = omx->allocateNode(name, observer, &omxNode);
9212     if (err != OK) {
9213         client.disconnect();
9214         return err;
9215     }
9216 
9217     err = SetComponentRole(omxNode, role);
9218     if (err != OK) {
9219         omxNode->freeNode();
9220         client.disconnect();
9221         return err;
9222     }
9223 
9224     bool isVideo = strncasecmp(mime, "video/", 6) == 0;
9225     bool isImage = strncasecmp(mime, "image/", 6) == 0;
9226 
9227     if (isVideo || isImage) {
9228         OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
9229         InitOMXParams(&param);
9230         param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
9231 
9232         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
9233             param.nProfileIndex = index;
9234             status_t err = omxNode->getParameter(
9235                     OMX_IndexParamVideoProfileLevelQuerySupported,
9236                     &param, sizeof(param));
9237             if (err != OK) {
9238                 break;
9239             }
9240             caps->addProfileLevel(param.eProfile, param.eLevel);
9241 
9242             // AVC components may not list the constrained profiles explicitly, but
9243             // decoders that support a profile also support its constrained version.
9244             // Encoders must explicitly support constrained profiles.
9245             if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
9246                 if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
9247                     caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
9248                 } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
9249                     caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
9250                 }
9251             }
9252 
9253             if (index == kMaxIndicesToCheck) {
9254                 ALOGW("[%s] stopping checking profiles after %u: %x/%x",
9255                         name, index,
9256                         param.eProfile, param.eLevel);
9257             }
9258         }
9259 
9260         // Color format query
9261         // return colors in the order reported by the OMX component
9262         // prefix "flexible" standard ones with the flexible equivalent
9263         OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
9264         InitOMXParams(&portFormat);
9265         portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
9266         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
9267             portFormat.nIndex = index;
9268             status_t err = omxNode->getParameter(
9269                     OMX_IndexParamVideoPortFormat,
9270                     &portFormat, sizeof(portFormat));
9271             if (err != OK) {
9272                 break;
9273             }
9274 
9275             OMX_U32 flexibleEquivalent;
9276             if (IsFlexibleColorFormat(
9277                     omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
9278                     &flexibleEquivalent)) {
9279                 caps->addColorFormat(flexibleEquivalent);
9280             }
9281             caps->addColorFormat(portFormat.eColorFormat);
9282 
9283             if (index == kMaxIndicesToCheck) {
9284                 ALOGW("[%s] stopping checking formats after %u: %s(%x)",
9285                         name, index,
9286                         asString(portFormat.eColorFormat), portFormat.eColorFormat);
9287             }
9288         }
9289     } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
9290         // More audio codecs if they have profiles.
9291         OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
9292         InitOMXParams(&param);
9293         param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
9294         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
9295             param.nProfileIndex = index;
9296             status_t err = omxNode->getParameter(
9297                     (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
9298                     &param, sizeof(param));
9299             if (err != OK) {
9300                 break;
9301             }
9302             // For audio, level is ignored.
9303             caps->addProfileLevel(param.eProfile, 0 /* level */);
9304 
9305             if (index == kMaxIndicesToCheck) {
9306                 ALOGW("[%s] stopping checking profiles after %u: %x",
9307                         name, index,
9308                         param.eProfile);
9309             }
9310         }
9311 
9312         // NOTE: Without Android extensions, OMX does not provide a way to query
9313         // AAC profile support
9314         if (param.nProfileIndex == 0) {
9315             ALOGW("component %s doesn't support profile query.", name);
9316         }
9317     }
9318 
9319     if (isVideo && !isEncoder) {
9320         native_handle_t *sidebandHandle = NULL;
9321         if (omxNode->configureVideoTunnelMode(
9322                 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
9323             // tunneled playback includes adaptive playback
9324         } else {
9325             // tunneled playback is not supported
9326             caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK);
9327             if (omxNode->setPortMode(
9328                     kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) != OK &&
9329                     omxNode->prepareForAdaptivePlayback(
9330                         kPortIndexOutput, OMX_TRUE,
9331                         1280 /* width */, 720 /* height */) != OK) {
9332                 // adaptive playback is not supported
9333                 caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK);
9334             }
9335 
9336             // all non-tunneled video decoders support detached surface mode
9337             if (android::media::codec::provider_->null_output_surface_support() &&
9338                     android::media::codec::provider_->null_output_surface()) {
9339                 caps->addDetail(MediaCodecInfo::Capabilities::FEATURE_DETACHED_SURFACE, 0);
9340             }
9341         }
9342     }
9343 
9344     if (isVideo && isEncoder) {
9345         OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
9346         InitOMXParams(&params);
9347         params.nPortIndex = kPortIndexOutput;
9348 
9349         OMX_VIDEO_PARAM_INTRAREFRESHTYPE fallbackParams;
9350         InitOMXParams(&fallbackParams);
9351         fallbackParams.nPortIndex = kPortIndexOutput;
9352         fallbackParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
9353 
9354         if (omxNode->getConfig(
9355                 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
9356                 &params, sizeof(params)) != OK &&
9357                 omxNode->getParameter(
9358                     OMX_IndexParamVideoIntraRefresh, &fallbackParams,
9359                     sizeof(fallbackParams)) != OK) {
9360             // intra refresh is not supported
9361             caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH);
9362         }
9363     }
9364 
9365     omxNode->freeNode();
9366     client.disconnect();
9367     return OK;
9368 }
9369 
9370 // These are supposed be equivalent to the logic in
9371 // "audio_channel_out_mask_from_count".
9372 //static
getOMXChannelMapping(size_t numChannels,OMX_AUDIO_CHANNELTYPE map[])9373 status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
9374     switch (numChannels) {
9375         case 1:
9376             map[0] = OMX_AUDIO_ChannelCF;
9377             break;
9378         case 2:
9379             map[0] = OMX_AUDIO_ChannelLF;
9380             map[1] = OMX_AUDIO_ChannelRF;
9381             break;
9382         case 3:
9383             map[0] = OMX_AUDIO_ChannelLF;
9384             map[1] = OMX_AUDIO_ChannelRF;
9385             map[2] = OMX_AUDIO_ChannelCF;
9386             break;
9387         case 4:
9388             map[0] = OMX_AUDIO_ChannelLF;
9389             map[1] = OMX_AUDIO_ChannelRF;
9390             map[2] = OMX_AUDIO_ChannelLR;
9391             map[3] = OMX_AUDIO_ChannelRR;
9392             break;
9393         case 5:
9394             map[0] = OMX_AUDIO_ChannelLF;
9395             map[1] = OMX_AUDIO_ChannelRF;
9396             map[2] = OMX_AUDIO_ChannelCF;
9397             map[3] = OMX_AUDIO_ChannelLR;
9398             map[4] = OMX_AUDIO_ChannelRR;
9399             break;
9400         case 6:
9401             map[0] = OMX_AUDIO_ChannelLF;
9402             map[1] = OMX_AUDIO_ChannelRF;
9403             map[2] = OMX_AUDIO_ChannelCF;
9404             map[3] = OMX_AUDIO_ChannelLFE;
9405             map[4] = OMX_AUDIO_ChannelLR;
9406             map[5] = OMX_AUDIO_ChannelRR;
9407             break;
9408         case 7:
9409             map[0] = OMX_AUDIO_ChannelLF;
9410             map[1] = OMX_AUDIO_ChannelRF;
9411             map[2] = OMX_AUDIO_ChannelCF;
9412             map[3] = OMX_AUDIO_ChannelLFE;
9413             map[4] = OMX_AUDIO_ChannelLR;
9414             map[5] = OMX_AUDIO_ChannelRR;
9415             map[6] = OMX_AUDIO_ChannelCS;
9416             break;
9417         case 8:
9418             map[0] = OMX_AUDIO_ChannelLF;
9419             map[1] = OMX_AUDIO_ChannelRF;
9420             map[2] = OMX_AUDIO_ChannelCF;
9421             map[3] = OMX_AUDIO_ChannelLFE;
9422             map[4] = OMX_AUDIO_ChannelLR;
9423             map[5] = OMX_AUDIO_ChannelRR;
9424             map[6] = OMX_AUDIO_ChannelLS;
9425             map[7] = OMX_AUDIO_ChannelRS;
9426             break;
9427         default:
9428             return -EINVAL;
9429     }
9430 
9431     return OK;
9432 }
9433 
querySupportedParameters(std::vector<std::string> * names)9434 status_t ACodec::querySupportedParameters(std::vector<std::string> *names) {
9435     if (!names) {
9436         return BAD_VALUE;
9437     }
9438     return OK;
9439 }
9440 
subscribeToParameters(const std::vector<std::string> & names)9441 status_t ACodec::subscribeToParameters([[maybe_unused]] const std::vector<std::string> &names) {
9442     return OK;
9443 }
9444 
unsubscribeFromParameters(const std::vector<std::string> & names)9445 status_t ACodec::unsubscribeFromParameters([[maybe_unused]] const std::vector<std::string> &names) {
9446     return OK;
9447 }
9448 
9449 }  // namespace android
9450