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