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