• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "ACodec"
19 
20 #ifdef __LP64__
21 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22 #endif
23 
24 #include <inttypes.h>
25 #include <utils/Trace.h>
26 
27 #include <gui/Surface.h>
28 
29 #include <media/stagefright/ACodec.h>
30 
31 #include <binder/MemoryDealer.h>
32 
33 #include <media/stagefright/foundation/hexdump.h>
34 #include <media/stagefright/foundation/ABuffer.h>
35 #include <media/stagefright/foundation/ADebug.h>
36 #include <media/stagefright/foundation/AMessage.h>
37 #include <media/stagefright/foundation/AUtils.h>
38 
39 #include <media/stagefright/BufferProducerWrapper.h>
40 #include <media/stagefright/MediaCodec.h>
41 #include <media/stagefright/MediaCodecList.h>
42 #include <media/stagefright/MediaDefs.h>
43 #include <media/stagefright/OMXClient.h>
44 #include <media/stagefright/OMXCodec.h>
45 #include <media/stagefright/PersistentSurface.h>
46 #include <media/stagefright/SurfaceUtils.h>
47 #include <media/hardware/HardwareAPI.h>
48 
49 #include <OMX_AudioExt.h>
50 #include <OMX_VideoExt.h>
51 #include <OMX_Component.h>
52 #include <OMX_IndexExt.h>
53 #include <OMX_AsString.h>
54 
55 #include "include/avc_utils.h"
56 
57 namespace android {
58 
59 // OMX errors are directly mapped into status_t range if
60 // there is no corresponding MediaError status code.
61 // Use the statusFromOMXError(int32_t omxError) function.
62 //
63 // Currently this is a direct map.
64 // See frameworks/native/include/media/openmax/OMX_Core.h
65 //
66 // Vendor OMX errors     from 0x90000000 - 0x9000FFFF
67 // Extension OMX errors  from 0x8F000000 - 0x90000000
68 // Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
69 //
70 
71 // returns true if err is a recognized OMX error code.
72 // as OMX error is OMX_S32, this is an int32_t type
isOMXError(int32_t err)73 static inline bool isOMXError(int32_t err) {
74     return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
75 }
76 
77 // converts an OMX error to a status_t
statusFromOMXError(int32_t omxError)78 static inline status_t statusFromOMXError(int32_t omxError) {
79     switch (omxError) {
80     case OMX_ErrorInvalidComponentName:
81     case OMX_ErrorComponentNotFound:
82         return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
83     default:
84         return isOMXError(omxError) ? omxError : 0; // no translation required
85     }
86 }
87 
88 // checks and converts status_t to a non-side-effect status_t
makeNoSideEffectStatus(status_t err)89 static inline status_t makeNoSideEffectStatus(status_t err) {
90     switch (err) {
91     // the following errors have side effects and may come
92     // from other code modules. Remap for safety reasons.
93     case INVALID_OPERATION:
94     case DEAD_OBJECT:
95         return UNKNOWN_ERROR;
96     default:
97         return err;
98     }
99 }
100 
101 template<class T>
InitOMXParams(T * params)102 static void InitOMXParams(T *params) {
103     params->nSize = sizeof(T);
104     params->nVersion.s.nVersionMajor = 1;
105     params->nVersion.s.nVersionMinor = 0;
106     params->nVersion.s.nRevision = 0;
107     params->nVersion.s.nStep = 0;
108 }
109 
110 struct MessageList : public RefBase {
MessageListandroid::MessageList111     MessageList() {
112     }
~MessageListandroid::MessageList113     virtual ~MessageList() {
114     }
getListandroid::MessageList115     std::list<sp<AMessage> > &getList() { return mList; }
116 private:
117     std::list<sp<AMessage> > mList;
118 
119     DISALLOW_EVIL_CONSTRUCTORS(MessageList);
120 };
121 
122 struct CodecObserver : public BnOMXObserver {
CodecObserverandroid::CodecObserver123     CodecObserver() {}
124 
setNotificationMessageandroid::CodecObserver125     void setNotificationMessage(const sp<AMessage> &msg) {
126         mNotify = msg;
127     }
128 
129     // from IOMXObserver
onMessagesandroid::CodecObserver130     virtual void onMessages(const std::list<omx_message> &messages) {
131         if (messages.empty()) {
132             return;
133         }
134 
135         sp<AMessage> notify = mNotify->dup();
136         bool first = true;
137         sp<MessageList> msgList = new MessageList();
138         for (std::list<omx_message>::const_iterator it = messages.cbegin();
139               it != messages.cend(); ++it) {
140             const omx_message &omx_msg = *it;
141             if (first) {
142                 notify->setInt32("node", omx_msg.node);
143                 first = false;
144             }
145 
146             sp<AMessage> msg = new AMessage;
147             msg->setInt32("type", omx_msg.type);
148             switch (omx_msg.type) {
149                 case omx_message::EVENT:
150                 {
151                     msg->setInt32("event", omx_msg.u.event_data.event);
152                     msg->setInt32("data1", omx_msg.u.event_data.data1);
153                     msg->setInt32("data2", omx_msg.u.event_data.data2);
154                     break;
155                 }
156 
157                 case omx_message::EMPTY_BUFFER_DONE:
158                 {
159                     msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
160                     msg->setInt32("fence_fd", omx_msg.fenceFd);
161                     break;
162                 }
163 
164                 case omx_message::FILL_BUFFER_DONE:
165                 {
166                     msg->setInt32(
167                             "buffer", omx_msg.u.extended_buffer_data.buffer);
168                     msg->setInt32(
169                             "range_offset",
170                             omx_msg.u.extended_buffer_data.range_offset);
171                     msg->setInt32(
172                             "range_length",
173                             omx_msg.u.extended_buffer_data.range_length);
174                     msg->setInt32(
175                             "flags",
176                             omx_msg.u.extended_buffer_data.flags);
177                     msg->setInt64(
178                             "timestamp",
179                             omx_msg.u.extended_buffer_data.timestamp);
180                     msg->setInt32(
181                             "fence_fd", omx_msg.fenceFd);
182                     break;
183                 }
184 
185                 case omx_message::FRAME_RENDERED:
186                 {
187                     msg->setInt64(
188                             "media_time_us", omx_msg.u.render_data.timestamp);
189                     msg->setInt64(
190                             "system_nano", omx_msg.u.render_data.nanoTime);
191                     break;
192                 }
193 
194                 default:
195                     ALOGE("Unrecognized message type: %d", omx_msg.type);
196                     break;
197             }
198             msgList->getList().push_back(msg);
199         }
200         notify->setObject("messages", msgList);
201         notify->post();
202     }
203 
204 protected:
~CodecObserverandroid::CodecObserver205     virtual ~CodecObserver() {}
206 
207 private:
208     sp<AMessage> mNotify;
209 
210     DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
211 };
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 
215 struct ACodec::BaseState : public AState {
216     BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
217 
218 protected:
219     enum PortMode {
220         KEEP_BUFFERS,
221         RESUBMIT_BUFFERS,
222         FREE_BUFFERS,
223     };
224 
225     ACodec *mCodec;
226 
227     virtual PortMode getPortMode(OMX_U32 portIndex);
228 
229     virtual bool onMessageReceived(const sp<AMessage> &msg);
230 
231     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
232 
233     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
234     virtual void onInputBufferFilled(const sp<AMessage> &msg);
235 
236     void postFillThisBuffer(BufferInfo *info);
237 
238 private:
239     // Handles an OMX message. Returns true iff message was handled.
240     bool onOMXMessage(const sp<AMessage> &msg);
241 
242     // Handles a list of messages. Returns true iff messages were handled.
243     bool onOMXMessageList(const sp<AMessage> &msg);
244 
245     // returns true iff this message is for this component and the component is alive
246     bool checkOMXMessage(const sp<AMessage> &msg);
247 
248     bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
249 
250     bool onOMXFillBufferDone(
251             IOMX::buffer_id bufferID,
252             size_t rangeOffset, size_t rangeLength,
253             OMX_U32 flags,
254             int64_t timeUs,
255             int fenceFd);
256 
257     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
258 
259     void getMoreInputDataIfPossible();
260 
261     DISALLOW_EVIL_CONSTRUCTORS(BaseState);
262 };
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 
266 struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
DeathNotifierandroid::ACodec::DeathNotifier267     DeathNotifier(const sp<AMessage> &notify)
268         : mNotify(notify) {
269     }
270 
binderDiedandroid::ACodec::DeathNotifier271     virtual void binderDied(const wp<IBinder> &) {
272         mNotify->post();
273     }
274 
275 protected:
~DeathNotifierandroid::ACodec::DeathNotifier276     virtual ~DeathNotifier() {}
277 
278 private:
279     sp<AMessage> mNotify;
280 
281     DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
282 };
283 
284 struct ACodec::UninitializedState : public ACodec::BaseState {
285     UninitializedState(ACodec *codec);
286 
287 protected:
288     virtual bool onMessageReceived(const sp<AMessage> &msg);
289     virtual void stateEntered();
290 
291 private:
292     void onSetup(const sp<AMessage> &msg);
293     bool onAllocateComponent(const sp<AMessage> &msg);
294 
295     sp<DeathNotifier> mDeathNotifier;
296 
297     DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
298 };
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 
302 struct ACodec::LoadedState : public ACodec::BaseState {
303     LoadedState(ACodec *codec);
304 
305 protected:
306     virtual bool onMessageReceived(const sp<AMessage> &msg);
307     virtual void stateEntered();
308 
309 private:
310     friend struct ACodec::UninitializedState;
311 
312     bool onConfigureComponent(const sp<AMessage> &msg);
313     void onCreateInputSurface(const sp<AMessage> &msg);
314     void onSetInputSurface(const sp<AMessage> &msg);
315     void onStart();
316     void onShutdown(bool keepComponentAllocated);
317 
318     status_t setupInputSurface();
319 
320     DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
321 };
322 
323 ////////////////////////////////////////////////////////////////////////////////
324 
325 struct ACodec::LoadedToIdleState : public ACodec::BaseState {
326     LoadedToIdleState(ACodec *codec);
327 
328 protected:
329     virtual bool onMessageReceived(const sp<AMessage> &msg);
330     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
331     virtual void stateEntered();
332 
333 private:
334     status_t allocateBuffers();
335 
336     DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
337 };
338 
339 ////////////////////////////////////////////////////////////////////////////////
340 
341 struct ACodec::IdleToExecutingState : public ACodec::BaseState {
342     IdleToExecutingState(ACodec *codec);
343 
344 protected:
345     virtual bool onMessageReceived(const sp<AMessage> &msg);
346     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347     virtual void stateEntered();
348 
349 private:
350     DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
351 };
352 
353 ////////////////////////////////////////////////////////////////////////////////
354 
355 struct ACodec::ExecutingState : public ACodec::BaseState {
356     ExecutingState(ACodec *codec);
357 
358     void submitRegularOutputBuffers();
359     void submitOutputMetaBuffers();
360     void submitOutputBuffers();
361 
362     // Submit output buffers to the decoder, submit input buffers to client
363     // to fill with data.
364     void resume();
365 
366     // Returns true iff input and output buffers are in play.
activeandroid::ACodec::ExecutingState367     bool active() const { return mActive; }
368 
369 protected:
370     virtual PortMode getPortMode(OMX_U32 portIndex);
371     virtual bool onMessageReceived(const sp<AMessage> &msg);
372     virtual void stateEntered();
373 
374     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
376 
377 private:
378     bool mActive;
379 
380     DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
381 };
382 
383 ////////////////////////////////////////////////////////////////////////////////
384 
385 struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
386     OutputPortSettingsChangedState(ACodec *codec);
387 
388 protected:
389     virtual PortMode getPortMode(OMX_U32 portIndex);
390     virtual bool onMessageReceived(const sp<AMessage> &msg);
391     virtual void stateEntered();
392 
393     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
394     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
395 
396 private:
397     DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
398 };
399 
400 ////////////////////////////////////////////////////////////////////////////////
401 
402 struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
403     ExecutingToIdleState(ACodec *codec);
404 
405 protected:
406     virtual bool onMessageReceived(const sp<AMessage> &msg);
407     virtual void stateEntered();
408 
409     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
410 
411     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
412     virtual void onInputBufferFilled(const sp<AMessage> &msg);
413 
414 private:
415     void changeStateIfWeOwnAllBuffers();
416 
417     bool mComponentNowIdle;
418 
419     DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
420 };
421 
422 ////////////////////////////////////////////////////////////////////////////////
423 
424 struct ACodec::IdleToLoadedState : public ACodec::BaseState {
425     IdleToLoadedState(ACodec *codec);
426 
427 protected:
428     virtual bool onMessageReceived(const sp<AMessage> &msg);
429     virtual void stateEntered();
430 
431     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
432 
433 private:
434     DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
435 };
436 
437 ////////////////////////////////////////////////////////////////////////////////
438 
439 struct ACodec::FlushingState : public ACodec::BaseState {
440     FlushingState(ACodec *codec);
441 
442 protected:
443     virtual bool onMessageReceived(const sp<AMessage> &msg);
444     virtual void stateEntered();
445 
446     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
447 
448     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
449     virtual void onInputBufferFilled(const sp<AMessage> &msg);
450 
451 private:
452     bool mFlushComplete[2];
453 
454     void changeStateIfWeOwnAllBuffers();
455 
456     DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
457 };
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 
setWriteFence(int fenceFd,const char * dbg)461 void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
462     if (mFenceFd >= 0) {
463         ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
464                 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
465     }
466     mFenceFd = fenceFd;
467     mIsReadFence = false;
468 }
469 
setReadFence(int fenceFd,const char * dbg)470 void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
471     if (mFenceFd >= 0) {
472         ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
473                 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
474     }
475     mFenceFd = fenceFd;
476     mIsReadFence = true;
477 }
478 
checkWriteFence(const char * dbg)479 void ACodec::BufferInfo::checkWriteFence(const char *dbg) {
480     if (mFenceFd >= 0 && mIsReadFence) {
481         ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
482     }
483 }
484 
checkReadFence(const char * dbg)485 void ACodec::BufferInfo::checkReadFence(const char *dbg) {
486     if (mFenceFd >= 0 && !mIsReadFence) {
487         ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
488     }
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 
ACodec()493 ACodec::ACodec()
494     : mQuirks(0),
495       mNode(0),
496       mNativeWindowUsageBits(0),
497       mSentFormat(false),
498       mIsVideo(false),
499       mIsEncoder(false),
500       mFatalError(false),
501       mShutdownInProgress(false),
502       mExplicitShutdown(false),
503       mEncoderDelay(0),
504       mEncoderPadding(0),
505       mRotationDegrees(0),
506       mChannelMaskPresent(false),
507       mChannelMask(0),
508       mDequeueCounter(0),
509       mInputMetadataType(kMetadataBufferTypeInvalid),
510       mOutputMetadataType(kMetadataBufferTypeInvalid),
511       mLegacyAdaptiveExperiment(false),
512       mMetadataBuffersToSubmit(0),
513       mRepeatFrameDelayUs(-1ll),
514       mMaxPtsGapUs(-1ll),
515       mMaxFps(-1),
516       mTimePerFrameUs(-1ll),
517       mTimePerCaptureUs(-1ll),
518       mCreateInputBuffersSuspended(false),
519       mTunneled(false) {
520     mUninitializedState = new UninitializedState(this);
521     mLoadedState = new LoadedState(this);
522     mLoadedToIdleState = new LoadedToIdleState(this);
523     mIdleToExecutingState = new IdleToExecutingState(this);
524     mExecutingState = new ExecutingState(this);
525 
526     mOutputPortSettingsChangedState =
527         new OutputPortSettingsChangedState(this);
528 
529     mExecutingToIdleState = new ExecutingToIdleState(this);
530     mIdleToLoadedState = new IdleToLoadedState(this);
531     mFlushingState = new FlushingState(this);
532 
533     mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
534     mInputEOSResult = OK;
535 
536     changeState(mUninitializedState);
537 }
538 
~ACodec()539 ACodec::~ACodec() {
540 }
541 
setNotificationMessage(const sp<AMessage> & msg)542 void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
543     mNotify = msg;
544 }
545 
initiateSetup(const sp<AMessage> & msg)546 void ACodec::initiateSetup(const sp<AMessage> &msg) {
547     msg->setWhat(kWhatSetup);
548     msg->setTarget(this);
549     msg->post();
550 }
551 
signalSetParameters(const sp<AMessage> & params)552 void ACodec::signalSetParameters(const sp<AMessage> &params) {
553     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
554     msg->setMessage("params", params);
555     msg->post();
556 }
557 
initiateAllocateComponent(const sp<AMessage> & msg)558 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
559     msg->setWhat(kWhatAllocateComponent);
560     msg->setTarget(this);
561     msg->post();
562 }
563 
initiateConfigureComponent(const sp<AMessage> & msg)564 void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
565     msg->setWhat(kWhatConfigureComponent);
566     msg->setTarget(this);
567     msg->post();
568 }
569 
setSurface(const sp<Surface> & surface)570 status_t ACodec::setSurface(const sp<Surface> &surface) {
571     sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
572     msg->setObject("surface", surface);
573 
574     sp<AMessage> response;
575     status_t err = msg->postAndAwaitResponse(&response);
576 
577     if (err == OK) {
578         (void)response->findInt32("err", &err);
579     }
580     return err;
581 }
582 
initiateCreateInputSurface()583 void ACodec::initiateCreateInputSurface() {
584     (new AMessage(kWhatCreateInputSurface, this))->post();
585 }
586 
initiateSetInputSurface(const sp<PersistentSurface> & surface)587 void ACodec::initiateSetInputSurface(
588         const sp<PersistentSurface> &surface) {
589     sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
590     msg->setObject("input-surface", surface);
591     msg->post();
592 }
593 
signalEndOfInputStream()594 void ACodec::signalEndOfInputStream() {
595     (new AMessage(kWhatSignalEndOfInputStream, this))->post();
596 }
597 
initiateStart()598 void ACodec::initiateStart() {
599     (new AMessage(kWhatStart, this))->post();
600 }
601 
signalFlush()602 void ACodec::signalFlush() {
603     ALOGV("[%s] signalFlush", mComponentName.c_str());
604     (new AMessage(kWhatFlush, this))->post();
605 }
606 
signalResume()607 void ACodec::signalResume() {
608     (new AMessage(kWhatResume, this))->post();
609 }
610 
initiateShutdown(bool keepComponentAllocated)611 void ACodec::initiateShutdown(bool keepComponentAllocated) {
612     sp<AMessage> msg = new AMessage(kWhatShutdown, this);
613     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
614     msg->post();
615     if (!keepComponentAllocated) {
616         // ensure shutdown completes in 3 seconds
617         (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
618     }
619 }
620 
signalRequestIDRFrame()621 void ACodec::signalRequestIDRFrame() {
622     (new AMessage(kWhatRequestIDRFrame, this))->post();
623 }
624 
625 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
626 // Some codecs may return input buffers before having them processed.
627 // This causes a halt if we already signaled an EOS on the input
628 // port.  For now keep submitting an output buffer if there was an
629 // EOS on the input port, but not yet on the output port.
signalSubmitOutputMetadataBufferIfEOS_workaround()630 void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
631     if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
632             mMetadataBuffersToSubmit > 0) {
633         (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
634     }
635 }
636 
handleSetSurface(const sp<Surface> & surface)637 status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
638     // allow keeping unset surface
639     if (surface == NULL) {
640         if (mNativeWindow != NULL) {
641             ALOGW("cannot unset a surface");
642             return INVALID_OPERATION;
643         }
644         return OK;
645     }
646 
647     // cannot switch from bytebuffers to surface
648     if (mNativeWindow == NULL) {
649         ALOGW("component was not configured with a surface");
650         return INVALID_OPERATION;
651     }
652 
653     ANativeWindow *nativeWindow = surface.get();
654     // if we have not yet started the codec, we can simply set the native window
655     if (mBuffers[kPortIndexInput].size() == 0) {
656         mNativeWindow = surface;
657         return OK;
658     }
659 
660     // we do not support changing a tunneled surface after start
661     if (mTunneled) {
662         ALOGW("cannot change tunneled surface");
663         return INVALID_OPERATION;
664     }
665 
666     int usageBits = 0;
667     status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
668     if (err != OK) {
669         return err;
670     }
671 
672     int ignoredFlags = kVideoGrallocUsage;
673     // New output surface is not allowed to add new usage flag except ignored ones.
674     if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
675         ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
676         return BAD_VALUE;
677     }
678 
679     // get min undequeued count. We cannot switch to a surface that has a higher
680     // undequeued count than we allocated.
681     int minUndequeuedBuffers = 0;
682     err = nativeWindow->query(
683             nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
684             &minUndequeuedBuffers);
685     if (err != 0) {
686         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
687                 strerror(-err), -err);
688         return err;
689     }
690     if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
691         ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
692                 minUndequeuedBuffers, mNumUndequeuedBuffers);
693         return BAD_VALUE;
694     }
695 
696     // we cannot change the number of output buffers while OMX is running
697     // set up surface to the same count
698     Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
699     ALOGV("setting up surface for %zu buffers", buffers.size());
700 
701     err = native_window_set_buffer_count(nativeWindow, buffers.size());
702     if (err != 0) {
703         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
704                 -err);
705         return err;
706     }
707 
708     // need to enable allocation when attaching
709     surface->getIGraphicBufferProducer()->allowAllocation(true);
710 
711     // for meta data mode, we move dequeud buffers to the new surface.
712     // for non-meta mode, we must move all registered buffers
713     for (size_t i = 0; i < buffers.size(); ++i) {
714         const BufferInfo &info = buffers[i];
715         // skip undequeued buffers for meta data mode
716         if (storingMetadataInDecodedBuffers()
717                 && !mLegacyAdaptiveExperiment
718                 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
719             ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
720             continue;
721         }
722         ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
723 
724         err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
725         if (err != OK) {
726             ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
727                     info.mGraphicBuffer->getNativeBuffer(),
728                     strerror(-err), -err);
729             return err;
730         }
731     }
732 
733     // cancel undequeued buffers to new surface
734     if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
735         for (size_t i = 0; i < buffers.size(); ++i) {
736             BufferInfo &info = buffers.editItemAt(i);
737             if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
738                 ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
739                 err = nativeWindow->cancelBuffer(
740                         nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
741                 info.mFenceFd = -1;
742                 if (err != OK) {
743                     ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
744                             info.mGraphicBuffer->getNativeBuffer(),
745                             strerror(-err), -err);
746                     return err;
747                 }
748             }
749         }
750         // disallow further allocation
751         (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
752     }
753 
754     // push blank buffers to previous window if requested
755     if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
756         pushBlankBuffersToNativeWindow(mNativeWindow.get());
757     }
758 
759     mNativeWindow = nativeWindow;
760     mNativeWindowUsageBits = usageBits;
761     return OK;
762 }
763 
allocateBuffersOnPort(OMX_U32 portIndex)764 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
765     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
766 
767     CHECK(mDealer[portIndex] == NULL);
768     CHECK(mBuffers[portIndex].isEmpty());
769 
770     status_t err;
771     if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
772         if (storingMetadataInDecodedBuffers()) {
773             err = allocateOutputMetadataBuffers();
774         } else {
775             err = allocateOutputBuffersFromNativeWindow();
776         }
777     } else {
778         OMX_PARAM_PORTDEFINITIONTYPE def;
779         InitOMXParams(&def);
780         def.nPortIndex = portIndex;
781 
782         err = mOMX->getParameter(
783                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
784 
785         if (err == OK) {
786             MetadataBufferType type =
787                 portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
788             int32_t bufSize = def.nBufferSize;
789             if (type == kMetadataBufferTypeGrallocSource) {
790                 bufSize = sizeof(VideoGrallocMetadata);
791             } else if (type == kMetadataBufferTypeANWBuffer) {
792                 bufSize = sizeof(VideoNativeMetadata);
793             }
794 
795             // If using gralloc or native source input metadata buffers, allocate largest
796             // metadata size as we prefer to generate native source metadata, but component
797             // may require gralloc source. For camera source, allocate at least enough
798             // size for native metadata buffers.
799             int32_t allottedSize = bufSize;
800             if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
801                 bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
802             } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
803                 bufSize = max(bufSize, (int32_t)sizeof(VideoNativeMetadata));
804             }
805 
806             ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
807                     mComponentName.c_str(),
808                     def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
809                     portIndex == kPortIndexInput ? "input" : "output");
810 
811             size_t totalSize = def.nBufferCountActual * bufSize;
812             mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
813 
814             for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
815                 sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
816                 if (mem == NULL || mem->pointer() == NULL) {
817                     return NO_MEMORY;
818                 }
819 
820                 BufferInfo info;
821                 info.mStatus = BufferInfo::OWNED_BY_US;
822                 info.mFenceFd = -1;
823                 info.mRenderInfo = NULL;
824 
825                 uint32_t requiresAllocateBufferBit =
826                     (portIndex == kPortIndexInput)
827                         ? OMXCodec::kRequiresAllocateBufferOnInputPorts
828                         : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
829 
830                 if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
831                         || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
832                     mem.clear();
833 
834                     void *ptr;
835                     err = mOMX->allocateBuffer(
836                             mNode, portIndex, bufSize, &info.mBufferID,
837                             &ptr);
838 
839                     info.mData = new ABuffer(ptr, bufSize);
840                 } else if (mQuirks & requiresAllocateBufferBit) {
841                     err = mOMX->allocateBufferWithBackup(
842                             mNode, portIndex, mem, &info.mBufferID, allottedSize);
843                 } else {
844                     err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
845                 }
846 
847                 if (mem != NULL) {
848                     info.mData = new ABuffer(mem->pointer(), bufSize);
849                     if (type == kMetadataBufferTypeANWBuffer) {
850                         ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
851                     }
852                 }
853 
854                 mBuffers[portIndex].push(info);
855             }
856         }
857     }
858 
859     if (err != OK) {
860         return err;
861     }
862 
863     sp<AMessage> notify = mNotify->dup();
864     notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
865 
866     notify->setInt32("portIndex", portIndex);
867 
868     sp<PortDescription> desc = new PortDescription;
869 
870     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
871         const BufferInfo &info = mBuffers[portIndex][i];
872 
873         desc->addBuffer(info.mBufferID, info.mData);
874     }
875 
876     notify->setObject("portDesc", desc);
877     notify->post();
878 
879     return OK;
880 }
881 
setupNativeWindowSizeFormatAndUsage(ANativeWindow * nativeWindow,int * finalUsage)882 status_t ACodec::setupNativeWindowSizeFormatAndUsage(
883         ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
884     OMX_PARAM_PORTDEFINITIONTYPE def;
885     InitOMXParams(&def);
886     def.nPortIndex = kPortIndexOutput;
887 
888     status_t err = mOMX->getParameter(
889             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
890 
891     if (err != OK) {
892         return err;
893     }
894 
895     OMX_U32 usage = 0;
896     err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
897     if (err != 0) {
898         ALOGW("querying usage flags from OMX IL component failed: %d", err);
899         // XXX: Currently this error is logged, but not fatal.
900         usage = 0;
901     }
902     int omxUsage = usage;
903 
904     if (mFlags & kFlagIsGrallocUsageProtected) {
905         usage |= GRALLOC_USAGE_PROTECTED;
906     }
907 
908     usage |= kVideoGrallocUsage;
909     *finalUsage = usage;
910 
911     ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
912     return setNativeWindowSizeFormatAndUsage(
913             nativeWindow,
914             def.format.video.nFrameWidth,
915             def.format.video.nFrameHeight,
916             def.format.video.eColorFormat,
917             mRotationDegrees,
918             usage);
919 }
920 
configureOutputBuffersFromNativeWindow(OMX_U32 * bufferCount,OMX_U32 * bufferSize,OMX_U32 * minUndequeuedBuffers)921 status_t ACodec::configureOutputBuffersFromNativeWindow(
922         OMX_U32 *bufferCount, OMX_U32 *bufferSize,
923         OMX_U32 *minUndequeuedBuffers) {
924     OMX_PARAM_PORTDEFINITIONTYPE def;
925     InitOMXParams(&def);
926     def.nPortIndex = kPortIndexOutput;
927 
928     status_t err = mOMX->getParameter(
929             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
930 
931     if (err == OK) {
932         err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
933     }
934     if (err != OK) {
935         mNativeWindowUsageBits = 0;
936         return err;
937     }
938 
939     // Exits here for tunneled video playback codecs -- i.e. skips native window
940     // buffer allocation step as this is managed by the tunneled OMX omponent
941     // itself and explicitly sets def.nBufferCountActual to 0.
942     if (mTunneled) {
943         ALOGV("Tunneled Playback: skipping native window buffer allocation.");
944         def.nBufferCountActual = 0;
945         err = mOMX->setParameter(
946                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
947 
948         *minUndequeuedBuffers = 0;
949         *bufferCount = 0;
950         *bufferSize = 0;
951         return err;
952     }
953 
954     *minUndequeuedBuffers = 0;
955     err = mNativeWindow->query(
956             mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
957             (int *)minUndequeuedBuffers);
958 
959     if (err != 0) {
960         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
961                 strerror(-err), -err);
962         return err;
963     }
964 
965     // FIXME: assume that surface is controlled by app (native window
966     // returns the number for the case when surface is not controlled by app)
967     // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
968     // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
969 
970     // Use conservative allocation while also trying to reduce starvation
971     //
972     // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
973     //    minimum needed for the consumer to be able to work
974     // 2. try to allocate two (2) additional buffers to reduce starvation from
975     //    the consumer
976     //    plus an extra buffer to account for incorrect minUndequeuedBufs
977     for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
978         OMX_U32 newBufferCount =
979             def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
980         def.nBufferCountActual = newBufferCount;
981         err = mOMX->setParameter(
982                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
983 
984         if (err == OK) {
985             *minUndequeuedBuffers += extraBuffers;
986             break;
987         }
988 
989         ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
990                 mComponentName.c_str(), newBufferCount, err);
991         /* exit condition */
992         if (extraBuffers == 0) {
993             return err;
994         }
995     }
996 
997     err = native_window_set_buffer_count(
998             mNativeWindow.get(), def.nBufferCountActual);
999 
1000     if (err != 0) {
1001         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1002                 -err);
1003         return err;
1004     }
1005 
1006     *bufferCount = def.nBufferCountActual;
1007     *bufferSize =  def.nBufferSize;
1008     return err;
1009 }
1010 
allocateOutputBuffersFromNativeWindow()1011 status_t ACodec::allocateOutputBuffersFromNativeWindow() {
1012     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1013     status_t err = configureOutputBuffersFromNativeWindow(
1014             &bufferCount, &bufferSize, &minUndequeuedBuffers);
1015     if (err != 0)
1016         return err;
1017     mNumUndequeuedBuffers = minUndequeuedBuffers;
1018 
1019     if (!storingMetadataInDecodedBuffers()) {
1020         static_cast<Surface*>(mNativeWindow.get())
1021                 ->getIGraphicBufferProducer()->allowAllocation(true);
1022     }
1023 
1024     ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1025          "output port",
1026          mComponentName.c_str(), bufferCount, bufferSize);
1027 
1028     // Dequeue buffers and send them to OMX
1029     for (OMX_U32 i = 0; i < bufferCount; i++) {
1030         ANativeWindowBuffer *buf;
1031         int fenceFd;
1032         err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1033         if (err != 0) {
1034             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1035             break;
1036         }
1037 
1038         sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1039         BufferInfo info;
1040         info.mStatus = BufferInfo::OWNED_BY_US;
1041         info.mFenceFd = fenceFd;
1042         info.mIsReadFence = false;
1043         info.mRenderInfo = NULL;
1044         info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
1045         info.mGraphicBuffer = graphicBuffer;
1046         mBuffers[kPortIndexOutput].push(info);
1047 
1048         IOMX::buffer_id bufferId;
1049         err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1050                 &bufferId);
1051         if (err != 0) {
1052             ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
1053                  "%d", i, err);
1054             break;
1055         }
1056 
1057         mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
1058 
1059         ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1060              mComponentName.c_str(),
1061              bufferId, graphicBuffer.get());
1062     }
1063 
1064     OMX_U32 cancelStart;
1065     OMX_U32 cancelEnd;
1066 
1067     if (err != 0) {
1068         // If an error occurred while dequeuing we need to cancel any buffers
1069         // that were dequeued.
1070         cancelStart = 0;
1071         cancelEnd = mBuffers[kPortIndexOutput].size();
1072     } else {
1073         // Return the required minimum undequeued buffers to the native window.
1074         cancelStart = bufferCount - minUndequeuedBuffers;
1075         cancelEnd = bufferCount;
1076     }
1077 
1078     for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1079         BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1080         if (info->mStatus == BufferInfo::OWNED_BY_US) {
1081             status_t error = cancelBufferToNativeWindow(info);
1082             if (err == 0) {
1083                 err = error;
1084             }
1085         }
1086     }
1087 
1088     if (!storingMetadataInDecodedBuffers()) {
1089         static_cast<Surface*>(mNativeWindow.get())
1090                 ->getIGraphicBufferProducer()->allowAllocation(false);
1091     }
1092 
1093     return err;
1094 }
1095 
allocateOutputMetadataBuffers()1096 status_t ACodec::allocateOutputMetadataBuffers() {
1097     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1098     status_t err = configureOutputBuffersFromNativeWindow(
1099             &bufferCount, &bufferSize, &minUndequeuedBuffers);
1100     if (err != 0)
1101         return err;
1102     mNumUndequeuedBuffers = minUndequeuedBuffers;
1103 
1104     ALOGV("[%s] Allocating %u meta buffers on output port",
1105          mComponentName.c_str(), bufferCount);
1106 
1107     size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1108             sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
1109     size_t totalSize = bufferCount * bufSize;
1110     mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1111 
1112     // Dequeue buffers and send them to OMX
1113     for (OMX_U32 i = 0; i < bufferCount; i++) {
1114         BufferInfo info;
1115         info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1116         info.mFenceFd = -1;
1117         info.mRenderInfo = NULL;
1118         info.mGraphicBuffer = NULL;
1119         info.mDequeuedAt = mDequeueCounter;
1120 
1121         sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
1122         if (mem == NULL || mem->pointer() == NULL) {
1123             return NO_MEMORY;
1124         }
1125         if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1126             ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1127         }
1128         info.mData = new ABuffer(mem->pointer(), mem->size());
1129 
1130         // we use useBuffer for metadata regardless of quirks
1131         err = mOMX->useBuffer(
1132                 mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1133 
1134         mBuffers[kPortIndexOutput].push(info);
1135 
1136         ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1137              mComponentName.c_str(), info.mBufferID, mem->pointer());
1138     }
1139 
1140     if (mLegacyAdaptiveExperiment) {
1141         // preallocate and preregister buffers
1142         static_cast<Surface *>(mNativeWindow.get())
1143                 ->getIGraphicBufferProducer()->allowAllocation(true);
1144 
1145         ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1146              "output port",
1147              mComponentName.c_str(), bufferCount, bufferSize);
1148 
1149         // Dequeue buffers then cancel them all
1150         for (OMX_U32 i = 0; i < bufferCount; i++) {
1151             BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1152 
1153             ANativeWindowBuffer *buf;
1154             int fenceFd;
1155             err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1156             if (err != 0) {
1157                 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1158                 break;
1159             }
1160 
1161             sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1162             mOMX->updateGraphicBufferInMeta(
1163                     mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1164             info->mStatus = BufferInfo::OWNED_BY_US;
1165             info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1166             info->mGraphicBuffer = graphicBuffer;
1167         }
1168 
1169         for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1170             BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1171             if (info->mStatus == BufferInfo::OWNED_BY_US) {
1172                 status_t error = cancelBufferToNativeWindow(info);
1173                 if (err == OK) {
1174                     err = error;
1175                 }
1176             }
1177         }
1178 
1179         static_cast<Surface*>(mNativeWindow.get())
1180                 ->getIGraphicBufferProducer()->allowAllocation(false);
1181     }
1182 
1183     mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1184     return err;
1185 }
1186 
submitOutputMetadataBuffer()1187 status_t ACodec::submitOutputMetadataBuffer() {
1188     CHECK(storingMetadataInDecodedBuffers());
1189     if (mMetadataBuffersToSubmit == 0)
1190         return OK;
1191 
1192     BufferInfo *info = dequeueBufferFromNativeWindow();
1193     if (info == NULL) {
1194         return ERROR_IO;
1195     }
1196 
1197     ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1198           mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1199 
1200     --mMetadataBuffersToSubmit;
1201     info->checkWriteFence("submitOutputMetadataBuffer");
1202     status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
1203     info->mFenceFd = -1;
1204     if (err == OK) {
1205         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1206     }
1207 
1208     return err;
1209 }
1210 
waitForFence(int fd,const char * dbg)1211 status_t ACodec::waitForFence(int fd, const char *dbg ) {
1212     status_t res = OK;
1213     if (fd >= 0) {
1214         sp<Fence> fence = new Fence(fd);
1215         res = fence->wait(IOMX::kFenceTimeoutMs);
1216         ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
1217     }
1218     return res;
1219 }
1220 
1221 // static
_asString(BufferInfo::Status s)1222 const char *ACodec::_asString(BufferInfo::Status s) {
1223     switch (s) {
1224         case BufferInfo::OWNED_BY_US:            return "OUR";
1225         case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
1226         case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
1227         case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
1228         case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
1229         case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
1230         default:                                 return "?";
1231     }
1232 }
1233 
dumpBuffers(OMX_U32 portIndex)1234 void ACodec::dumpBuffers(OMX_U32 portIndex) {
1235     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1236     ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
1237             portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
1238     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1239         const BufferInfo &info = mBuffers[portIndex][i];
1240         ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
1241                 i, info.mBufferID, info.mGraphicBuffer.get(),
1242                 info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
1243                 _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
1244     }
1245 }
1246 
cancelBufferToNativeWindow(BufferInfo * info)1247 status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1248     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1249 
1250     ALOGV("[%s] Calling cancelBuffer on buffer %u",
1251          mComponentName.c_str(), info->mBufferID);
1252 
1253     info->checkWriteFence("cancelBufferToNativeWindow");
1254     int err = mNativeWindow->cancelBuffer(
1255         mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
1256     info->mFenceFd = -1;
1257 
1258     ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
1259             mComponentName.c_str(), info->mBufferID);
1260     // change ownership even if cancelBuffer fails
1261     info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1262 
1263     return err;
1264 }
1265 
updateRenderInfoForDequeuedBuffer(ANativeWindowBuffer * buf,int fenceFd,BufferInfo * info)1266 void ACodec::updateRenderInfoForDequeuedBuffer(
1267         ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
1268 
1269     info->mRenderInfo =
1270         mRenderTracker.updateInfoForDequeuedBuffer(
1271                 buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
1272 
1273     // check for any fences already signaled
1274     notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
1275 }
1276 
onFrameRendered(int64_t mediaTimeUs,nsecs_t systemNano)1277 void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
1278     if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
1279         mRenderTracker.dumpRenderQueue();
1280     }
1281 }
1282 
notifyOfRenderedFrames(bool dropIncomplete,FrameRenderTracker::Info * until)1283 void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
1284     sp<AMessage> msg = mNotify->dup();
1285     msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
1286     std::list<FrameRenderTracker::Info> done =
1287         mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
1288 
1289     // unlink untracked frames
1290     for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
1291             it != done.cend(); ++it) {
1292         ssize_t index = it->getIndex();
1293         if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1294             mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1295         } else if (index >= 0) {
1296             // THIS SHOULD NEVER HAPPEN
1297             ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
1298         }
1299     }
1300 
1301     if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
1302         msg->post();
1303     }
1304 }
1305 
dequeueBufferFromNativeWindow()1306 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
1307     ANativeWindowBuffer *buf;
1308     CHECK(mNativeWindow.get() != NULL);
1309 
1310     if (mTunneled) {
1311         ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1312               " video playback mode mode!");
1313         return NULL;
1314     }
1315 
1316     if (mFatalError) {
1317         ALOGW("not dequeuing from native window due to fatal error");
1318         return NULL;
1319     }
1320 
1321     int fenceFd = -1;
1322     do {
1323         status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1324         if (err != 0) {
1325             ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1326             return NULL;
1327         }
1328 
1329         bool stale = false;
1330         for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1331             BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1332 
1333             if (info->mGraphicBuffer != NULL &&
1334                     info->mGraphicBuffer->handle == buf->handle) {
1335                 // Since consumers can attach buffers to BufferQueues, it is possible
1336                 // that a known yet stale buffer can return from a surface that we
1337                 // once used.  We can simply ignore this as we have already dequeued
1338                 // this buffer properly.  NOTE: this does not eliminate all cases,
1339                 // e.g. it is possible that we have queued the valid buffer to the
1340                 // NW, and a stale copy of the same buffer gets dequeued - which will
1341                 // be treated as the valid buffer by ACodec.
1342                 if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1343                     ALOGI("dequeued stale buffer %p. discarding", buf);
1344                     stale = true;
1345                     break;
1346                 }
1347 
1348                 ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1349                 info->mStatus = BufferInfo::OWNED_BY_US;
1350                 info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
1351                 updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1352                 return info;
1353             }
1354         }
1355 
1356         // It is also possible to receive a previously unregistered buffer
1357         // in non-meta mode. These should be treated as stale buffers. The
1358         // same is possible in meta mode, in which case, it will be treated
1359         // as a normal buffer, which is not desirable.
1360         // TODO: fix this.
1361         if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1362             ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1363             stale = true;
1364         }
1365         if (stale) {
1366             // TODO: detach stale buffer, but there is no API yet to do it.
1367             buf = NULL;
1368         }
1369     } while (buf == NULL);
1370 
1371     // get oldest undequeued buffer
1372     BufferInfo *oldest = NULL;
1373     for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1374         BufferInfo *info =
1375             &mBuffers[kPortIndexOutput].editItemAt(i);
1376         if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1377             (oldest == NULL ||
1378              // avoid potential issues from counter rolling over
1379              mDequeueCounter - info->mDequeuedAt >
1380                     mDequeueCounter - oldest->mDequeuedAt)) {
1381             oldest = info;
1382         }
1383     }
1384 
1385     // it is impossible dequeue a buffer when there are no buffers with ANW
1386     CHECK(oldest != NULL);
1387     // it is impossible to dequeue an unknown buffer in non-meta mode, as the
1388     // while loop above does not complete
1389     CHECK(storingMetadataInDecodedBuffers());
1390 
1391     // discard buffer in LRU info and replace with new buffer
1392     oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1393     oldest->mStatus = BufferInfo::OWNED_BY_US;
1394     oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
1395     mRenderTracker.untrackFrame(oldest->mRenderInfo);
1396     oldest->mRenderInfo = NULL;
1397 
1398     mOMX->updateGraphicBufferInMeta(
1399             mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1400             oldest->mBufferID);
1401 
1402     if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1403         VideoGrallocMetadata *grallocMeta =
1404             reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1405         ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1406                 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1407                 mDequeueCounter - oldest->mDequeuedAt,
1408                 (void *)(uintptr_t)grallocMeta->pHandle,
1409                 oldest->mGraphicBuffer->handle, oldest->mData->base());
1410     } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1411         VideoNativeMetadata *nativeMeta =
1412             reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1413         ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1414                 (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1415                 mDequeueCounter - oldest->mDequeuedAt,
1416                 (void *)(uintptr_t)nativeMeta->pBuffer,
1417                 oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1418     }
1419 
1420     updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
1421     return oldest;
1422 }
1423 
freeBuffersOnPort(OMX_U32 portIndex)1424 status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1425     status_t err = OK;
1426     for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1427         i--;
1428         status_t err2 = freeBuffer(portIndex, i);
1429         if (err == OK) {
1430             err = err2;
1431         }
1432     }
1433 
1434     // clear mDealer even on an error
1435     mDealer[portIndex].clear();
1436     return err;
1437 }
1438 
freeOutputBuffersNotOwnedByComponent()1439 status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1440     status_t err = OK;
1441     for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1442         i--;
1443         BufferInfo *info =
1444             &mBuffers[kPortIndexOutput].editItemAt(i);
1445 
1446         // At this time some buffers may still be with the component
1447         // or being drained.
1448         if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
1449             info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1450             status_t err2 = freeBuffer(kPortIndexOutput, i);
1451             if (err == OK) {
1452                 err = err2;
1453             }
1454         }
1455     }
1456 
1457     return err;
1458 }
1459 
freeBuffer(OMX_U32 portIndex,size_t i)1460 status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1461     BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1462     status_t err = OK;
1463 
1464     // there should not be any fences in the metadata
1465     MetadataBufferType type =
1466         portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
1467     if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
1468             && info->mData->size() >= sizeof(VideoNativeMetadata)) {
1469         int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
1470         if (fenceFd >= 0) {
1471             ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
1472                     fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
1473         }
1474     }
1475 
1476     switch (info->mStatus) {
1477         case BufferInfo::OWNED_BY_US:
1478             if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
1479                 (void)cancelBufferToNativeWindow(info);
1480             }
1481             // fall through
1482 
1483         case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1484             err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
1485             break;
1486 
1487         default:
1488             ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
1489             err = FAILED_TRANSACTION;
1490             break;
1491     }
1492 
1493     if (info->mFenceFd >= 0) {
1494         ::close(info->mFenceFd);
1495     }
1496 
1497     if (portIndex == kPortIndexOutput) {
1498         mRenderTracker.untrackFrame(info->mRenderInfo, i);
1499         info->mRenderInfo = NULL;
1500     }
1501 
1502     // remove buffer even if mOMX->freeBuffer fails
1503     mBuffers[portIndex].removeAt(i);
1504     return err;
1505 }
1506 
findBufferByID(uint32_t portIndex,IOMX::buffer_id bufferID,ssize_t * index)1507 ACodec::BufferInfo *ACodec::findBufferByID(
1508         uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1509     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1510         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1511 
1512         if (info->mBufferID == bufferID) {
1513             if (index != NULL) {
1514                 *index = i;
1515             }
1516             return info;
1517         }
1518     }
1519 
1520     ALOGE("Could not find buffer with ID %u", bufferID);
1521     return NULL;
1522 }
1523 
setComponentRole(bool isEncoder,const char * mime)1524 status_t ACodec::setComponentRole(
1525         bool isEncoder, const char *mime) {
1526     struct MimeToRole {
1527         const char *mime;
1528         const char *decoderRole;
1529         const char *encoderRole;
1530     };
1531 
1532     static const MimeToRole kMimeToRole[] = {
1533         { MEDIA_MIMETYPE_AUDIO_MPEG,
1534             "audio_decoder.mp3", "audio_encoder.mp3" },
1535         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
1536             "audio_decoder.mp1", "audio_encoder.mp1" },
1537         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
1538             "audio_decoder.mp2", "audio_encoder.mp2" },
1539         { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1540             "audio_decoder.amrnb", "audio_encoder.amrnb" },
1541         { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1542             "audio_decoder.amrwb", "audio_encoder.amrwb" },
1543         { MEDIA_MIMETYPE_AUDIO_AAC,
1544             "audio_decoder.aac", "audio_encoder.aac" },
1545         { MEDIA_MIMETYPE_AUDIO_VORBIS,
1546             "audio_decoder.vorbis", "audio_encoder.vorbis" },
1547         { MEDIA_MIMETYPE_AUDIO_OPUS,
1548             "audio_decoder.opus", "audio_encoder.opus" },
1549         { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1550             "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1551         { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1552             "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1553         { MEDIA_MIMETYPE_VIDEO_AVC,
1554             "video_decoder.avc", "video_encoder.avc" },
1555         { MEDIA_MIMETYPE_VIDEO_HEVC,
1556             "video_decoder.hevc", "video_encoder.hevc" },
1557         { MEDIA_MIMETYPE_VIDEO_MPEG4,
1558             "video_decoder.mpeg4", "video_encoder.mpeg4" },
1559         { MEDIA_MIMETYPE_VIDEO_H263,
1560             "video_decoder.h263", "video_encoder.h263" },
1561         { MEDIA_MIMETYPE_VIDEO_VP8,
1562             "video_decoder.vp8", "video_encoder.vp8" },
1563         { MEDIA_MIMETYPE_VIDEO_VP9,
1564             "video_decoder.vp9", "video_encoder.vp9" },
1565         { MEDIA_MIMETYPE_AUDIO_RAW,
1566             "audio_decoder.raw", "audio_encoder.raw" },
1567         { MEDIA_MIMETYPE_AUDIO_FLAC,
1568             "audio_decoder.flac", "audio_encoder.flac" },
1569         { MEDIA_MIMETYPE_AUDIO_MSGSM,
1570             "audio_decoder.gsm", "audio_encoder.gsm" },
1571         { MEDIA_MIMETYPE_VIDEO_MPEG2,
1572             "video_decoder.mpeg2", "video_encoder.mpeg2" },
1573         { MEDIA_MIMETYPE_AUDIO_AC3,
1574             "audio_decoder.ac3", "audio_encoder.ac3" },
1575         { MEDIA_MIMETYPE_AUDIO_EAC3,
1576             "audio_decoder.eac3", "audio_encoder.eac3" },
1577     };
1578 
1579     static const size_t kNumMimeToRole =
1580         sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1581 
1582     size_t i;
1583     for (i = 0; i < kNumMimeToRole; ++i) {
1584         if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1585             break;
1586         }
1587     }
1588 
1589     if (i == kNumMimeToRole) {
1590         return ERROR_UNSUPPORTED;
1591     }
1592 
1593     const char *role =
1594         isEncoder ? kMimeToRole[i].encoderRole
1595                   : kMimeToRole[i].decoderRole;
1596 
1597     if (role != NULL) {
1598         OMX_PARAM_COMPONENTROLETYPE roleParams;
1599         InitOMXParams(&roleParams);
1600 
1601         strncpy((char *)roleParams.cRole,
1602                 role, OMX_MAX_STRINGNAME_SIZE - 1);
1603 
1604         roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1605 
1606         status_t err = mOMX->setParameter(
1607                 mNode, OMX_IndexParamStandardComponentRole,
1608                 &roleParams, sizeof(roleParams));
1609 
1610         if (err != OK) {
1611             ALOGW("[%s] Failed to set standard component role '%s'.",
1612                  mComponentName.c_str(), role);
1613 
1614             return err;
1615         }
1616     }
1617 
1618     return OK;
1619 }
1620 
configureCodec(const char * mime,const sp<AMessage> & msg)1621 status_t ACodec::configureCodec(
1622         const char *mime, const sp<AMessage> &msg) {
1623     int32_t encoder;
1624     if (!msg->findInt32("encoder", &encoder)) {
1625         encoder = false;
1626     }
1627 
1628     sp<AMessage> inputFormat = new AMessage();
1629     sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1630 
1631     mIsEncoder = encoder;
1632 
1633     mInputMetadataType = kMetadataBufferTypeInvalid;
1634     mOutputMetadataType = kMetadataBufferTypeInvalid;
1635 
1636     status_t err = setComponentRole(encoder /* isEncoder */, mime);
1637 
1638     if (err != OK) {
1639         return err;
1640     }
1641 
1642     int32_t bitRate = 0;
1643     // FLAC encoder doesn't need a bitrate, other encoders do
1644     if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1645             && !msg->findInt32("bitrate", &bitRate)) {
1646         return INVALID_OPERATION;
1647     }
1648 
1649     int32_t storeMeta;
1650     if (encoder
1651             && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1652             && storeMeta != 0) {
1653         err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1654         if (err != OK) {
1655             ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1656                     mComponentName.c_str(), err);
1657 
1658             return err;
1659         }
1660         // For this specific case we could be using camera source even if storeMetaDataInBuffers
1661         // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1662         if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1663             mInputMetadataType = kMetadataBufferTypeCameraSource;
1664         }
1665 
1666         uint32_t usageBits;
1667         if (mOMX->getParameter(
1668                 mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1669                 &usageBits, sizeof(usageBits)) == OK) {
1670             inputFormat->setInt32(
1671                     "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1672         }
1673     }
1674 
1675     int32_t prependSPSPPS = 0;
1676     if (encoder
1677             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
1678             && prependSPSPPS != 0) {
1679         OMX_INDEXTYPE index;
1680         err = mOMX->getExtensionIndex(
1681                 mNode,
1682                 "OMX.google.android.index.prependSPSPPSToIDRFrames",
1683                 &index);
1684 
1685         if (err == OK) {
1686             PrependSPSPPSToIDRFramesParams params;
1687             InitOMXParams(&params);
1688             params.bEnable = OMX_TRUE;
1689 
1690             err = mOMX->setParameter(
1691                     mNode, index, &params, sizeof(params));
1692         }
1693 
1694         if (err != OK) {
1695             ALOGE("Encoder could not be configured to emit SPS/PPS before "
1696                   "IDR frames. (err %d)", err);
1697 
1698             return err;
1699         }
1700     }
1701 
1702     // Only enable metadata mode on encoder output if encoder can prepend
1703     // sps/pps to idr frames, since in metadata mode the bitstream is in an
1704     // opaque handle, to which we don't have access.
1705     int32_t video = !strncasecmp(mime, "video/", 6);
1706     mIsVideo = video;
1707     if (encoder && video) {
1708         OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1709             && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1710             && storeMeta != 0);
1711 
1712         err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1713         if (err != OK) {
1714             ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1715                 mComponentName.c_str(), err);
1716         }
1717 
1718         if (!msg->findInt64(
1719                     "repeat-previous-frame-after",
1720                     &mRepeatFrameDelayUs)) {
1721             mRepeatFrameDelayUs = -1ll;
1722         }
1723 
1724         if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
1725             mMaxPtsGapUs = -1ll;
1726         }
1727 
1728         if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
1729             mMaxFps = -1;
1730         }
1731 
1732         if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
1733             mTimePerCaptureUs = -1ll;
1734         }
1735 
1736         if (!msg->findInt32(
1737                     "create-input-buffers-suspended",
1738                     (int32_t*)&mCreateInputBuffersSuspended)) {
1739             mCreateInputBuffersSuspended = false;
1740         }
1741     }
1742 
1743     // NOTE: we only use native window for video decoders
1744     sp<RefBase> obj;
1745     bool haveNativeWindow = msg->findObject("native-window", &obj)
1746             && obj != NULL && video && !encoder;
1747     mLegacyAdaptiveExperiment = false;
1748     if (video && !encoder) {
1749         inputFormat->setInt32("adaptive-playback", false);
1750 
1751         int32_t usageProtected;
1752         if (msg->findInt32("protected", &usageProtected) && usageProtected) {
1753             if (!haveNativeWindow) {
1754                 ALOGE("protected output buffers must be sent to an ANativeWindow");
1755                 return PERMISSION_DENIED;
1756             }
1757             mFlags |= kFlagIsGrallocUsageProtected;
1758             mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1759         }
1760     }
1761     if (haveNativeWindow) {
1762         sp<ANativeWindow> nativeWindow =
1763             static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
1764 
1765         // START of temporary support for automatic FRC - THIS WILL BE REMOVED
1766         int32_t autoFrc;
1767         if (msg->findInt32("auto-frc", &autoFrc)) {
1768             bool enabled = autoFrc;
1769             OMX_CONFIG_BOOLEANTYPE config;
1770             InitOMXParams(&config);
1771             config.bEnabled = (OMX_BOOL)enabled;
1772             status_t temp = mOMX->setConfig(
1773                     mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
1774                     &config, sizeof(config));
1775             if (temp == OK) {
1776                 outputFormat->setInt32("auto-frc", enabled);
1777             } else if (enabled) {
1778                 ALOGI("codec does not support requested auto-frc (err %d)", temp);
1779             }
1780         }
1781         // END of temporary support for automatic FRC
1782 
1783         int32_t tunneled;
1784         if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
1785             tunneled != 0) {
1786             ALOGI("Configuring TUNNELED video playback.");
1787             mTunneled = true;
1788 
1789             int32_t audioHwSync = 0;
1790             if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
1791                 ALOGW("No Audio HW Sync provided for video tunnel");
1792             }
1793             err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
1794             if (err != OK) {
1795                 ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
1796                         audioHwSync, nativeWindow.get());
1797                 return err;
1798             }
1799 
1800             int32_t maxWidth = 0, maxHeight = 0;
1801             if (msg->findInt32("max-width", &maxWidth) &&
1802                     msg->findInt32("max-height", &maxHeight)) {
1803 
1804                 err = mOMX->prepareForAdaptivePlayback(
1805                         mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1806                 if (err != OK) {
1807                     ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1808                             mComponentName.c_str(), err);
1809                     // allow failure
1810                     err = OK;
1811                 } else {
1812                     inputFormat->setInt32("max-width", maxWidth);
1813                     inputFormat->setInt32("max-height", maxHeight);
1814                     inputFormat->setInt32("adaptive-playback", true);
1815                 }
1816             }
1817         } else {
1818             ALOGV("Configuring CPU controlled video playback.");
1819             mTunneled = false;
1820 
1821             // Explicity reset the sideband handle of the window for
1822             // non-tunneled video in case the window was previously used
1823             // for a tunneled video playback.
1824             err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
1825             if (err != OK) {
1826                 ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
1827                 return err;
1828             }
1829 
1830             // Always try to enable dynamic output buffers on native surface
1831             err = mOMX->storeMetaDataInBuffers(
1832                     mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
1833             if (err != OK) {
1834                 ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1835                         mComponentName.c_str(), err);
1836 
1837                 // if adaptive playback has been requested, try JB fallback
1838                 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1839                 // LARGE MEMORY REQUIREMENT
1840 
1841                 // we will not do adaptive playback on software accessed
1842                 // surfaces as they never had to respond to changes in the
1843                 // crop window, and we don't trust that they will be able to.
1844                 int usageBits = 0;
1845                 bool canDoAdaptivePlayback;
1846 
1847                 if (nativeWindow->query(
1848                         nativeWindow.get(),
1849                         NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1850                         &usageBits) != OK) {
1851                     canDoAdaptivePlayback = false;
1852                 } else {
1853                     canDoAdaptivePlayback =
1854                         (usageBits &
1855                                 (GRALLOC_USAGE_SW_READ_MASK |
1856                                  GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1857                 }
1858 
1859                 int32_t maxWidth = 0, maxHeight = 0;
1860                 if (canDoAdaptivePlayback &&
1861                         msg->findInt32("max-width", &maxWidth) &&
1862                         msg->findInt32("max-height", &maxHeight)) {
1863                     ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1864                             mComponentName.c_str(), maxWidth, maxHeight);
1865 
1866                     err = mOMX->prepareForAdaptivePlayback(
1867                             mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
1868                             maxHeight);
1869                     ALOGW_IF(err != OK,
1870                             "[%s] prepareForAdaptivePlayback failed w/ err %d",
1871                             mComponentName.c_str(), err);
1872 
1873                     if (err == OK) {
1874                         inputFormat->setInt32("max-width", maxWidth);
1875                         inputFormat->setInt32("max-height", maxHeight);
1876                         inputFormat->setInt32("adaptive-playback", true);
1877                     }
1878                 }
1879                 // allow failure
1880                 err = OK;
1881             } else {
1882                 ALOGV("[%s] storeMetaDataInBuffers succeeded",
1883                         mComponentName.c_str());
1884                 CHECK(storingMetadataInDecodedBuffers());
1885                 mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1886                         "legacy-adaptive", !msg->contains("no-experiments"));
1887 
1888                 inputFormat->setInt32("adaptive-playback", true);
1889             }
1890 
1891             int32_t push;
1892             if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
1893                     && push != 0) {
1894                 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1895             }
1896         }
1897 
1898         int32_t rotationDegrees;
1899         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1900             mRotationDegrees = rotationDegrees;
1901         } else {
1902             mRotationDegrees = 0;
1903         }
1904     }
1905 
1906     if (video) {
1907         // determine need for software renderer
1908         bool usingSwRenderer = false;
1909         if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
1910             usingSwRenderer = true;
1911             haveNativeWindow = false;
1912         }
1913 
1914         if (encoder) {
1915             err = setupVideoEncoder(mime, msg);
1916         } else {
1917             err = setupVideoDecoder(mime, msg, haveNativeWindow);
1918         }
1919 
1920         if (err != OK) {
1921             return err;
1922         }
1923 
1924         if (haveNativeWindow) {
1925             mNativeWindow = static_cast<Surface *>(obj.get());
1926         }
1927 
1928         // initialize native window now to get actual output format
1929         // TODO: this is needed for some encoders even though they don't use native window
1930         err = initNativeWindow();
1931         if (err != OK) {
1932             return err;
1933         }
1934 
1935         // fallback for devices that do not handle flex-YUV for native buffers
1936         if (haveNativeWindow) {
1937             int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
1938             if (msg->findInt32("color-format", &requestedColorFormat) &&
1939                     requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1940                 status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1941                 if (err != OK) {
1942                     return err;
1943                 }
1944                 int32_t colorFormat = OMX_COLOR_FormatUnused;
1945                 OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1946                 if (!outputFormat->findInt32("color-format", &colorFormat)) {
1947                     ALOGE("ouptut port did not have a color format (wrong domain?)");
1948                     return BAD_VALUE;
1949                 }
1950                 ALOGD("[%s] Requested output format %#x and got %#x.",
1951                         mComponentName.c_str(), requestedColorFormat, colorFormat);
1952                 if (!isFlexibleColorFormat(
1953                                 mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
1954                         || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
1955                     // device did not handle flex-YUV request for native window, fall back
1956                     // to SW renderer
1957                     ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
1958                     mNativeWindow.clear();
1959                     mNativeWindowUsageBits = 0;
1960                     haveNativeWindow = false;
1961                     usingSwRenderer = true;
1962                     if (storingMetadataInDecodedBuffers()) {
1963                         err = mOMX->storeMetaDataInBuffers(
1964                                 mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1965                         mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
1966                         // TODO: implement adaptive-playback support for bytebuffer mode.
1967                         // This is done by SW codecs, but most HW codecs don't support it.
1968                         inputFormat->setInt32("adaptive-playback", false);
1969                     }
1970                     if (err == OK) {
1971                         err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1972                     }
1973                     if (mFlags & kFlagIsGrallocUsageProtected) {
1974                         // fallback is not supported for protected playback
1975                         err = PERMISSION_DENIED;
1976                     } else if (err == OK) {
1977                         err = setupVideoDecoder(mime, msg, false);
1978                     }
1979                 }
1980             }
1981         }
1982 
1983         if (usingSwRenderer) {
1984             outputFormat->setInt32("using-sw-renderer", 1);
1985         }
1986     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
1987         int32_t numChannels, sampleRate;
1988         if (!msg->findInt32("channel-count", &numChannels)
1989                 || !msg->findInt32("sample-rate", &sampleRate)) {
1990             // Since we did not always check for these, leave them optional
1991             // and have the decoder figure it all out.
1992             err = OK;
1993         } else {
1994             err = setupRawAudioFormat(
1995                     encoder ? kPortIndexInput : kPortIndexOutput,
1996                     sampleRate,
1997                     numChannels);
1998         }
1999     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2000         int32_t numChannels, sampleRate;
2001         if (!msg->findInt32("channel-count", &numChannels)
2002                 || !msg->findInt32("sample-rate", &sampleRate)) {
2003             err = INVALID_OPERATION;
2004         } else {
2005             int32_t isADTS, aacProfile;
2006             int32_t sbrMode;
2007             int32_t maxOutputChannelCount;
2008             int32_t pcmLimiterEnable;
2009             drcParams_t drc;
2010             if (!msg->findInt32("is-adts", &isADTS)) {
2011                 isADTS = 0;
2012             }
2013             if (!msg->findInt32("aac-profile", &aacProfile)) {
2014                 aacProfile = OMX_AUDIO_AACObjectNull;
2015             }
2016             if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2017                 sbrMode = -1;
2018             }
2019 
2020             if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
2021                 maxOutputChannelCount = -1;
2022             }
2023             if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
2024                 // value is unknown
2025                 pcmLimiterEnable = -1;
2026             }
2027             if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
2028                 // value is unknown
2029                 drc.encodedTargetLevel = -1;
2030             }
2031             if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
2032                 // value is unknown
2033                 drc.drcCut = -1;
2034             }
2035             if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
2036                 // value is unknown
2037                 drc.drcBoost = -1;
2038             }
2039             if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
2040                 // value is unknown
2041                 drc.heavyCompression = -1;
2042             }
2043             if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
2044                 // value is unknown
2045                 drc.targetRefLevel = -1;
2046             }
2047 
2048             err = setupAACCodec(
2049                     encoder, numChannels, sampleRate, bitRate, aacProfile,
2050                     isADTS != 0, sbrMode, maxOutputChannelCount, drc,
2051                     pcmLimiterEnable);
2052         }
2053     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
2054         err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2055     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
2056         err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2057     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2058             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2059         // These are PCM-like formats with a fixed sample rate but
2060         // a variable number of channels.
2061 
2062         int32_t numChannels;
2063         if (!msg->findInt32("channel-count", &numChannels)) {
2064             err = INVALID_OPERATION;
2065         } else {
2066             int32_t sampleRate;
2067             if (!msg->findInt32("sample-rate", &sampleRate)) {
2068                 sampleRate = 8000;
2069             }
2070             err = setupG711Codec(encoder, sampleRate, numChannels);
2071         }
2072     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2073         int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
2074         if (encoder &&
2075                 (!msg->findInt32("channel-count", &numChannels)
2076                         || !msg->findInt32("sample-rate", &sampleRate))) {
2077             ALOGE("missing channel count or sample rate for FLAC encoder");
2078             err = INVALID_OPERATION;
2079         } else {
2080             if (encoder) {
2081                 if (!msg->findInt32(
2082                             "complexity", &compressionLevel) &&
2083                     !msg->findInt32(
2084                             "flac-compression-level", &compressionLevel)) {
2085                     compressionLevel = 5; // default FLAC compression level
2086                 } else if (compressionLevel < 0) {
2087                     ALOGW("compression level %d outside [0..8] range, "
2088                           "using 0",
2089                           compressionLevel);
2090                     compressionLevel = 0;
2091                 } else if (compressionLevel > 8) {
2092                     ALOGW("compression level %d outside [0..8] range, "
2093                           "using 8",
2094                           compressionLevel);
2095                     compressionLevel = 8;
2096                 }
2097             }
2098             err = setupFlacCodec(
2099                     encoder, numChannels, sampleRate, compressionLevel);
2100         }
2101     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2102         int32_t numChannels, sampleRate;
2103         if (encoder
2104                 || !msg->findInt32("channel-count", &numChannels)
2105                 || !msg->findInt32("sample-rate", &sampleRate)) {
2106             err = INVALID_OPERATION;
2107         } else {
2108             err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2109         }
2110     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
2111         int32_t numChannels;
2112         int32_t sampleRate;
2113         if (!msg->findInt32("channel-count", &numChannels)
2114                 || !msg->findInt32("sample-rate", &sampleRate)) {
2115             err = INVALID_OPERATION;
2116         } else {
2117             err = setupAC3Codec(encoder, numChannels, sampleRate);
2118         }
2119     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
2120         int32_t numChannels;
2121         int32_t sampleRate;
2122         if (!msg->findInt32("channel-count", &numChannels)
2123                 || !msg->findInt32("sample-rate", &sampleRate)) {
2124             err = INVALID_OPERATION;
2125         } else {
2126             err = setupEAC3Codec(encoder, numChannels, sampleRate);
2127         }
2128     }
2129 
2130     if (err != OK) {
2131         return err;
2132     }
2133 
2134     if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
2135         mEncoderDelay = 0;
2136     }
2137 
2138     if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
2139         mEncoderPadding = 0;
2140     }
2141 
2142     if (msg->findInt32("channel-mask", &mChannelMask)) {
2143         mChannelMaskPresent = true;
2144     } else {
2145         mChannelMaskPresent = false;
2146     }
2147 
2148     int32_t maxInputSize;
2149     if (msg->findInt32("max-input-size", &maxInputSize)) {
2150         err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2151     } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
2152         err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2153     }
2154 
2155     int32_t priority;
2156     if (msg->findInt32("priority", &priority)) {
2157         err = setPriority(priority);
2158     }
2159 
2160     int32_t rateInt = -1;
2161     float rateFloat = -1;
2162     if (!msg->findFloat("operating-rate", &rateFloat)) {
2163         msg->findInt32("operating-rate", &rateInt);
2164         rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2165     }
2166     if (rateFloat > 0) {
2167         err = setOperatingRate(rateFloat, video);
2168     }
2169 
2170     mBaseOutputFormat = outputFormat;
2171 
2172     err = getPortFormat(kPortIndexInput, inputFormat);
2173     if (err == OK) {
2174         err = getPortFormat(kPortIndexOutput, outputFormat);
2175         if (err == OK) {
2176             mInputFormat = inputFormat;
2177             mOutputFormat = outputFormat;
2178         }
2179     }
2180     return err;
2181 }
2182 
setPriority(int32_t priority)2183 status_t ACodec::setPriority(int32_t priority) {
2184     if (priority < 0) {
2185         return BAD_VALUE;
2186     }
2187     OMX_PARAM_U32TYPE config;
2188     InitOMXParams(&config);
2189     config.nU32 = (OMX_U32)priority;
2190     status_t temp = mOMX->setConfig(
2191             mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
2192             &config, sizeof(config));
2193     if (temp != OK) {
2194         ALOGI("codec does not support config priority (err %d)", temp);
2195     }
2196     return OK;
2197 }
2198 
setOperatingRate(float rateFloat,bool isVideo)2199 status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2200     if (rateFloat < 0) {
2201         return BAD_VALUE;
2202     }
2203     OMX_U32 rate;
2204     if (isVideo) {
2205         if (rateFloat > 65535) {
2206             return BAD_VALUE;
2207         }
2208         rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2209     } else {
2210         if (rateFloat > UINT_MAX) {
2211             return BAD_VALUE;
2212         }
2213         rate = (OMX_U32)(rateFloat);
2214     }
2215     OMX_PARAM_U32TYPE config;
2216     InitOMXParams(&config);
2217     config.nU32 = rate;
2218     status_t err = mOMX->setConfig(
2219             mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2220             &config, sizeof(config));
2221     if (err != OK) {
2222         ALOGI("codec does not support config operating rate (err %d)", err);
2223     }
2224     return OK;
2225 }
2226 
setMinBufferSize(OMX_U32 portIndex,size_t size)2227 status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2228     OMX_PARAM_PORTDEFINITIONTYPE def;
2229     InitOMXParams(&def);
2230     def.nPortIndex = portIndex;
2231 
2232     status_t err = mOMX->getParameter(
2233             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2234 
2235     if (err != OK) {
2236         return err;
2237     }
2238 
2239     if (def.nBufferSize >= size) {
2240         return OK;
2241     }
2242 
2243     def.nBufferSize = size;
2244 
2245     err = mOMX->setParameter(
2246             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2247 
2248     if (err != OK) {
2249         return err;
2250     }
2251 
2252     err = mOMX->getParameter(
2253             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2254 
2255     if (err != OK) {
2256         return err;
2257     }
2258 
2259     if (def.nBufferSize < size) {
2260         ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2261         return FAILED_TRANSACTION;
2262     }
2263 
2264     return OK;
2265 }
2266 
selectAudioPortFormat(OMX_U32 portIndex,OMX_AUDIO_CODINGTYPE desiredFormat)2267 status_t ACodec::selectAudioPortFormat(
2268         OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
2269     OMX_AUDIO_PARAM_PORTFORMATTYPE format;
2270     InitOMXParams(&format);
2271 
2272     format.nPortIndex = portIndex;
2273     for (OMX_U32 index = 0;; ++index) {
2274         format.nIndex = index;
2275 
2276         status_t err = mOMX->getParameter(
2277                 mNode, OMX_IndexParamAudioPortFormat,
2278                 &format, sizeof(format));
2279 
2280         if (err != OK) {
2281             return err;
2282         }
2283 
2284         if (format.eEncoding == desiredFormat) {
2285             break;
2286         }
2287     }
2288 
2289     return mOMX->setParameter(
2290             mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2291 }
2292 
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)2293 status_t ACodec::setupAACCodec(
2294         bool encoder, int32_t numChannels, int32_t sampleRate,
2295         int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
2296         int32_t maxOutputChannelCount, const drcParams_t& drc,
2297         int32_t pcmLimiterEnable) {
2298     if (encoder && isADTS) {
2299         return -EINVAL;
2300     }
2301 
2302     status_t err = setupRawAudioFormat(
2303             encoder ? kPortIndexInput : kPortIndexOutput,
2304             sampleRate,
2305             numChannels);
2306 
2307     if (err != OK) {
2308         return err;
2309     }
2310 
2311     if (encoder) {
2312         err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
2313 
2314         if (err != OK) {
2315             return err;
2316         }
2317 
2318         OMX_PARAM_PORTDEFINITIONTYPE def;
2319         InitOMXParams(&def);
2320         def.nPortIndex = kPortIndexOutput;
2321 
2322         err = mOMX->getParameter(
2323                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2324 
2325         if (err != OK) {
2326             return err;
2327         }
2328 
2329         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
2330         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
2331 
2332         err = mOMX->setParameter(
2333                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2334 
2335         if (err != OK) {
2336             return err;
2337         }
2338 
2339         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2340         InitOMXParams(&profile);
2341         profile.nPortIndex = kPortIndexOutput;
2342 
2343         err = mOMX->getParameter(
2344                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2345 
2346         if (err != OK) {
2347             return err;
2348         }
2349 
2350         profile.nChannels = numChannels;
2351 
2352         profile.eChannelMode =
2353             (numChannels == 1)
2354                 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
2355 
2356         profile.nSampleRate = sampleRate;
2357         profile.nBitRate = bitRate;
2358         profile.nAudioBandWidth = 0;
2359         profile.nFrameLength = 0;
2360         profile.nAACtools = OMX_AUDIO_AACToolAll;
2361         profile.nAACERtools = OMX_AUDIO_AACERNone;
2362         profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
2363         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2364         switch (sbrMode) {
2365         case 0:
2366             // disable sbr
2367             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2368             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2369             break;
2370         case 1:
2371             // enable single-rate sbr
2372             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2373             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2374             break;
2375         case 2:
2376             // enable dual-rate sbr
2377             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2378             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2379             break;
2380         case -1:
2381             // enable both modes -> the codec will decide which mode should be used
2382             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2383             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2384             break;
2385         default:
2386             // unsupported sbr mode
2387             return BAD_VALUE;
2388         }
2389 
2390 
2391         err = mOMX->setParameter(
2392                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2393 
2394         if (err != OK) {
2395             return err;
2396         }
2397 
2398         return err;
2399     }
2400 
2401     OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2402     InitOMXParams(&profile);
2403     profile.nPortIndex = kPortIndexInput;
2404 
2405     err = mOMX->getParameter(
2406             mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2407 
2408     if (err != OK) {
2409         return err;
2410     }
2411 
2412     profile.nChannels = numChannels;
2413     profile.nSampleRate = sampleRate;
2414 
2415     profile.eAACStreamFormat =
2416         isADTS
2417             ? OMX_AUDIO_AACStreamFormatMP4ADTS
2418             : OMX_AUDIO_AACStreamFormatMP4FF;
2419 
2420     OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2421     InitOMXParams(&presentation);
2422     presentation.nMaxOutputChannels = maxOutputChannelCount;
2423     presentation.nDrcCut = drc.drcCut;
2424     presentation.nDrcBoost = drc.drcBoost;
2425     presentation.nHeavyCompression = drc.heavyCompression;
2426     presentation.nTargetReferenceLevel = drc.targetRefLevel;
2427     presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
2428     presentation.nPCMLimiterEnable = pcmLimiterEnable;
2429 
2430     status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2431     if (res == OK) {
2432         // optional parameters, will not cause configuration failure
2433         mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
2434                 &presentation, sizeof(presentation));
2435     } else {
2436         ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
2437     }
2438     return res;
2439 }
2440 
setupAC3Codec(bool encoder,int32_t numChannels,int32_t sampleRate)2441 status_t ACodec::setupAC3Codec(
2442         bool encoder, int32_t numChannels, int32_t sampleRate) {
2443     status_t err = setupRawAudioFormat(
2444             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2445 
2446     if (err != OK) {
2447         return err;
2448     }
2449 
2450     if (encoder) {
2451         ALOGW("AC3 encoding is not supported.");
2452         return INVALID_OPERATION;
2453     }
2454 
2455     OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
2456     InitOMXParams(&def);
2457     def.nPortIndex = kPortIndexInput;
2458 
2459     err = mOMX->getParameter(
2460             mNode,
2461             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2462             &def,
2463             sizeof(def));
2464 
2465     if (err != OK) {
2466         return err;
2467     }
2468 
2469     def.nChannels = numChannels;
2470     def.nSampleRate = sampleRate;
2471 
2472     return mOMX->setParameter(
2473             mNode,
2474             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2475             &def,
2476             sizeof(def));
2477 }
2478 
setupEAC3Codec(bool encoder,int32_t numChannels,int32_t sampleRate)2479 status_t ACodec::setupEAC3Codec(
2480         bool encoder, int32_t numChannels, int32_t sampleRate) {
2481     status_t err = setupRawAudioFormat(
2482             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2483 
2484     if (err != OK) {
2485         return err;
2486     }
2487 
2488     if (encoder) {
2489         ALOGW("EAC3 encoding is not supported.");
2490         return INVALID_OPERATION;
2491     }
2492 
2493     OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
2494     InitOMXParams(&def);
2495     def.nPortIndex = kPortIndexInput;
2496 
2497     err = mOMX->getParameter(
2498             mNode,
2499             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
2500             &def,
2501             sizeof(def));
2502 
2503     if (err != OK) {
2504         return err;
2505     }
2506 
2507     def.nChannels = numChannels;
2508     def.nSampleRate = sampleRate;
2509 
2510     return mOMX->setParameter(
2511             mNode,
2512             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
2513             &def,
2514             sizeof(def));
2515 }
2516 
pickModeFromBitRate(bool isAMRWB,int32_t bps)2517 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
2518         bool isAMRWB, int32_t bps) {
2519     if (isAMRWB) {
2520         if (bps <= 6600) {
2521             return OMX_AUDIO_AMRBandModeWB0;
2522         } else if (bps <= 8850) {
2523             return OMX_AUDIO_AMRBandModeWB1;
2524         } else if (bps <= 12650) {
2525             return OMX_AUDIO_AMRBandModeWB2;
2526         } else if (bps <= 14250) {
2527             return OMX_AUDIO_AMRBandModeWB3;
2528         } else if (bps <= 15850) {
2529             return OMX_AUDIO_AMRBandModeWB4;
2530         } else if (bps <= 18250) {
2531             return OMX_AUDIO_AMRBandModeWB5;
2532         } else if (bps <= 19850) {
2533             return OMX_AUDIO_AMRBandModeWB6;
2534         } else if (bps <= 23050) {
2535             return OMX_AUDIO_AMRBandModeWB7;
2536         }
2537 
2538         // 23850 bps
2539         return OMX_AUDIO_AMRBandModeWB8;
2540     } else {  // AMRNB
2541         if (bps <= 4750) {
2542             return OMX_AUDIO_AMRBandModeNB0;
2543         } else if (bps <= 5150) {
2544             return OMX_AUDIO_AMRBandModeNB1;
2545         } else if (bps <= 5900) {
2546             return OMX_AUDIO_AMRBandModeNB2;
2547         } else if (bps <= 6700) {
2548             return OMX_AUDIO_AMRBandModeNB3;
2549         } else if (bps <= 7400) {
2550             return OMX_AUDIO_AMRBandModeNB4;
2551         } else if (bps <= 7950) {
2552             return OMX_AUDIO_AMRBandModeNB5;
2553         } else if (bps <= 10200) {
2554             return OMX_AUDIO_AMRBandModeNB6;
2555         }
2556 
2557         // 12200 bps
2558         return OMX_AUDIO_AMRBandModeNB7;
2559     }
2560 }
2561 
setupAMRCodec(bool encoder,bool isWAMR,int32_t bitrate)2562 status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2563     OMX_AUDIO_PARAM_AMRTYPE def;
2564     InitOMXParams(&def);
2565     def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2566 
2567     status_t err =
2568         mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2569 
2570     if (err != OK) {
2571         return err;
2572     }
2573 
2574     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2575     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
2576 
2577     err = mOMX->setParameter(
2578             mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2579 
2580     if (err != OK) {
2581         return err;
2582     }
2583 
2584     return setupRawAudioFormat(
2585             encoder ? kPortIndexInput : kPortIndexOutput,
2586             isWAMR ? 16000 : 8000 /* sampleRate */,
2587             1 /* numChannels */);
2588 }
2589 
setupG711Codec(bool encoder,int32_t sampleRate,int32_t numChannels)2590 status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2591     if (encoder) {
2592         return INVALID_OPERATION;
2593     }
2594 
2595     return setupRawAudioFormat(
2596             kPortIndexInput, sampleRate, numChannels);
2597 }
2598 
setupFlacCodec(bool encoder,int32_t numChannels,int32_t sampleRate,int32_t compressionLevel)2599 status_t ACodec::setupFlacCodec(
2600         bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
2601 
2602     if (encoder) {
2603         OMX_AUDIO_PARAM_FLACTYPE def;
2604         InitOMXParams(&def);
2605         def.nPortIndex = kPortIndexOutput;
2606 
2607         // configure compression level
2608         status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
2609         if (err != OK) {
2610             ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
2611             return err;
2612         }
2613         def.nCompressionLevel = compressionLevel;
2614         err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
2615         if (err != OK) {
2616             ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
2617             return err;
2618         }
2619     }
2620 
2621     return setupRawAudioFormat(
2622             encoder ? kPortIndexInput : kPortIndexOutput,
2623             sampleRate,
2624             numChannels);
2625 }
2626 
setupRawAudioFormat(OMX_U32 portIndex,int32_t sampleRate,int32_t numChannels)2627 status_t ACodec::setupRawAudioFormat(
2628         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2629     OMX_PARAM_PORTDEFINITIONTYPE def;
2630     InitOMXParams(&def);
2631     def.nPortIndex = portIndex;
2632 
2633     status_t err = mOMX->getParameter(
2634             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2635 
2636     if (err != OK) {
2637         return err;
2638     }
2639 
2640     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2641 
2642     err = mOMX->setParameter(
2643             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2644 
2645     if (err != OK) {
2646         return err;
2647     }
2648 
2649     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2650     InitOMXParams(&pcmParams);
2651     pcmParams.nPortIndex = portIndex;
2652 
2653     err = mOMX->getParameter(
2654             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2655 
2656     if (err != OK) {
2657         return err;
2658     }
2659 
2660     pcmParams.nChannels = numChannels;
2661     pcmParams.eNumData = OMX_NumericalDataSigned;
2662     pcmParams.bInterleaved = OMX_TRUE;
2663     pcmParams.nBitPerSample = 16;
2664     pcmParams.nSamplingRate = sampleRate;
2665     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2666 
2667     if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2668         return OMX_ErrorNone;
2669     }
2670 
2671     return mOMX->setParameter(
2672             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2673 }
2674 
configureTunneledVideoPlayback(int32_t audioHwSync,const sp<ANativeWindow> & nativeWindow)2675 status_t ACodec::configureTunneledVideoPlayback(
2676         int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
2677     native_handle_t* sidebandHandle;
2678 
2679     status_t err = mOMX->configureVideoTunnelMode(
2680             mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
2681     if (err != OK) {
2682         ALOGE("configureVideoTunnelMode failed! (err %d).", err);
2683         return err;
2684     }
2685 
2686     err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
2687     if (err != OK) {
2688         ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
2689                 sidebandHandle, err);
2690         return err;
2691     }
2692 
2693     return OK;
2694 }
2695 
setVideoPortFormatType(OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE compressionFormat,OMX_COLOR_FORMATTYPE colorFormat,bool usingNativeBuffers)2696 status_t ACodec::setVideoPortFormatType(
2697         OMX_U32 portIndex,
2698         OMX_VIDEO_CODINGTYPE compressionFormat,
2699         OMX_COLOR_FORMATTYPE colorFormat,
2700         bool usingNativeBuffers) {
2701     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2702     InitOMXParams(&format);
2703     format.nPortIndex = portIndex;
2704     format.nIndex = 0;
2705     bool found = false;
2706 
2707     OMX_U32 index = 0;
2708     for (;;) {
2709         format.nIndex = index;
2710         status_t err = mOMX->getParameter(
2711                 mNode, OMX_IndexParamVideoPortFormat,
2712                 &format, sizeof(format));
2713 
2714         if (err != OK) {
2715             return err;
2716         }
2717 
2718         // substitute back flexible color format to codec supported format
2719         OMX_U32 flexibleEquivalent;
2720         if (compressionFormat == OMX_VIDEO_CodingUnused
2721                 && isFlexibleColorFormat(
2722                         mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
2723                 && colorFormat == flexibleEquivalent) {
2724             ALOGI("[%s] using color format %#x in place of %#x",
2725                     mComponentName.c_str(), format.eColorFormat, colorFormat);
2726             colorFormat = format.eColorFormat;
2727         }
2728 
2729         // The following assertion is violated by TI's video decoder.
2730         // CHECK_EQ(format.nIndex, index);
2731 
2732         if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2733             if (portIndex == kPortIndexInput
2734                     && colorFormat == format.eColorFormat) {
2735                 // eCompressionFormat does not seem right.
2736                 found = true;
2737                 break;
2738             }
2739             if (portIndex == kPortIndexOutput
2740                     && compressionFormat == format.eCompressionFormat) {
2741                 // eColorFormat does not seem right.
2742                 found = true;
2743                 break;
2744             }
2745         }
2746 
2747         if (format.eCompressionFormat == compressionFormat
2748             && format.eColorFormat == colorFormat) {
2749             found = true;
2750             break;
2751         }
2752 
2753         ++index;
2754     }
2755 
2756     if (!found) {
2757         return UNKNOWN_ERROR;
2758     }
2759 
2760     status_t err = mOMX->setParameter(
2761             mNode, OMX_IndexParamVideoPortFormat,
2762             &format, sizeof(format));
2763 
2764     return err;
2765 }
2766 
2767 // Set optimal output format. OMX component lists output formats in the order
2768 // of preference, but this got more complicated since the introduction of flexible
2769 // YUV formats. We support a legacy behavior for applications that do not use
2770 // surface output, do not specify an output format, but expect a "usable" standard
2771 // OMX format. SW readable and standard formats must be flex-YUV.
2772 //
2773 // Suggested preference order:
2774 // - optimal format for texture rendering (mediaplayer behavior)
2775 // - optimal SW readable & texture renderable format (flex-YUV support)
2776 // - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
2777 // - legacy "usable" standard formats
2778 //
2779 // For legacy support, we prefer a standard format, but will settle for a SW readable
2780 // flex-YUV format.
setSupportedOutputFormat(bool getLegacyFlexibleFormat)2781 status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
2782     OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2783     InitOMXParams(&format);
2784     format.nPortIndex = kPortIndexOutput;
2785 
2786     InitOMXParams(&legacyFormat);
2787     // this field will change when we find a suitable legacy format
2788     legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2789 
2790     for (OMX_U32 index = 0; ; ++index) {
2791         format.nIndex = index;
2792         status_t err = mOMX->getParameter(
2793                 mNode, OMX_IndexParamVideoPortFormat,
2794                 &format, sizeof(format));
2795         if (err != OK) {
2796             // no more formats, pick legacy format if found
2797             if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
2798                  memcpy(&format, &legacyFormat, sizeof(format));
2799                  break;
2800             }
2801             return err;
2802         }
2803         if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
2804             return OMX_ErrorBadParameter;
2805         }
2806         if (!getLegacyFlexibleFormat) {
2807             break;
2808         }
2809         // standard formats that were exposed to users before
2810         if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
2811                 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
2812                 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
2813                 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
2814                 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
2815             break;
2816         }
2817         // find best legacy non-standard format
2818         OMX_U32 flexibleEquivalent;
2819         if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
2820                 && isFlexibleColorFormat(
2821                         mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
2822                         &flexibleEquivalent)
2823                 && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
2824             memcpy(&legacyFormat, &format, sizeof(format));
2825         }
2826     }
2827     return mOMX->setParameter(
2828             mNode, OMX_IndexParamVideoPortFormat,
2829             &format, sizeof(format));
2830 }
2831 
2832 static const struct VideoCodingMapEntry {
2833     const char *mMime;
2834     OMX_VIDEO_CODINGTYPE mVideoCodingType;
2835 } kVideoCodingMapEntry[] = {
2836     { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
2837     { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2838     { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2839     { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2840     { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
2841     { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
2842     { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2843 };
2844 
GetVideoCodingTypeFromMime(const char * mime,OMX_VIDEO_CODINGTYPE * codingType)2845 static status_t GetVideoCodingTypeFromMime(
2846         const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2847     for (size_t i = 0;
2848          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2849          ++i) {
2850         if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2851             *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2852             return OK;
2853         }
2854     }
2855 
2856     *codingType = OMX_VIDEO_CodingUnused;
2857 
2858     return ERROR_UNSUPPORTED;
2859 }
2860 
GetMimeTypeForVideoCoding(OMX_VIDEO_CODINGTYPE codingType,AString * mime)2861 static status_t GetMimeTypeForVideoCoding(
2862         OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2863     for (size_t i = 0;
2864          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2865          ++i) {
2866         if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2867             *mime = kVideoCodingMapEntry[i].mMime;
2868             return OK;
2869         }
2870     }
2871 
2872     mime->clear();
2873 
2874     return ERROR_UNSUPPORTED;
2875 }
2876 
setupVideoDecoder(const char * mime,const sp<AMessage> & msg,bool haveNativeWindow)2877 status_t ACodec::setupVideoDecoder(
2878         const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
2879     int32_t width, height;
2880     if (!msg->findInt32("width", &width)
2881             || !msg->findInt32("height", &height)) {
2882         return INVALID_OPERATION;
2883     }
2884 
2885     OMX_VIDEO_CODINGTYPE compressionFormat;
2886     status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
2887 
2888     if (err != OK) {
2889         return err;
2890     }
2891 
2892     err = setVideoPortFormatType(
2893             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2894 
2895     if (err != OK) {
2896         return err;
2897     }
2898 
2899     int32_t tmp;
2900     if (msg->findInt32("color-format", &tmp)) {
2901         OMX_COLOR_FORMATTYPE colorFormat =
2902             static_cast<OMX_COLOR_FORMATTYPE>(tmp);
2903         err = setVideoPortFormatType(
2904                 kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
2905         if (err != OK) {
2906             ALOGW("[%s] does not support color format %d",
2907                   mComponentName.c_str(), colorFormat);
2908             err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
2909         }
2910     } else {
2911         err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
2912     }
2913 
2914     if (err != OK) {
2915         return err;
2916     }
2917 
2918     int32_t frameRateInt;
2919     float frameRateFloat;
2920     if (!msg->findFloat("frame-rate", &frameRateFloat)) {
2921         if (!msg->findInt32("frame-rate", &frameRateInt)) {
2922             frameRateInt = -1;
2923         }
2924         frameRateFloat = (float)frameRateInt;
2925     }
2926 
2927     err = setVideoFormatOnPort(
2928             kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2929 
2930     if (err != OK) {
2931         return err;
2932     }
2933 
2934     err = setVideoFormatOnPort(
2935             kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2936 
2937     if (err != OK) {
2938         return err;
2939     }
2940 
2941     return OK;
2942 }
2943 
setupVideoEncoder(const char * mime,const sp<AMessage> & msg)2944 status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
2945     int32_t tmp;
2946     if (!msg->findInt32("color-format", &tmp)) {
2947         return INVALID_OPERATION;
2948     }
2949 
2950     OMX_COLOR_FORMATTYPE colorFormat =
2951         static_cast<OMX_COLOR_FORMATTYPE>(tmp);
2952 
2953     status_t err = setVideoPortFormatType(
2954             kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
2955 
2956     if (err != OK) {
2957         ALOGE("[%s] does not support color format %d",
2958               mComponentName.c_str(), colorFormat);
2959 
2960         return err;
2961     }
2962 
2963     /* Input port configuration */
2964 
2965     OMX_PARAM_PORTDEFINITIONTYPE def;
2966     InitOMXParams(&def);
2967 
2968     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2969 
2970     def.nPortIndex = kPortIndexInput;
2971 
2972     err = mOMX->getParameter(
2973             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2974 
2975     if (err != OK) {
2976         return err;
2977     }
2978 
2979     int32_t width, height, bitrate;
2980     if (!msg->findInt32("width", &width)
2981             || !msg->findInt32("height", &height)
2982             || !msg->findInt32("bitrate", &bitrate)) {
2983         return INVALID_OPERATION;
2984     }
2985 
2986     video_def->nFrameWidth = width;
2987     video_def->nFrameHeight = height;
2988 
2989     int32_t stride;
2990     if (!msg->findInt32("stride", &stride)) {
2991         stride = width;
2992     }
2993 
2994     video_def->nStride = stride;
2995 
2996     int32_t sliceHeight;
2997     if (!msg->findInt32("slice-height", &sliceHeight)) {
2998         sliceHeight = height;
2999     }
3000 
3001     video_def->nSliceHeight = sliceHeight;
3002 
3003     def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
3004 
3005     float frameRate;
3006     if (!msg->findFloat("frame-rate", &frameRate)) {
3007         int32_t tmp;
3008         if (!msg->findInt32("frame-rate", &tmp)) {
3009             return INVALID_OPERATION;
3010         }
3011         frameRate = (float)tmp;
3012         mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
3013     }
3014 
3015     video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
3016     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3017     // this is redundant as it was already set up in setVideoPortFormatType
3018     // FIXME for now skip this only for flexible YUV formats
3019     if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3020         video_def->eColorFormat = colorFormat;
3021     }
3022 
3023     err = mOMX->setParameter(
3024             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3025 
3026     if (err != OK) {
3027         ALOGE("[%s] failed to set input port definition parameters.",
3028               mComponentName.c_str());
3029 
3030         return err;
3031     }
3032 
3033     /* Output port configuration */
3034 
3035     OMX_VIDEO_CODINGTYPE compressionFormat;
3036     err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
3037 
3038     if (err != OK) {
3039         return err;
3040     }
3041 
3042     err = setVideoPortFormatType(
3043             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
3044 
3045     if (err != OK) {
3046         ALOGE("[%s] does not support compression format %d",
3047              mComponentName.c_str(), compressionFormat);
3048 
3049         return err;
3050     }
3051 
3052     def.nPortIndex = kPortIndexOutput;
3053 
3054     err = mOMX->getParameter(
3055             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3056 
3057     if (err != OK) {
3058         return err;
3059     }
3060 
3061     video_def->nFrameWidth = width;
3062     video_def->nFrameHeight = height;
3063     video_def->xFramerate = 0;
3064     video_def->nBitrate = bitrate;
3065     video_def->eCompressionFormat = compressionFormat;
3066     video_def->eColorFormat = OMX_COLOR_FormatUnused;
3067 
3068     err = mOMX->setParameter(
3069             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3070 
3071     if (err != OK) {
3072         ALOGE("[%s] failed to set output port definition parameters.",
3073               mComponentName.c_str());
3074 
3075         return err;
3076     }
3077 
3078     switch (compressionFormat) {
3079         case OMX_VIDEO_CodingMPEG4:
3080             err = setupMPEG4EncoderParameters(msg);
3081             break;
3082 
3083         case OMX_VIDEO_CodingH263:
3084             err = setupH263EncoderParameters(msg);
3085             break;
3086 
3087         case OMX_VIDEO_CodingAVC:
3088             err = setupAVCEncoderParameters(msg);
3089             break;
3090 
3091         case OMX_VIDEO_CodingHEVC:
3092             err = setupHEVCEncoderParameters(msg);
3093             break;
3094 
3095         case OMX_VIDEO_CodingVP8:
3096         case OMX_VIDEO_CodingVP9:
3097             err = setupVPXEncoderParameters(msg);
3098             break;
3099 
3100         default:
3101             break;
3102     }
3103 
3104     if (err == OK) {
3105         ALOGI("setupVideoEncoder succeeded");
3106     }
3107 
3108     return err;
3109 }
3110 
setCyclicIntraMacroblockRefresh(const sp<AMessage> & msg,int32_t mode)3111 status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
3112     OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
3113     InitOMXParams(&params);
3114     params.nPortIndex = kPortIndexOutput;
3115 
3116     params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
3117 
3118     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
3119             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
3120         int32_t mbs;
3121         if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
3122             return INVALID_OPERATION;
3123         }
3124         params.nCirMBs = mbs;
3125     }
3126 
3127     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
3128             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
3129         int32_t mbs;
3130         if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
3131             return INVALID_OPERATION;
3132         }
3133         params.nAirMBs = mbs;
3134 
3135         int32_t ref;
3136         if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
3137             return INVALID_OPERATION;
3138         }
3139         params.nAirRef = ref;
3140     }
3141 
3142     status_t err = mOMX->setParameter(
3143             mNode, OMX_IndexParamVideoIntraRefresh,
3144             &params, sizeof(params));
3145     return err;
3146 }
3147 
setPFramesSpacing(int32_t iFramesInterval,int32_t frameRate)3148 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
3149     if (iFramesInterval < 0) {
3150         return 0xFFFFFFFF;
3151     } else if (iFramesInterval == 0) {
3152         return 0;
3153     }
3154     OMX_U32 ret = frameRate * iFramesInterval;
3155     return ret;
3156 }
3157 
getBitrateMode(const sp<AMessage> & msg)3158 static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
3159     int32_t tmp;
3160     if (!msg->findInt32("bitrate-mode", &tmp)) {
3161         return OMX_Video_ControlRateVariable;
3162     }
3163 
3164     return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
3165 }
3166 
setupMPEG4EncoderParameters(const sp<AMessage> & msg)3167 status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
3168     int32_t bitrate, iFrameInterval;
3169     if (!msg->findInt32("bitrate", &bitrate)
3170             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3171         return INVALID_OPERATION;
3172     }
3173 
3174     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3175 
3176     float frameRate;
3177     if (!msg->findFloat("frame-rate", &frameRate)) {
3178         int32_t tmp;
3179         if (!msg->findInt32("frame-rate", &tmp)) {
3180             return INVALID_OPERATION;
3181         }
3182         frameRate = (float)tmp;
3183     }
3184 
3185     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
3186     InitOMXParams(&mpeg4type);
3187     mpeg4type.nPortIndex = kPortIndexOutput;
3188 
3189     status_t err = mOMX->getParameter(
3190             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
3191 
3192     if (err != OK) {
3193         return err;
3194     }
3195 
3196     mpeg4type.nSliceHeaderSpacing = 0;
3197     mpeg4type.bSVH = OMX_FALSE;
3198     mpeg4type.bGov = OMX_FALSE;
3199 
3200     mpeg4type.nAllowedPictureTypes =
3201         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3202 
3203     mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3204     if (mpeg4type.nPFrames == 0) {
3205         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3206     }
3207     mpeg4type.nBFrames = 0;
3208     mpeg4type.nIDCVLCThreshold = 0;
3209     mpeg4type.bACPred = OMX_TRUE;
3210     mpeg4type.nMaxPacketSize = 256;
3211     mpeg4type.nTimeIncRes = 1000;
3212     mpeg4type.nHeaderExtension = 0;
3213     mpeg4type.bReversibleVLC = OMX_FALSE;
3214 
3215     int32_t profile;
3216     if (msg->findInt32("profile", &profile)) {
3217         int32_t level;
3218         if (!msg->findInt32("level", &level)) {
3219             return INVALID_OPERATION;
3220         }
3221 
3222         err = verifySupportForProfileAndLevel(profile, level);
3223 
3224         if (err != OK) {
3225             return err;
3226         }
3227 
3228         mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
3229         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
3230     }
3231 
3232     err = mOMX->setParameter(
3233             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
3234 
3235     if (err != OK) {
3236         return err;
3237     }
3238 
3239     err = configureBitrate(bitrate, bitrateMode);
3240 
3241     if (err != OK) {
3242         return err;
3243     }
3244 
3245     return setupErrorCorrectionParameters();
3246 }
3247 
setupH263EncoderParameters(const sp<AMessage> & msg)3248 status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
3249     int32_t bitrate, iFrameInterval;
3250     if (!msg->findInt32("bitrate", &bitrate)
3251             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3252         return INVALID_OPERATION;
3253     }
3254 
3255     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3256 
3257     float frameRate;
3258     if (!msg->findFloat("frame-rate", &frameRate)) {
3259         int32_t tmp;
3260         if (!msg->findInt32("frame-rate", &tmp)) {
3261             return INVALID_OPERATION;
3262         }
3263         frameRate = (float)tmp;
3264     }
3265 
3266     OMX_VIDEO_PARAM_H263TYPE h263type;
3267     InitOMXParams(&h263type);
3268     h263type.nPortIndex = kPortIndexOutput;
3269 
3270     status_t err = mOMX->getParameter(
3271             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
3272 
3273     if (err != OK) {
3274         return err;
3275     }
3276 
3277     h263type.nAllowedPictureTypes =
3278         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3279 
3280     h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3281     if (h263type.nPFrames == 0) {
3282         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3283     }
3284     h263type.nBFrames = 0;
3285 
3286     int32_t profile;
3287     if (msg->findInt32("profile", &profile)) {
3288         int32_t level;
3289         if (!msg->findInt32("level", &level)) {
3290             return INVALID_OPERATION;
3291         }
3292 
3293         err = verifySupportForProfileAndLevel(profile, level);
3294 
3295         if (err != OK) {
3296             return err;
3297         }
3298 
3299         h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
3300         h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
3301     }
3302 
3303     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
3304     h263type.bForceRoundingTypeToZero = OMX_FALSE;
3305     h263type.nPictureHeaderRepetition = 0;
3306     h263type.nGOBHeaderInterval = 0;
3307 
3308     err = mOMX->setParameter(
3309             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
3310 
3311     if (err != OK) {
3312         return err;
3313     }
3314 
3315     err = configureBitrate(bitrate, bitrateMode);
3316 
3317     if (err != OK) {
3318         return err;
3319     }
3320 
3321     return setupErrorCorrectionParameters();
3322 }
3323 
3324 // static
getAVCLevelFor(int width,int height,int rate,int bitrate,OMX_VIDEO_AVCPROFILETYPE profile)3325 int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3326         int width, int height, int rate, int bitrate,
3327         OMX_VIDEO_AVCPROFILETYPE profile) {
3328     // convert bitrate to main/baseline profile kbps equivalent
3329     switch (profile) {
3330         case OMX_VIDEO_AVCProfileHigh10:
3331             bitrate = divUp(bitrate, 3000); break;
3332         case OMX_VIDEO_AVCProfileHigh:
3333             bitrate = divUp(bitrate, 1250); break;
3334         default:
3335             bitrate = divUp(bitrate, 1000); break;
3336     }
3337 
3338     // convert size and rate to MBs
3339     width = divUp(width, 16);
3340     height = divUp(height, 16);
3341     int mbs = width * height;
3342     rate *= mbs;
3343     int maxDimension = max(width, height);
3344 
3345     static const int limits[][5] = {
3346         /*   MBps     MB   dim  bitrate        level */
3347         {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3348         {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3349         {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3350         {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3351         {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3352         {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3353         {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3354         {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3355         {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3356         {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3357         {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3358         {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3359         {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3360         {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3361         {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3362         {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3363         { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3364     };
3365 
3366     for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3367         const int (&limit)[5] = limits[i];
3368         if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3369                 && bitrate <= limit[3]) {
3370             return limit[4];
3371         }
3372     }
3373     return 0;
3374 }
3375 
setupAVCEncoderParameters(const sp<AMessage> & msg)3376 status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
3377     int32_t bitrate, iFrameInterval;
3378     if (!msg->findInt32("bitrate", &bitrate)
3379             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3380         return INVALID_OPERATION;
3381     }
3382 
3383     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3384 
3385     float frameRate;
3386     if (!msg->findFloat("frame-rate", &frameRate)) {
3387         int32_t tmp;
3388         if (!msg->findInt32("frame-rate", &tmp)) {
3389             return INVALID_OPERATION;
3390         }
3391         frameRate = (float)tmp;
3392     }
3393 
3394     status_t err = OK;
3395     int32_t intraRefreshMode = 0;
3396     if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
3397         err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
3398         if (err != OK) {
3399             ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
3400                     err, intraRefreshMode);
3401             return err;
3402         }
3403     }
3404 
3405     OMX_VIDEO_PARAM_AVCTYPE h264type;
3406     InitOMXParams(&h264type);
3407     h264type.nPortIndex = kPortIndexOutput;
3408 
3409     err = mOMX->getParameter(
3410             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
3411 
3412     if (err != OK) {
3413         return err;
3414     }
3415 
3416     h264type.nAllowedPictureTypes =
3417         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3418 
3419     int32_t profile;
3420     if (msg->findInt32("profile", &profile)) {
3421         int32_t level;
3422         if (!msg->findInt32("level", &level)) {
3423             return INVALID_OPERATION;
3424         }
3425 
3426         err = verifySupportForProfileAndLevel(profile, level);
3427 
3428         if (err != OK) {
3429             return err;
3430         }
3431 
3432         h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
3433         h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
3434     }
3435 
3436     // XXX
3437     if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
3438         ALOGW("Use baseline profile instead of %d for AVC recording",
3439             h264type.eProfile);
3440         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
3441     }
3442 
3443     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
3444         h264type.nSliceHeaderSpacing = 0;
3445         h264type.bUseHadamard = OMX_TRUE;
3446         h264type.nRefFrames = 1;
3447         h264type.nBFrames = 0;
3448         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3449         if (h264type.nPFrames == 0) {
3450             h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3451         }
3452         h264type.nRefIdx10ActiveMinus1 = 0;
3453         h264type.nRefIdx11ActiveMinus1 = 0;
3454         h264type.bEntropyCodingCABAC = OMX_FALSE;
3455         h264type.bWeightedPPrediction = OMX_FALSE;
3456         h264type.bconstIpred = OMX_FALSE;
3457         h264type.bDirect8x8Inference = OMX_FALSE;
3458         h264type.bDirectSpatialTemporal = OMX_FALSE;
3459         h264type.nCabacInitIdc = 0;
3460     }
3461 
3462     if (h264type.nBFrames != 0) {
3463         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
3464     }
3465 
3466     h264type.bEnableUEP = OMX_FALSE;
3467     h264type.bEnableFMO = OMX_FALSE;
3468     h264type.bEnableASO = OMX_FALSE;
3469     h264type.bEnableRS = OMX_FALSE;
3470     h264type.bFrameMBsOnly = OMX_TRUE;
3471     h264type.bMBAFF = OMX_FALSE;
3472     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
3473 
3474     err = mOMX->setParameter(
3475             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
3476 
3477     if (err != OK) {
3478         return err;
3479     }
3480 
3481     return configureBitrate(bitrate, bitrateMode);
3482 }
3483 
setupHEVCEncoderParameters(const sp<AMessage> & msg)3484 status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3485     int32_t bitrate, iFrameInterval;
3486     if (!msg->findInt32("bitrate", &bitrate)
3487             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3488         return INVALID_OPERATION;
3489     }
3490 
3491     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3492 
3493     float frameRate;
3494     if (!msg->findFloat("frame-rate", &frameRate)) {
3495         int32_t tmp;
3496         if (!msg->findInt32("frame-rate", &tmp)) {
3497             return INVALID_OPERATION;
3498         }
3499         frameRate = (float)tmp;
3500     }
3501 
3502     OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3503     InitOMXParams(&hevcType);
3504     hevcType.nPortIndex = kPortIndexOutput;
3505 
3506     status_t err = OK;
3507     err = mOMX->getParameter(
3508             mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3509     if (err != OK) {
3510         return err;
3511     }
3512 
3513     int32_t profile;
3514     if (msg->findInt32("profile", &profile)) {
3515         int32_t level;
3516         if (!msg->findInt32("level", &level)) {
3517             return INVALID_OPERATION;
3518         }
3519 
3520         err = verifySupportForProfileAndLevel(profile, level);
3521         if (err != OK) {
3522             return err;
3523         }
3524 
3525         hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3526         hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3527     }
3528 
3529     // TODO: Need OMX structure definition for setting iFrameInterval
3530 
3531     err = mOMX->setParameter(
3532             mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3533     if (err != OK) {
3534         return err;
3535     }
3536 
3537     return configureBitrate(bitrate, bitrateMode);
3538 }
3539 
setupVPXEncoderParameters(const sp<AMessage> & msg)3540 status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
3541     int32_t bitrate;
3542     int32_t iFrameInterval = 0;
3543     size_t tsLayers = 0;
3544     OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
3545         OMX_VIDEO_VPXTemporalLayerPatternNone;
3546     static const uint32_t kVp8LayerRateAlloction
3547         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
3548         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
3549         {100, 100, 100},  // 1 layer
3550         { 60, 100, 100},  // 2 layers {60%, 40%}
3551         { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
3552     };
3553     if (!msg->findInt32("bitrate", &bitrate)) {
3554         return INVALID_OPERATION;
3555     }
3556     msg->findInt32("i-frame-interval", &iFrameInterval);
3557 
3558     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3559 
3560     float frameRate;
3561     if (!msg->findFloat("frame-rate", &frameRate)) {
3562         int32_t tmp;
3563         if (!msg->findInt32("frame-rate", &tmp)) {
3564             return INVALID_OPERATION;
3565         }
3566         frameRate = (float)tmp;
3567     }
3568 
3569     AString tsSchema;
3570     if (msg->findString("ts-schema", &tsSchema)) {
3571         if (tsSchema == "webrtc.vp8.1-layer") {
3572             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3573             tsLayers = 1;
3574         } else if (tsSchema == "webrtc.vp8.2-layer") {
3575             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3576             tsLayers = 2;
3577         } else if (tsSchema == "webrtc.vp8.3-layer") {
3578             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3579             tsLayers = 3;
3580         } else {
3581             ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
3582         }
3583     }
3584 
3585     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
3586     InitOMXParams(&vp8type);
3587     vp8type.nPortIndex = kPortIndexOutput;
3588     status_t err = mOMX->getParameter(
3589             mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3590             &vp8type, sizeof(vp8type));
3591 
3592     if (err == OK) {
3593         if (iFrameInterval > 0) {
3594             vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
3595         }
3596         vp8type.eTemporalPattern = pattern;
3597         vp8type.nTemporalLayerCount = tsLayers;
3598         if (tsLayers > 0) {
3599             for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
3600                 vp8type.nTemporalLayerBitrateRatio[i] =
3601                     kVp8LayerRateAlloction[tsLayers - 1][i];
3602             }
3603         }
3604         if (bitrateMode == OMX_Video_ControlRateConstant) {
3605             vp8type.nMinQuantizer = 2;
3606             vp8type.nMaxQuantizer = 63;
3607         }
3608 
3609         err = mOMX->setParameter(
3610                 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3611                 &vp8type, sizeof(vp8type));
3612         if (err != OK) {
3613             ALOGW("Extended VP8 parameters set failed: %d", err);
3614         }
3615     }
3616 
3617     return configureBitrate(bitrate, bitrateMode);
3618 }
3619 
verifySupportForProfileAndLevel(int32_t profile,int32_t level)3620 status_t ACodec::verifySupportForProfileAndLevel(
3621         int32_t profile, int32_t level) {
3622     OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3623     InitOMXParams(&params);
3624     params.nPortIndex = kPortIndexOutput;
3625 
3626     for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
3627         status_t err = mOMX->getParameter(
3628                 mNode,
3629                 OMX_IndexParamVideoProfileLevelQuerySupported,
3630                 &params,
3631                 sizeof(params));
3632 
3633         if (err != OK) {
3634             return err;
3635         }
3636 
3637         int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
3638         int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
3639 
3640         if (profile == supportedProfile && level <= supportedLevel) {
3641             return OK;
3642         }
3643     }
3644 }
3645 
configureBitrate(int32_t bitrate,OMX_VIDEO_CONTROLRATETYPE bitrateMode)3646 status_t ACodec::configureBitrate(
3647         int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
3648     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
3649     InitOMXParams(&bitrateType);
3650     bitrateType.nPortIndex = kPortIndexOutput;
3651 
3652     status_t err = mOMX->getParameter(
3653             mNode, OMX_IndexParamVideoBitrate,
3654             &bitrateType, sizeof(bitrateType));
3655 
3656     if (err != OK) {
3657         return err;
3658     }
3659 
3660     bitrateType.eControlRate = bitrateMode;
3661     bitrateType.nTargetBitrate = bitrate;
3662 
3663     return mOMX->setParameter(
3664             mNode, OMX_IndexParamVideoBitrate,
3665             &bitrateType, sizeof(bitrateType));
3666 }
3667 
setupErrorCorrectionParameters()3668 status_t ACodec::setupErrorCorrectionParameters() {
3669     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
3670     InitOMXParams(&errorCorrectionType);
3671     errorCorrectionType.nPortIndex = kPortIndexOutput;
3672 
3673     status_t err = mOMX->getParameter(
3674             mNode, OMX_IndexParamVideoErrorCorrection,
3675             &errorCorrectionType, sizeof(errorCorrectionType));
3676 
3677     if (err != OK) {
3678         return OK;  // Optional feature. Ignore this failure
3679     }
3680 
3681     errorCorrectionType.bEnableHEC = OMX_FALSE;
3682     errorCorrectionType.bEnableResync = OMX_TRUE;
3683     errorCorrectionType.nResynchMarkerSpacing = 256;
3684     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
3685     errorCorrectionType.bEnableRVLC = OMX_FALSE;
3686 
3687     return mOMX->setParameter(
3688             mNode, OMX_IndexParamVideoErrorCorrection,
3689             &errorCorrectionType, sizeof(errorCorrectionType));
3690 }
3691 
setVideoFormatOnPort(OMX_U32 portIndex,int32_t width,int32_t height,OMX_VIDEO_CODINGTYPE compressionFormat,float frameRate)3692 status_t ACodec::setVideoFormatOnPort(
3693         OMX_U32 portIndex,
3694         int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
3695         float frameRate) {
3696     OMX_PARAM_PORTDEFINITIONTYPE def;
3697     InitOMXParams(&def);
3698     def.nPortIndex = portIndex;
3699 
3700     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3701 
3702     status_t err = mOMX->getParameter(
3703             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3704     if (err != OK) {
3705         return err;
3706     }
3707 
3708     if (portIndex == kPortIndexInput) {
3709         // XXX Need a (much) better heuristic to compute input buffer sizes.
3710         const size_t X = 64 * 1024;
3711         if (def.nBufferSize < X) {
3712             def.nBufferSize = X;
3713         }
3714     }
3715 
3716     if (def.eDomain != OMX_PortDomainVideo) {
3717         ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3718         return FAILED_TRANSACTION;
3719     }
3720 
3721     video_def->nFrameWidth = width;
3722     video_def->nFrameHeight = height;
3723 
3724     if (portIndex == kPortIndexInput) {
3725         video_def->eCompressionFormat = compressionFormat;
3726         video_def->eColorFormat = OMX_COLOR_FormatUnused;
3727         if (frameRate >= 0) {
3728             video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
3729         }
3730     }
3731 
3732     err = mOMX->setParameter(
3733             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3734 
3735     return err;
3736 }
3737 
initNativeWindow()3738 status_t ACodec::initNativeWindow() {
3739     if (mNativeWindow != NULL) {
3740         return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3741     }
3742 
3743     mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3744     return OK;
3745 }
3746 
countBuffersOwnedByComponent(OMX_U32 portIndex) const3747 size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3748     size_t n = 0;
3749 
3750     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3751         const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3752 
3753         if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3754             ++n;
3755         }
3756     }
3757 
3758     return n;
3759 }
3760 
countBuffersOwnedByNativeWindow() const3761 size_t ACodec::countBuffersOwnedByNativeWindow() const {
3762     size_t n = 0;
3763 
3764     for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
3765         const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
3766 
3767         if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3768             ++n;
3769         }
3770     }
3771 
3772     return n;
3773 }
3774 
waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs()3775 void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
3776     if (mNativeWindow == NULL) {
3777         return;
3778     }
3779 
3780     while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
3781             && dequeueBufferFromNativeWindow() != NULL) {
3782         // these buffers will be submitted as regular buffers; account for this
3783         if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
3784             --mMetadataBuffersToSubmit;
3785         }
3786     }
3787 }
3788 
allYourBuffersAreBelongToUs(OMX_U32 portIndex)3789 bool ACodec::allYourBuffersAreBelongToUs(
3790         OMX_U32 portIndex) {
3791     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3792         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3793 
3794         if (info->mStatus != BufferInfo::OWNED_BY_US
3795                 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3796             ALOGV("[%s] Buffer %u on port %u still has status %d",
3797                     mComponentName.c_str(),
3798                     info->mBufferID, portIndex, info->mStatus);
3799             return false;
3800         }
3801     }
3802 
3803     return true;
3804 }
3805 
allYourBuffersAreBelongToUs()3806 bool ACodec::allYourBuffersAreBelongToUs() {
3807     return allYourBuffersAreBelongToUs(kPortIndexInput)
3808         && allYourBuffersAreBelongToUs(kPortIndexOutput);
3809 }
3810 
deferMessage(const sp<AMessage> & msg)3811 void ACodec::deferMessage(const sp<AMessage> &msg) {
3812     mDeferredQueue.push_back(msg);
3813 }
3814 
processDeferredMessages()3815 void ACodec::processDeferredMessages() {
3816     List<sp<AMessage> > queue = mDeferredQueue;
3817     mDeferredQueue.clear();
3818 
3819     List<sp<AMessage> >::iterator it = queue.begin();
3820     while (it != queue.end()) {
3821         onMessageReceived(*it++);
3822     }
3823 }
3824 
3825 // static
describeDefaultColorFormat(DescribeColorFormatParams & params)3826 bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
3827     MediaImage &image = params.sMediaImage;
3828     memset(&image, 0, sizeof(image));
3829 
3830     image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3831     image.mNumPlanes = 0;
3832 
3833     const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
3834     image.mWidth = params.nFrameWidth;
3835     image.mHeight = params.nFrameHeight;
3836 
3837     // only supporting YUV420
3838     if (fmt != OMX_COLOR_FormatYUV420Planar &&
3839         fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
3840         fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
3841         fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
3842         fmt != HAL_PIXEL_FORMAT_YV12) {
3843         ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3844         return false;
3845     }
3846 
3847     // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3848     if (params.nStride != 0 && params.nSliceHeight == 0) {
3849         ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3850                 params.nFrameHeight);
3851         params.nSliceHeight = params.nFrameHeight;
3852     }
3853 
3854     // we need stride and slice-height to be non-zero
3855     if (params.nStride == 0 || params.nSliceHeight == 0) {
3856         ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3857                 fmt, fmt, params.nStride, params.nSliceHeight);
3858         return false;
3859     }
3860 
3861     // set-up YUV format
3862     image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
3863     image.mNumPlanes = 3;
3864     image.mBitDepth = 8;
3865     image.mPlane[image.Y].mOffset = 0;
3866     image.mPlane[image.Y].mColInc = 1;
3867     image.mPlane[image.Y].mRowInc = params.nStride;
3868     image.mPlane[image.Y].mHorizSubsampling = 1;
3869     image.mPlane[image.Y].mVertSubsampling = 1;
3870 
3871     switch ((int)fmt) {
3872         case HAL_PIXEL_FORMAT_YV12:
3873             if (params.bUsingNativeBuffers) {
3874                 size_t ystride = align(params.nStride, 16);
3875                 size_t cstride = align(params.nStride / 2, 16);
3876                 image.mPlane[image.Y].mRowInc = ystride;
3877 
3878                 image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
3879                 image.mPlane[image.V].mColInc = 1;
3880                 image.mPlane[image.V].mRowInc = cstride;
3881                 image.mPlane[image.V].mHorizSubsampling = 2;
3882                 image.mPlane[image.V].mVertSubsampling = 2;
3883 
3884                 image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
3885                         + (cstride * params.nSliceHeight / 2);
3886                 image.mPlane[image.U].mColInc = 1;
3887                 image.mPlane[image.U].mRowInc = cstride;
3888                 image.mPlane[image.U].mHorizSubsampling = 2;
3889                 image.mPlane[image.U].mVertSubsampling = 2;
3890                 break;
3891             } else {
3892                 // fall through as YV12 is used for YUV420Planar by some codecs
3893             }
3894 
3895         case OMX_COLOR_FormatYUV420Planar:
3896         case OMX_COLOR_FormatYUV420PackedPlanar:
3897             image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
3898             image.mPlane[image.U].mColInc = 1;
3899             image.mPlane[image.U].mRowInc = params.nStride / 2;
3900             image.mPlane[image.U].mHorizSubsampling = 2;
3901             image.mPlane[image.U].mVertSubsampling = 2;
3902 
3903             image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
3904                     + (params.nStride * params.nSliceHeight / 4);
3905             image.mPlane[image.V].mColInc = 1;
3906             image.mPlane[image.V].mRowInc = params.nStride / 2;
3907             image.mPlane[image.V].mHorizSubsampling = 2;
3908             image.mPlane[image.V].mVertSubsampling = 2;
3909             break;
3910 
3911         case OMX_COLOR_FormatYUV420SemiPlanar:
3912             // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
3913         case OMX_COLOR_FormatYUV420PackedSemiPlanar:
3914             // NV12
3915             image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
3916             image.mPlane[image.U].mColInc = 2;
3917             image.mPlane[image.U].mRowInc = params.nStride;
3918             image.mPlane[image.U].mHorizSubsampling = 2;
3919             image.mPlane[image.U].mVertSubsampling = 2;
3920 
3921             image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
3922             image.mPlane[image.V].mColInc = 2;
3923             image.mPlane[image.V].mRowInc = params.nStride;
3924             image.mPlane[image.V].mHorizSubsampling = 2;
3925             image.mPlane[image.V].mVertSubsampling = 2;
3926             break;
3927 
3928         default:
3929             TRESPASS();
3930     }
3931     return true;
3932 }
3933 
3934 // static
describeColorFormat(const sp<IOMX> & omx,IOMX::node_id node,DescribeColorFormatParams & describeParams)3935 bool ACodec::describeColorFormat(
3936         const sp<IOMX> &omx, IOMX::node_id node,
3937         DescribeColorFormatParams &describeParams)
3938 {
3939     OMX_INDEXTYPE describeColorFormatIndex;
3940     if (omx->getExtensionIndex(
3941             node, "OMX.google.android.index.describeColorFormat",
3942             &describeColorFormatIndex) != OK ||
3943         omx->getParameter(
3944             node, describeColorFormatIndex,
3945             &describeParams, sizeof(describeParams)) != OK) {
3946         return describeDefaultColorFormat(describeParams);
3947     }
3948     return describeParams.sMediaImage.mType !=
3949             MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3950 }
3951 
3952 // static
isFlexibleColorFormat(const sp<IOMX> & omx,IOMX::node_id node,uint32_t colorFormat,bool usingNativeBuffers,OMX_U32 * flexibleEquivalent)3953 bool ACodec::isFlexibleColorFormat(
3954          const sp<IOMX> &omx, IOMX::node_id node,
3955          uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3956     DescribeColorFormatParams describeParams;
3957     InitOMXParams(&describeParams);
3958     describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3959     // reasonable dummy values
3960     describeParams.nFrameWidth = 128;
3961     describeParams.nFrameHeight = 128;
3962     describeParams.nStride = 128;
3963     describeParams.nSliceHeight = 128;
3964     describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3965 
3966     CHECK(flexibleEquivalent != NULL);
3967 
3968     if (!describeColorFormat(omx, node, describeParams)) {
3969         return false;
3970     }
3971 
3972     const MediaImage &img = describeParams.sMediaImage;
3973     if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3974         if (img.mNumPlanes != 3 ||
3975             img.mPlane[img.Y].mHorizSubsampling != 1 ||
3976             img.mPlane[img.Y].mVertSubsampling != 1) {
3977             return false;
3978         }
3979 
3980         // YUV 420
3981         if (img.mPlane[img.U].mHorizSubsampling == 2
3982                 && img.mPlane[img.U].mVertSubsampling == 2
3983                 && img.mPlane[img.V].mHorizSubsampling == 2
3984                 && img.mPlane[img.V].mVertSubsampling == 2) {
3985             // possible flexible YUV420 format
3986             if (img.mBitDepth <= 8) {
3987                *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3988                return true;
3989             }
3990         }
3991     }
3992     return false;
3993 }
3994 
getPortFormat(OMX_U32 portIndex,sp<AMessage> & notify)3995 status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3996     const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
3997     OMX_PARAM_PORTDEFINITIONTYPE def;
3998     InitOMXParams(&def);
3999     def.nPortIndex = portIndex;
4000 
4001     status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4002     if (err != OK) {
4003         return err;
4004     }
4005 
4006     if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4007         ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4008         return BAD_VALUE;
4009     }
4010 
4011     switch (def.eDomain) {
4012         case OMX_PortDomainVideo:
4013         {
4014             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4015             switch ((int)videoDef->eCompressionFormat) {
4016                 case OMX_VIDEO_CodingUnused:
4017                 {
4018                     CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4019                     notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4020 
4021                     notify->setInt32("stride", videoDef->nStride);
4022                     notify->setInt32("slice-height", videoDef->nSliceHeight);
4023                     notify->setInt32("color-format", videoDef->eColorFormat);
4024 
4025                     if (mNativeWindow == NULL) {
4026                         DescribeColorFormatParams describeParams;
4027                         InitOMXParams(&describeParams);
4028                         describeParams.eColorFormat = videoDef->eColorFormat;
4029                         describeParams.nFrameWidth = videoDef->nFrameWidth;
4030                         describeParams.nFrameHeight = videoDef->nFrameHeight;
4031                         describeParams.nStride = videoDef->nStride;
4032                         describeParams.nSliceHeight = videoDef->nSliceHeight;
4033                         describeParams.bUsingNativeBuffers = OMX_FALSE;
4034 
4035                         if (describeColorFormat(mOMX, mNode, describeParams)) {
4036                             notify->setBuffer(
4037                                     "image-data",
4038                                     ABuffer::CreateAsCopy(
4039                                             &describeParams.sMediaImage,
4040                                             sizeof(describeParams.sMediaImage)));
4041 
4042                             MediaImage *img = &describeParams.sMediaImage;
4043                             ALOGV("[%s] MediaImage { F(%ux%u) @%u+%u+%u @%u+%u+%u @%u+%u+%u }",
4044                                     mComponentName.c_str(), img->mWidth, img->mHeight,
4045                                     img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
4046                                     img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
4047                                     img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
4048                         }
4049                     }
4050 
4051                     if (portIndex != kPortIndexOutput) {
4052                         // TODO: also get input crop
4053                         break;
4054                     }
4055 
4056                     OMX_CONFIG_RECTTYPE rect;
4057                     InitOMXParams(&rect);
4058                     rect.nPortIndex = portIndex;
4059 
4060                     if (mOMX->getConfig(
4061                                 mNode,
4062                                 (portIndex == kPortIndexOutput ?
4063                                         OMX_IndexConfigCommonOutputCrop :
4064                                         OMX_IndexConfigCommonInputCrop),
4065                                 &rect, sizeof(rect)) != OK) {
4066                         rect.nLeft = 0;
4067                         rect.nTop = 0;
4068                         rect.nWidth = videoDef->nFrameWidth;
4069                         rect.nHeight = videoDef->nFrameHeight;
4070                     }
4071 
4072                     if (rect.nLeft < 0 ||
4073                         rect.nTop < 0 ||
4074                         rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4075                         rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4076                         ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4077                                 rect.nLeft, rect.nTop,
4078                                 rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4079                                 videoDef->nFrameWidth, videoDef->nFrameHeight);
4080                         return BAD_VALUE;
4081                     }
4082 
4083                     notify->setRect(
4084                             "crop",
4085                             rect.nLeft,
4086                             rect.nTop,
4087                             rect.nLeft + rect.nWidth - 1,
4088                             rect.nTop + rect.nHeight - 1);
4089 
4090                     break;
4091                 }
4092 
4093                 case OMX_VIDEO_CodingVP8:
4094                 case OMX_VIDEO_CodingVP9:
4095                 {
4096                     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
4097                     InitOMXParams(&vp8type);
4098                     vp8type.nPortIndex = kPortIndexOutput;
4099                     status_t err = mOMX->getParameter(
4100                             mNode,
4101                             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
4102                             &vp8type,
4103                             sizeof(vp8type));
4104 
4105                     if (err == OK) {
4106                         AString tsSchema = "none";
4107                         if (vp8type.eTemporalPattern
4108                                 == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
4109                             switch (vp8type.nTemporalLayerCount) {
4110                                 case 1:
4111                                 {
4112                                     tsSchema = "webrtc.vp8.1-layer";
4113                                     break;
4114                                 }
4115                                 case 2:
4116                                 {
4117                                     tsSchema = "webrtc.vp8.2-layer";
4118                                     break;
4119                                 }
4120                                 case 3:
4121                                 {
4122                                     tsSchema = "webrtc.vp8.3-layer";
4123                                     break;
4124                                 }
4125                                 default:
4126                                 {
4127                                     break;
4128                                 }
4129                             }
4130                         }
4131                         notify->setString("ts-schema", tsSchema);
4132                     }
4133                     // Fall through to set up mime.
4134                 }
4135 
4136                 default:
4137                 {
4138                     if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4139                         // should be CodingUnused
4140                         ALOGE("Raw port video compression format is %s(%d)",
4141                                 asString(videoDef->eCompressionFormat),
4142                                 videoDef->eCompressionFormat);
4143                         return BAD_VALUE;
4144                     }
4145                     AString mime;
4146                     if (GetMimeTypeForVideoCoding(
4147                         videoDef->eCompressionFormat, &mime) != OK) {
4148                         notify->setString("mime", "application/octet-stream");
4149                     } else {
4150                         notify->setString("mime", mime.c_str());
4151                     }
4152                     break;
4153                 }
4154             }
4155             notify->setInt32("width", videoDef->nFrameWidth);
4156             notify->setInt32("height", videoDef->nFrameHeight);
4157             ALOGV("[%s] %s format is %s", mComponentName.c_str(),
4158                     portIndex == kPortIndexInput ? "input" : "output",
4159                     notify->debugString().c_str());
4160 
4161             break;
4162         }
4163 
4164         case OMX_PortDomainAudio:
4165         {
4166             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4167 
4168             switch ((int)audioDef->eEncoding) {
4169                 case OMX_AUDIO_CodingPCM:
4170                 {
4171                     OMX_AUDIO_PARAM_PCMMODETYPE params;
4172                     InitOMXParams(&params);
4173                     params.nPortIndex = portIndex;
4174 
4175                     err = mOMX->getParameter(
4176                             mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4177                     if (err != OK) {
4178                         return err;
4179                     }
4180 
4181                     if (params.nChannels <= 0
4182                             || (params.nChannels != 1 && !params.bInterleaved)
4183                             || params.nBitPerSample != 16u
4184                             || params.eNumData != OMX_NumericalDataSigned
4185                             || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4186                         ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
4187                                 params.nChannels,
4188                                 params.bInterleaved ? " interleaved" : "",
4189                                 params.nBitPerSample,
4190                                 asString(params.eNumData), params.eNumData,
4191                                 asString(params.ePCMMode), params.ePCMMode);
4192                         return FAILED_TRANSACTION;
4193                     }
4194 
4195                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4196                     notify->setInt32("channel-count", params.nChannels);
4197                     notify->setInt32("sample-rate", params.nSamplingRate);
4198 
4199                     if (mChannelMaskPresent) {
4200                         notify->setInt32("channel-mask", mChannelMask);
4201                     }
4202                     break;
4203                 }
4204 
4205                 case OMX_AUDIO_CodingAAC:
4206                 {
4207                     OMX_AUDIO_PARAM_AACPROFILETYPE params;
4208                     InitOMXParams(&params);
4209                     params.nPortIndex = portIndex;
4210 
4211                     err = mOMX->getParameter(
4212                             mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4213                     if (err != OK) {
4214                         return err;
4215                     }
4216 
4217                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4218                     notify->setInt32("channel-count", params.nChannels);
4219                     notify->setInt32("sample-rate", params.nSampleRate);
4220                     break;
4221                 }
4222 
4223                 case OMX_AUDIO_CodingAMR:
4224                 {
4225                     OMX_AUDIO_PARAM_AMRTYPE params;
4226                     InitOMXParams(&params);
4227                     params.nPortIndex = portIndex;
4228 
4229                     err = mOMX->getParameter(
4230                             mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4231                     if (err != OK) {
4232                         return err;
4233                     }
4234 
4235                     notify->setInt32("channel-count", 1);
4236                     if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
4237                         notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4238                         notify->setInt32("sample-rate", 16000);
4239                     } else {
4240                         notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4241                         notify->setInt32("sample-rate", 8000);
4242                     }
4243                     break;
4244                 }
4245 
4246                 case OMX_AUDIO_CodingFLAC:
4247                 {
4248                     OMX_AUDIO_PARAM_FLACTYPE params;
4249                     InitOMXParams(&params);
4250                     params.nPortIndex = portIndex;
4251 
4252                     err = mOMX->getParameter(
4253                             mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4254                     if (err != OK) {
4255                         return err;
4256                     }
4257 
4258                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4259                     notify->setInt32("channel-count", params.nChannels);
4260                     notify->setInt32("sample-rate", params.nSampleRate);
4261                     break;
4262                 }
4263 
4264                 case OMX_AUDIO_CodingMP3:
4265                 {
4266                     OMX_AUDIO_PARAM_MP3TYPE params;
4267                     InitOMXParams(&params);
4268                     params.nPortIndex = portIndex;
4269 
4270                     err = mOMX->getParameter(
4271                             mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4272                     if (err != OK) {
4273                         return err;
4274                     }
4275 
4276                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4277                     notify->setInt32("channel-count", params.nChannels);
4278                     notify->setInt32("sample-rate", params.nSampleRate);
4279                     break;
4280                 }
4281 
4282                 case OMX_AUDIO_CodingVORBIS:
4283                 {
4284                     OMX_AUDIO_PARAM_VORBISTYPE params;
4285                     InitOMXParams(&params);
4286                     params.nPortIndex = portIndex;
4287 
4288                     err = mOMX->getParameter(
4289                             mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4290                     if (err != OK) {
4291                         return err;
4292                     }
4293 
4294                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4295                     notify->setInt32("channel-count", params.nChannels);
4296                     notify->setInt32("sample-rate", params.nSampleRate);
4297                     break;
4298                 }
4299 
4300                 case OMX_AUDIO_CodingAndroidAC3:
4301                 {
4302                     OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
4303                     InitOMXParams(&params);
4304                     params.nPortIndex = portIndex;
4305 
4306                     err = mOMX->getParameter(
4307                             mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4308                             &params, sizeof(params));
4309                     if (err != OK) {
4310                         return err;
4311                     }
4312 
4313                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
4314                     notify->setInt32("channel-count", params.nChannels);
4315                     notify->setInt32("sample-rate", params.nSampleRate);
4316                     break;
4317                 }
4318 
4319                 case OMX_AUDIO_CodingAndroidEAC3:
4320                 {
4321                     OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
4322                     InitOMXParams(&params);
4323                     params.nPortIndex = portIndex;
4324 
4325                     err = mOMX->getParameter(
4326                             mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4327                             &params, sizeof(params));
4328                     if (err != OK) {
4329                         return err;
4330                     }
4331 
4332                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
4333                     notify->setInt32("channel-count", params.nChannels);
4334                     notify->setInt32("sample-rate", params.nSampleRate);
4335                     break;
4336                 }
4337 
4338                 case OMX_AUDIO_CodingAndroidOPUS:
4339                 {
4340                     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
4341                     InitOMXParams(&params);
4342                     params.nPortIndex = portIndex;
4343 
4344                     err = mOMX->getParameter(
4345                             mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4346                             &params, sizeof(params));
4347                     if (err != OK) {
4348                         return err;
4349                     }
4350 
4351                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
4352                     notify->setInt32("channel-count", params.nChannels);
4353                     notify->setInt32("sample-rate", params.nSampleRate);
4354                     break;
4355                 }
4356 
4357                 case OMX_AUDIO_CodingG711:
4358                 {
4359                     OMX_AUDIO_PARAM_PCMMODETYPE params;
4360                     InitOMXParams(&params);
4361                     params.nPortIndex = portIndex;
4362 
4363                     err = mOMX->getParameter(
4364                             mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4365                     if (err != OK) {
4366                         return err;
4367                     }
4368 
4369                     const char *mime = NULL;
4370                     if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
4371                         mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
4372                     } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
4373                         mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
4374                     } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
4375                         mime = MEDIA_MIMETYPE_AUDIO_RAW;
4376                     }
4377                     notify->setString("mime", mime);
4378                     notify->setInt32("channel-count", params.nChannels);
4379                     notify->setInt32("sample-rate", params.nSamplingRate);
4380                     break;
4381                 }
4382 
4383                 case OMX_AUDIO_CodingGSMFR:
4384                 {
4385                     OMX_AUDIO_PARAM_PCMMODETYPE params;
4386                     InitOMXParams(&params);
4387                     params.nPortIndex = portIndex;
4388 
4389                     err = mOMX->getParameter(
4390                                 mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4391                     if (err != OK) {
4392                         return err;
4393                     }
4394 
4395                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
4396                     notify->setInt32("channel-count", params.nChannels);
4397                     notify->setInt32("sample-rate", params.nSamplingRate);
4398                     break;
4399                 }
4400 
4401                 default:
4402                     ALOGE("Unsupported audio coding: %s(%d)\n",
4403                             asString(audioDef->eEncoding), audioDef->eEncoding);
4404                     return BAD_TYPE;
4405             }
4406             break;
4407         }
4408 
4409         default:
4410             ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4411             return BAD_TYPE;
4412     }
4413 
4414     return OK;
4415 }
4416 
sendFormatChange(const sp<AMessage> & reply)4417 void ACodec::sendFormatChange(const sp<AMessage> &reply) {
4418     sp<AMessage> notify = mBaseOutputFormat->dup();
4419     notify->setInt32("what", kWhatOutputFormatChanged);
4420 
4421     if (getPortFormat(kPortIndexOutput, notify) != OK) {
4422         ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4423         return;
4424     }
4425 
4426     AString mime;
4427     CHECK(notify->findString("mime", &mime));
4428 
4429     int32_t left, top, right, bottom;
4430     if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4431         mNativeWindow != NULL &&
4432         notify->findRect("crop", &left, &top, &right, &bottom)) {
4433         // notify renderer of the crop change
4434         // NOTE: native window uses extended right-bottom coordinate
4435         reply->setRect("crop", left, top, right + 1, bottom + 1);
4436     } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4437                (mEncoderDelay || mEncoderPadding)) {
4438         int32_t channelCount;
4439         CHECK(notify->findInt32("channel-count", &channelCount));
4440         size_t frameSize = channelCount * sizeof(int16_t);
4441         if (mSkipCutBuffer != NULL) {
4442             size_t prevbufsize = mSkipCutBuffer->size();
4443             if (prevbufsize != 0) {
4444                 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4445             }
4446         }
4447         mSkipCutBuffer = new SkipCutBuffer(
4448                 mEncoderDelay * frameSize,
4449                 mEncoderPadding * frameSize);
4450     }
4451 
4452     notify->post();
4453 
4454     mSentFormat = true;
4455 }
4456 
signalError(OMX_ERRORTYPE error,status_t internalError)4457 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4458     sp<AMessage> notify = mNotify->dup();
4459     notify->setInt32("what", CodecBase::kWhatError);
4460     ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4461 
4462     if (internalError == UNKNOWN_ERROR) { // find better error code
4463         const status_t omxStatus = statusFromOMXError(error);
4464         if (omxStatus != 0) {
4465             internalError = omxStatus;
4466         } else {
4467             ALOGW("Invalid OMX error %#x", error);
4468         }
4469     }
4470 
4471     mFatalError = true;
4472 
4473     notify->setInt32("err", internalError);
4474     notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4475     notify->post();
4476 }
4477 
4478 ////////////////////////////////////////////////////////////////////////////////
4479 
PortDescription()4480 ACodec::PortDescription::PortDescription() {
4481 }
4482 
requestIDRFrame()4483 status_t ACodec::requestIDRFrame() {
4484     if (!mIsEncoder) {
4485         return ERROR_UNSUPPORTED;
4486     }
4487 
4488     OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4489     InitOMXParams(&params);
4490 
4491     params.nPortIndex = kPortIndexOutput;
4492     params.IntraRefreshVOP = OMX_TRUE;
4493 
4494     return mOMX->setConfig(
4495             mNode,
4496             OMX_IndexConfigVideoIntraVOPRefresh,
4497             &params,
4498             sizeof(params));
4499 }
4500 
addBuffer(IOMX::buffer_id id,const sp<ABuffer> & buffer)4501 void ACodec::PortDescription::addBuffer(
4502         IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4503     mBufferIDs.push_back(id);
4504     mBuffers.push_back(buffer);
4505 }
4506 
countBuffers()4507 size_t ACodec::PortDescription::countBuffers() {
4508     return mBufferIDs.size();
4509 }
4510 
bufferIDAt(size_t index) const4511 IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4512     return mBufferIDs.itemAt(index);
4513 }
4514 
bufferAt(size_t index) const4515 sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4516     return mBuffers.itemAt(index);
4517 }
4518 
4519 ////////////////////////////////////////////////////////////////////////////////
4520 
BaseState(ACodec * codec,const sp<AState> & parentState)4521 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4522     : AState(parentState),
4523       mCodec(codec) {
4524 }
4525 
getPortMode(OMX_U32)4526 ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4527         OMX_U32 /* portIndex */) {
4528     return KEEP_BUFFERS;
4529 }
4530 
onMessageReceived(const sp<AMessage> & msg)4531 bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4532     switch (msg->what()) {
4533         case kWhatInputBufferFilled:
4534         {
4535             onInputBufferFilled(msg);
4536             break;
4537         }
4538 
4539         case kWhatOutputBufferDrained:
4540         {
4541             onOutputBufferDrained(msg);
4542             break;
4543         }
4544 
4545         case ACodec::kWhatOMXMessageList:
4546         {
4547             return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
4548         }
4549 
4550         case ACodec::kWhatOMXMessageItem:
4551         {
4552             // no need to check as we already did it for kWhatOMXMessageList
4553             return onOMXMessage(msg);
4554         }
4555 
4556         case ACodec::kWhatOMXMessage:
4557         {
4558             return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
4559         }
4560 
4561         case ACodec::kWhatSetSurface:
4562         {
4563             sp<AReplyToken> replyID;
4564             CHECK(msg->senderAwaitsResponse(&replyID));
4565 
4566             sp<RefBase> obj;
4567             CHECK(msg->findObject("surface", &obj));
4568 
4569             status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
4570 
4571             sp<AMessage> response = new AMessage;
4572             response->setInt32("err", err);
4573             response->postReply(replyID);
4574             break;
4575         }
4576 
4577         case ACodec::kWhatCreateInputSurface:
4578         case ACodec::kWhatSetInputSurface:
4579         case ACodec::kWhatSignalEndOfInputStream:
4580         {
4581             // This may result in an app illegal state exception.
4582             ALOGE("Message 0x%x was not handled", msg->what());
4583             mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
4584             return true;
4585         }
4586 
4587         case ACodec::kWhatOMXDied:
4588         {
4589             // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4590             ALOGE("OMX/mediaserver died, signalling error!");
4591             mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4592             break;
4593         }
4594 
4595         case ACodec::kWhatReleaseCodecInstance:
4596         {
4597             ALOGI("[%s] forcing the release of codec",
4598                     mCodec->mComponentName.c_str());
4599             status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
4600             ALOGE_IF("[%s] failed to release codec instance: err=%d",
4601                        mCodec->mComponentName.c_str(), err);
4602             sp<AMessage> notify = mCodec->mNotify->dup();
4603             notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4604             notify->post();
4605             break;
4606         }
4607 
4608         default:
4609             return false;
4610     }
4611 
4612     return true;
4613 }
4614 
checkOMXMessage(const sp<AMessage> & msg)4615 bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
4616     // there is a possibility that this is an outstanding message for a
4617     // codec that we have already destroyed
4618     if (mCodec->mNode == 0) {
4619         ALOGI("ignoring message as already freed component: %s",
4620                 msg->debugString().c_str());
4621         return false;
4622     }
4623 
4624     IOMX::node_id nodeID;
4625     CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4626     if (nodeID != mCodec->mNode) {
4627         ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4628         return false;
4629     }
4630     return true;
4631 }
4632 
onOMXMessageList(const sp<AMessage> & msg)4633 bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
4634     sp<RefBase> obj;
4635     CHECK(msg->findObject("messages", &obj));
4636     sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
4637 
4638     bool receivedRenderedEvents = false;
4639     for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
4640           it != msgList->getList().cend(); ++it) {
4641         (*it)->setWhat(ACodec::kWhatOMXMessageItem);
4642         mCodec->handleMessage(*it);
4643         int32_t type;
4644         CHECK((*it)->findInt32("type", &type));
4645         if (type == omx_message::FRAME_RENDERED) {
4646             receivedRenderedEvents = true;
4647         }
4648     }
4649 
4650     if (receivedRenderedEvents) {
4651         // NOTE: all buffers are rendered in this case
4652         mCodec->notifyOfRenderedFrames();
4653     }
4654     return true;
4655 }
4656 
onOMXMessage(const sp<AMessage> & msg)4657 bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4658     int32_t type;
4659     CHECK(msg->findInt32("type", &type));
4660 
4661     switch (type) {
4662         case omx_message::EVENT:
4663         {
4664             int32_t event, data1, data2;
4665             CHECK(msg->findInt32("event", &event));
4666             CHECK(msg->findInt32("data1", &data1));
4667             CHECK(msg->findInt32("data2", &data2));
4668 
4669             if (event == OMX_EventCmdComplete
4670                     && data1 == OMX_CommandFlush
4671                     && data2 == (int32_t)OMX_ALL) {
4672                 // Use of this notification is not consistent across
4673                 // implementations. We'll drop this notification and rely
4674                 // on flush-complete notifications on the individual port
4675                 // indices instead.
4676 
4677                 return true;
4678             }
4679 
4680             return onOMXEvent(
4681                     static_cast<OMX_EVENTTYPE>(event),
4682                     static_cast<OMX_U32>(data1),
4683                     static_cast<OMX_U32>(data2));
4684         }
4685 
4686         case omx_message::EMPTY_BUFFER_DONE:
4687         {
4688             IOMX::buffer_id bufferID;
4689             int32_t fenceFd;
4690 
4691             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4692             CHECK(msg->findInt32("fence_fd", &fenceFd));
4693 
4694             return onOMXEmptyBufferDone(bufferID, fenceFd);
4695         }
4696 
4697         case omx_message::FILL_BUFFER_DONE:
4698         {
4699             IOMX::buffer_id bufferID;
4700             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4701 
4702             int32_t rangeOffset, rangeLength, flags, fenceFd;
4703             int64_t timeUs;
4704 
4705             CHECK(msg->findInt32("range_offset", &rangeOffset));
4706             CHECK(msg->findInt32("range_length", &rangeLength));
4707             CHECK(msg->findInt32("flags", &flags));
4708             CHECK(msg->findInt64("timestamp", &timeUs));
4709             CHECK(msg->findInt32("fence_fd", &fenceFd));
4710 
4711             return onOMXFillBufferDone(
4712                     bufferID,
4713                     (size_t)rangeOffset, (size_t)rangeLength,
4714                     (OMX_U32)flags,
4715                     timeUs,
4716                     fenceFd);
4717         }
4718 
4719         case omx_message::FRAME_RENDERED:
4720         {
4721             int64_t mediaTimeUs, systemNano;
4722 
4723             CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
4724             CHECK(msg->findInt64("system_nano", &systemNano));
4725 
4726             return onOMXFrameRendered(
4727                     mediaTimeUs, systemNano);
4728         }
4729 
4730         default:
4731             ALOGE("Unexpected message type: %d", type);
4732             return false;
4733     }
4734 }
4735 
onOMXFrameRendered(int64_t mediaTimeUs __unused,nsecs_t systemNano __unused)4736 bool ACodec::BaseState::onOMXFrameRendered(
4737         int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
4738     // ignore outside of Executing and PortSettingsChanged states
4739     return true;
4740 }
4741 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)4742 bool ACodec::BaseState::onOMXEvent(
4743         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4744     if (event != OMX_EventError) {
4745         ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4746              mCodec->mComponentName.c_str(), event, data1, data2);
4747 
4748         return false;
4749     }
4750 
4751     ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4752 
4753     // verify OMX component sends back an error we expect.
4754     OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4755     if (!isOMXError(omxError)) {
4756         ALOGW("Invalid OMX error %#x", omxError);
4757         omxError = OMX_ErrorUndefined;
4758     }
4759     mCodec->signalError(omxError);
4760 
4761     return true;
4762 }
4763 
onOMXEmptyBufferDone(IOMX::buffer_id bufferID,int fenceFd)4764 bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
4765     ALOGV("[%s] onOMXEmptyBufferDone %u",
4766          mCodec->mComponentName.c_str(), bufferID);
4767 
4768     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4769     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4770     if (status != BufferInfo::OWNED_BY_COMPONENT) {
4771         ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
4772         mCodec->dumpBuffers(kPortIndexInput);
4773         if (fenceFd >= 0) {
4774             ::close(fenceFd);
4775         }
4776         return false;
4777     }
4778     info->mStatus = BufferInfo::OWNED_BY_US;
4779 
4780     // input buffers cannot take fences, so wait for any fence now
4781     (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
4782     fenceFd = -1;
4783 
4784     // still save fence for completeness
4785     info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
4786 
4787     // We're in "store-metadata-in-buffers" mode, the underlying
4788     // OMX component had access to data that's implicitly refcounted
4789     // by this "MediaBuffer" object. Now that the OMX component has
4790     // told us that it's done with the input buffer, we can decrement
4791     // the mediaBuffer's reference count.
4792     info->mData->setMediaBufferBase(NULL);
4793 
4794     PortMode mode = getPortMode(kPortIndexInput);
4795 
4796     switch (mode) {
4797         case KEEP_BUFFERS:
4798             break;
4799 
4800         case RESUBMIT_BUFFERS:
4801             postFillThisBuffer(info);
4802             break;
4803 
4804         case FREE_BUFFERS:
4805         default:
4806             ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4807             return false;
4808     }
4809 
4810     return true;
4811 }
4812 
postFillThisBuffer(BufferInfo * info)4813 void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4814     if (mCodec->mPortEOS[kPortIndexInput]) {
4815         return;
4816     }
4817 
4818     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4819 
4820     sp<AMessage> notify = mCodec->mNotify->dup();
4821     notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4822     notify->setInt32("buffer-id", info->mBufferID);
4823 
4824     info->mData->meta()->clear();
4825     notify->setBuffer("buffer", info->mData);
4826 
4827     sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4828     reply->setInt32("buffer-id", info->mBufferID);
4829 
4830     notify->setMessage("reply", reply);
4831 
4832     notify->post();
4833 
4834     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4835 }
4836 
onInputBufferFilled(const sp<AMessage> & msg)4837 void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4838     IOMX::buffer_id bufferID;
4839     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4840     sp<ABuffer> buffer;
4841     int32_t err = OK;
4842     bool eos = false;
4843     PortMode mode = getPortMode(kPortIndexInput);
4844 
4845     if (!msg->findBuffer("buffer", &buffer)) {
4846         /* these are unfilled buffers returned by client */
4847         CHECK(msg->findInt32("err", &err));
4848 
4849         if (err == OK) {
4850             /* buffers with no errors are returned on MediaCodec.flush */
4851             mode = KEEP_BUFFERS;
4852         } else {
4853             ALOGV("[%s] saw error %d instead of an input buffer",
4854                  mCodec->mComponentName.c_str(), err);
4855             eos = true;
4856         }
4857 
4858         buffer.clear();
4859     }
4860 
4861     int32_t tmp;
4862     if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
4863         eos = true;
4864         err = ERROR_END_OF_STREAM;
4865     }
4866 
4867     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4868     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4869     if (status != BufferInfo::OWNED_BY_UPSTREAM) {
4870         ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
4871         mCodec->dumpBuffers(kPortIndexInput);
4872         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4873         return;
4874     }
4875 
4876     info->mStatus = BufferInfo::OWNED_BY_US;
4877 
4878     switch (mode) {
4879         case KEEP_BUFFERS:
4880         {
4881             if (eos) {
4882                 if (!mCodec->mPortEOS[kPortIndexInput]) {
4883                     mCodec->mPortEOS[kPortIndexInput] = true;
4884                     mCodec->mInputEOSResult = err;
4885                 }
4886             }
4887             break;
4888         }
4889 
4890         case RESUBMIT_BUFFERS:
4891         {
4892             if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4893                 // Do not send empty input buffer w/o EOS to the component.
4894                 if (buffer->size() == 0 && !eos) {
4895                     postFillThisBuffer(info);
4896                     break;
4897                 }
4898 
4899                 int64_t timeUs;
4900                 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4901 
4902                 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4903 
4904                 int32_t isCSD;
4905                 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4906                     flags |= OMX_BUFFERFLAG_CODECCONFIG;
4907                 }
4908 
4909                 if (eos) {
4910                     flags |= OMX_BUFFERFLAG_EOS;
4911                 }
4912 
4913                 if (buffer != info->mData) {
4914                     ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4915                          mCodec->mComponentName.c_str(),
4916                          bufferID,
4917                          buffer.get(), info->mData.get());
4918 
4919                     if (buffer->size() > info->mData->capacity()) {
4920                         ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
4921                                 buffer->size(),           // this is the data received
4922                                 info->mData->capacity()); // this is out buffer size
4923                         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4924                         return;
4925                     }
4926                     memcpy(info->mData->data(), buffer->data(), buffer->size());
4927                 }
4928 
4929                 if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4930                     ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4931                          mCodec->mComponentName.c_str(), bufferID);
4932                 } else if (flags & OMX_BUFFERFLAG_EOS) {
4933                     ALOGV("[%s] calling emptyBuffer %u w/ EOS",
4934                          mCodec->mComponentName.c_str(), bufferID);
4935                 } else {
4936 #if TRACK_BUFFER_TIMING
4937                     ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4938                          mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4939 #else
4940                     ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4941                          mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4942 #endif
4943                 }
4944 
4945 #if TRACK_BUFFER_TIMING
4946                 ACodec::BufferStats stats;
4947                 stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4948                 stats.mFillBufferDoneTimeUs = -1ll;
4949                 mCodec->mBufferStats.add(timeUs, stats);
4950 #endif
4951 
4952                 if (mCodec->storingMetadataInDecodedBuffers()) {
4953                     // try to submit an output buffer for each input buffer
4954                     PortMode outputMode = getPortMode(kPortIndexOutput);
4955 
4956                     ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
4957                             mCodec->mMetadataBuffersToSubmit,
4958                             (outputMode == FREE_BUFFERS ? "FREE" :
4959                              outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4960                     if (outputMode == RESUBMIT_BUFFERS) {
4961                         mCodec->submitOutputMetadataBuffer();
4962                     }
4963                 }
4964                 info->checkReadFence("onInputBufferFilled");
4965                 status_t err2 = mCodec->mOMX->emptyBuffer(
4966                     mCodec->mNode,
4967                     bufferID,
4968                     0,
4969                     buffer->size(),
4970                     flags,
4971                     timeUs,
4972                     info->mFenceFd);
4973                 info->mFenceFd = -1;
4974                 if (err2 != OK) {
4975                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
4976                     return;
4977                 }
4978                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4979 
4980                 if (!eos && err == OK) {
4981                     getMoreInputDataIfPossible();
4982                 } else {
4983                     ALOGV("[%s] Signalled EOS (%d) on the input port",
4984                          mCodec->mComponentName.c_str(), err);
4985 
4986                     mCodec->mPortEOS[kPortIndexInput] = true;
4987                     mCodec->mInputEOSResult = err;
4988                 }
4989             } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4990                 if (err != OK && err != ERROR_END_OF_STREAM) {
4991                     ALOGV("[%s] Signalling EOS on the input port due to error %d",
4992                          mCodec->mComponentName.c_str(), err);
4993                 } else {
4994                     ALOGV("[%s] Signalling EOS on the input port",
4995                          mCodec->mComponentName.c_str());
4996                 }
4997 
4998                 ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4999                      mCodec->mComponentName.c_str(), bufferID);
5000 
5001                 info->checkReadFence("onInputBufferFilled");
5002                 status_t err2 = mCodec->mOMX->emptyBuffer(
5003                         mCodec->mNode,
5004                         bufferID,
5005                         0,
5006                         0,
5007                         OMX_BUFFERFLAG_EOS,
5008                         0,
5009                         info->mFenceFd);
5010                 info->mFenceFd = -1;
5011                 if (err2 != OK) {
5012                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
5013                     return;
5014                 }
5015                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5016 
5017                 mCodec->mPortEOS[kPortIndexInput] = true;
5018                 mCodec->mInputEOSResult = err;
5019             }
5020             break;
5021         }
5022 
5023         case FREE_BUFFERS:
5024             break;
5025 
5026         default:
5027             ALOGE("invalid port mode: %d", mode);
5028             break;
5029     }
5030 }
5031 
getMoreInputDataIfPossible()5032 void ACodec::BaseState::getMoreInputDataIfPossible() {
5033     if (mCodec->mPortEOS[kPortIndexInput]) {
5034         return;
5035     }
5036 
5037     BufferInfo *eligible = NULL;
5038 
5039     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5040         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5041 
5042 #if 0
5043         if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5044             // There's already a "read" pending.
5045             return;
5046         }
5047 #endif
5048 
5049         if (info->mStatus == BufferInfo::OWNED_BY_US) {
5050             eligible = info;
5051         }
5052     }
5053 
5054     if (eligible == NULL) {
5055         return;
5056     }
5057 
5058     postFillThisBuffer(eligible);
5059 }
5060 
onOMXFillBufferDone(IOMX::buffer_id bufferID,size_t rangeOffset,size_t rangeLength,OMX_U32 flags,int64_t timeUs,int fenceFd)5061 bool ACodec::BaseState::onOMXFillBufferDone(
5062         IOMX::buffer_id bufferID,
5063         size_t rangeOffset, size_t rangeLength,
5064         OMX_U32 flags,
5065         int64_t timeUs,
5066         int fenceFd) {
5067     ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
5068          mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5069 
5070     ssize_t index;
5071     status_t err= OK;
5072 
5073 #if TRACK_BUFFER_TIMING
5074     index = mCodec->mBufferStats.indexOfKey(timeUs);
5075     if (index >= 0) {
5076         ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5077         stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5078 
5079         ALOGI("frame PTS %lld: %lld",
5080                 timeUs,
5081                 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5082 
5083         mCodec->mBufferStats.removeItemsAt(index);
5084         stats = NULL;
5085     }
5086 #endif
5087 
5088     BufferInfo *info =
5089         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5090     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5091     if (status != BufferInfo::OWNED_BY_COMPONENT) {
5092         ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5093         mCodec->dumpBuffers(kPortIndexOutput);
5094         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5095         if (fenceFd >= 0) {
5096             ::close(fenceFd);
5097         }
5098         return true;
5099     }
5100 
5101     info->mDequeuedAt = ++mCodec->mDequeueCounter;
5102     info->mStatus = BufferInfo::OWNED_BY_US;
5103 
5104     if (info->mRenderInfo != NULL) {
5105         // The fence for an emptied buffer must have signaled, but there still could be queued
5106         // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
5107         // as we will soon requeue this buffer to the surface. While in theory we could still keep
5108         // track of buffers that are requeued to the surface, it is better to add support to the
5109         // buffer-queue to notify us of released buffers and their fences (in the future).
5110         mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
5111     }
5112 
5113     // byte buffers cannot take fences, so wait for any fence now
5114     if (mCodec->mNativeWindow == NULL) {
5115         (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
5116         fenceFd = -1;
5117     }
5118     info->setReadFence(fenceFd, "onOMXFillBufferDone");
5119 
5120     PortMode mode = getPortMode(kPortIndexOutput);
5121 
5122     switch (mode) {
5123         case KEEP_BUFFERS:
5124             break;
5125 
5126         case RESUBMIT_BUFFERS:
5127         {
5128             if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5129                     || mCodec->mPortEOS[kPortIndexOutput])) {
5130                 ALOGV("[%s] calling fillBuffer %u",
5131                      mCodec->mComponentName.c_str(), info->mBufferID);
5132 
5133                 err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
5134                 info->mFenceFd = -1;
5135                 if (err != OK) {
5136                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5137                     return true;
5138                 }
5139 
5140                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5141                 break;
5142             }
5143 
5144             sp<AMessage> reply =
5145                 new AMessage(kWhatOutputBufferDrained, mCodec);
5146 
5147             if (!mCodec->mSentFormat && rangeLength > 0) {
5148                 mCodec->sendFormatChange(reply);
5149             }
5150             if (mCodec->usingMetadataOnEncoderOutput()) {
5151                 native_handle_t *handle = NULL;
5152                 VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5153                 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5154                 if (info->mData->size() >= sizeof(grallocMeta)
5155                         && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
5156                     handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
5157                 } else if (info->mData->size() >= sizeof(nativeMeta)
5158                         && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
5159 #ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5160                     // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
5161                     handle = NULL;
5162 #else
5163                     handle = (native_handle_t *)nativeMeta.pBuffer->handle;
5164 #endif
5165                 }
5166                 info->mData->meta()->setPointer("handle", handle);
5167                 info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5168                 info->mData->meta()->setInt32("rangeLength", rangeLength);
5169             } else {
5170                 info->mData->setRange(rangeOffset, rangeLength);
5171             }
5172 #if 0
5173             if (mCodec->mNativeWindow == NULL) {
5174                 if (IsIDR(info->mData)) {
5175                     ALOGI("IDR frame");
5176                 }
5177             }
5178 #endif
5179 
5180             if (mCodec->mSkipCutBuffer != NULL) {
5181                 mCodec->mSkipCutBuffer->submit(info->mData);
5182             }
5183             info->mData->meta()->setInt64("timeUs", timeUs);
5184 
5185             sp<AMessage> notify = mCodec->mNotify->dup();
5186             notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5187             notify->setInt32("buffer-id", info->mBufferID);
5188             notify->setBuffer("buffer", info->mData);
5189             notify->setInt32("flags", flags);
5190 
5191             reply->setInt32("buffer-id", info->mBufferID);
5192 
5193             notify->setMessage("reply", reply);
5194 
5195             notify->post();
5196 
5197             info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5198 
5199             if (flags & OMX_BUFFERFLAG_EOS) {
5200                 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
5201 
5202                 sp<AMessage> notify = mCodec->mNotify->dup();
5203                 notify->setInt32("what", CodecBase::kWhatEOS);
5204                 notify->setInt32("err", mCodec->mInputEOSResult);
5205                 notify->post();
5206 
5207                 mCodec->mPortEOS[kPortIndexOutput] = true;
5208             }
5209             break;
5210         }
5211 
5212         case FREE_BUFFERS:
5213             err = mCodec->freeBuffer(kPortIndexOutput, index);
5214             if (err != OK) {
5215                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5216                 return true;
5217             }
5218             break;
5219 
5220         default:
5221             ALOGE("Invalid port mode: %d", mode);
5222             return false;
5223     }
5224 
5225     return true;
5226 }
5227 
onOutputBufferDrained(const sp<AMessage> & msg)5228 void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5229     IOMX::buffer_id bufferID;
5230     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5231     ssize_t index;
5232     BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5233     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5234     if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
5235         ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5236         mCodec->dumpBuffers(kPortIndexOutput);
5237         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5238         return;
5239     }
5240 
5241     android_native_rect_t crop;
5242     if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5243         status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5244         ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5245     }
5246 
5247     int32_t render;
5248     if (mCodec->mNativeWindow != NULL
5249             && msg->findInt32("render", &render) && render != 0
5250             && info->mData != NULL && info->mData->size() != 0) {
5251         ATRACE_NAME("render");
5252         // The client wants this buffer to be rendered.
5253 
5254         // save buffers sent to the surface so we can get render time when they return
5255         int64_t mediaTimeUs = -1;
5256         info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
5257         if (mediaTimeUs >= 0) {
5258             mCodec->mRenderTracker.onFrameQueued(
5259                     mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
5260         }
5261 
5262         int64_t timestampNs = 0;
5263         if (!msg->findInt64("timestampNs", &timestampNs)) {
5264             // use media timestamp if client did not request a specific render timestamp
5265             if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5266                 ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5267                 timestampNs *= 1000;
5268             }
5269         }
5270 
5271         status_t err;
5272         err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
5273         ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5274 
5275         info->checkReadFence("onOutputBufferDrained before queueBuffer");
5276         err = mCodec->mNativeWindow->queueBuffer(
5277                     mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
5278         info->mFenceFd = -1;
5279         if (err == OK) {
5280             info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5281         } else {
5282             ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5283             mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5284             info->mStatus = BufferInfo::OWNED_BY_US;
5285             // keeping read fence as write fence to avoid clobbering
5286             info->mIsReadFence = false;
5287         }
5288     } else {
5289         if (mCodec->mNativeWindow != NULL &&
5290             (info->mData == NULL || info->mData->size() != 0)) {
5291             // move read fence into write fence to avoid clobbering
5292             info->mIsReadFence = false;
5293             ATRACE_NAME("frame-drop");
5294         }
5295         info->mStatus = BufferInfo::OWNED_BY_US;
5296     }
5297 
5298     PortMode mode = getPortMode(kPortIndexOutput);
5299 
5300     switch (mode) {
5301         case KEEP_BUFFERS:
5302         {
5303             // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5304 
5305             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5306                 // We cannot resubmit the buffer we just rendered, dequeue
5307                 // the spare instead.
5308 
5309                 info = mCodec->dequeueBufferFromNativeWindow();
5310             }
5311             break;
5312         }
5313 
5314         case RESUBMIT_BUFFERS:
5315         {
5316             if (!mCodec->mPortEOS[kPortIndexOutput]) {
5317                 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5318                     // We cannot resubmit the buffer we just rendered, dequeue
5319                     // the spare instead.
5320 
5321                     info = mCodec->dequeueBufferFromNativeWindow();
5322                 }
5323 
5324                 if (info != NULL) {
5325                     ALOGV("[%s] calling fillBuffer %u",
5326                          mCodec->mComponentName.c_str(), info->mBufferID);
5327                     info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
5328                     status_t err = mCodec->mOMX->fillBuffer(
5329                             mCodec->mNode, info->mBufferID, info->mFenceFd);
5330                     info->mFenceFd = -1;
5331                     if (err == OK) {
5332                         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5333                     } else {
5334                         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5335                     }
5336                 }
5337             }
5338             break;
5339         }
5340 
5341         case FREE_BUFFERS:
5342         {
5343             status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
5344             if (err != OK) {
5345                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5346             }
5347             break;
5348         }
5349 
5350         default:
5351             ALOGE("Invalid port mode: %d", mode);
5352             return;
5353     }
5354 }
5355 
5356 ////////////////////////////////////////////////////////////////////////////////
5357 
UninitializedState(ACodec * codec)5358 ACodec::UninitializedState::UninitializedState(ACodec *codec)
5359     : BaseState(codec) {
5360 }
5361 
stateEntered()5362 void ACodec::UninitializedState::stateEntered() {
5363     ALOGV("Now uninitialized");
5364 
5365     if (mDeathNotifier != NULL) {
5366         IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
5367         mDeathNotifier.clear();
5368     }
5369 
5370     mCodec->mNativeWindow.clear();
5371     mCodec->mNativeWindowUsageBits = 0;
5372     mCodec->mNode = 0;
5373     mCodec->mOMX.clear();
5374     mCodec->mQuirks = 0;
5375     mCodec->mFlags = 0;
5376     mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5377     mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5378     mCodec->mComponentName.clear();
5379 }
5380 
onMessageReceived(const sp<AMessage> & msg)5381 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5382     bool handled = false;
5383 
5384     switch (msg->what()) {
5385         case ACodec::kWhatSetup:
5386         {
5387             onSetup(msg);
5388 
5389             handled = true;
5390             break;
5391         }
5392 
5393         case ACodec::kWhatAllocateComponent:
5394         {
5395             onAllocateComponent(msg);
5396             handled = true;
5397             break;
5398         }
5399 
5400         case ACodec::kWhatShutdown:
5401         {
5402             int32_t keepComponentAllocated;
5403             CHECK(msg->findInt32(
5404                         "keepComponentAllocated", &keepComponentAllocated));
5405             ALOGW_IF(keepComponentAllocated,
5406                      "cannot keep component allocated on shutdown in Uninitialized state");
5407 
5408             sp<AMessage> notify = mCodec->mNotify->dup();
5409             notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5410             notify->post();
5411 
5412             handled = true;
5413             break;
5414         }
5415 
5416         case ACodec::kWhatFlush:
5417         {
5418             sp<AMessage> notify = mCodec->mNotify->dup();
5419             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5420             notify->post();
5421 
5422             handled = true;
5423             break;
5424         }
5425 
5426         case ACodec::kWhatReleaseCodecInstance:
5427         {
5428             // nothing to do, as we have already signaled shutdown
5429             handled = true;
5430             break;
5431         }
5432 
5433         default:
5434             return BaseState::onMessageReceived(msg);
5435     }
5436 
5437     return handled;
5438 }
5439 
onSetup(const sp<AMessage> & msg)5440 void ACodec::UninitializedState::onSetup(
5441         const sp<AMessage> &msg) {
5442     if (onAllocateComponent(msg)
5443             && mCodec->mLoadedState->onConfigureComponent(msg)) {
5444         mCodec->mLoadedState->onStart();
5445     }
5446 }
5447 
onAllocateComponent(const sp<AMessage> & msg)5448 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
5449     ALOGV("onAllocateComponent");
5450 
5451     CHECK(mCodec->mNode == 0);
5452 
5453     OMXClient client;
5454     if (client.connect() != OK) {
5455         mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
5456         return false;
5457     }
5458 
5459     sp<IOMX> omx = client.interface();
5460 
5461     sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5462 
5463     mDeathNotifier = new DeathNotifier(notify);
5464     if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5465         // This was a local binder, if it dies so do we, we won't care
5466         // about any notifications in the afterlife.
5467         mDeathNotifier.clear();
5468     }
5469 
5470     Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
5471 
5472     AString mime;
5473 
5474     AString componentName;
5475     uint32_t quirks = 0;
5476     int32_t encoder = false;
5477     if (msg->findString("componentName", &componentName)) {
5478         ssize_t index = matchingCodecs.add();
5479         OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5480         entry->mName = String8(componentName.c_str());
5481 
5482         if (!OMXCodec::findCodecQuirks(
5483                     componentName.c_str(), &entry->mQuirks)) {
5484             entry->mQuirks = 0;
5485         }
5486     } else {
5487         CHECK(msg->findString("mime", &mime));
5488 
5489         if (!msg->findInt32("encoder", &encoder)) {
5490             encoder = false;
5491         }
5492 
5493         OMXCodec::findMatchingCodecs(
5494                 mime.c_str(),
5495                 encoder, // createEncoder
5496                 NULL,  // matchComponentName
5497                 0,     // flags
5498                 &matchingCodecs);
5499     }
5500 
5501     sp<CodecObserver> observer = new CodecObserver;
5502     IOMX::node_id node = 0;
5503 
5504     status_t err = NAME_NOT_FOUND;
5505     for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
5506             ++matchIndex) {
5507         componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5508         quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5509 
5510         pid_t tid = gettid();
5511         int prevPriority = androidGetThreadPriority(tid);
5512         androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
5513         err = omx->allocateNode(componentName.c_str(), observer, &node);
5514         androidSetThreadPriority(tid, prevPriority);
5515 
5516         if (err == OK) {
5517             break;
5518         } else {
5519             ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
5520         }
5521 
5522         node = 0;
5523     }
5524 
5525     if (node == 0) {
5526         if (!mime.empty()) {
5527             ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
5528                     encoder ? "en" : "de", mime.c_str(), err);
5529         } else {
5530             ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
5531         }
5532 
5533         mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5534         return false;
5535     }
5536 
5537     notify = new AMessage(kWhatOMXMessageList, mCodec);
5538     observer->setNotificationMessage(notify);
5539 
5540     mCodec->mComponentName = componentName;
5541     mCodec->mRenderTracker.setComponentName(componentName);
5542     mCodec->mFlags = 0;
5543 
5544     if (componentName.endsWith(".secure")) {
5545         mCodec->mFlags |= kFlagIsSecure;
5546         mCodec->mFlags |= kFlagIsGrallocUsageProtected;
5547         mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5548     }
5549 
5550     mCodec->mQuirks = quirks;
5551     mCodec->mOMX = omx;
5552     mCodec->mNode = node;
5553 
5554     {
5555         sp<AMessage> notify = mCodec->mNotify->dup();
5556         notify->setInt32("what", CodecBase::kWhatComponentAllocated);
5557         notify->setString("componentName", mCodec->mComponentName.c_str());
5558         notify->post();
5559     }
5560 
5561     mCodec->changeState(mCodec->mLoadedState);
5562 
5563     return true;
5564 }
5565 
5566 ////////////////////////////////////////////////////////////////////////////////
5567 
LoadedState(ACodec * codec)5568 ACodec::LoadedState::LoadedState(ACodec *codec)
5569     : BaseState(codec) {
5570 }
5571 
stateEntered()5572 void ACodec::LoadedState::stateEntered() {
5573     ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5574 
5575     mCodec->mPortEOS[kPortIndexInput] =
5576         mCodec->mPortEOS[kPortIndexOutput] = false;
5577 
5578     mCodec->mInputEOSResult = OK;
5579 
5580     mCodec->mDequeueCounter = 0;
5581     mCodec->mMetadataBuffersToSubmit = 0;
5582     mCodec->mRepeatFrameDelayUs = -1ll;
5583     mCodec->mInputFormat.clear();
5584     mCodec->mOutputFormat.clear();
5585     mCodec->mBaseOutputFormat.clear();
5586 
5587     if (mCodec->mShutdownInProgress) {
5588         bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5589 
5590         mCodec->mShutdownInProgress = false;
5591         mCodec->mKeepComponentAllocated = false;
5592 
5593         onShutdown(keepComponentAllocated);
5594     }
5595     mCodec->mExplicitShutdown = false;
5596 
5597     mCodec->processDeferredMessages();
5598 }
5599 
onShutdown(bool keepComponentAllocated)5600 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5601     if (!keepComponentAllocated) {
5602         (void)mCodec->mOMX->freeNode(mCodec->mNode);
5603 
5604         mCodec->changeState(mCodec->mUninitializedState);
5605     }
5606 
5607     if (mCodec->mExplicitShutdown) {
5608         sp<AMessage> notify = mCodec->mNotify->dup();
5609         notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5610         notify->post();
5611         mCodec->mExplicitShutdown = false;
5612     }
5613 }
5614 
onMessageReceived(const sp<AMessage> & msg)5615 bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5616     bool handled = false;
5617 
5618     switch (msg->what()) {
5619         case ACodec::kWhatConfigureComponent:
5620         {
5621             onConfigureComponent(msg);
5622             handled = true;
5623             break;
5624         }
5625 
5626         case ACodec::kWhatCreateInputSurface:
5627         {
5628             onCreateInputSurface(msg);
5629             handled = true;
5630             break;
5631         }
5632 
5633         case ACodec::kWhatSetInputSurface:
5634         {
5635             onSetInputSurface(msg);
5636             handled = true;
5637             break;
5638         }
5639 
5640         case ACodec::kWhatStart:
5641         {
5642             onStart();
5643             handled = true;
5644             break;
5645         }
5646 
5647         case ACodec::kWhatShutdown:
5648         {
5649             int32_t keepComponentAllocated;
5650             CHECK(msg->findInt32(
5651                         "keepComponentAllocated", &keepComponentAllocated));
5652 
5653             mCodec->mExplicitShutdown = true;
5654             onShutdown(keepComponentAllocated);
5655 
5656             handled = true;
5657             break;
5658         }
5659 
5660         case ACodec::kWhatFlush:
5661         {
5662             sp<AMessage> notify = mCodec->mNotify->dup();
5663             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5664             notify->post();
5665 
5666             handled = true;
5667             break;
5668         }
5669 
5670         default:
5671             return BaseState::onMessageReceived(msg);
5672     }
5673 
5674     return handled;
5675 }
5676 
onConfigureComponent(const sp<AMessage> & msg)5677 bool ACodec::LoadedState::onConfigureComponent(
5678         const sp<AMessage> &msg) {
5679     ALOGV("onConfigureComponent");
5680 
5681     CHECK(mCodec->mNode != 0);
5682 
5683     status_t err = OK;
5684     AString mime;
5685     if (!msg->findString("mime", &mime)) {
5686         err = BAD_VALUE;
5687     } else {
5688         err = mCodec->configureCodec(mime.c_str(), msg);
5689     }
5690     if (err != OK) {
5691         ALOGE("[%s] configureCodec returning error %d",
5692               mCodec->mComponentName.c_str(), err);
5693 
5694         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5695         return false;
5696     }
5697 
5698     {
5699         sp<AMessage> notify = mCodec->mNotify->dup();
5700         notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5701         notify->setMessage("input-format", mCodec->mInputFormat);
5702         notify->setMessage("output-format", mCodec->mOutputFormat);
5703         notify->post();
5704     }
5705 
5706     return true;
5707 }
5708 
setupInputSurface()5709 status_t ACodec::LoadedState::setupInputSurface() {
5710     status_t err = OK;
5711 
5712     if (mCodec->mRepeatFrameDelayUs > 0ll) {
5713         err = mCodec->mOMX->setInternalOption(
5714                 mCodec->mNode,
5715                 kPortIndexInput,
5716                 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5717                 &mCodec->mRepeatFrameDelayUs,
5718                 sizeof(mCodec->mRepeatFrameDelayUs));
5719 
5720         if (err != OK) {
5721             ALOGE("[%s] Unable to configure option to repeat previous "
5722                   "frames (err %d)",
5723                   mCodec->mComponentName.c_str(),
5724                   err);
5725             return err;
5726         }
5727     }
5728 
5729     if (mCodec->mMaxPtsGapUs > 0ll) {
5730         err = mCodec->mOMX->setInternalOption(
5731                 mCodec->mNode,
5732                 kPortIndexInput,
5733                 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
5734                 &mCodec->mMaxPtsGapUs,
5735                 sizeof(mCodec->mMaxPtsGapUs));
5736 
5737         if (err != OK) {
5738             ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
5739                     mCodec->mComponentName.c_str(),
5740                     err);
5741             return err;
5742         }
5743     }
5744 
5745     if (mCodec->mMaxFps > 0) {
5746         err = mCodec->mOMX->setInternalOption(
5747                 mCodec->mNode,
5748                 kPortIndexInput,
5749                 IOMX::INTERNAL_OPTION_MAX_FPS,
5750                 &mCodec->mMaxFps,
5751                 sizeof(mCodec->mMaxFps));
5752 
5753         if (err != OK) {
5754             ALOGE("[%s] Unable to configure max fps (err %d)",
5755                     mCodec->mComponentName.c_str(),
5756                     err);
5757             return err;
5758         }
5759     }
5760 
5761     if (mCodec->mTimePerCaptureUs > 0ll
5762             && mCodec->mTimePerFrameUs > 0ll) {
5763         int64_t timeLapse[2];
5764         timeLapse[0] = mCodec->mTimePerFrameUs;
5765         timeLapse[1] = mCodec->mTimePerCaptureUs;
5766         err = mCodec->mOMX->setInternalOption(
5767                 mCodec->mNode,
5768                 kPortIndexInput,
5769                 IOMX::INTERNAL_OPTION_TIME_LAPSE,
5770                 &timeLapse[0],
5771                 sizeof(timeLapse));
5772 
5773         if (err != OK) {
5774             ALOGE("[%s] Unable to configure time lapse (err %d)",
5775                     mCodec->mComponentName.c_str(),
5776                     err);
5777             return err;
5778         }
5779     }
5780 
5781     if (mCodec->mCreateInputBuffersSuspended) {
5782         bool suspend = true;
5783         err = mCodec->mOMX->setInternalOption(
5784                 mCodec->mNode,
5785                 kPortIndexInput,
5786                 IOMX::INTERNAL_OPTION_SUSPEND,
5787                 &suspend,
5788                 sizeof(suspend));
5789 
5790         if (err != OK) {
5791             ALOGE("[%s] Unable to configure option to suspend (err %d)",
5792                   mCodec->mComponentName.c_str(),
5793                   err);
5794             return err;
5795         }
5796     }
5797 
5798     uint32_t usageBits;
5799     if (mCodec->mOMX->getParameter(
5800             mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
5801             &usageBits, sizeof(usageBits)) == OK) {
5802         mCodec->mInputFormat->setInt32(
5803                 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
5804     }
5805 
5806     return OK;
5807 }
5808 
onCreateInputSurface(const sp<AMessage> &)5809 void ACodec::LoadedState::onCreateInputSurface(
5810         const sp<AMessage> & /* msg */) {
5811     ALOGV("onCreateInputSurface");
5812 
5813     sp<AMessage> notify = mCodec->mNotify->dup();
5814     notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5815 
5816     sp<IGraphicBufferProducer> bufferProducer;
5817     status_t err = mCodec->mOMX->createInputSurface(
5818             mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType);
5819 
5820     if (err == OK) {
5821         err = setupInputSurface();
5822     }
5823 
5824     if (err == OK) {
5825         notify->setObject("input-surface",
5826                 new BufferProducerWrapper(bufferProducer));
5827     } else {
5828         // Can't use mCodec->signalError() here -- MediaCodec won't forward
5829         // the error through because it's in the "configured" state.  We
5830         // send a kWhatInputSurfaceCreated with an error value instead.
5831         ALOGE("[%s] onCreateInputSurface returning error %d",
5832                 mCodec->mComponentName.c_str(), err);
5833         notify->setInt32("err", err);
5834     }
5835     notify->post();
5836 }
5837 
onSetInputSurface(const sp<AMessage> & msg)5838 void ACodec::LoadedState::onSetInputSurface(
5839         const sp<AMessage> &msg) {
5840     ALOGV("onSetInputSurface");
5841 
5842     sp<AMessage> notify = mCodec->mNotify->dup();
5843     notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5844 
5845     sp<RefBase> obj;
5846     CHECK(msg->findObject("input-surface", &obj));
5847     sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5848 
5849     status_t err = mCodec->mOMX->setInputSurface(
5850             mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
5851             &mCodec->mInputMetadataType);
5852 
5853     if (err == OK) {
5854         err = setupInputSurface();
5855     }
5856 
5857     if (err != OK) {
5858         // Can't use mCodec->signalError() here -- MediaCodec won't forward
5859         // the error through because it's in the "configured" state.  We
5860         // send a kWhatInputSurfaceAccepted with an error value instead.
5861         ALOGE("[%s] onSetInputSurface returning error %d",
5862                 mCodec->mComponentName.c_str(), err);
5863         notify->setInt32("err", err);
5864     }
5865     notify->post();
5866 }
5867 
onStart()5868 void ACodec::LoadedState::onStart() {
5869     ALOGV("onStart");
5870 
5871     status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
5872     if (err != OK) {
5873         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5874     } else {
5875         mCodec->changeState(mCodec->mLoadedToIdleState);
5876     }
5877 }
5878 
5879 ////////////////////////////////////////////////////////////////////////////////
5880 
LoadedToIdleState(ACodec * codec)5881 ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5882     : BaseState(codec) {
5883 }
5884 
stateEntered()5885 void ACodec::LoadedToIdleState::stateEntered() {
5886     ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5887 
5888     status_t err;
5889     if ((err = allocateBuffers()) != OK) {
5890         ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5891              "(error 0x%08x)",
5892              err);
5893 
5894         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5895 
5896         mCodec->changeState(mCodec->mLoadedState);
5897     }
5898 }
5899 
allocateBuffers()5900 status_t ACodec::LoadedToIdleState::allocateBuffers() {
5901     status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5902 
5903     if (err != OK) {
5904         return err;
5905     }
5906 
5907     return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5908 }
5909 
onMessageReceived(const sp<AMessage> & msg)5910 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5911     switch (msg->what()) {
5912         case kWhatSetParameters:
5913         case kWhatShutdown:
5914         {
5915             mCodec->deferMessage(msg);
5916             return true;
5917         }
5918 
5919         case kWhatSignalEndOfInputStream:
5920         {
5921             mCodec->onSignalEndOfInputStream();
5922             return true;
5923         }
5924 
5925         case kWhatResume:
5926         {
5927             // We'll be active soon enough.
5928             return true;
5929         }
5930 
5931         case kWhatFlush:
5932         {
5933             // We haven't even started yet, so we're flushed alright...
5934             sp<AMessage> notify = mCodec->mNotify->dup();
5935             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5936             notify->post();
5937             return true;
5938         }
5939 
5940         default:
5941             return BaseState::onMessageReceived(msg);
5942     }
5943 }
5944 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)5945 bool ACodec::LoadedToIdleState::onOMXEvent(
5946         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5947     switch (event) {
5948         case OMX_EventCmdComplete:
5949         {
5950             status_t err = OK;
5951             if (data1 != (OMX_U32)OMX_CommandStateSet
5952                     || data2 != (OMX_U32)OMX_StateIdle) {
5953                 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
5954                         asString((OMX_COMMANDTYPE)data1), data1,
5955                         asString((OMX_STATETYPE)data2), data2);
5956                 err = FAILED_TRANSACTION;
5957             }
5958 
5959             if (err == OK) {
5960                 err = mCodec->mOMX->sendCommand(
5961                     mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
5962             }
5963 
5964             if (err != OK) {
5965                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5966             } else {
5967                 mCodec->changeState(mCodec->mIdleToExecutingState);
5968             }
5969 
5970             return true;
5971         }
5972 
5973         default:
5974             return BaseState::onOMXEvent(event, data1, data2);
5975     }
5976 }
5977 
5978 ////////////////////////////////////////////////////////////////////////////////
5979 
IdleToExecutingState(ACodec * codec)5980 ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5981     : BaseState(codec) {
5982 }
5983 
stateEntered()5984 void ACodec::IdleToExecutingState::stateEntered() {
5985     ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5986 }
5987 
onMessageReceived(const sp<AMessage> & msg)5988 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5989     switch (msg->what()) {
5990         case kWhatSetParameters:
5991         case kWhatShutdown:
5992         {
5993             mCodec->deferMessage(msg);
5994             return true;
5995         }
5996 
5997         case kWhatResume:
5998         {
5999             // We'll be active soon enough.
6000             return true;
6001         }
6002 
6003         case kWhatFlush:
6004         {
6005             // We haven't even started yet, so we're flushed alright...
6006             sp<AMessage> notify = mCodec->mNotify->dup();
6007             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6008             notify->post();
6009 
6010             return true;
6011         }
6012 
6013         case kWhatSignalEndOfInputStream:
6014         {
6015             mCodec->onSignalEndOfInputStream();
6016             return true;
6017         }
6018 
6019         default:
6020             return BaseState::onMessageReceived(msg);
6021     }
6022 }
6023 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6024 bool ACodec::IdleToExecutingState::onOMXEvent(
6025         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6026     switch (event) {
6027         case OMX_EventCmdComplete:
6028         {
6029             if (data1 != (OMX_U32)OMX_CommandStateSet
6030                     || data2 != (OMX_U32)OMX_StateExecuting) {
6031                 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
6032                         asString((OMX_COMMANDTYPE)data1), data1,
6033                         asString((OMX_STATETYPE)data2), data2);
6034                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6035                 return true;
6036             }
6037 
6038             mCodec->mExecutingState->resume();
6039             mCodec->changeState(mCodec->mExecutingState);
6040 
6041             return true;
6042         }
6043 
6044         default:
6045             return BaseState::onOMXEvent(event, data1, data2);
6046     }
6047 }
6048 
6049 ////////////////////////////////////////////////////////////////////////////////
6050 
ExecutingState(ACodec * codec)6051 ACodec::ExecutingState::ExecutingState(ACodec *codec)
6052     : BaseState(codec),
6053       mActive(false) {
6054 }
6055 
getPortMode(OMX_U32)6056 ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6057         OMX_U32 /* portIndex */) {
6058     return RESUBMIT_BUFFERS;
6059 }
6060 
submitOutputMetaBuffers()6061 void ACodec::ExecutingState::submitOutputMetaBuffers() {
6062     // submit as many buffers as there are input buffers with the codec
6063     // in case we are in port reconfiguring
6064     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6065         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6066 
6067         if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6068             if (mCodec->submitOutputMetadataBuffer() != OK)
6069                 break;
6070         }
6071     }
6072 
6073     // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6074     mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6075 }
6076 
submitRegularOutputBuffers()6077 void ACodec::ExecutingState::submitRegularOutputBuffers() {
6078     bool failed = false;
6079     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6080         BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6081 
6082         if (mCodec->mNativeWindow != NULL) {
6083             if (info->mStatus != BufferInfo::OWNED_BY_US
6084                     && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6085                 ALOGE("buffers should be owned by us or the surface");
6086                 failed = true;
6087                 break;
6088             }
6089 
6090             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6091                 continue;
6092             }
6093         } else {
6094             if (info->mStatus != BufferInfo::OWNED_BY_US) {
6095                 ALOGE("buffers should be owned by us");
6096                 failed = true;
6097                 break;
6098             }
6099         }
6100 
6101         ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6102 
6103         info->checkWriteFence("submitRegularOutputBuffers");
6104         status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
6105         info->mFenceFd = -1;
6106         if (err != OK) {
6107             failed = true;
6108             break;
6109         }
6110 
6111         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6112     }
6113 
6114     if (failed) {
6115         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6116     }
6117 }
6118 
submitOutputBuffers()6119 void ACodec::ExecutingState::submitOutputBuffers() {
6120     submitRegularOutputBuffers();
6121     if (mCodec->storingMetadataInDecodedBuffers()) {
6122         submitOutputMetaBuffers();
6123     }
6124 }
6125 
resume()6126 void ACodec::ExecutingState::resume() {
6127     if (mActive) {
6128         ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6129         return;
6130     }
6131 
6132     submitOutputBuffers();
6133 
6134     // Post all available input buffers
6135     if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6136         ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6137     }
6138 
6139     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
6140         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6141         if (info->mStatus == BufferInfo::OWNED_BY_US) {
6142             postFillThisBuffer(info);
6143         }
6144     }
6145 
6146     mActive = true;
6147 }
6148 
stateEntered()6149 void ACodec::ExecutingState::stateEntered() {
6150     ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6151 
6152     mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6153     mCodec->processDeferredMessages();
6154 }
6155 
onMessageReceived(const sp<AMessage> & msg)6156 bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6157     bool handled = false;
6158 
6159     switch (msg->what()) {
6160         case kWhatShutdown:
6161         {
6162             int32_t keepComponentAllocated;
6163             CHECK(msg->findInt32(
6164                         "keepComponentAllocated", &keepComponentAllocated));
6165 
6166             mCodec->mShutdownInProgress = true;
6167             mCodec->mExplicitShutdown = true;
6168             mCodec->mKeepComponentAllocated = keepComponentAllocated;
6169 
6170             mActive = false;
6171 
6172             status_t err = mCodec->mOMX->sendCommand(
6173                     mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
6174             if (err != OK) {
6175                 if (keepComponentAllocated) {
6176                     mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6177                 }
6178                 // TODO: do some recovery here.
6179             } else {
6180                 mCodec->changeState(mCodec->mExecutingToIdleState);
6181             }
6182 
6183             handled = true;
6184             break;
6185         }
6186 
6187         case kWhatFlush:
6188         {
6189             ALOGV("[%s] ExecutingState flushing now "
6190                  "(codec owns %zu/%zu input, %zu/%zu output).",
6191                     mCodec->mComponentName.c_str(),
6192                     mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6193                     mCodec->mBuffers[kPortIndexInput].size(),
6194                     mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6195                     mCodec->mBuffers[kPortIndexOutput].size());
6196 
6197             mActive = false;
6198 
6199             status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
6200             if (err != OK) {
6201                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6202             } else {
6203                 mCodec->changeState(mCodec->mFlushingState);
6204             }
6205 
6206             handled = true;
6207             break;
6208         }
6209 
6210         case kWhatResume:
6211         {
6212             resume();
6213 
6214             handled = true;
6215             break;
6216         }
6217 
6218         case kWhatRequestIDRFrame:
6219         {
6220             status_t err = mCodec->requestIDRFrame();
6221             if (err != OK) {
6222                 ALOGW("Requesting an IDR frame failed.");
6223             }
6224 
6225             handled = true;
6226             break;
6227         }
6228 
6229         case kWhatSetParameters:
6230         {
6231             sp<AMessage> params;
6232             CHECK(msg->findMessage("params", &params));
6233 
6234             status_t err = mCodec->setParameters(params);
6235 
6236             sp<AMessage> reply;
6237             if (msg->findMessage("reply", &reply)) {
6238                 reply->setInt32("err", err);
6239                 reply->post();
6240             }
6241 
6242             handled = true;
6243             break;
6244         }
6245 
6246         case ACodec::kWhatSignalEndOfInputStream:
6247         {
6248             mCodec->onSignalEndOfInputStream();
6249             handled = true;
6250             break;
6251         }
6252 
6253         // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6254         case kWhatSubmitOutputMetadataBufferIfEOS:
6255         {
6256             if (mCodec->mPortEOS[kPortIndexInput] &&
6257                     !mCodec->mPortEOS[kPortIndexOutput]) {
6258                 status_t err = mCodec->submitOutputMetadataBuffer();
6259                 if (err == OK) {
6260                     mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6261                 }
6262             }
6263             return true;
6264         }
6265 
6266         default:
6267             handled = BaseState::onMessageReceived(msg);
6268             break;
6269     }
6270 
6271     return handled;
6272 }
6273 
setParameters(const sp<AMessage> & params)6274 status_t ACodec::setParameters(const sp<AMessage> &params) {
6275     int32_t videoBitrate;
6276     if (params->findInt32("video-bitrate", &videoBitrate)) {
6277         OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6278         InitOMXParams(&configParams);
6279         configParams.nPortIndex = kPortIndexOutput;
6280         configParams.nEncodeBitrate = videoBitrate;
6281 
6282         status_t err = mOMX->setConfig(
6283                 mNode,
6284                 OMX_IndexConfigVideoBitrate,
6285                 &configParams,
6286                 sizeof(configParams));
6287 
6288         if (err != OK) {
6289             ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6290                    videoBitrate, err);
6291 
6292             return err;
6293         }
6294     }
6295 
6296     int64_t skipFramesBeforeUs;
6297     if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
6298         status_t err =
6299             mOMX->setInternalOption(
6300                      mNode,
6301                      kPortIndexInput,
6302                      IOMX::INTERNAL_OPTION_START_TIME,
6303                      &skipFramesBeforeUs,
6304                      sizeof(skipFramesBeforeUs));
6305 
6306         if (err != OK) {
6307             ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
6308             return err;
6309         }
6310     }
6311 
6312     int32_t dropInputFrames;
6313     if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6314         bool suspend = dropInputFrames != 0;
6315 
6316         status_t err =
6317             mOMX->setInternalOption(
6318                      mNode,
6319                      kPortIndexInput,
6320                      IOMX::INTERNAL_OPTION_SUSPEND,
6321                      &suspend,
6322                      sizeof(suspend));
6323 
6324         if (err != OK) {
6325             ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6326             return err;
6327         }
6328     }
6329 
6330     int32_t dummy;
6331     if (params->findInt32("request-sync", &dummy)) {
6332         status_t err = requestIDRFrame();
6333 
6334         if (err != OK) {
6335             ALOGE("Requesting a sync frame failed w/ err %d", err);
6336             return err;
6337         }
6338     }
6339 
6340     float rate;
6341     if (params->findFloat("operating-rate", &rate) && rate > 0) {
6342         status_t err = setOperatingRate(rate, mIsVideo);
6343         if (err != OK) {
6344             ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
6345             return err;
6346         }
6347     }
6348 
6349     return OK;
6350 }
6351 
onSignalEndOfInputStream()6352 void ACodec::onSignalEndOfInputStream() {
6353     sp<AMessage> notify = mNotify->dup();
6354     notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
6355 
6356     status_t err = mOMX->signalEndOfInputStream(mNode);
6357     if (err != OK) {
6358         notify->setInt32("err", err);
6359     }
6360     notify->post();
6361 }
6362 
onOMXFrameRendered(int64_t mediaTimeUs,nsecs_t systemNano)6363 bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
6364     mCodec->onFrameRendered(mediaTimeUs, systemNano);
6365     return true;
6366 }
6367 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6368 bool ACodec::ExecutingState::onOMXEvent(
6369         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6370     switch (event) {
6371         case OMX_EventPortSettingsChanged:
6372         {
6373             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6374 
6375             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6376                 mCodec->mMetadataBuffersToSubmit = 0;
6377                 CHECK_EQ(mCodec->mOMX->sendCommand(
6378                             mCodec->mNode,
6379                             OMX_CommandPortDisable, kPortIndexOutput),
6380                          (status_t)OK);
6381 
6382                 mCodec->freeOutputBuffersNotOwnedByComponent();
6383 
6384                 mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
6385             } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
6386                 mCodec->mSentFormat = false;
6387 
6388                 if (mCodec->mTunneled) {
6389                     sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec);
6390                     mCodec->sendFormatChange(dummy);
6391                 }
6392             } else {
6393                 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6394                      mCodec->mComponentName.c_str(), data2);
6395             }
6396 
6397             return true;
6398         }
6399 
6400         case OMX_EventBufferFlag:
6401         {
6402             return true;
6403         }
6404 
6405         default:
6406             return BaseState::onOMXEvent(event, data1, data2);
6407     }
6408 }
6409 
6410 ////////////////////////////////////////////////////////////////////////////////
6411 
OutputPortSettingsChangedState(ACodec * codec)6412 ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6413         ACodec *codec)
6414     : BaseState(codec) {
6415 }
6416 
getPortMode(OMX_U32 portIndex)6417 ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6418         OMX_U32 portIndex) {
6419     if (portIndex == kPortIndexOutput) {
6420         return FREE_BUFFERS;
6421     }
6422 
6423     CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6424 
6425     return RESUBMIT_BUFFERS;
6426 }
6427 
onMessageReceived(const sp<AMessage> & msg)6428 bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6429         const sp<AMessage> &msg) {
6430     bool handled = false;
6431 
6432     switch (msg->what()) {
6433         case kWhatFlush:
6434         case kWhatShutdown:
6435         case kWhatResume:
6436         case kWhatSetParameters:
6437         {
6438             if (msg->what() == kWhatResume) {
6439                 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6440             }
6441 
6442             mCodec->deferMessage(msg);
6443             handled = true;
6444             break;
6445         }
6446 
6447         default:
6448             handled = BaseState::onMessageReceived(msg);
6449             break;
6450     }
6451 
6452     return handled;
6453 }
6454 
stateEntered()6455 void ACodec::OutputPortSettingsChangedState::stateEntered() {
6456     ALOGV("[%s] Now handling output port settings change",
6457          mCodec->mComponentName.c_str());
6458 }
6459 
onOMXFrameRendered(int64_t mediaTimeUs,nsecs_t systemNano)6460 bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
6461         int64_t mediaTimeUs, nsecs_t systemNano) {
6462     mCodec->onFrameRendered(mediaTimeUs, systemNano);
6463     return true;
6464 }
6465 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6466 bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6467         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6468     switch (event) {
6469         case OMX_EventCmdComplete:
6470         {
6471             if (data1 == (OMX_U32)OMX_CommandPortDisable) {
6472                 if (data2 != (OMX_U32)kPortIndexOutput) {
6473                     ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
6474                     return false;
6475                 }
6476 
6477                 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6478 
6479                 status_t err = OK;
6480                 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
6481                     ALOGE("disabled port should be empty, but has %zu buffers",
6482                             mCodec->mBuffers[kPortIndexOutput].size());
6483                     err = FAILED_TRANSACTION;
6484                 } else {
6485                     mCodec->mDealer[kPortIndexOutput].clear();
6486                 }
6487 
6488                 if (err == OK) {
6489                     err = mCodec->mOMX->sendCommand(
6490                             mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
6491                 }
6492 
6493                 if (err == OK) {
6494                     err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6495                     ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
6496                             "reconfiguration: (%d)", err);
6497                 }
6498 
6499                 if (err != OK) {
6500                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6501 
6502                     // This is technically not correct, but appears to be
6503                     // the only way to free the component instance.
6504                     // Controlled transitioning from excecuting->idle
6505                     // and idle->loaded seem impossible probably because
6506                     // the output port never finishes re-enabling.
6507                     mCodec->mShutdownInProgress = true;
6508                     mCodec->mKeepComponentAllocated = false;
6509                     mCodec->changeState(mCodec->mLoadedState);
6510                 }
6511 
6512                 return true;
6513             } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6514                 if (data2 != (OMX_U32)kPortIndexOutput) {
6515                     ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6516                     return false;
6517                 }
6518 
6519                 mCodec->mSentFormat = false;
6520 
6521                 if (mCodec->mTunneled) {
6522                     sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec);
6523                     mCodec->sendFormatChange(dummy);
6524                 }
6525 
6526                 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6527 
6528                 if (mCodec->mExecutingState->active()) {
6529                     mCodec->mExecutingState->submitOutputBuffers();
6530                 }
6531 
6532                 mCodec->changeState(mCodec->mExecutingState);
6533 
6534                 return true;
6535             }
6536 
6537             return false;
6538         }
6539 
6540         default:
6541             return false;
6542     }
6543 }
6544 
6545 ////////////////////////////////////////////////////////////////////////////////
6546 
ExecutingToIdleState(ACodec * codec)6547 ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
6548     : BaseState(codec),
6549       mComponentNowIdle(false) {
6550 }
6551 
onMessageReceived(const sp<AMessage> & msg)6552 bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6553     bool handled = false;
6554 
6555     switch (msg->what()) {
6556         case kWhatFlush:
6557         {
6558             // Don't send me a flush request if you previously wanted me
6559             // to shutdown.
6560             ALOGW("Ignoring flush request in ExecutingToIdleState");
6561             break;
6562         }
6563 
6564         case kWhatShutdown:
6565         {
6566             // We're already doing that...
6567 
6568             handled = true;
6569             break;
6570         }
6571 
6572         default:
6573             handled = BaseState::onMessageReceived(msg);
6574             break;
6575     }
6576 
6577     return handled;
6578 }
6579 
stateEntered()6580 void ACodec::ExecutingToIdleState::stateEntered() {
6581     ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
6582 
6583     mComponentNowIdle = false;
6584     mCodec->mSentFormat = false;
6585 }
6586 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6587 bool ACodec::ExecutingToIdleState::onOMXEvent(
6588         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6589     switch (event) {
6590         case OMX_EventCmdComplete:
6591         {
6592             if (data1 != (OMX_U32)OMX_CommandStateSet
6593                     || data2 != (OMX_U32)OMX_StateIdle) {
6594                 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
6595                         asString((OMX_COMMANDTYPE)data1), data1,
6596                         asString((OMX_STATETYPE)data2), data2);
6597                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6598                 return true;
6599             }
6600 
6601             mComponentNowIdle = true;
6602 
6603             changeStateIfWeOwnAllBuffers();
6604 
6605             return true;
6606         }
6607 
6608         case OMX_EventPortSettingsChanged:
6609         case OMX_EventBufferFlag:
6610         {
6611             // We're shutting down and don't care about this anymore.
6612             return true;
6613         }
6614 
6615         default:
6616             return BaseState::onOMXEvent(event, data1, data2);
6617     }
6618 }
6619 
changeStateIfWeOwnAllBuffers()6620 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
6621     if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6622         status_t err = mCodec->mOMX->sendCommand(
6623                 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6624         if (err == OK) {
6625             err = mCodec->freeBuffersOnPort(kPortIndexInput);
6626             status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
6627             if (err == OK) {
6628                 err = err2;
6629             }
6630         }
6631 
6632         if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
6633                 && mCodec->mNativeWindow != NULL) {
6634             // We push enough 1x1 blank buffers to ensure that one of
6635             // them has made it to the display.  This allows the OMX
6636             // component teardown to zero out any protected buffers
6637             // without the risk of scanning out one of those buffers.
6638             pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6639         }
6640 
6641         if (err != OK) {
6642             mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6643             return;
6644         }
6645 
6646         mCodec->changeState(mCodec->mIdleToLoadedState);
6647     }
6648 }
6649 
onInputBufferFilled(const sp<AMessage> & msg)6650 void ACodec::ExecutingToIdleState::onInputBufferFilled(
6651         const sp<AMessage> &msg) {
6652     BaseState::onInputBufferFilled(msg);
6653 
6654     changeStateIfWeOwnAllBuffers();
6655 }
6656 
onOutputBufferDrained(const sp<AMessage> & msg)6657 void ACodec::ExecutingToIdleState::onOutputBufferDrained(
6658         const sp<AMessage> &msg) {
6659     BaseState::onOutputBufferDrained(msg);
6660 
6661     changeStateIfWeOwnAllBuffers();
6662 }
6663 
6664 ////////////////////////////////////////////////////////////////////////////////
6665 
IdleToLoadedState(ACodec * codec)6666 ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6667     : BaseState(codec) {
6668 }
6669 
onMessageReceived(const sp<AMessage> & msg)6670 bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6671     bool handled = false;
6672 
6673     switch (msg->what()) {
6674         case kWhatShutdown:
6675         {
6676             // We're already doing that...
6677 
6678             handled = true;
6679             break;
6680         }
6681 
6682         case kWhatFlush:
6683         {
6684             // Don't send me a flush request if you previously wanted me
6685             // to shutdown.
6686             ALOGE("Got flush request in IdleToLoadedState");
6687             break;
6688         }
6689 
6690         default:
6691             handled = BaseState::onMessageReceived(msg);
6692             break;
6693     }
6694 
6695     return handled;
6696 }
6697 
stateEntered()6698 void ACodec::IdleToLoadedState::stateEntered() {
6699     ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6700 }
6701 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6702 bool ACodec::IdleToLoadedState::onOMXEvent(
6703         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6704     switch (event) {
6705         case OMX_EventCmdComplete:
6706         {
6707             if (data1 != (OMX_U32)OMX_CommandStateSet
6708                     || data2 != (OMX_U32)OMX_StateLoaded) {
6709                 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
6710                         asString((OMX_COMMANDTYPE)data1), data1,
6711                         asString((OMX_STATETYPE)data2), data2);
6712                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6713                 return true;
6714             }
6715 
6716             mCodec->changeState(mCodec->mLoadedState);
6717 
6718             return true;
6719         }
6720 
6721         default:
6722             return BaseState::onOMXEvent(event, data1, data2);
6723     }
6724 }
6725 
6726 ////////////////////////////////////////////////////////////////////////////////
6727 
FlushingState(ACodec * codec)6728 ACodec::FlushingState::FlushingState(ACodec *codec)
6729     : BaseState(codec) {
6730 }
6731 
stateEntered()6732 void ACodec::FlushingState::stateEntered() {
6733     ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6734 
6735     mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6736 }
6737 
onMessageReceived(const sp<AMessage> & msg)6738 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6739     bool handled = false;
6740 
6741     switch (msg->what()) {
6742         case kWhatShutdown:
6743         {
6744             mCodec->deferMessage(msg);
6745             break;
6746         }
6747 
6748         case kWhatFlush:
6749         {
6750             // We're already doing this right now.
6751             handled = true;
6752             break;
6753         }
6754 
6755         default:
6756             handled = BaseState::onMessageReceived(msg);
6757             break;
6758     }
6759 
6760     return handled;
6761 }
6762 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)6763 bool ACodec::FlushingState::onOMXEvent(
6764         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6765     ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6766             mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6767 
6768     switch (event) {
6769         case OMX_EventCmdComplete:
6770         {
6771             if (data1 != (OMX_U32)OMX_CommandFlush) {
6772                 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
6773                         asString((OMX_COMMANDTYPE)data1), data1, data2);
6774                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6775                 return true;
6776             }
6777 
6778             if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6779                 if (mFlushComplete[data2]) {
6780                     ALOGW("Flush already completed for %s port",
6781                             data2 == kPortIndexInput ? "input" : "output");
6782                     return true;
6783                 }
6784                 mFlushComplete[data2] = true;
6785 
6786                 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6787                     changeStateIfWeOwnAllBuffers();
6788                 }
6789             } else if (data2 == OMX_ALL) {
6790                 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6791                     ALOGW("received flush complete event for OMX_ALL before ports have been"
6792                             "flushed (%d/%d)",
6793                             mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6794                     return false;
6795                 }
6796 
6797                 changeStateIfWeOwnAllBuffers();
6798             } else {
6799                 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6800             }
6801 
6802             return true;
6803         }
6804 
6805         case OMX_EventPortSettingsChanged:
6806         {
6807             sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6808             msg->setInt32("type", omx_message::EVENT);
6809             msg->setInt32("node", mCodec->mNode);
6810             msg->setInt32("event", event);
6811             msg->setInt32("data1", data1);
6812             msg->setInt32("data2", data2);
6813 
6814             ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6815                  mCodec->mComponentName.c_str());
6816 
6817             mCodec->deferMessage(msg);
6818 
6819             return true;
6820         }
6821 
6822         default:
6823             return BaseState::onOMXEvent(event, data1, data2);
6824     }
6825 
6826     return true;
6827 }
6828 
onOutputBufferDrained(const sp<AMessage> & msg)6829 void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6830     BaseState::onOutputBufferDrained(msg);
6831 
6832     changeStateIfWeOwnAllBuffers();
6833 }
6834 
onInputBufferFilled(const sp<AMessage> & msg)6835 void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6836     BaseState::onInputBufferFilled(msg);
6837 
6838     changeStateIfWeOwnAllBuffers();
6839 }
6840 
changeStateIfWeOwnAllBuffers()6841 void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6842     if (mFlushComplete[kPortIndexInput]
6843             && mFlushComplete[kPortIndexOutput]
6844             && mCodec->allYourBuffersAreBelongToUs()) {
6845         // We now own all buffers except possibly those still queued with
6846         // the native window for rendering. Let's get those back as well.
6847         mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
6848 
6849         mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6850 
6851         sp<AMessage> notify = mCodec->mNotify->dup();
6852         notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6853         notify->post();
6854 
6855         mCodec->mPortEOS[kPortIndexInput] =
6856             mCodec->mPortEOS[kPortIndexOutput] = false;
6857 
6858         mCodec->mInputEOSResult = OK;
6859 
6860         if (mCodec->mSkipCutBuffer != NULL) {
6861             mCodec->mSkipCutBuffer->clear();
6862         }
6863 
6864         mCodec->changeState(mCodec->mExecutingState);
6865     }
6866 }
6867 
6868 }  // namespace android
6869