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