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