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