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