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