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