• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "ACodec"
19 
20 #include <media/stagefright/ACodec.h>
21 
22 #include <binder/MemoryDealer.h>
23 
24 #include <media/stagefright/foundation/hexdump.h>
25 #include <media/stagefright/foundation/ABuffer.h>
26 #include <media/stagefright/foundation/ADebug.h>
27 #include <media/stagefright/foundation/AMessage.h>
28 
29 #include <media/stagefright/BufferProducerWrapper.h>
30 #include <media/stagefright/MediaCodecList.h>
31 #include <media/stagefright/MediaDefs.h>
32 #include <media/stagefright/NativeWindowWrapper.h>
33 #include <media/stagefright/OMXClient.h>
34 #include <media/stagefright/OMXCodec.h>
35 
36 #include <media/hardware/HardwareAPI.h>
37 
38 #include <OMX_Component.h>
39 
40 #include "include/avc_utils.h"
41 
42 namespace android {
43 
44 template<class T>
InitOMXParams(T * params)45 static void InitOMXParams(T *params) {
46     params->nSize = sizeof(T);
47     params->nVersion.s.nVersionMajor = 1;
48     params->nVersion.s.nVersionMinor = 0;
49     params->nVersion.s.nRevision = 0;
50     params->nVersion.s.nStep = 0;
51 }
52 
53 struct CodecObserver : public BnOMXObserver {
CodecObserverandroid::CodecObserver54     CodecObserver() {}
55 
setNotificationMessageandroid::CodecObserver56     void setNotificationMessage(const sp<AMessage> &msg) {
57         mNotify = msg;
58     }
59 
60     // from IOMXObserver
onMessageandroid::CodecObserver61     virtual void onMessage(const omx_message &omx_msg) {
62         sp<AMessage> msg = mNotify->dup();
63 
64         msg->setInt32("type", omx_msg.type);
65         msg->setPointer("node", omx_msg.node);
66 
67         switch (omx_msg.type) {
68             case omx_message::EVENT:
69             {
70                 msg->setInt32("event", omx_msg.u.event_data.event);
71                 msg->setInt32("data1", omx_msg.u.event_data.data1);
72                 msg->setInt32("data2", omx_msg.u.event_data.data2);
73                 break;
74             }
75 
76             case omx_message::EMPTY_BUFFER_DONE:
77             {
78                 msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79                 break;
80             }
81 
82             case omx_message::FILL_BUFFER_DONE:
83             {
84                 msg->setPointer(
85                         "buffer", omx_msg.u.extended_buffer_data.buffer);
86                 msg->setInt32(
87                         "range_offset",
88                         omx_msg.u.extended_buffer_data.range_offset);
89                 msg->setInt32(
90                         "range_length",
91                         omx_msg.u.extended_buffer_data.range_length);
92                 msg->setInt32(
93                         "flags",
94                         omx_msg.u.extended_buffer_data.flags);
95                 msg->setInt64(
96                         "timestamp",
97                         omx_msg.u.extended_buffer_data.timestamp);
98                 msg->setPointer(
99                         "platform_private",
100                         omx_msg.u.extended_buffer_data.platform_private);
101                 msg->setPointer(
102                         "data_ptr",
103                         omx_msg.u.extended_buffer_data.data_ptr);
104                 break;
105             }
106 
107             default:
108                 TRESPASS();
109                 break;
110         }
111 
112         msg->post();
113     }
114 
115 protected:
~CodecObserverandroid::CodecObserver116     virtual ~CodecObserver() {}
117 
118 private:
119     sp<AMessage> mNotify;
120 
121     DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122 };
123 
124 ////////////////////////////////////////////////////////////////////////////////
125 
126 struct ACodec::BaseState : public AState {
127     BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128 
129 protected:
130     enum PortMode {
131         KEEP_BUFFERS,
132         RESUBMIT_BUFFERS,
133         FREE_BUFFERS,
134     };
135 
136     ACodec *mCodec;
137 
138     virtual PortMode getPortMode(OMX_U32 portIndex);
139 
140     virtual bool onMessageReceived(const sp<AMessage> &msg);
141 
142     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143 
144     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145     virtual void onInputBufferFilled(const sp<AMessage> &msg);
146 
147     void postFillThisBuffer(BufferInfo *info);
148 
149 private:
150     bool onOMXMessage(const sp<AMessage> &msg);
151 
152     bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153 
154     bool onOMXFillBufferDone(
155             IOMX::buffer_id bufferID,
156             size_t rangeOffset, size_t rangeLength,
157             OMX_U32 flags,
158             int64_t timeUs,
159             void *platformPrivate,
160             void *dataPtr);
161 
162     void getMoreInputDataIfPossible();
163 
164     DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165 };
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 
169 struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
DeathNotifierandroid::ACodec::DeathNotifier170     DeathNotifier(const sp<AMessage> &notify)
171         : mNotify(notify) {
172     }
173 
binderDiedandroid::ACodec::DeathNotifier174     virtual void binderDied(const wp<IBinder> &) {
175         mNotify->post();
176     }
177 
178 protected:
~DeathNotifierandroid::ACodec::DeathNotifier179     virtual ~DeathNotifier() {}
180 
181 private:
182     sp<AMessage> mNotify;
183 
184     DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185 };
186 
187 struct ACodec::UninitializedState : public ACodec::BaseState {
188     UninitializedState(ACodec *codec);
189 
190 protected:
191     virtual bool onMessageReceived(const sp<AMessage> &msg);
192     virtual void stateEntered();
193 
194 private:
195     void onSetup(const sp<AMessage> &msg);
196     bool onAllocateComponent(const sp<AMessage> &msg);
197 
198     sp<DeathNotifier> mDeathNotifier;
199 
200     DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201 };
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 
205 struct ACodec::LoadedState : public ACodec::BaseState {
206     LoadedState(ACodec *codec);
207 
208 protected:
209     virtual bool onMessageReceived(const sp<AMessage> &msg);
210     virtual void stateEntered();
211 
212 private:
213     friend struct ACodec::UninitializedState;
214 
215     bool onConfigureComponent(const sp<AMessage> &msg);
216     void onCreateInputSurface(const sp<AMessage> &msg);
217     void onStart();
218     void onShutdown(bool keepComponentAllocated);
219 
220     DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221 };
222 
223 ////////////////////////////////////////////////////////////////////////////////
224 
225 struct ACodec::LoadedToIdleState : public ACodec::BaseState {
226     LoadedToIdleState(ACodec *codec);
227 
228 protected:
229     virtual bool onMessageReceived(const sp<AMessage> &msg);
230     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231     virtual void stateEntered();
232 
233 private:
234     status_t allocateBuffers();
235 
236     DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237 };
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 
241 struct ACodec::IdleToExecutingState : public ACodec::BaseState {
242     IdleToExecutingState(ACodec *codec);
243 
244 protected:
245     virtual bool onMessageReceived(const sp<AMessage> &msg);
246     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247     virtual void stateEntered();
248 
249 private:
250     DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251 };
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 
255 struct ACodec::ExecutingState : public ACodec::BaseState {
256     ExecutingState(ACodec *codec);
257 
258     void submitOutputBuffers();
259 
260     // Submit output buffers to the decoder, submit input buffers to client
261     // to fill with data.
262     void resume();
263 
264     // Returns true iff input and output buffers are in play.
activeandroid::ACodec::ExecutingState265     bool active() const { return mActive; }
266 
267 protected:
268     virtual PortMode getPortMode(OMX_U32 portIndex);
269     virtual bool onMessageReceived(const sp<AMessage> &msg);
270     virtual void stateEntered();
271 
272     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
273 
274 private:
275     bool mActive;
276 
277     DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
278 };
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 
282 struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
283     OutputPortSettingsChangedState(ACodec *codec);
284 
285 protected:
286     virtual PortMode getPortMode(OMX_U32 portIndex);
287     virtual bool onMessageReceived(const sp<AMessage> &msg);
288     virtual void stateEntered();
289 
290     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
291 
292 private:
293     DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
294 };
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 
298 struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
299     ExecutingToIdleState(ACodec *codec);
300 
301 protected:
302     virtual bool onMessageReceived(const sp<AMessage> &msg);
303     virtual void stateEntered();
304 
305     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
306 
307     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
308     virtual void onInputBufferFilled(const sp<AMessage> &msg);
309 
310 private:
311     void changeStateIfWeOwnAllBuffers();
312 
313     bool mComponentNowIdle;
314 
315     DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
316 };
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 
320 struct ACodec::IdleToLoadedState : public ACodec::BaseState {
321     IdleToLoadedState(ACodec *codec);
322 
323 protected:
324     virtual bool onMessageReceived(const sp<AMessage> &msg);
325     virtual void stateEntered();
326 
327     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
328 
329 private:
330     DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
331 };
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 
335 struct ACodec::FlushingState : public ACodec::BaseState {
336     FlushingState(ACodec *codec);
337 
338 protected:
339     virtual bool onMessageReceived(const sp<AMessage> &msg);
340     virtual void stateEntered();
341 
342     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
343 
344     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
345     virtual void onInputBufferFilled(const sp<AMessage> &msg);
346 
347 private:
348     bool mFlushComplete[2];
349 
350     void changeStateIfWeOwnAllBuffers();
351 
352     DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
353 };
354 
355 ////////////////////////////////////////////////////////////////////////////////
356 
ACodec()357 ACodec::ACodec()
358     : mQuirks(0),
359       mNode(NULL),
360       mSentFormat(false),
361       mIsEncoder(false),
362       mShutdownInProgress(false),
363       mEncoderDelay(0),
364       mEncoderPadding(0),
365       mChannelMaskPresent(false),
366       mChannelMask(0) {
367     mUninitializedState = new UninitializedState(this);
368     mLoadedState = new LoadedState(this);
369     mLoadedToIdleState = new LoadedToIdleState(this);
370     mIdleToExecutingState = new IdleToExecutingState(this);
371     mExecutingState = new ExecutingState(this);
372 
373     mOutputPortSettingsChangedState =
374         new OutputPortSettingsChangedState(this);
375 
376     mExecutingToIdleState = new ExecutingToIdleState(this);
377     mIdleToLoadedState = new IdleToLoadedState(this);
378     mFlushingState = new FlushingState(this);
379 
380     mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
381     mInputEOSResult = OK;
382 
383     changeState(mUninitializedState);
384 }
385 
~ACodec()386 ACodec::~ACodec() {
387 }
388 
setNotificationMessage(const sp<AMessage> & msg)389 void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
390     mNotify = msg;
391 }
392 
initiateSetup(const sp<AMessage> & msg)393 void ACodec::initiateSetup(const sp<AMessage> &msg) {
394     msg->setWhat(kWhatSetup);
395     msg->setTarget(id());
396     msg->post();
397 }
398 
signalSetParameters(const sp<AMessage> & params)399 void ACodec::signalSetParameters(const sp<AMessage> &params) {
400     sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
401     msg->setMessage("params", params);
402     msg->post();
403 }
404 
initiateAllocateComponent(const sp<AMessage> & msg)405 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
406     msg->setWhat(kWhatAllocateComponent);
407     msg->setTarget(id());
408     msg->post();
409 }
410 
initiateConfigureComponent(const sp<AMessage> & msg)411 void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
412     msg->setWhat(kWhatConfigureComponent);
413     msg->setTarget(id());
414     msg->post();
415 }
416 
initiateCreateInputSurface()417 void ACodec::initiateCreateInputSurface() {
418     (new AMessage(kWhatCreateInputSurface, id()))->post();
419 }
420 
signalEndOfInputStream()421 void ACodec::signalEndOfInputStream() {
422     (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
423 }
424 
initiateStart()425 void ACodec::initiateStart() {
426     (new AMessage(kWhatStart, id()))->post();
427 }
428 
signalFlush()429 void ACodec::signalFlush() {
430     ALOGV("[%s] signalFlush", mComponentName.c_str());
431     (new AMessage(kWhatFlush, id()))->post();
432 }
433 
signalResume()434 void ACodec::signalResume() {
435     (new AMessage(kWhatResume, id()))->post();
436 }
437 
initiateShutdown(bool keepComponentAllocated)438 void ACodec::initiateShutdown(bool keepComponentAllocated) {
439     sp<AMessage> msg = new AMessage(kWhatShutdown, id());
440     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
441     msg->post();
442 }
443 
signalRequestIDRFrame()444 void ACodec::signalRequestIDRFrame() {
445     (new AMessage(kWhatRequestIDRFrame, id()))->post();
446 }
447 
allocateBuffersOnPort(OMX_U32 portIndex)448 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
449     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
450 
451     CHECK(mDealer[portIndex] == NULL);
452     CHECK(mBuffers[portIndex].isEmpty());
453 
454     status_t err;
455     if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
456         err = allocateOutputBuffersFromNativeWindow();
457     } else {
458         OMX_PARAM_PORTDEFINITIONTYPE def;
459         InitOMXParams(&def);
460         def.nPortIndex = portIndex;
461 
462         err = mOMX->getParameter(
463                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
464 
465         if (err == OK) {
466             ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
467                     mComponentName.c_str(),
468                     def.nBufferCountActual, def.nBufferSize,
469                     portIndex == kPortIndexInput ? "input" : "output");
470 
471             size_t totalSize = def.nBufferCountActual * def.nBufferSize;
472             mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
473 
474             for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
475                 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
476                 CHECK(mem.get() != NULL);
477 
478                 BufferInfo info;
479                 info.mStatus = BufferInfo::OWNED_BY_US;
480 
481                 uint32_t requiresAllocateBufferBit =
482                     (portIndex == kPortIndexInput)
483                         ? OMXCodec::kRequiresAllocateBufferOnInputPorts
484                         : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
485 
486                 if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
487                     mem.clear();
488 
489                     void *ptr;
490                     err = mOMX->allocateBuffer(
491                             mNode, portIndex, def.nBufferSize, &info.mBufferID,
492                             &ptr);
493 
494                     info.mData = new ABuffer(ptr, def.nBufferSize);
495                 } else if (mQuirks & requiresAllocateBufferBit) {
496                     err = mOMX->allocateBufferWithBackup(
497                             mNode, portIndex, mem, &info.mBufferID);
498                 } else {
499                     err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
500                 }
501 
502                 if (mem != NULL) {
503                     info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
504                 }
505 
506                 mBuffers[portIndex].push(info);
507             }
508         }
509     }
510 
511     if (err != OK) {
512         return err;
513     }
514 
515     sp<AMessage> notify = mNotify->dup();
516     notify->setInt32("what", ACodec::kWhatBuffersAllocated);
517 
518     notify->setInt32("portIndex", portIndex);
519 
520     sp<PortDescription> desc = new PortDescription;
521 
522     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
523         const BufferInfo &info = mBuffers[portIndex][i];
524 
525         desc->addBuffer(info.mBufferID, info.mData);
526     }
527 
528     notify->setObject("portDesc", desc);
529     notify->post();
530 
531     return OK;
532 }
533 
allocateOutputBuffersFromNativeWindow()534 status_t ACodec::allocateOutputBuffersFromNativeWindow() {
535     OMX_PARAM_PORTDEFINITIONTYPE def;
536     InitOMXParams(&def);
537     def.nPortIndex = kPortIndexOutput;
538 
539     status_t err = mOMX->getParameter(
540             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
541 
542     if (err != OK) {
543         return err;
544     }
545 
546     err = native_window_set_buffers_geometry(
547             mNativeWindow.get(),
548             def.format.video.nFrameWidth,
549             def.format.video.nFrameHeight,
550             def.format.video.eColorFormat);
551 
552     if (err != 0) {
553         ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
554                 strerror(-err), -err);
555         return err;
556     }
557 
558     // Set up the native window.
559     OMX_U32 usage = 0;
560     err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
561     if (err != 0) {
562         ALOGW("querying usage flags from OMX IL component failed: %d", err);
563         // XXX: Currently this error is logged, but not fatal.
564         usage = 0;
565     }
566 
567     if (mFlags & kFlagIsSecure) {
568         usage |= GRALLOC_USAGE_PROTECTED;
569     }
570 
571     // Make sure to check whether either Stagefright or the video decoder
572     // requested protected buffers.
573     if (usage & GRALLOC_USAGE_PROTECTED) {
574         // Verify that the ANativeWindow sends images directly to
575         // SurfaceFlinger.
576         int queuesToNativeWindow = 0;
577         err = mNativeWindow->query(
578                 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
579                 &queuesToNativeWindow);
580         if (err != 0) {
581             ALOGE("error authenticating native window: %d", err);
582             return err;
583         }
584         if (queuesToNativeWindow != 1) {
585             ALOGE("native window could not be authenticated");
586             return PERMISSION_DENIED;
587         }
588     }
589 
590     err = native_window_set_usage(
591             mNativeWindow.get(),
592             usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
593 
594     if (err != 0) {
595         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
596         return err;
597     }
598 
599     int minUndequeuedBufs = 0;
600     err = mNativeWindow->query(
601             mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
602             &minUndequeuedBufs);
603 
604     if (err != 0) {
605         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
606                 strerror(-err), -err);
607         return err;
608     }
609 
610     // XXX: Is this the right logic to use?  It's not clear to me what the OMX
611     // buffer counts refer to - how do they account for the renderer holding on
612     // to buffers?
613     if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
614         OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
615         def.nBufferCountActual = newBufferCount;
616         err = mOMX->setParameter(
617                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
618 
619         if (err != OK) {
620             ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
621                     mComponentName.c_str(), newBufferCount, err);
622             return err;
623         }
624     }
625 
626     err = native_window_set_buffer_count(
627             mNativeWindow.get(), def.nBufferCountActual);
628 
629     if (err != 0) {
630         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
631                 -err);
632         return err;
633     }
634 
635     ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
636          "output port",
637          mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
638 
639     // Dequeue buffers and send them to OMX
640     for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
641         ANativeWindowBuffer *buf;
642         err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
643         if (err != 0) {
644             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
645             break;
646         }
647 
648         sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
649         BufferInfo info;
650         info.mStatus = BufferInfo::OWNED_BY_US;
651         info.mData = new ABuffer(NULL /* data */, def.nBufferSize /* capacity */);
652         info.mGraphicBuffer = graphicBuffer;
653         mBuffers[kPortIndexOutput].push(info);
654 
655         IOMX::buffer_id bufferId;
656         err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
657                 &bufferId);
658         if (err != 0) {
659             ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
660                  "%d", i, err);
661             break;
662         }
663 
664         mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
665 
666         ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
667              mComponentName.c_str(),
668              bufferId, graphicBuffer.get());
669     }
670 
671     OMX_U32 cancelStart;
672     OMX_U32 cancelEnd;
673 
674     if (err != 0) {
675         // If an error occurred while dequeuing we need to cancel any buffers
676         // that were dequeued.
677         cancelStart = 0;
678         cancelEnd = mBuffers[kPortIndexOutput].size();
679     } else {
680         // Return the last two buffers to the native window.
681         cancelStart = def.nBufferCountActual - minUndequeuedBufs;
682         cancelEnd = def.nBufferCountActual;
683     }
684 
685     for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
686         BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
687         cancelBufferToNativeWindow(info);
688     }
689 
690     return err;
691 }
692 
cancelBufferToNativeWindow(BufferInfo * info)693 status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
694     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
695 
696     ALOGV("[%s] Calling cancelBuffer on buffer %p",
697          mComponentName.c_str(), info->mBufferID);
698 
699     int err = mNativeWindow->cancelBuffer(
700         mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
701 
702     CHECK_EQ(err, 0);
703 
704     info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
705 
706     return OK;
707 }
708 
dequeueBufferFromNativeWindow()709 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
710     ANativeWindowBuffer *buf;
711     int fenceFd = -1;
712     if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
713         ALOGE("dequeueBuffer failed.");
714         return NULL;
715     }
716 
717     for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
718         BufferInfo *info =
719             &mBuffers[kPortIndexOutput].editItemAt(i);
720 
721         if (info->mGraphicBuffer->handle == buf->handle) {
722             CHECK_EQ((int)info->mStatus,
723                      (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
724 
725             info->mStatus = BufferInfo::OWNED_BY_US;
726 
727             return info;
728         }
729     }
730 
731     TRESPASS();
732 
733     return NULL;
734 }
735 
freeBuffersOnPort(OMX_U32 portIndex)736 status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
737     for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
738         CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
739     }
740 
741     mDealer[portIndex].clear();
742 
743     return OK;
744 }
745 
freeOutputBuffersNotOwnedByComponent()746 status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
747     for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
748         BufferInfo *info =
749             &mBuffers[kPortIndexOutput].editItemAt(i);
750 
751         // At this time some buffers may still be with the component
752         // or being drained.
753         if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
754             info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
755             CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
756         }
757     }
758 
759     return OK;
760 }
761 
freeBuffer(OMX_U32 portIndex,size_t i)762 status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
763     BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
764 
765     CHECK(info->mStatus == BufferInfo::OWNED_BY_US
766             || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
767 
768     if (portIndex == kPortIndexOutput && mNativeWindow != NULL
769             && info->mStatus == BufferInfo::OWNED_BY_US) {
770         CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
771     }
772 
773     CHECK_EQ(mOMX->freeBuffer(
774                 mNode, portIndex, info->mBufferID),
775              (status_t)OK);
776 
777     mBuffers[portIndex].removeAt(i);
778 
779     return OK;
780 }
781 
findBufferByID(uint32_t portIndex,IOMX::buffer_id bufferID,ssize_t * index)782 ACodec::BufferInfo *ACodec::findBufferByID(
783         uint32_t portIndex, IOMX::buffer_id bufferID,
784         ssize_t *index) {
785     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
786         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
787 
788         if (info->mBufferID == bufferID) {
789             if (index != NULL) {
790                 *index = i;
791             }
792             return info;
793         }
794     }
795 
796     TRESPASS();
797 
798     return NULL;
799 }
800 
setComponentRole(bool isEncoder,const char * mime)801 status_t ACodec::setComponentRole(
802         bool isEncoder, const char *mime) {
803     struct MimeToRole {
804         const char *mime;
805         const char *decoderRole;
806         const char *encoderRole;
807     };
808 
809     static const MimeToRole kMimeToRole[] = {
810         { MEDIA_MIMETYPE_AUDIO_MPEG,
811             "audio_decoder.mp3", "audio_encoder.mp3" },
812         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
813             "audio_decoder.mp1", "audio_encoder.mp1" },
814         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
815             "audio_decoder.mp2", "audio_encoder.mp2" },
816         { MEDIA_MIMETYPE_AUDIO_AMR_NB,
817             "audio_decoder.amrnb", "audio_encoder.amrnb" },
818         { MEDIA_MIMETYPE_AUDIO_AMR_WB,
819             "audio_decoder.amrwb", "audio_encoder.amrwb" },
820         { MEDIA_MIMETYPE_AUDIO_AAC,
821             "audio_decoder.aac", "audio_encoder.aac" },
822         { MEDIA_MIMETYPE_AUDIO_VORBIS,
823             "audio_decoder.vorbis", "audio_encoder.vorbis" },
824         { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
825             "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
826         { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
827             "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
828         { MEDIA_MIMETYPE_VIDEO_AVC,
829             "video_decoder.avc", "video_encoder.avc" },
830         { MEDIA_MIMETYPE_VIDEO_MPEG4,
831             "video_decoder.mpeg4", "video_encoder.mpeg4" },
832         { MEDIA_MIMETYPE_VIDEO_H263,
833             "video_decoder.h263", "video_encoder.h263" },
834         { MEDIA_MIMETYPE_VIDEO_VPX,
835             "video_decoder.vpx", "video_encoder.vpx" },
836         { MEDIA_MIMETYPE_AUDIO_RAW,
837             "audio_decoder.raw", "audio_encoder.raw" },
838         { MEDIA_MIMETYPE_AUDIO_FLAC,
839             "audio_decoder.flac", "audio_encoder.flac" },
840         { MEDIA_MIMETYPE_AUDIO_MSGSM,
841             "audio_decoder.gsm", "audio_encoder.gsm" },
842     };
843 
844     static const size_t kNumMimeToRole =
845         sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
846 
847     size_t i;
848     for (i = 0; i < kNumMimeToRole; ++i) {
849         if (!strcasecmp(mime, kMimeToRole[i].mime)) {
850             break;
851         }
852     }
853 
854     if (i == kNumMimeToRole) {
855         return ERROR_UNSUPPORTED;
856     }
857 
858     const char *role =
859         isEncoder ? kMimeToRole[i].encoderRole
860                   : kMimeToRole[i].decoderRole;
861 
862     if (role != NULL) {
863         OMX_PARAM_COMPONENTROLETYPE roleParams;
864         InitOMXParams(&roleParams);
865 
866         strncpy((char *)roleParams.cRole,
867                 role, OMX_MAX_STRINGNAME_SIZE - 1);
868 
869         roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
870 
871         status_t err = mOMX->setParameter(
872                 mNode, OMX_IndexParamStandardComponentRole,
873                 &roleParams, sizeof(roleParams));
874 
875         if (err != OK) {
876             ALOGW("[%s] Failed to set standard component role '%s'.",
877                  mComponentName.c_str(), role);
878 
879             return err;
880         }
881     }
882 
883     return OK;
884 }
885 
configureCodec(const char * mime,const sp<AMessage> & msg)886 status_t ACodec::configureCodec(
887         const char *mime, const sp<AMessage> &msg) {
888     int32_t encoder;
889     if (!msg->findInt32("encoder", &encoder)) {
890         encoder = false;
891     }
892 
893     mIsEncoder = encoder;
894 
895     status_t err = setComponentRole(encoder /* isEncoder */, mime);
896 
897     if (err != OK) {
898         return err;
899     }
900 
901     int32_t bitRate = 0;
902     // FLAC encoder doesn't need a bitrate, other encoders do
903     if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
904             && !msg->findInt32("bitrate", &bitRate)) {
905         return INVALID_OPERATION;
906     }
907 
908     int32_t storeMeta;
909     if (encoder
910             && msg->findInt32("store-metadata-in-buffers", &storeMeta)
911             && storeMeta != 0) {
912         err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
913 
914         if (err != OK) {
915             ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
916                   mComponentName.c_str(), err);
917 
918             return err;
919         }
920     }
921 
922     int32_t prependSPSPPS;
923     if (encoder
924             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
925             && prependSPSPPS != 0) {
926         OMX_INDEXTYPE index;
927         err = mOMX->getExtensionIndex(
928                 mNode,
929                 "OMX.google.android.index.prependSPSPPSToIDRFrames",
930                 &index);
931 
932         if (err == OK) {
933             PrependSPSPPSToIDRFramesParams params;
934             InitOMXParams(&params);
935             params.bEnable = OMX_TRUE;
936 
937             err = mOMX->setParameter(
938                     mNode, index, &params, sizeof(params));
939         }
940 
941         if (err != OK) {
942             ALOGE("Encoder could not be configured to emit SPS/PPS before "
943                   "IDR frames. (err %d)", err);
944 
945             return err;
946         }
947     }
948 
949     if (!strncasecmp(mime, "video/", 6)) {
950         if (encoder) {
951             err = setupVideoEncoder(mime, msg);
952         } else {
953             int32_t width, height;
954             if (!msg->findInt32("width", &width)
955                     || !msg->findInt32("height", &height)) {
956                 err = INVALID_OPERATION;
957             } else {
958                 err = setupVideoDecoder(mime, width, height);
959             }
960         }
961     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
962         int32_t numChannels, sampleRate;
963         if (!msg->findInt32("channel-count", &numChannels)
964                 || !msg->findInt32("sample-rate", &sampleRate)) {
965             // Since we did not always check for these, leave them optional
966             // and have the decoder figure it all out.
967             err = OK;
968         } else {
969             err = setupRawAudioFormat(
970                     encoder ? kPortIndexInput : kPortIndexOutput,
971                     sampleRate,
972                     numChannels);
973         }
974     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
975         int32_t numChannels, sampleRate;
976         if (!msg->findInt32("channel-count", &numChannels)
977                 || !msg->findInt32("sample-rate", &sampleRate)) {
978             err = INVALID_OPERATION;
979         } else {
980             int32_t isADTS, aacProfile;
981             if (!msg->findInt32("is-adts", &isADTS)) {
982                 isADTS = 0;
983             }
984             if (!msg->findInt32("aac-profile", &aacProfile)) {
985                 aacProfile = OMX_AUDIO_AACObjectNull;
986             }
987 
988             err = setupAACCodec(
989                     encoder, numChannels, sampleRate, bitRate, aacProfile,
990                     isADTS != 0);
991         }
992     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
993         err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
994     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
995         err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
996     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
997             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
998         // These are PCM-like formats with a fixed sample rate but
999         // a variable number of channels.
1000 
1001         int32_t numChannels;
1002         if (!msg->findInt32("channel-count", &numChannels)) {
1003             err = INVALID_OPERATION;
1004         } else {
1005             err = setupG711Codec(encoder, numChannels);
1006         }
1007     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1008         int32_t numChannels, sampleRate, compressionLevel = -1;
1009         if (encoder &&
1010                 (!msg->findInt32("channel-count", &numChannels)
1011                         || !msg->findInt32("sample-rate", &sampleRate))) {
1012             ALOGE("missing channel count or sample rate for FLAC encoder");
1013             err = INVALID_OPERATION;
1014         } else {
1015             if (encoder) {
1016                 if (!msg->findInt32(
1017                             "flac-compression-level", &compressionLevel)) {
1018                     compressionLevel = 5;// default FLAC compression level
1019                 } else if (compressionLevel < 0) {
1020                     ALOGW("compression level %d outside [0..8] range, "
1021                           "using 0",
1022                           compressionLevel);
1023                     compressionLevel = 0;
1024                 } else if (compressionLevel > 8) {
1025                     ALOGW("compression level %d outside [0..8] range, "
1026                           "using 8",
1027                           compressionLevel);
1028                     compressionLevel = 8;
1029                 }
1030             }
1031             err = setupFlacCodec(
1032                     encoder, numChannels, sampleRate, compressionLevel);
1033         }
1034     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1035         int32_t numChannels, sampleRate;
1036         if (encoder
1037                 || !msg->findInt32("channel-count", &numChannels)
1038                 || !msg->findInt32("sample-rate", &sampleRate)) {
1039             err = INVALID_OPERATION;
1040         } else {
1041             err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1042         }
1043     }
1044 
1045     if (err != OK) {
1046         return err;
1047     }
1048 
1049     if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
1050         mEncoderDelay = 0;
1051     }
1052 
1053     if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
1054         mEncoderPadding = 0;
1055     }
1056 
1057     if (msg->findInt32("channel-mask", &mChannelMask)) {
1058         mChannelMaskPresent = true;
1059     } else {
1060         mChannelMaskPresent = false;
1061     }
1062 
1063     int32_t maxInputSize;
1064     if (msg->findInt32("max-input-size", &maxInputSize)) {
1065         err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1066     } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
1067         err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1068     }
1069 
1070     return err;
1071 }
1072 
setMinBufferSize(OMX_U32 portIndex,size_t size)1073 status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1074     OMX_PARAM_PORTDEFINITIONTYPE def;
1075     InitOMXParams(&def);
1076     def.nPortIndex = portIndex;
1077 
1078     status_t err = mOMX->getParameter(
1079             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1080 
1081     if (err != OK) {
1082         return err;
1083     }
1084 
1085     if (def.nBufferSize >= size) {
1086         return OK;
1087     }
1088 
1089     def.nBufferSize = size;
1090 
1091     err = mOMX->setParameter(
1092             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1093 
1094     if (err != OK) {
1095         return err;
1096     }
1097 
1098     err = mOMX->getParameter(
1099             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1100 
1101     if (err != OK) {
1102         return err;
1103     }
1104 
1105     CHECK(def.nBufferSize >= size);
1106 
1107     return OK;
1108 }
1109 
selectAudioPortFormat(OMX_U32 portIndex,OMX_AUDIO_CODINGTYPE desiredFormat)1110 status_t ACodec::selectAudioPortFormat(
1111         OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
1112     OMX_AUDIO_PARAM_PORTFORMATTYPE format;
1113     InitOMXParams(&format);
1114 
1115     format.nPortIndex = portIndex;
1116     for (OMX_U32 index = 0;; ++index) {
1117         format.nIndex = index;
1118 
1119         status_t err = mOMX->getParameter(
1120                 mNode, OMX_IndexParamAudioPortFormat,
1121                 &format, sizeof(format));
1122 
1123         if (err != OK) {
1124             return err;
1125         }
1126 
1127         if (format.eEncoding == desiredFormat) {
1128             break;
1129         }
1130     }
1131 
1132     return mOMX->setParameter(
1133             mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
1134 }
1135 
setupAACCodec(bool encoder,int32_t numChannels,int32_t sampleRate,int32_t bitRate,int32_t aacProfile,bool isADTS)1136 status_t ACodec::setupAACCodec(
1137         bool encoder, int32_t numChannels, int32_t sampleRate,
1138         int32_t bitRate, int32_t aacProfile, bool isADTS) {
1139     if (encoder && isADTS) {
1140         return -EINVAL;
1141     }
1142 
1143     status_t err = setupRawAudioFormat(
1144             encoder ? kPortIndexInput : kPortIndexOutput,
1145             sampleRate,
1146             numChannels);
1147 
1148     if (err != OK) {
1149         return err;
1150     }
1151 
1152     if (encoder) {
1153         err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
1154 
1155         if (err != OK) {
1156             return err;
1157         }
1158 
1159         OMX_PARAM_PORTDEFINITIONTYPE def;
1160         InitOMXParams(&def);
1161         def.nPortIndex = kPortIndexOutput;
1162 
1163         err = mOMX->getParameter(
1164                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1165 
1166         if (err != OK) {
1167             return err;
1168         }
1169 
1170         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
1171         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
1172 
1173         err = mOMX->setParameter(
1174                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1175 
1176         if (err != OK) {
1177             return err;
1178         }
1179 
1180         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1181         InitOMXParams(&profile);
1182         profile.nPortIndex = kPortIndexOutput;
1183 
1184         err = mOMX->getParameter(
1185                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1186 
1187         if (err != OK) {
1188             return err;
1189         }
1190 
1191         profile.nChannels = numChannels;
1192 
1193         profile.eChannelMode =
1194             (numChannels == 1)
1195                 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
1196 
1197         profile.nSampleRate = sampleRate;
1198         profile.nBitRate = bitRate;
1199         profile.nAudioBandWidth = 0;
1200         profile.nFrameLength = 0;
1201         profile.nAACtools = OMX_AUDIO_AACToolAll;
1202         profile.nAACERtools = OMX_AUDIO_AACERNone;
1203         profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
1204         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1205 
1206         err = mOMX->setParameter(
1207                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1208 
1209         if (err != OK) {
1210             return err;
1211         }
1212 
1213         return err;
1214     }
1215 
1216     OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1217     InitOMXParams(&profile);
1218     profile.nPortIndex = kPortIndexInput;
1219 
1220     err = mOMX->getParameter(
1221             mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1222 
1223     if (err != OK) {
1224         return err;
1225     }
1226 
1227     profile.nChannels = numChannels;
1228     profile.nSampleRate = sampleRate;
1229 
1230     profile.eAACStreamFormat =
1231         isADTS
1232             ? OMX_AUDIO_AACStreamFormatMP4ADTS
1233             : OMX_AUDIO_AACStreamFormatMP4FF;
1234 
1235     return mOMX->setParameter(
1236             mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1237 }
1238 
pickModeFromBitRate(bool isAMRWB,int32_t bps)1239 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
1240         bool isAMRWB, int32_t bps) {
1241     if (isAMRWB) {
1242         if (bps <= 6600) {
1243             return OMX_AUDIO_AMRBandModeWB0;
1244         } else if (bps <= 8850) {
1245             return OMX_AUDIO_AMRBandModeWB1;
1246         } else if (bps <= 12650) {
1247             return OMX_AUDIO_AMRBandModeWB2;
1248         } else if (bps <= 14250) {
1249             return OMX_AUDIO_AMRBandModeWB3;
1250         } else if (bps <= 15850) {
1251             return OMX_AUDIO_AMRBandModeWB4;
1252         } else if (bps <= 18250) {
1253             return OMX_AUDIO_AMRBandModeWB5;
1254         } else if (bps <= 19850) {
1255             return OMX_AUDIO_AMRBandModeWB6;
1256         } else if (bps <= 23050) {
1257             return OMX_AUDIO_AMRBandModeWB7;
1258         }
1259 
1260         // 23850 bps
1261         return OMX_AUDIO_AMRBandModeWB8;
1262     } else {  // AMRNB
1263         if (bps <= 4750) {
1264             return OMX_AUDIO_AMRBandModeNB0;
1265         } else if (bps <= 5150) {
1266             return OMX_AUDIO_AMRBandModeNB1;
1267         } else if (bps <= 5900) {
1268             return OMX_AUDIO_AMRBandModeNB2;
1269         } else if (bps <= 6700) {
1270             return OMX_AUDIO_AMRBandModeNB3;
1271         } else if (bps <= 7400) {
1272             return OMX_AUDIO_AMRBandModeNB4;
1273         } else if (bps <= 7950) {
1274             return OMX_AUDIO_AMRBandModeNB5;
1275         } else if (bps <= 10200) {
1276             return OMX_AUDIO_AMRBandModeNB6;
1277         }
1278 
1279         // 12200 bps
1280         return OMX_AUDIO_AMRBandModeNB7;
1281     }
1282 }
1283 
setupAMRCodec(bool encoder,bool isWAMR,int32_t bitrate)1284 status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1285     OMX_AUDIO_PARAM_AMRTYPE def;
1286     InitOMXParams(&def);
1287     def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1288 
1289     status_t err =
1290         mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1291 
1292     if (err != OK) {
1293         return err;
1294     }
1295 
1296     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1297     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
1298 
1299     err = mOMX->setParameter(
1300             mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1301 
1302     if (err != OK) {
1303         return err;
1304     }
1305 
1306     return setupRawAudioFormat(
1307             encoder ? kPortIndexInput : kPortIndexOutput,
1308             isWAMR ? 16000 : 8000 /* sampleRate */,
1309             1 /* numChannels */);
1310 }
1311 
setupG711Codec(bool encoder,int32_t numChannels)1312 status_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
1313     CHECK(!encoder);  // XXX TODO
1314 
1315     return setupRawAudioFormat(
1316             kPortIndexInput, 8000 /* sampleRate */, numChannels);
1317 }
1318 
setupFlacCodec(bool encoder,int32_t numChannels,int32_t sampleRate,int32_t compressionLevel)1319 status_t ACodec::setupFlacCodec(
1320         bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
1321 
1322     if (encoder) {
1323         OMX_AUDIO_PARAM_FLACTYPE def;
1324         InitOMXParams(&def);
1325         def.nPortIndex = kPortIndexOutput;
1326 
1327         // configure compression level
1328         status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
1329         if (err != OK) {
1330             ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
1331             return err;
1332         }
1333         def.nCompressionLevel = compressionLevel;
1334         err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
1335         if (err != OK) {
1336             ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
1337             return err;
1338         }
1339     }
1340 
1341     return setupRawAudioFormat(
1342             encoder ? kPortIndexInput : kPortIndexOutput,
1343             sampleRate,
1344             numChannels);
1345 }
1346 
setupRawAudioFormat(OMX_U32 portIndex,int32_t sampleRate,int32_t numChannels)1347 status_t ACodec::setupRawAudioFormat(
1348         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1349     OMX_PARAM_PORTDEFINITIONTYPE def;
1350     InitOMXParams(&def);
1351     def.nPortIndex = portIndex;
1352 
1353     status_t err = mOMX->getParameter(
1354             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1355 
1356     if (err != OK) {
1357         return err;
1358     }
1359 
1360     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1361 
1362     err = mOMX->setParameter(
1363             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1364 
1365     if (err != OK) {
1366         return err;
1367     }
1368 
1369     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1370     InitOMXParams(&pcmParams);
1371     pcmParams.nPortIndex = portIndex;
1372 
1373     err = mOMX->getParameter(
1374             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1375 
1376     if (err != OK) {
1377         return err;
1378     }
1379 
1380     pcmParams.nChannels = numChannels;
1381     pcmParams.eNumData = OMX_NumericalDataSigned;
1382     pcmParams.bInterleaved = OMX_TRUE;
1383     pcmParams.nBitPerSample = 16;
1384     pcmParams.nSamplingRate = sampleRate;
1385     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1386 
1387     if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1388         return OMX_ErrorNone;
1389     }
1390 
1391     return mOMX->setParameter(
1392             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1393 }
1394 
setVideoPortFormatType(OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE compressionFormat,OMX_COLOR_FORMATTYPE colorFormat)1395 status_t ACodec::setVideoPortFormatType(
1396         OMX_U32 portIndex,
1397         OMX_VIDEO_CODINGTYPE compressionFormat,
1398         OMX_COLOR_FORMATTYPE colorFormat) {
1399     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1400     InitOMXParams(&format);
1401     format.nPortIndex = portIndex;
1402     format.nIndex = 0;
1403     bool found = false;
1404 
1405     OMX_U32 index = 0;
1406     for (;;) {
1407         format.nIndex = index;
1408         status_t err = mOMX->getParameter(
1409                 mNode, OMX_IndexParamVideoPortFormat,
1410                 &format, sizeof(format));
1411 
1412         if (err != OK) {
1413             return err;
1414         }
1415 
1416         // The following assertion is violated by TI's video decoder.
1417         // CHECK_EQ(format.nIndex, index);
1418 
1419         if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1420             if (portIndex == kPortIndexInput
1421                     && colorFormat == format.eColorFormat) {
1422                 // eCompressionFormat does not seem right.
1423                 found = true;
1424                 break;
1425             }
1426             if (portIndex == kPortIndexOutput
1427                     && compressionFormat == format.eCompressionFormat) {
1428                 // eColorFormat does not seem right.
1429                 found = true;
1430                 break;
1431             }
1432         }
1433 
1434         if (format.eCompressionFormat == compressionFormat
1435             && format.eColorFormat == colorFormat) {
1436             found = true;
1437             break;
1438         }
1439 
1440         ++index;
1441     }
1442 
1443     if (!found) {
1444         return UNKNOWN_ERROR;
1445     }
1446 
1447     status_t err = mOMX->setParameter(
1448             mNode, OMX_IndexParamVideoPortFormat,
1449             &format, sizeof(format));
1450 
1451     return err;
1452 }
1453 
setSupportedOutputFormat()1454 status_t ACodec::setSupportedOutputFormat() {
1455     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1456     InitOMXParams(&format);
1457     format.nPortIndex = kPortIndexOutput;
1458     format.nIndex = 0;
1459 
1460     status_t err = mOMX->getParameter(
1461             mNode, OMX_IndexParamVideoPortFormat,
1462             &format, sizeof(format));
1463     CHECK_EQ(err, (status_t)OK);
1464     CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1465 
1466     return mOMX->setParameter(
1467             mNode, OMX_IndexParamVideoPortFormat,
1468             &format, sizeof(format));
1469 }
1470 
1471 static const struct VideoCodingMapEntry {
1472     const char *mMime;
1473     OMX_VIDEO_CODINGTYPE mVideoCodingType;
1474 } kVideoCodingMapEntry[] = {
1475     { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1476     { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1477     { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1478     { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
1479     { MEDIA_MIMETYPE_VIDEO_VPX, OMX_VIDEO_CodingVPX },
1480 };
1481 
GetVideoCodingTypeFromMime(const char * mime,OMX_VIDEO_CODINGTYPE * codingType)1482 static status_t GetVideoCodingTypeFromMime(
1483         const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1484     for (size_t i = 0;
1485          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1486          ++i) {
1487         if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1488             *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1489             return OK;
1490         }
1491     }
1492 
1493     *codingType = OMX_VIDEO_CodingUnused;
1494 
1495     return ERROR_UNSUPPORTED;
1496 }
1497 
GetMimeTypeForVideoCoding(OMX_VIDEO_CODINGTYPE codingType,AString * mime)1498 static status_t GetMimeTypeForVideoCoding(
1499         OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1500     for (size_t i = 0;
1501          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1502          ++i) {
1503         if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1504             *mime = kVideoCodingMapEntry[i].mMime;
1505             return OK;
1506         }
1507     }
1508 
1509     mime->clear();
1510 
1511     return ERROR_UNSUPPORTED;
1512 }
1513 
setupVideoDecoder(const char * mime,int32_t width,int32_t height)1514 status_t ACodec::setupVideoDecoder(
1515         const char *mime, int32_t width, int32_t height) {
1516     OMX_VIDEO_CODINGTYPE compressionFormat;
1517     status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
1518 
1519     if (err != OK) {
1520         return err;
1521     }
1522 
1523     err = setVideoPortFormatType(
1524             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1525 
1526     if (err != OK) {
1527         return err;
1528     }
1529 
1530     err = setSupportedOutputFormat();
1531 
1532     if (err != OK) {
1533         return err;
1534     }
1535 
1536     err = setVideoFormatOnPort(
1537             kPortIndexInput, width, height, compressionFormat);
1538 
1539     if (err != OK) {
1540         return err;
1541     }
1542 
1543     err = setVideoFormatOnPort(
1544             kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1545 
1546     if (err != OK) {
1547         return err;
1548     }
1549 
1550     return OK;
1551 }
1552 
setupVideoEncoder(const char * mime,const sp<AMessage> & msg)1553 status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
1554     int32_t tmp;
1555     if (!msg->findInt32("color-format", &tmp)) {
1556         return INVALID_OPERATION;
1557     }
1558 
1559     OMX_COLOR_FORMATTYPE colorFormat =
1560         static_cast<OMX_COLOR_FORMATTYPE>(tmp);
1561 
1562     status_t err = setVideoPortFormatType(
1563             kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
1564 
1565     if (err != OK) {
1566         ALOGE("[%s] does not support color format %d",
1567               mComponentName.c_str(), colorFormat);
1568 
1569         return err;
1570     }
1571 
1572     /* Input port configuration */
1573 
1574     OMX_PARAM_PORTDEFINITIONTYPE def;
1575     InitOMXParams(&def);
1576 
1577     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1578 
1579     def.nPortIndex = kPortIndexInput;
1580 
1581     err = mOMX->getParameter(
1582             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1583 
1584     if (err != OK) {
1585         return err;
1586     }
1587 
1588     int32_t width, height, bitrate;
1589     if (!msg->findInt32("width", &width)
1590             || !msg->findInt32("height", &height)
1591             || !msg->findInt32("bitrate", &bitrate)) {
1592         return INVALID_OPERATION;
1593     }
1594 
1595     video_def->nFrameWidth = width;
1596     video_def->nFrameHeight = height;
1597 
1598     int32_t stride;
1599     if (!msg->findInt32("stride", &stride)) {
1600         stride = width;
1601     }
1602 
1603     video_def->nStride = stride;
1604 
1605     int32_t sliceHeight;
1606     if (!msg->findInt32("slice-height", &sliceHeight)) {
1607         sliceHeight = height;
1608     }
1609 
1610     video_def->nSliceHeight = sliceHeight;
1611 
1612     def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
1613 
1614     float frameRate;
1615     if (!msg->findFloat("frame-rate", &frameRate)) {
1616         int32_t tmp;
1617         if (!msg->findInt32("frame-rate", &tmp)) {
1618             return INVALID_OPERATION;
1619         }
1620         frameRate = (float)tmp;
1621     }
1622 
1623     video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
1624     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
1625     video_def->eColorFormat = colorFormat;
1626 
1627     err = mOMX->setParameter(
1628             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1629 
1630     if (err != OK) {
1631         ALOGE("[%s] failed to set input port definition parameters.",
1632               mComponentName.c_str());
1633 
1634         return err;
1635     }
1636 
1637     /* Output port configuration */
1638 
1639     OMX_VIDEO_CODINGTYPE compressionFormat;
1640     err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
1641 
1642     if (err != OK) {
1643         return err;
1644     }
1645 
1646     err = setVideoPortFormatType(
1647             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
1648 
1649     if (err != OK) {
1650         ALOGE("[%s] does not support compression format %d",
1651              mComponentName.c_str(), compressionFormat);
1652 
1653         return err;
1654     }
1655 
1656     def.nPortIndex = kPortIndexOutput;
1657 
1658     err = mOMX->getParameter(
1659             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1660 
1661     if (err != OK) {
1662         return err;
1663     }
1664 
1665     video_def->nFrameWidth = width;
1666     video_def->nFrameHeight = height;
1667     video_def->xFramerate = 0;
1668     video_def->nBitrate = bitrate;
1669     video_def->eCompressionFormat = compressionFormat;
1670     video_def->eColorFormat = OMX_COLOR_FormatUnused;
1671 
1672     err = mOMX->setParameter(
1673             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1674 
1675     if (err != OK) {
1676         ALOGE("[%s] failed to set output port definition parameters.",
1677               mComponentName.c_str());
1678 
1679         return err;
1680     }
1681 
1682     switch (compressionFormat) {
1683         case OMX_VIDEO_CodingMPEG4:
1684             err = setupMPEG4EncoderParameters(msg);
1685             break;
1686 
1687         case OMX_VIDEO_CodingH263:
1688             err = setupH263EncoderParameters(msg);
1689             break;
1690 
1691         case OMX_VIDEO_CodingAVC:
1692             err = setupAVCEncoderParameters(msg);
1693             break;
1694 
1695         default:
1696             break;
1697     }
1698 
1699     ALOGI("setupVideoEncoder succeeded");
1700 
1701     return err;
1702 }
1703 
setCyclicIntraMacroblockRefresh(const sp<AMessage> & msg,int32_t mode)1704 status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
1705     OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
1706     InitOMXParams(&params);
1707     params.nPortIndex = kPortIndexOutput;
1708 
1709     params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
1710 
1711     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
1712             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
1713         int32_t mbs;
1714         if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
1715             return INVALID_OPERATION;
1716         }
1717         params.nCirMBs = mbs;
1718     }
1719 
1720     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
1721             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
1722         int32_t mbs;
1723         if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
1724             return INVALID_OPERATION;
1725         }
1726         params.nAirMBs = mbs;
1727 
1728         int32_t ref;
1729         if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
1730             return INVALID_OPERATION;
1731         }
1732         params.nAirRef = ref;
1733     }
1734 
1735     status_t err = mOMX->setParameter(
1736             mNode, OMX_IndexParamVideoIntraRefresh,
1737             &params, sizeof(params));
1738     return err;
1739 }
1740 
setPFramesSpacing(int32_t iFramesInterval,int32_t frameRate)1741 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
1742     if (iFramesInterval < 0) {
1743         return 0xFFFFFFFF;
1744     } else if (iFramesInterval == 0) {
1745         return 0;
1746     }
1747     OMX_U32 ret = frameRate * iFramesInterval;
1748     CHECK(ret > 1);
1749     return ret;
1750 }
1751 
getBitrateMode(const sp<AMessage> & msg)1752 static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
1753     int32_t tmp;
1754     if (!msg->findInt32("bitrate-mode", &tmp)) {
1755         return OMX_Video_ControlRateVariable;
1756     }
1757 
1758     return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
1759 }
1760 
setupMPEG4EncoderParameters(const sp<AMessage> & msg)1761 status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
1762     int32_t bitrate, iFrameInterval;
1763     if (!msg->findInt32("bitrate", &bitrate)
1764             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
1765         return INVALID_OPERATION;
1766     }
1767 
1768     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
1769 
1770     float frameRate;
1771     if (!msg->findFloat("frame-rate", &frameRate)) {
1772         int32_t tmp;
1773         if (!msg->findInt32("frame-rate", &tmp)) {
1774             return INVALID_OPERATION;
1775         }
1776         frameRate = (float)tmp;
1777     }
1778 
1779     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
1780     InitOMXParams(&mpeg4type);
1781     mpeg4type.nPortIndex = kPortIndexOutput;
1782 
1783     status_t err = mOMX->getParameter(
1784             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1785 
1786     if (err != OK) {
1787         return err;
1788     }
1789 
1790     mpeg4type.nSliceHeaderSpacing = 0;
1791     mpeg4type.bSVH = OMX_FALSE;
1792     mpeg4type.bGov = OMX_FALSE;
1793 
1794     mpeg4type.nAllowedPictureTypes =
1795         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1796 
1797     mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
1798     if (mpeg4type.nPFrames == 0) {
1799         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1800     }
1801     mpeg4type.nBFrames = 0;
1802     mpeg4type.nIDCVLCThreshold = 0;
1803     mpeg4type.bACPred = OMX_TRUE;
1804     mpeg4type.nMaxPacketSize = 256;
1805     mpeg4type.nTimeIncRes = 1000;
1806     mpeg4type.nHeaderExtension = 0;
1807     mpeg4type.bReversibleVLC = OMX_FALSE;
1808 
1809     int32_t profile;
1810     if (msg->findInt32("profile", &profile)) {
1811         int32_t level;
1812         if (!msg->findInt32("level", &level)) {
1813             return INVALID_OPERATION;
1814         }
1815 
1816         err = verifySupportForProfileAndLevel(profile, level);
1817 
1818         if (err != OK) {
1819             return err;
1820         }
1821 
1822         mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
1823         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
1824     }
1825 
1826     err = mOMX->setParameter(
1827             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1828 
1829     if (err != OK) {
1830         return err;
1831     }
1832 
1833     err = configureBitrate(bitrate, bitrateMode);
1834 
1835     if (err != OK) {
1836         return err;
1837     }
1838 
1839     return setupErrorCorrectionParameters();
1840 }
1841 
setupH263EncoderParameters(const sp<AMessage> & msg)1842 status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
1843     int32_t bitrate, iFrameInterval;
1844     if (!msg->findInt32("bitrate", &bitrate)
1845             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
1846         return INVALID_OPERATION;
1847     }
1848 
1849     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
1850 
1851     float frameRate;
1852     if (!msg->findFloat("frame-rate", &frameRate)) {
1853         int32_t tmp;
1854         if (!msg->findInt32("frame-rate", &tmp)) {
1855             return INVALID_OPERATION;
1856         }
1857         frameRate = (float)tmp;
1858     }
1859 
1860     OMX_VIDEO_PARAM_H263TYPE h263type;
1861     InitOMXParams(&h263type);
1862     h263type.nPortIndex = kPortIndexOutput;
1863 
1864     status_t err = mOMX->getParameter(
1865             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1866 
1867     if (err != OK) {
1868         return err;
1869     }
1870 
1871     h263type.nAllowedPictureTypes =
1872         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1873 
1874     h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
1875     if (h263type.nPFrames == 0) {
1876         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1877     }
1878     h263type.nBFrames = 0;
1879 
1880     int32_t profile;
1881     if (msg->findInt32("profile", &profile)) {
1882         int32_t level;
1883         if (!msg->findInt32("level", &level)) {
1884             return INVALID_OPERATION;
1885         }
1886 
1887         err = verifySupportForProfileAndLevel(profile, level);
1888 
1889         if (err != OK) {
1890             return err;
1891         }
1892 
1893         h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
1894         h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
1895     }
1896 
1897     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
1898     h263type.bForceRoundingTypeToZero = OMX_FALSE;
1899     h263type.nPictureHeaderRepetition = 0;
1900     h263type.nGOBHeaderInterval = 0;
1901 
1902     err = mOMX->setParameter(
1903             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1904 
1905     if (err != OK) {
1906         return err;
1907     }
1908 
1909     err = configureBitrate(bitrate, bitrateMode);
1910 
1911     if (err != OK) {
1912         return err;
1913     }
1914 
1915     return setupErrorCorrectionParameters();
1916 }
1917 
setupAVCEncoderParameters(const sp<AMessage> & msg)1918 status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
1919     int32_t bitrate, iFrameInterval;
1920     if (!msg->findInt32("bitrate", &bitrate)
1921             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
1922         return INVALID_OPERATION;
1923     }
1924 
1925     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
1926 
1927     float frameRate;
1928     if (!msg->findFloat("frame-rate", &frameRate)) {
1929         int32_t tmp;
1930         if (!msg->findInt32("frame-rate", &tmp)) {
1931             return INVALID_OPERATION;
1932         }
1933         frameRate = (float)tmp;
1934     }
1935 
1936     status_t err = OK;
1937     int32_t intraRefreshMode = 0;
1938     if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
1939         err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
1940         if (err != OK) {
1941             ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
1942                     err, intraRefreshMode);
1943             return err;
1944         }
1945     }
1946 
1947     OMX_VIDEO_PARAM_AVCTYPE h264type;
1948     InitOMXParams(&h264type);
1949     h264type.nPortIndex = kPortIndexOutput;
1950 
1951     err = mOMX->getParameter(
1952             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1953 
1954     if (err != OK) {
1955         return err;
1956     }
1957 
1958     h264type.nAllowedPictureTypes =
1959         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1960 
1961     int32_t profile;
1962     if (msg->findInt32("profile", &profile)) {
1963         int32_t level;
1964         if (!msg->findInt32("level", &level)) {
1965             return INVALID_OPERATION;
1966         }
1967 
1968         err = verifySupportForProfileAndLevel(profile, level);
1969 
1970         if (err != OK) {
1971             return err;
1972         }
1973 
1974         h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
1975         h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
1976     }
1977 
1978     // XXX
1979     if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
1980         ALOGW("Use baseline profile instead of %d for AVC recording",
1981             h264type.eProfile);
1982         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
1983     }
1984 
1985     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
1986         h264type.nSliceHeaderSpacing = 0;
1987         h264type.bUseHadamard = OMX_TRUE;
1988         h264type.nRefFrames = 1;
1989         h264type.nBFrames = 0;
1990         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
1991         if (h264type.nPFrames == 0) {
1992             h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1993         }
1994         h264type.nRefIdx10ActiveMinus1 = 0;
1995         h264type.nRefIdx11ActiveMinus1 = 0;
1996         h264type.bEntropyCodingCABAC = OMX_FALSE;
1997         h264type.bWeightedPPrediction = OMX_FALSE;
1998         h264type.bconstIpred = OMX_FALSE;
1999         h264type.bDirect8x8Inference = OMX_FALSE;
2000         h264type.bDirectSpatialTemporal = OMX_FALSE;
2001         h264type.nCabacInitIdc = 0;
2002     }
2003 
2004     if (h264type.nBFrames != 0) {
2005         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
2006     }
2007 
2008     h264type.bEnableUEP = OMX_FALSE;
2009     h264type.bEnableFMO = OMX_FALSE;
2010     h264type.bEnableASO = OMX_FALSE;
2011     h264type.bEnableRS = OMX_FALSE;
2012     h264type.bFrameMBsOnly = OMX_TRUE;
2013     h264type.bMBAFF = OMX_FALSE;
2014     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
2015 
2016     err = mOMX->setParameter(
2017             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
2018 
2019     if (err != OK) {
2020         return err;
2021     }
2022 
2023     return configureBitrate(bitrate, bitrateMode);
2024 }
2025 
verifySupportForProfileAndLevel(int32_t profile,int32_t level)2026 status_t ACodec::verifySupportForProfileAndLevel(
2027         int32_t profile, int32_t level) {
2028     OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
2029     InitOMXParams(&params);
2030     params.nPortIndex = kPortIndexOutput;
2031 
2032     for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
2033         status_t err = mOMX->getParameter(
2034                 mNode,
2035                 OMX_IndexParamVideoProfileLevelQuerySupported,
2036                 &params,
2037                 sizeof(params));
2038 
2039         if (err != OK) {
2040             return err;
2041         }
2042 
2043         int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
2044         int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
2045 
2046         if (profile == supportedProfile && level <= supportedLevel) {
2047             return OK;
2048         }
2049     }
2050 }
2051 
configureBitrate(int32_t bitrate,OMX_VIDEO_CONTROLRATETYPE bitrateMode)2052 status_t ACodec::configureBitrate(
2053         int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
2054     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
2055     InitOMXParams(&bitrateType);
2056     bitrateType.nPortIndex = kPortIndexOutput;
2057 
2058     status_t err = mOMX->getParameter(
2059             mNode, OMX_IndexParamVideoBitrate,
2060             &bitrateType, sizeof(bitrateType));
2061 
2062     if (err != OK) {
2063         return err;
2064     }
2065 
2066     bitrateType.eControlRate = bitrateMode;
2067     bitrateType.nTargetBitrate = bitrate;
2068 
2069     return mOMX->setParameter(
2070             mNode, OMX_IndexParamVideoBitrate,
2071             &bitrateType, sizeof(bitrateType));
2072 }
2073 
setupErrorCorrectionParameters()2074 status_t ACodec::setupErrorCorrectionParameters() {
2075     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
2076     InitOMXParams(&errorCorrectionType);
2077     errorCorrectionType.nPortIndex = kPortIndexOutput;
2078 
2079     status_t err = mOMX->getParameter(
2080             mNode, OMX_IndexParamVideoErrorCorrection,
2081             &errorCorrectionType, sizeof(errorCorrectionType));
2082 
2083     if (err != OK) {
2084         return OK;  // Optional feature. Ignore this failure
2085     }
2086 
2087     errorCorrectionType.bEnableHEC = OMX_FALSE;
2088     errorCorrectionType.bEnableResync = OMX_TRUE;
2089     errorCorrectionType.nResynchMarkerSpacing = 256;
2090     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
2091     errorCorrectionType.bEnableRVLC = OMX_FALSE;
2092 
2093     return mOMX->setParameter(
2094             mNode, OMX_IndexParamVideoErrorCorrection,
2095             &errorCorrectionType, sizeof(errorCorrectionType));
2096 }
2097 
setVideoFormatOnPort(OMX_U32 portIndex,int32_t width,int32_t height,OMX_VIDEO_CODINGTYPE compressionFormat)2098 status_t ACodec::setVideoFormatOnPort(
2099         OMX_U32 portIndex,
2100         int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2101     OMX_PARAM_PORTDEFINITIONTYPE def;
2102     InitOMXParams(&def);
2103     def.nPortIndex = portIndex;
2104 
2105     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2106 
2107     status_t err = mOMX->getParameter(
2108             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2109 
2110     CHECK_EQ(err, (status_t)OK);
2111 
2112     if (portIndex == kPortIndexInput) {
2113         // XXX Need a (much) better heuristic to compute input buffer sizes.
2114         const size_t X = 64 * 1024;
2115         if (def.nBufferSize < X) {
2116             def.nBufferSize = X;
2117         }
2118     }
2119 
2120     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2121 
2122     video_def->nFrameWidth = width;
2123     video_def->nFrameHeight = height;
2124 
2125     if (portIndex == kPortIndexInput) {
2126         video_def->eCompressionFormat = compressionFormat;
2127         video_def->eColorFormat = OMX_COLOR_FormatUnused;
2128     }
2129 
2130     err = mOMX->setParameter(
2131             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2132 
2133     return err;
2134 }
2135 
initNativeWindow()2136 status_t ACodec::initNativeWindow() {
2137     if (mNativeWindow != NULL) {
2138         return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2139     }
2140 
2141     mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2142     return OK;
2143 }
2144 
countBuffersOwnedByComponent(OMX_U32 portIndex) const2145 size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2146     size_t n = 0;
2147 
2148     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2149         const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2150 
2151         if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2152             ++n;
2153         }
2154     }
2155 
2156     return n;
2157 }
2158 
countBuffersOwnedByNativeWindow() const2159 size_t ACodec::countBuffersOwnedByNativeWindow() const {
2160     size_t n = 0;
2161 
2162     for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
2163         const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
2164 
2165         if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2166             ++n;
2167         }
2168     }
2169 
2170     return n;
2171 }
2172 
waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs()2173 void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
2174     if (mNativeWindow == NULL) {
2175         return;
2176     }
2177 
2178     int minUndequeuedBufs = 0;
2179     status_t err = mNativeWindow->query(
2180             mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
2181             &minUndequeuedBufs);
2182 
2183     if (err != OK) {
2184         ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
2185                 mComponentName.c_str(), strerror(-err), -err);
2186 
2187         minUndequeuedBufs = 0;
2188     }
2189 
2190     while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
2191             && dequeueBufferFromNativeWindow() != NULL) {
2192     }
2193 }
2194 
allYourBuffersAreBelongToUs(OMX_U32 portIndex)2195 bool ACodec::allYourBuffersAreBelongToUs(
2196         OMX_U32 portIndex) {
2197     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2198         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2199 
2200         if (info->mStatus != BufferInfo::OWNED_BY_US
2201                 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2202             ALOGV("[%s] Buffer %p on port %ld still has status %d",
2203                     mComponentName.c_str(),
2204                     info->mBufferID, portIndex, info->mStatus);
2205             return false;
2206         }
2207     }
2208 
2209     return true;
2210 }
2211 
allYourBuffersAreBelongToUs()2212 bool ACodec::allYourBuffersAreBelongToUs() {
2213     return allYourBuffersAreBelongToUs(kPortIndexInput)
2214         && allYourBuffersAreBelongToUs(kPortIndexOutput);
2215 }
2216 
deferMessage(const sp<AMessage> & msg)2217 void ACodec::deferMessage(const sp<AMessage> &msg) {
2218     bool wasEmptyBefore = mDeferredQueue.empty();
2219     mDeferredQueue.push_back(msg);
2220 }
2221 
processDeferredMessages()2222 void ACodec::processDeferredMessages() {
2223     List<sp<AMessage> > queue = mDeferredQueue;
2224     mDeferredQueue.clear();
2225 
2226     List<sp<AMessage> >::iterator it = queue.begin();
2227     while (it != queue.end()) {
2228         onMessageReceived(*it++);
2229     }
2230 }
2231 
sendFormatChange()2232 void ACodec::sendFormatChange() {
2233     sp<AMessage> notify = mNotify->dup();
2234     notify->setInt32("what", kWhatOutputFormatChanged);
2235 
2236     OMX_PARAM_PORTDEFINITIONTYPE def;
2237     InitOMXParams(&def);
2238     def.nPortIndex = kPortIndexOutput;
2239 
2240     CHECK_EQ(mOMX->getParameter(
2241                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
2242              (status_t)OK);
2243 
2244     CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
2245 
2246     switch (def.eDomain) {
2247         case OMX_PortDomainVideo:
2248         {
2249             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2250 
2251             AString mime;
2252             if (!mIsEncoder) {
2253                 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2254             } else if (GetMimeTypeForVideoCoding(
2255                         videoDef->eCompressionFormat, &mime) != OK) {
2256                 notify->setString("mime", "application/octet-stream");
2257             } else {
2258                 notify->setString("mime", mime.c_str());
2259             }
2260 
2261             notify->setInt32("width", videoDef->nFrameWidth);
2262             notify->setInt32("height", videoDef->nFrameHeight);
2263 
2264             if (!mIsEncoder) {
2265                 notify->setInt32("stride", videoDef->nStride);
2266                 notify->setInt32("slice-height", videoDef->nSliceHeight);
2267                 notify->setInt32("color-format", videoDef->eColorFormat);
2268 
2269                 OMX_CONFIG_RECTTYPE rect;
2270                 InitOMXParams(&rect);
2271                 rect.nPortIndex = kPortIndexOutput;
2272 
2273                 if (mOMX->getConfig(
2274                             mNode, OMX_IndexConfigCommonOutputCrop,
2275                             &rect, sizeof(rect)) != OK) {
2276                     rect.nLeft = 0;
2277                     rect.nTop = 0;
2278                     rect.nWidth = videoDef->nFrameWidth;
2279                     rect.nHeight = videoDef->nFrameHeight;
2280                 }
2281 
2282                 CHECK_GE(rect.nLeft, 0);
2283                 CHECK_GE(rect.nTop, 0);
2284                 CHECK_GE(rect.nWidth, 0u);
2285                 CHECK_GE(rect.nHeight, 0u);
2286                 CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2287                 CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2288 
2289                 notify->setRect(
2290                         "crop",
2291                         rect.nLeft,
2292                         rect.nTop,
2293                         rect.nLeft + rect.nWidth - 1,
2294                         rect.nTop + rect.nHeight - 1);
2295 
2296                 if (mNativeWindow != NULL) {
2297                     android_native_rect_t crop;
2298                     crop.left = rect.nLeft;
2299                     crop.top = rect.nTop;
2300                     crop.right = rect.nLeft + rect.nWidth;
2301                     crop.bottom = rect.nTop + rect.nHeight;
2302 
2303                     CHECK_EQ(0, native_window_set_crop(
2304                                 mNativeWindow.get(), &crop));
2305                 }
2306             }
2307             break;
2308         }
2309 
2310         case OMX_PortDomainAudio:
2311         {
2312             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
2313 
2314             switch (audioDef->eEncoding) {
2315                 case OMX_AUDIO_CodingPCM:
2316                 {
2317                     OMX_AUDIO_PARAM_PCMMODETYPE params;
2318                     InitOMXParams(&params);
2319                     params.nPortIndex = kPortIndexOutput;
2320 
2321                     CHECK_EQ(mOMX->getParameter(
2322                                 mNode, OMX_IndexParamAudioPcm,
2323                                 &params, sizeof(params)),
2324                              (status_t)OK);
2325 
2326                     CHECK(params.nChannels == 1 || params.bInterleaved);
2327                     CHECK_EQ(params.nBitPerSample, 16u);
2328                     CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
2329                     CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
2330 
2331                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2332                     notify->setInt32("channel-count", params.nChannels);
2333                     notify->setInt32("sample-rate", params.nSamplingRate);
2334                     if (mEncoderDelay + mEncoderPadding) {
2335                         size_t frameSize = params.nChannels * sizeof(int16_t);
2336                         if (mSkipCutBuffer != NULL) {
2337                             size_t prevbufsize = mSkipCutBuffer->size();
2338                             if (prevbufsize != 0) {
2339                                 ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
2340                             }
2341                         }
2342                         mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
2343                                                            mEncoderPadding * frameSize);
2344                     }
2345 
2346                     if (mChannelMaskPresent) {
2347                         notify->setInt32("channel-mask", mChannelMask);
2348                     }
2349                     break;
2350                 }
2351 
2352                 case OMX_AUDIO_CodingAAC:
2353                 {
2354                     OMX_AUDIO_PARAM_AACPROFILETYPE params;
2355                     InitOMXParams(&params);
2356                     params.nPortIndex = kPortIndexOutput;
2357 
2358                     CHECK_EQ(mOMX->getParameter(
2359                                 mNode, OMX_IndexParamAudioAac,
2360                                 &params, sizeof(params)),
2361                              (status_t)OK);
2362 
2363                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2364                     notify->setInt32("channel-count", params.nChannels);
2365                     notify->setInt32("sample-rate", params.nSampleRate);
2366                     break;
2367                 }
2368 
2369                 case OMX_AUDIO_CodingAMR:
2370                 {
2371                     OMX_AUDIO_PARAM_AMRTYPE params;
2372                     InitOMXParams(&params);
2373                     params.nPortIndex = kPortIndexOutput;
2374 
2375                     CHECK_EQ(mOMX->getParameter(
2376                                 mNode, OMX_IndexParamAudioAmr,
2377                                 &params, sizeof(params)),
2378                              (status_t)OK);
2379 
2380                     notify->setInt32("channel-count", 1);
2381                     if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2382                         notify->setString(
2383                                 "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2384 
2385                         notify->setInt32("sample-rate", 16000);
2386                     } else {
2387                         notify->setString(
2388                                 "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2389 
2390                         notify->setInt32("sample-rate", 8000);
2391                     }
2392                     break;
2393                 }
2394 
2395                 case OMX_AUDIO_CodingFLAC:
2396                 {
2397                     OMX_AUDIO_PARAM_FLACTYPE params;
2398                     InitOMXParams(&params);
2399                     params.nPortIndex = kPortIndexOutput;
2400 
2401                     CHECK_EQ(mOMX->getParameter(
2402                                 mNode, OMX_IndexParamAudioFlac,
2403                                 &params, sizeof(params)),
2404                              (status_t)OK);
2405 
2406                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2407                     notify->setInt32("channel-count", params.nChannels);
2408                     notify->setInt32("sample-rate", params.nSampleRate);
2409                     break;
2410                 }
2411 
2412                 default:
2413                     TRESPASS();
2414             }
2415             break;
2416         }
2417 
2418         default:
2419             TRESPASS();
2420     }
2421 
2422     notify->post();
2423 
2424     mSentFormat = true;
2425 }
2426 
signalError(OMX_ERRORTYPE error,status_t internalError)2427 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2428     sp<AMessage> notify = mNotify->dup();
2429     notify->setInt32("what", ACodec::kWhatError);
2430     notify->setInt32("omx-error", error);
2431     notify->setInt32("err", internalError);
2432     notify->post();
2433 }
2434 
pushBlankBuffersToNativeWindow()2435 status_t ACodec::pushBlankBuffersToNativeWindow() {
2436     status_t err = NO_ERROR;
2437     ANativeWindowBuffer* anb = NULL;
2438     int numBufs = 0;
2439     int minUndequeuedBufs = 0;
2440 
2441     // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2442     // no frames get dropped by SurfaceFlinger assuming that these are video
2443     // frames.
2444     err = native_window_api_disconnect(mNativeWindow.get(),
2445             NATIVE_WINDOW_API_MEDIA);
2446     if (err != NO_ERROR) {
2447         ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2448                 strerror(-err), -err);
2449         return err;
2450     }
2451 
2452     err = native_window_api_connect(mNativeWindow.get(),
2453             NATIVE_WINDOW_API_CPU);
2454     if (err != NO_ERROR) {
2455         ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2456                 strerror(-err), -err);
2457         return err;
2458     }
2459 
2460     err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2461             HAL_PIXEL_FORMAT_RGBX_8888);
2462     if (err != NO_ERROR) {
2463         ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2464                 strerror(-err), -err);
2465         goto error;
2466     }
2467 
2468     err = native_window_set_usage(mNativeWindow.get(),
2469             GRALLOC_USAGE_SW_WRITE_OFTEN);
2470     if (err != NO_ERROR) {
2471         ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2472                 strerror(-err), -err);
2473         goto error;
2474     }
2475 
2476     err = mNativeWindow->query(mNativeWindow.get(),
2477             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2478     if (err != NO_ERROR) {
2479         ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2480                 "failed: %s (%d)", strerror(-err), -err);
2481         goto error;
2482     }
2483 
2484     numBufs = minUndequeuedBufs + 1;
2485     err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2486     if (err != NO_ERROR) {
2487         ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2488                 strerror(-err), -err);
2489         goto error;
2490     }
2491 
2492     // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2493     // buffer twice.  This should guarantee that the buffer has been displayed
2494     // on the screen and then been replaced, so an previous video frames are
2495     // guaranteed NOT to be currently displayed.
2496     for (int i = 0; i < numBufs + 1; i++) {
2497         int fenceFd = -1;
2498         err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2499         if (err != NO_ERROR) {
2500             ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2501                     strerror(-err), -err);
2502             goto error;
2503         }
2504 
2505         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2506 
2507         // Fill the buffer with the a 1x1 checkerboard pattern ;)
2508         uint32_t* img = NULL;
2509         err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2510         if (err != NO_ERROR) {
2511             ALOGE("error pushing blank frames: lock failed: %s (%d)",
2512                     strerror(-err), -err);
2513             goto error;
2514         }
2515 
2516         *img = 0;
2517 
2518         err = buf->unlock();
2519         if (err != NO_ERROR) {
2520             ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2521                     strerror(-err), -err);
2522             goto error;
2523         }
2524 
2525         err = mNativeWindow->queueBuffer(mNativeWindow.get(),
2526                 buf->getNativeBuffer(), -1);
2527         if (err != NO_ERROR) {
2528             ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2529                     strerror(-err), -err);
2530             goto error;
2531         }
2532 
2533         anb = NULL;
2534     }
2535 
2536 error:
2537 
2538     if (err != NO_ERROR) {
2539         // Clean up after an error.
2540         if (anb != NULL) {
2541             mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2542         }
2543 
2544         native_window_api_disconnect(mNativeWindow.get(),
2545                 NATIVE_WINDOW_API_CPU);
2546         native_window_api_connect(mNativeWindow.get(),
2547                 NATIVE_WINDOW_API_MEDIA);
2548 
2549         return err;
2550     } else {
2551         // Clean up after success.
2552         err = native_window_api_disconnect(mNativeWindow.get(),
2553                 NATIVE_WINDOW_API_CPU);
2554         if (err != NO_ERROR) {
2555             ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2556                     strerror(-err), -err);
2557             return err;
2558         }
2559 
2560         err = native_window_api_connect(mNativeWindow.get(),
2561                 NATIVE_WINDOW_API_MEDIA);
2562         if (err != NO_ERROR) {
2563             ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2564                     strerror(-err), -err);
2565             return err;
2566         }
2567 
2568         return NO_ERROR;
2569     }
2570 }
2571 
2572 ////////////////////////////////////////////////////////////////////////////////
2573 
PortDescription()2574 ACodec::PortDescription::PortDescription() {
2575 }
2576 
requestIDRFrame()2577 status_t ACodec::requestIDRFrame() {
2578     if (!mIsEncoder) {
2579         return ERROR_UNSUPPORTED;
2580     }
2581 
2582     OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2583     InitOMXParams(&params);
2584 
2585     params.nPortIndex = kPortIndexOutput;
2586     params.IntraRefreshVOP = OMX_TRUE;
2587 
2588     return mOMX->setConfig(
2589             mNode,
2590             OMX_IndexConfigVideoIntraVOPRefresh,
2591             &params,
2592             sizeof(params));
2593 }
2594 
addBuffer(IOMX::buffer_id id,const sp<ABuffer> & buffer)2595 void ACodec::PortDescription::addBuffer(
2596         IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2597     mBufferIDs.push_back(id);
2598     mBuffers.push_back(buffer);
2599 }
2600 
countBuffers()2601 size_t ACodec::PortDescription::countBuffers() {
2602     return mBufferIDs.size();
2603 }
2604 
bufferIDAt(size_t index) const2605 IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2606     return mBufferIDs.itemAt(index);
2607 }
2608 
bufferAt(size_t index) const2609 sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2610     return mBuffers.itemAt(index);
2611 }
2612 
2613 ////////////////////////////////////////////////////////////////////////////////
2614 
BaseState(ACodec * codec,const sp<AState> & parentState)2615 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2616     : AState(parentState),
2617       mCodec(codec) {
2618 }
2619 
getPortMode(OMX_U32 portIndex)2620 ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2621     return KEEP_BUFFERS;
2622 }
2623 
onMessageReceived(const sp<AMessage> & msg)2624 bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2625     switch (msg->what()) {
2626         case kWhatInputBufferFilled:
2627         {
2628             onInputBufferFilled(msg);
2629             break;
2630         }
2631 
2632         case kWhatOutputBufferDrained:
2633         {
2634             onOutputBufferDrained(msg);
2635             break;
2636         }
2637 
2638         case ACodec::kWhatOMXMessage:
2639         {
2640             return onOMXMessage(msg);
2641         }
2642 
2643         case ACodec::kWhatCreateInputSurface:
2644         case ACodec::kWhatSignalEndOfInputStream:
2645         {
2646             ALOGE("Message 0x%x was not handled", msg->what());
2647             mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
2648             return true;
2649         }
2650 
2651         case ACodec::kWhatOMXDied:
2652         {
2653             ALOGE("OMX/mediaserver died, signalling error!");
2654             mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2655             break;
2656         }
2657 
2658         default:
2659             return false;
2660     }
2661 
2662     return true;
2663 }
2664 
onOMXMessage(const sp<AMessage> & msg)2665 bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2666     int32_t type;
2667     CHECK(msg->findInt32("type", &type));
2668 
2669     IOMX::node_id nodeID;
2670     CHECK(msg->findPointer("node", &nodeID));
2671     CHECK_EQ(nodeID, mCodec->mNode);
2672 
2673     switch (type) {
2674         case omx_message::EVENT:
2675         {
2676             int32_t event, data1, data2;
2677             CHECK(msg->findInt32("event", &event));
2678             CHECK(msg->findInt32("data1", &data1));
2679             CHECK(msg->findInt32("data2", &data2));
2680 
2681             if (event == OMX_EventCmdComplete
2682                     && data1 == OMX_CommandFlush
2683                     && data2 == (int32_t)OMX_ALL) {
2684                 // Use of this notification is not consistent across
2685                 // implementations. We'll drop this notification and rely
2686                 // on flush-complete notifications on the individual port
2687                 // indices instead.
2688 
2689                 return true;
2690             }
2691 
2692             return onOMXEvent(
2693                     static_cast<OMX_EVENTTYPE>(event),
2694                     static_cast<OMX_U32>(data1),
2695                     static_cast<OMX_U32>(data2));
2696         }
2697 
2698         case omx_message::EMPTY_BUFFER_DONE:
2699         {
2700             IOMX::buffer_id bufferID;
2701             CHECK(msg->findPointer("buffer", &bufferID));
2702 
2703             return onOMXEmptyBufferDone(bufferID);
2704         }
2705 
2706         case omx_message::FILL_BUFFER_DONE:
2707         {
2708             IOMX::buffer_id bufferID;
2709             CHECK(msg->findPointer("buffer", &bufferID));
2710 
2711             int32_t rangeOffset, rangeLength, flags;
2712             int64_t timeUs;
2713             void *platformPrivate;
2714             void *dataPtr;
2715 
2716             CHECK(msg->findInt32("range_offset", &rangeOffset));
2717             CHECK(msg->findInt32("range_length", &rangeLength));
2718             CHECK(msg->findInt32("flags", &flags));
2719             CHECK(msg->findInt64("timestamp", &timeUs));
2720             CHECK(msg->findPointer("platform_private", &platformPrivate));
2721             CHECK(msg->findPointer("data_ptr", &dataPtr));
2722 
2723             return onOMXFillBufferDone(
2724                     bufferID,
2725                     (size_t)rangeOffset, (size_t)rangeLength,
2726                     (OMX_U32)flags,
2727                     timeUs,
2728                     platformPrivate,
2729                     dataPtr);
2730         }
2731 
2732         default:
2733             TRESPASS();
2734             break;
2735     }
2736 }
2737 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)2738 bool ACodec::BaseState::onOMXEvent(
2739         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2740     if (event != OMX_EventError) {
2741         ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2742              mCodec->mComponentName.c_str(), event, data1, data2);
2743 
2744         return false;
2745     }
2746 
2747     ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2748 
2749     mCodec->signalError((OMX_ERRORTYPE)data1);
2750 
2751     return true;
2752 }
2753 
onOMXEmptyBufferDone(IOMX::buffer_id bufferID)2754 bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
2755     ALOGV("[%s] onOMXEmptyBufferDone %p",
2756          mCodec->mComponentName.c_str(), bufferID);
2757 
2758     BufferInfo *info =
2759         mCodec->findBufferByID(kPortIndexInput, bufferID);
2760 
2761     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2762     info->mStatus = BufferInfo::OWNED_BY_US;
2763 
2764     const sp<AMessage> &bufferMeta = info->mData->meta();
2765     void *mediaBuffer;
2766     if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2767             && mediaBuffer != NULL) {
2768         // We're in "store-metadata-in-buffers" mode, the underlying
2769         // OMX component had access to data that's implicitly refcounted
2770         // by this "mediaBuffer" object. Now that the OMX component has
2771         // told us that it's done with the input buffer, we can decrement
2772         // the mediaBuffer's reference count.
2773 
2774         ALOGV("releasing mbuf %p", mediaBuffer);
2775 
2776         ((MediaBuffer *)mediaBuffer)->release();
2777         mediaBuffer = NULL;
2778 
2779         bufferMeta->setPointer("mediaBuffer", NULL);
2780     }
2781 
2782     PortMode mode = getPortMode(kPortIndexInput);
2783 
2784     switch (mode) {
2785         case KEEP_BUFFERS:
2786             break;
2787 
2788         case RESUBMIT_BUFFERS:
2789             postFillThisBuffer(info);
2790             break;
2791 
2792         default:
2793         {
2794             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2795             TRESPASS();  // Not currently used
2796             break;
2797         }
2798     }
2799 
2800     return true;
2801 }
2802 
postFillThisBuffer(BufferInfo * info)2803 void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2804     if (mCodec->mPortEOS[kPortIndexInput]) {
2805         return;
2806     }
2807 
2808     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2809 
2810     sp<AMessage> notify = mCodec->mNotify->dup();
2811     notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2812     notify->setPointer("buffer-id", info->mBufferID);
2813 
2814     info->mData->meta()->clear();
2815     notify->setBuffer("buffer", info->mData);
2816 
2817     sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2818     reply->setPointer("buffer-id", info->mBufferID);
2819 
2820     notify->setMessage("reply", reply);
2821 
2822     notify->post();
2823 
2824     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2825 }
2826 
onInputBufferFilled(const sp<AMessage> & msg)2827 void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2828     IOMX::buffer_id bufferID;
2829     CHECK(msg->findPointer("buffer-id", &bufferID));
2830 
2831     sp<ABuffer> buffer;
2832     int32_t err = OK;
2833     bool eos = false;
2834 
2835     if (!msg->findBuffer("buffer", &buffer)) {
2836         CHECK(msg->findInt32("err", &err));
2837 
2838         ALOGV("[%s] saw error %d instead of an input buffer",
2839              mCodec->mComponentName.c_str(), err);
2840 
2841         buffer.clear();
2842 
2843         eos = true;
2844     }
2845 
2846     int32_t tmp;
2847     if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
2848         eos = true;
2849         err = ERROR_END_OF_STREAM;
2850     }
2851 
2852     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2853     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2854 
2855     info->mStatus = BufferInfo::OWNED_BY_US;
2856 
2857     PortMode mode = getPortMode(kPortIndexInput);
2858 
2859     switch (mode) {
2860         case KEEP_BUFFERS:
2861         {
2862             if (eos) {
2863                 if (!mCodec->mPortEOS[kPortIndexInput]) {
2864                     mCodec->mPortEOS[kPortIndexInput] = true;
2865                     mCodec->mInputEOSResult = err;
2866                 }
2867             }
2868             break;
2869         }
2870 
2871         case RESUBMIT_BUFFERS:
2872         {
2873             if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2874                 int64_t timeUs;
2875                 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2876 
2877                 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2878 
2879                 int32_t isCSD;
2880                 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2881                     flags |= OMX_BUFFERFLAG_CODECCONFIG;
2882                 }
2883 
2884                 if (eos) {
2885                     flags |= OMX_BUFFERFLAG_EOS;
2886                 }
2887 
2888                 if (buffer != info->mData) {
2889                     ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
2890                          mCodec->mComponentName.c_str(),
2891                          bufferID,
2892                          buffer.get(), info->mData.get());
2893 
2894                     CHECK_LE(buffer->size(), info->mData->capacity());
2895                     memcpy(info->mData->data(), buffer->data(), buffer->size());
2896                 }
2897 
2898                 if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
2899                     ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2900                          mCodec->mComponentName.c_str(), bufferID);
2901                 } else if (flags & OMX_BUFFERFLAG_EOS) {
2902                     ALOGV("[%s] calling emptyBuffer %p w/ EOS",
2903                          mCodec->mComponentName.c_str(), bufferID);
2904                 } else {
2905 #if TRACK_BUFFER_TIMING
2906                     ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
2907                          mCodec->mComponentName.c_str(), bufferID, timeUs);
2908 #else
2909                     ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2910                          mCodec->mComponentName.c_str(), bufferID, timeUs);
2911 #endif
2912                 }
2913 
2914 #if TRACK_BUFFER_TIMING
2915                 ACodec::BufferStats stats;
2916                 stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
2917                 stats.mFillBufferDoneTimeUs = -1ll;
2918                 mCodec->mBufferStats.add(timeUs, stats);
2919 #endif
2920 
2921                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
2922                             mCodec->mNode,
2923                             bufferID,
2924                             0,
2925                             buffer->size(),
2926                             flags,
2927                             timeUs),
2928                          (status_t)OK);
2929 
2930                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2931 
2932                 if (!eos) {
2933                     getMoreInputDataIfPossible();
2934                 } else {
2935                     ALOGV("[%s] Signalled EOS on the input port",
2936                          mCodec->mComponentName.c_str());
2937 
2938                     mCodec->mPortEOS[kPortIndexInput] = true;
2939                     mCodec->mInputEOSResult = err;
2940                 }
2941             } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2942                 if (err != ERROR_END_OF_STREAM) {
2943                     ALOGV("[%s] Signalling EOS on the input port "
2944                          "due to error %d",
2945                          mCodec->mComponentName.c_str(), err);
2946                 } else {
2947                     ALOGV("[%s] Signalling EOS on the input port",
2948                          mCodec->mComponentName.c_str());
2949                 }
2950 
2951                 ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2952                      mCodec->mComponentName.c_str(), bufferID);
2953 
2954                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
2955                             mCodec->mNode,
2956                             bufferID,
2957                             0,
2958                             0,
2959                             OMX_BUFFERFLAG_EOS,
2960                             0),
2961                          (status_t)OK);
2962 
2963                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2964 
2965                 mCodec->mPortEOS[kPortIndexInput] = true;
2966                 mCodec->mInputEOSResult = err;
2967             }
2968             break;
2969 
2970             default:
2971                 CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2972                 break;
2973         }
2974     }
2975 }
2976 
getMoreInputDataIfPossible()2977 void ACodec::BaseState::getMoreInputDataIfPossible() {
2978     if (mCodec->mPortEOS[kPortIndexInput]) {
2979         return;
2980     }
2981 
2982     BufferInfo *eligible = NULL;
2983 
2984     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2985         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2986 
2987 #if 0
2988         if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2989             // There's already a "read" pending.
2990             return;
2991         }
2992 #endif
2993 
2994         if (info->mStatus == BufferInfo::OWNED_BY_US) {
2995             eligible = info;
2996         }
2997     }
2998 
2999     if (eligible == NULL) {
3000         return;
3001     }
3002 
3003     postFillThisBuffer(eligible);
3004 }
3005 
onOMXFillBufferDone(IOMX::buffer_id bufferID,size_t rangeOffset,size_t rangeLength,OMX_U32 flags,int64_t timeUs,void * platformPrivate,void * dataPtr)3006 bool ACodec::BaseState::onOMXFillBufferDone(
3007         IOMX::buffer_id bufferID,
3008         size_t rangeOffset, size_t rangeLength,
3009         OMX_U32 flags,
3010         int64_t timeUs,
3011         void *platformPrivate,
3012         void *dataPtr) {
3013     ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
3014          mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3015 
3016     ssize_t index;
3017 
3018 #if TRACK_BUFFER_TIMING
3019     index = mCodec->mBufferStats.indexOfKey(timeUs);
3020     if (index >= 0) {
3021         ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3022         stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3023 
3024         ALOGI("frame PTS %lld: %lld",
3025                 timeUs,
3026                 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3027 
3028         mCodec->mBufferStats.removeItemsAt(index);
3029         stats = NULL;
3030     }
3031 #endif
3032 
3033     BufferInfo *info =
3034         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3035 
3036     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3037 
3038     info->mStatus = BufferInfo::OWNED_BY_US;
3039 
3040     PortMode mode = getPortMode(kPortIndexOutput);
3041 
3042     switch (mode) {
3043         case KEEP_BUFFERS:
3044             break;
3045 
3046         case RESUBMIT_BUFFERS:
3047         {
3048             if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3049                 ALOGV("[%s] calling fillBuffer %p",
3050                      mCodec->mComponentName.c_str(), info->mBufferID);
3051 
3052                 CHECK_EQ(mCodec->mOMX->fillBuffer(
3053                             mCodec->mNode, info->mBufferID),
3054                          (status_t)OK);
3055 
3056                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3057                 break;
3058             }
3059 
3060             if (!mCodec->mSentFormat) {
3061                 mCodec->sendFormatChange();
3062             }
3063 
3064             info->mData->setRange(rangeOffset, rangeLength);
3065 #if 0
3066             if (mCodec->mNativeWindow == NULL) {
3067                 if (IsIDR(info->mData)) {
3068                     ALOGI("IDR frame");
3069                 }
3070             }
3071 #endif
3072 
3073             if (mCodec->mSkipCutBuffer != NULL) {
3074                 mCodec->mSkipCutBuffer->submit(info->mData);
3075             }
3076             info->mData->meta()->setInt64("timeUs", timeUs);
3077 
3078             sp<AMessage> notify = mCodec->mNotify->dup();
3079             notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
3080             notify->setPointer("buffer-id", info->mBufferID);
3081             notify->setBuffer("buffer", info->mData);
3082             notify->setInt32("flags", flags);
3083 
3084             sp<AMessage> reply =
3085                 new AMessage(kWhatOutputBufferDrained, mCodec->id());
3086 
3087             reply->setPointer("buffer-id", info->mBufferID);
3088 
3089             notify->setMessage("reply", reply);
3090 
3091             notify->post();
3092 
3093             info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3094 
3095             if (flags & OMX_BUFFERFLAG_EOS) {
3096                 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
3097 
3098                 sp<AMessage> notify = mCodec->mNotify->dup();
3099                 notify->setInt32("what", ACodec::kWhatEOS);
3100                 notify->setInt32("err", mCodec->mInputEOSResult);
3101                 notify->post();
3102 
3103                 mCodec->mPortEOS[kPortIndexOutput] = true;
3104             }
3105             break;
3106         }
3107 
3108         default:
3109         {
3110             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3111 
3112             CHECK_EQ((status_t)OK,
3113                      mCodec->freeBuffer(kPortIndexOutput, index));
3114             break;
3115         }
3116     }
3117 
3118     return true;
3119 }
3120 
onOutputBufferDrained(const sp<AMessage> & msg)3121 void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3122     IOMX::buffer_id bufferID;
3123     CHECK(msg->findPointer("buffer-id", &bufferID));
3124 
3125     ssize_t index;
3126     BufferInfo *info =
3127         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3128     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3129 
3130     int32_t render;
3131     if (mCodec->mNativeWindow != NULL
3132             && msg->findInt32("render", &render) && render != 0
3133             && (info->mData == NULL || info->mData->size() != 0)) {
3134         // The client wants this buffer to be rendered.
3135 
3136         status_t err;
3137         if ((err = mCodec->mNativeWindow->queueBuffer(
3138                     mCodec->mNativeWindow.get(),
3139                     info->mGraphicBuffer.get(), -1)) == OK) {
3140             info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3141         } else {
3142             mCodec->signalError(OMX_ErrorUndefined, err);
3143             info->mStatus = BufferInfo::OWNED_BY_US;
3144         }
3145     } else {
3146         info->mStatus = BufferInfo::OWNED_BY_US;
3147     }
3148 
3149     PortMode mode = getPortMode(kPortIndexOutput);
3150 
3151     switch (mode) {
3152         case KEEP_BUFFERS:
3153         {
3154             // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3155 
3156             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3157                 // We cannot resubmit the buffer we just rendered, dequeue
3158                 // the spare instead.
3159 
3160                 info = mCodec->dequeueBufferFromNativeWindow();
3161             }
3162             break;
3163         }
3164 
3165         case RESUBMIT_BUFFERS:
3166         {
3167             if (!mCodec->mPortEOS[kPortIndexOutput]) {
3168                 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3169                     // We cannot resubmit the buffer we just rendered, dequeue
3170                     // the spare instead.
3171 
3172                     info = mCodec->dequeueBufferFromNativeWindow();
3173                 }
3174 
3175                 if (info != NULL) {
3176                     ALOGV("[%s] calling fillBuffer %p",
3177                          mCodec->mComponentName.c_str(), info->mBufferID);
3178 
3179                     CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3180                              (status_t)OK);
3181 
3182                     info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3183                 }
3184             }
3185             break;
3186         }
3187 
3188         default:
3189         {
3190             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3191 
3192             CHECK_EQ((status_t)OK,
3193                      mCodec->freeBuffer(kPortIndexOutput, index));
3194             break;
3195         }
3196     }
3197 }
3198 
3199 ////////////////////////////////////////////////////////////////////////////////
3200 
UninitializedState(ACodec * codec)3201 ACodec::UninitializedState::UninitializedState(ACodec *codec)
3202     : BaseState(codec) {
3203 }
3204 
stateEntered()3205 void ACodec::UninitializedState::stateEntered() {
3206     ALOGV("Now uninitialized");
3207 
3208     if (mDeathNotifier != NULL) {
3209         mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3210         mDeathNotifier.clear();
3211     }
3212 
3213     mCodec->mNativeWindow.clear();
3214     mCodec->mNode = NULL;
3215     mCodec->mOMX.clear();
3216     mCodec->mQuirks = 0;
3217     mCodec->mFlags = 0;
3218     mCodec->mComponentName.clear();
3219 }
3220 
onMessageReceived(const sp<AMessage> & msg)3221 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3222     bool handled = false;
3223 
3224     switch (msg->what()) {
3225         case ACodec::kWhatSetup:
3226         {
3227             onSetup(msg);
3228 
3229             handled = true;
3230             break;
3231         }
3232 
3233         case ACodec::kWhatAllocateComponent:
3234         {
3235             onAllocateComponent(msg);
3236             handled = true;
3237             break;
3238         }
3239 
3240         case ACodec::kWhatShutdown:
3241         {
3242             int32_t keepComponentAllocated;
3243             CHECK(msg->findInt32(
3244                         "keepComponentAllocated", &keepComponentAllocated));
3245             CHECK(!keepComponentAllocated);
3246 
3247             sp<AMessage> notify = mCodec->mNotify->dup();
3248             notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3249             notify->post();
3250 
3251             handled = true;
3252             break;
3253         }
3254 
3255         case ACodec::kWhatFlush:
3256         {
3257             sp<AMessage> notify = mCodec->mNotify->dup();
3258             notify->setInt32("what", ACodec::kWhatFlushCompleted);
3259             notify->post();
3260 
3261             handled = true;
3262             break;
3263         }
3264 
3265         default:
3266             return BaseState::onMessageReceived(msg);
3267     }
3268 
3269     return handled;
3270 }
3271 
onSetup(const sp<AMessage> & msg)3272 void ACodec::UninitializedState::onSetup(
3273         const sp<AMessage> &msg) {
3274     if (onAllocateComponent(msg)
3275             && mCodec->mLoadedState->onConfigureComponent(msg)) {
3276         mCodec->mLoadedState->onStart();
3277     }
3278 }
3279 
onAllocateComponent(const sp<AMessage> & msg)3280 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
3281     ALOGV("onAllocateComponent");
3282 
3283     CHECK(mCodec->mNode == NULL);
3284 
3285     OMXClient client;
3286     CHECK_EQ(client.connect(), (status_t)OK);
3287 
3288     sp<IOMX> omx = client.interface();
3289 
3290     sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3291 
3292     mDeathNotifier = new DeathNotifier(notify);
3293     if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3294         // This was a local binder, if it dies so do we, we won't care
3295         // about any notifications in the afterlife.
3296         mDeathNotifier.clear();
3297     }
3298 
3299     Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
3300 
3301     AString mime;
3302 
3303     AString componentName;
3304     uint32_t quirks = 0;
3305     if (msg->findString("componentName", &componentName)) {
3306         ssize_t index = matchingCodecs.add();
3307         OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3308         entry->mName = String8(componentName.c_str());
3309 
3310         if (!OMXCodec::findCodecQuirks(
3311                     componentName.c_str(), &entry->mQuirks)) {
3312             entry->mQuirks = 0;
3313         }
3314     } else {
3315         CHECK(msg->findString("mime", &mime));
3316 
3317         int32_t encoder;
3318         if (!msg->findInt32("encoder", &encoder)) {
3319             encoder = false;
3320         }
3321 
3322         OMXCodec::findMatchingCodecs(
3323                 mime.c_str(),
3324                 encoder, // createEncoder
3325                 NULL,  // matchComponentName
3326                 0,     // flags
3327                 &matchingCodecs);
3328     }
3329 
3330     sp<CodecObserver> observer = new CodecObserver;
3331     IOMX::node_id node = NULL;
3332 
3333     for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
3334             ++matchIndex) {
3335         componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3336         quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3337 
3338         pid_t tid = androidGetTid();
3339         int prevPriority = androidGetThreadPriority(tid);
3340         androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
3341         status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3342         androidSetThreadPriority(tid, prevPriority);
3343 
3344         if (err == OK) {
3345             break;
3346         }
3347 
3348         node = NULL;
3349     }
3350 
3351     if (node == NULL) {
3352         if (!mime.empty()) {
3353             ALOGE("Unable to instantiate a decoder for type '%s'.",
3354                  mime.c_str());
3355         } else {
3356             ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
3357         }
3358 
3359         mCodec->signalError(OMX_ErrorComponentNotFound);
3360         return false;
3361     }
3362 
3363     notify = new AMessage(kWhatOMXMessage, mCodec->id());
3364     observer->setNotificationMessage(notify);
3365 
3366     mCodec->mComponentName = componentName;
3367     mCodec->mFlags = 0;
3368 
3369     if (componentName.endsWith(".secure")) {
3370         mCodec->mFlags |= kFlagIsSecure;
3371     }
3372 
3373     mCodec->mQuirks = quirks;
3374     mCodec->mOMX = omx;
3375     mCodec->mNode = node;
3376 
3377     {
3378         sp<AMessage> notify = mCodec->mNotify->dup();
3379         notify->setInt32("what", ACodec::kWhatComponentAllocated);
3380         notify->setString("componentName", mCodec->mComponentName.c_str());
3381         notify->post();
3382     }
3383 
3384     mCodec->changeState(mCodec->mLoadedState);
3385 
3386     return true;
3387 }
3388 
3389 ////////////////////////////////////////////////////////////////////////////////
3390 
LoadedState(ACodec * codec)3391 ACodec::LoadedState::LoadedState(ACodec *codec)
3392     : BaseState(codec) {
3393 }
3394 
stateEntered()3395 void ACodec::LoadedState::stateEntered() {
3396     ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3397 
3398     mCodec->mPortEOS[kPortIndexInput] =
3399         mCodec->mPortEOS[kPortIndexOutput] = false;
3400 
3401     mCodec->mInputEOSResult = OK;
3402 
3403     if (mCodec->mShutdownInProgress) {
3404         bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3405 
3406         mCodec->mShutdownInProgress = false;
3407         mCodec->mKeepComponentAllocated = false;
3408 
3409         onShutdown(keepComponentAllocated);
3410     }
3411 }
3412 
onShutdown(bool keepComponentAllocated)3413 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3414     if (!keepComponentAllocated) {
3415         CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3416 
3417         mCodec->changeState(mCodec->mUninitializedState);
3418     }
3419 
3420     sp<AMessage> notify = mCodec->mNotify->dup();
3421     notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3422     notify->post();
3423 }
3424 
onMessageReceived(const sp<AMessage> & msg)3425 bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3426     bool handled = false;
3427 
3428     switch (msg->what()) {
3429         case ACodec::kWhatConfigureComponent:
3430         {
3431             onConfigureComponent(msg);
3432             handled = true;
3433             break;
3434         }
3435 
3436         case ACodec::kWhatCreateInputSurface:
3437         {
3438             onCreateInputSurface(msg);
3439             handled = true;
3440             break;
3441         }
3442 
3443         case ACodec::kWhatStart:
3444         {
3445             onStart();
3446             handled = true;
3447             break;
3448         }
3449 
3450         case ACodec::kWhatShutdown:
3451         {
3452             int32_t keepComponentAllocated;
3453             CHECK(msg->findInt32(
3454                         "keepComponentAllocated", &keepComponentAllocated));
3455 
3456             onShutdown(keepComponentAllocated);
3457 
3458             handled = true;
3459             break;
3460         }
3461 
3462         case ACodec::kWhatFlush:
3463         {
3464             sp<AMessage> notify = mCodec->mNotify->dup();
3465             notify->setInt32("what", ACodec::kWhatFlushCompleted);
3466             notify->post();
3467 
3468             handled = true;
3469             break;
3470         }
3471 
3472         default:
3473             return BaseState::onMessageReceived(msg);
3474     }
3475 
3476     return handled;
3477 }
3478 
onConfigureComponent(const sp<AMessage> & msg)3479 bool ACodec::LoadedState::onConfigureComponent(
3480         const sp<AMessage> &msg) {
3481     ALOGV("onConfigureComponent");
3482 
3483     CHECK(mCodec->mNode != NULL);
3484 
3485     AString mime;
3486     CHECK(msg->findString("mime", &mime));
3487 
3488     status_t err = mCodec->configureCodec(mime.c_str(), msg);
3489 
3490     if (err != OK) {
3491         ALOGE("[%s] configureCodec returning error %d",
3492               mCodec->mComponentName.c_str(), err);
3493 
3494         mCodec->signalError(OMX_ErrorUndefined, err);
3495         return false;
3496     }
3497 
3498     sp<RefBase> obj;
3499     if (msg->findObject("native-window", &obj)
3500             && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
3501         sp<NativeWindowWrapper> nativeWindow(
3502                 static_cast<NativeWindowWrapper *>(obj.get()));
3503         CHECK(nativeWindow != NULL);
3504         mCodec->mNativeWindow = nativeWindow->getNativeWindow();
3505 
3506         native_window_set_scaling_mode(
3507                 mCodec->mNativeWindow.get(),
3508                 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3509     }
3510     CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3511 
3512     {
3513         sp<AMessage> notify = mCodec->mNotify->dup();
3514         notify->setInt32("what", ACodec::kWhatComponentConfigured);
3515         notify->post();
3516     }
3517 
3518     return true;
3519 }
3520 
onCreateInputSurface(const sp<AMessage> & msg)3521 void ACodec::LoadedState::onCreateInputSurface(
3522         const sp<AMessage> &msg) {
3523     ALOGV("onCreateInputSurface");
3524 
3525     sp<AMessage> notify = mCodec->mNotify->dup();
3526     notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
3527 
3528     sp<IGraphicBufferProducer> bufferProducer;
3529     status_t err;
3530 
3531     err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
3532             &bufferProducer);
3533     if (err == OK) {
3534         notify->setObject("input-surface",
3535                 new BufferProducerWrapper(bufferProducer));
3536     } else {
3537         // Can't use mCodec->signalError() here -- MediaCodec won't forward
3538         // the error through because it's in the "configured" state.  We
3539         // send a kWhatInputSurfaceCreated with an error value instead.
3540         ALOGE("[%s] onCreateInputSurface returning error %d",
3541                 mCodec->mComponentName.c_str(), err);
3542         notify->setInt32("err", err);
3543     }
3544     notify->post();
3545 }
3546 
onStart()3547 void ACodec::LoadedState::onStart() {
3548     ALOGV("onStart");
3549 
3550     CHECK_EQ(mCodec->mOMX->sendCommand(
3551                 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3552              (status_t)OK);
3553 
3554     mCodec->changeState(mCodec->mLoadedToIdleState);
3555 }
3556 
3557 ////////////////////////////////////////////////////////////////////////////////
3558 
LoadedToIdleState(ACodec * codec)3559 ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3560     : BaseState(codec) {
3561 }
3562 
stateEntered()3563 void ACodec::LoadedToIdleState::stateEntered() {
3564     ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3565 
3566     status_t err;
3567     if ((err = allocateBuffers()) != OK) {
3568         ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3569              "(error 0x%08x)",
3570              err);
3571 
3572         mCodec->signalError(OMX_ErrorUndefined, err);
3573 
3574         mCodec->changeState(mCodec->mLoadedState);
3575     }
3576 }
3577 
allocateBuffers()3578 status_t ACodec::LoadedToIdleState::allocateBuffers() {
3579     status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3580 
3581     if (err != OK) {
3582         return err;
3583     }
3584 
3585     return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3586 }
3587 
onMessageReceived(const sp<AMessage> & msg)3588 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3589     switch (msg->what()) {
3590         case kWhatShutdown:
3591         {
3592             mCodec->deferMessage(msg);
3593             return true;
3594         }
3595 
3596         case kWhatSignalEndOfInputStream:
3597         {
3598             mCodec->onSignalEndOfInputStream();
3599             return true;
3600         }
3601 
3602         case kWhatResume:
3603         {
3604             // We'll be active soon enough.
3605             return true;
3606         }
3607 
3608         case kWhatFlush:
3609         {
3610             // We haven't even started yet, so we're flushed alright...
3611             sp<AMessage> notify = mCodec->mNotify->dup();
3612             notify->setInt32("what", ACodec::kWhatFlushCompleted);
3613             notify->post();
3614             return true;
3615         }
3616 
3617         default:
3618             return BaseState::onMessageReceived(msg);
3619     }
3620 }
3621 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)3622 bool ACodec::LoadedToIdleState::onOMXEvent(
3623         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3624     switch (event) {
3625         case OMX_EventCmdComplete:
3626         {
3627             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3628             CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3629 
3630             CHECK_EQ(mCodec->mOMX->sendCommand(
3631                         mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3632                      (status_t)OK);
3633 
3634             mCodec->changeState(mCodec->mIdleToExecutingState);
3635 
3636             return true;
3637         }
3638 
3639         default:
3640             return BaseState::onOMXEvent(event, data1, data2);
3641     }
3642 }
3643 
3644 ////////////////////////////////////////////////////////////////////////////////
3645 
IdleToExecutingState(ACodec * codec)3646 ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3647     : BaseState(codec) {
3648 }
3649 
stateEntered()3650 void ACodec::IdleToExecutingState::stateEntered() {
3651     ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3652 }
3653 
onMessageReceived(const sp<AMessage> & msg)3654 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3655     switch (msg->what()) {
3656         case kWhatShutdown:
3657         {
3658             mCodec->deferMessage(msg);
3659             return true;
3660         }
3661 
3662         case kWhatResume:
3663         {
3664             // We'll be active soon enough.
3665             return true;
3666         }
3667 
3668         case kWhatFlush:
3669         {
3670             // We haven't even started yet, so we're flushed alright...
3671             sp<AMessage> notify = mCodec->mNotify->dup();
3672             notify->setInt32("what", ACodec::kWhatFlushCompleted);
3673             notify->post();
3674 
3675             return true;
3676         }
3677 
3678         case kWhatSignalEndOfInputStream:
3679         {
3680             mCodec->onSignalEndOfInputStream();
3681             return true;
3682         }
3683 
3684         default:
3685             return BaseState::onMessageReceived(msg);
3686     }
3687 }
3688 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)3689 bool ACodec::IdleToExecutingState::onOMXEvent(
3690         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3691     switch (event) {
3692         case OMX_EventCmdComplete:
3693         {
3694             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3695             CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3696 
3697             mCodec->mExecutingState->resume();
3698             mCodec->changeState(mCodec->mExecutingState);
3699 
3700             return true;
3701         }
3702 
3703         default:
3704             return BaseState::onOMXEvent(event, data1, data2);
3705     }
3706 }
3707 
3708 ////////////////////////////////////////////////////////////////////////////////
3709 
ExecutingState(ACodec * codec)3710 ACodec::ExecutingState::ExecutingState(ACodec *codec)
3711     : BaseState(codec),
3712       mActive(false) {
3713 }
3714 
getPortMode(OMX_U32 portIndex)3715 ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3716         OMX_U32 portIndex) {
3717     return RESUBMIT_BUFFERS;
3718 }
3719 
submitOutputBuffers()3720 void ACodec::ExecutingState::submitOutputBuffers() {
3721     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3722         BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3723 
3724         if (mCodec->mNativeWindow != NULL) {
3725             CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3726                     || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3727 
3728             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3729                 continue;
3730             }
3731         } else {
3732             CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3733         }
3734 
3735         ALOGV("[%s] calling fillBuffer %p",
3736              mCodec->mComponentName.c_str(), info->mBufferID);
3737 
3738         CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3739                  (status_t)OK);
3740 
3741         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3742     }
3743 }
3744 
resume()3745 void ACodec::ExecutingState::resume() {
3746     if (mActive) {
3747         ALOGV("[%s] We're already active, no need to resume.",
3748              mCodec->mComponentName.c_str());
3749 
3750         return;
3751     }
3752 
3753     submitOutputBuffers();
3754 
3755     // Post the first input buffer.
3756     CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3757     BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3758 
3759     postFillThisBuffer(info);
3760 
3761     mActive = true;
3762 }
3763 
stateEntered()3764 void ACodec::ExecutingState::stateEntered() {
3765     ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3766 
3767     mCodec->processDeferredMessages();
3768 }
3769 
onMessageReceived(const sp<AMessage> & msg)3770 bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3771     bool handled = false;
3772 
3773     switch (msg->what()) {
3774         case kWhatShutdown:
3775         {
3776             int32_t keepComponentAllocated;
3777             CHECK(msg->findInt32(
3778                         "keepComponentAllocated", &keepComponentAllocated));
3779 
3780             mCodec->mShutdownInProgress = true;
3781             mCodec->mKeepComponentAllocated = keepComponentAllocated;
3782 
3783             mActive = false;
3784 
3785             CHECK_EQ(mCodec->mOMX->sendCommand(
3786                         mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3787                      (status_t)OK);
3788 
3789             mCodec->changeState(mCodec->mExecutingToIdleState);
3790 
3791             handled = true;
3792             break;
3793         }
3794 
3795         case kWhatFlush:
3796         {
3797             ALOGV("[%s] ExecutingState flushing now "
3798                  "(codec owns %d/%d input, %d/%d output).",
3799                     mCodec->mComponentName.c_str(),
3800                     mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3801                     mCodec->mBuffers[kPortIndexInput].size(),
3802                     mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3803                     mCodec->mBuffers[kPortIndexOutput].size());
3804 
3805             mActive = false;
3806 
3807             CHECK_EQ(mCodec->mOMX->sendCommand(
3808                         mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3809                      (status_t)OK);
3810 
3811             mCodec->changeState(mCodec->mFlushingState);
3812             handled = true;
3813             break;
3814         }
3815 
3816         case kWhatResume:
3817         {
3818             resume();
3819 
3820             handled = true;
3821             break;
3822         }
3823 
3824         case kWhatRequestIDRFrame:
3825         {
3826             status_t err = mCodec->requestIDRFrame();
3827             if (err != OK) {
3828                 ALOGW("Requesting an IDR frame failed.");
3829             }
3830 
3831             handled = true;
3832             break;
3833         }
3834 
3835         case kWhatSetParameters:
3836         {
3837             sp<AMessage> params;
3838             CHECK(msg->findMessage("params", &params));
3839 
3840             status_t err = mCodec->setParameters(params);
3841 
3842             sp<AMessage> reply;
3843             if (msg->findMessage("reply", &reply)) {
3844                 reply->setInt32("err", err);
3845                 reply->post();
3846             }
3847 
3848             handled = true;
3849             break;
3850         }
3851 
3852         case ACodec::kWhatSignalEndOfInputStream:
3853         {
3854             mCodec->onSignalEndOfInputStream();
3855             handled = true;
3856             break;
3857         }
3858 
3859         default:
3860             handled = BaseState::onMessageReceived(msg);
3861             break;
3862     }
3863 
3864     return handled;
3865 }
3866 
setParameters(const sp<AMessage> & params)3867 status_t ACodec::setParameters(const sp<AMessage> &params) {
3868     int32_t videoBitrate;
3869     if (params->findInt32("videoBitrate", &videoBitrate)) {
3870         OMX_VIDEO_CONFIG_BITRATETYPE configParams;
3871         InitOMXParams(&configParams);
3872         configParams.nPortIndex = kPortIndexOutput;
3873         configParams.nEncodeBitrate = videoBitrate;
3874 
3875         status_t err = mOMX->setConfig(
3876                 mNode,
3877                 OMX_IndexConfigVideoBitrate,
3878                 &configParams,
3879                 sizeof(configParams));
3880 
3881         if (err != OK) {
3882             ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
3883                    videoBitrate, err);
3884 
3885             return err;
3886         }
3887     }
3888 
3889     return OK;
3890 }
3891 
onSignalEndOfInputStream()3892 void ACodec::onSignalEndOfInputStream() {
3893     sp<AMessage> notify = mNotify->dup();
3894     notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
3895 
3896     status_t err = mOMX->signalEndOfInputStream(mNode);
3897     if (err != OK) {
3898         notify->setInt32("err", err);
3899     }
3900     notify->post();
3901 }
3902 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)3903 bool ACodec::ExecutingState::onOMXEvent(
3904         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3905     switch (event) {
3906         case OMX_EventPortSettingsChanged:
3907         {
3908             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3909 
3910             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3911                 CHECK_EQ(mCodec->mOMX->sendCommand(
3912                             mCodec->mNode,
3913                             OMX_CommandPortDisable, kPortIndexOutput),
3914                          (status_t)OK);
3915 
3916                 mCodec->freeOutputBuffersNotOwnedByComponent();
3917 
3918                 mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
3919             } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
3920                 mCodec->mSentFormat = false;
3921             } else {
3922                 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3923                      mCodec->mComponentName.c_str(), data2);
3924             }
3925 
3926             return true;
3927         }
3928 
3929         case OMX_EventBufferFlag:
3930         {
3931             return true;
3932         }
3933 
3934         default:
3935             return BaseState::onOMXEvent(event, data1, data2);
3936     }
3937 }
3938 
3939 ////////////////////////////////////////////////////////////////////////////////
3940 
OutputPortSettingsChangedState(ACodec * codec)3941 ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3942         ACodec *codec)
3943     : BaseState(codec) {
3944 }
3945 
getPortMode(OMX_U32 portIndex)3946 ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3947         OMX_U32 portIndex) {
3948     if (portIndex == kPortIndexOutput) {
3949         return FREE_BUFFERS;
3950     }
3951 
3952     CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
3953 
3954     return RESUBMIT_BUFFERS;
3955 }
3956 
onMessageReceived(const sp<AMessage> & msg)3957 bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
3958         const sp<AMessage> &msg) {
3959     bool handled = false;
3960 
3961     switch (msg->what()) {
3962         case kWhatFlush:
3963         case kWhatShutdown:
3964         case kWhatResume:
3965         {
3966             if (msg->what() == kWhatResume) {
3967                 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
3968             }
3969 
3970             mCodec->deferMessage(msg);
3971             handled = true;
3972             break;
3973         }
3974 
3975         default:
3976             handled = BaseState::onMessageReceived(msg);
3977             break;
3978     }
3979 
3980     return handled;
3981 }
3982 
stateEntered()3983 void ACodec::OutputPortSettingsChangedState::stateEntered() {
3984     ALOGV("[%s] Now handling output port settings change",
3985          mCodec->mComponentName.c_str());
3986 }
3987 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)3988 bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3989         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3990     switch (event) {
3991         case OMX_EventCmdComplete:
3992         {
3993             if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3994                 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3995 
3996                 ALOGV("[%s] Output port now disabled.",
3997                         mCodec->mComponentName.c_str());
3998 
3999                 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4000                 mCodec->mDealer[kPortIndexOutput].clear();
4001 
4002                 CHECK_EQ(mCodec->mOMX->sendCommand(
4003                             mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4004                          (status_t)OK);
4005 
4006                 status_t err;
4007                 if ((err = mCodec->allocateBuffersOnPort(
4008                                 kPortIndexOutput)) != OK) {
4009                     ALOGE("Failed to allocate output port buffers after "
4010                          "port reconfiguration (error 0x%08x)",
4011                          err);
4012 
4013                     mCodec->signalError(OMX_ErrorUndefined, err);
4014 
4015                     // This is technically not correct, but appears to be
4016                     // the only way to free the component instance.
4017                     // Controlled transitioning from excecuting->idle
4018                     // and idle->loaded seem impossible probably because
4019                     // the output port never finishes re-enabling.
4020                     mCodec->mShutdownInProgress = true;
4021                     mCodec->mKeepComponentAllocated = false;
4022                     mCodec->changeState(mCodec->mLoadedState);
4023                 }
4024 
4025                 return true;
4026             } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4027                 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4028 
4029                 mCodec->mSentFormat = false;
4030 
4031                 ALOGV("[%s] Output port now reenabled.",
4032                         mCodec->mComponentName.c_str());
4033 
4034                 if (mCodec->mExecutingState->active()) {
4035                     mCodec->mExecutingState->submitOutputBuffers();
4036                 }
4037 
4038                 mCodec->changeState(mCodec->mExecutingState);
4039 
4040                 return true;
4041             }
4042 
4043             return false;
4044         }
4045 
4046         default:
4047             return false;
4048     }
4049 }
4050 
4051 ////////////////////////////////////////////////////////////////////////////////
4052 
ExecutingToIdleState(ACodec * codec)4053 ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
4054     : BaseState(codec),
4055       mComponentNowIdle(false) {
4056 }
4057 
onMessageReceived(const sp<AMessage> & msg)4058 bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4059     bool handled = false;
4060 
4061     switch (msg->what()) {
4062         case kWhatFlush:
4063         {
4064             // Don't send me a flush request if you previously wanted me
4065             // to shutdown.
4066             TRESPASS();
4067             break;
4068         }
4069 
4070         case kWhatShutdown:
4071         {
4072             // We're already doing that...
4073 
4074             handled = true;
4075             break;
4076         }
4077 
4078         default:
4079             handled = BaseState::onMessageReceived(msg);
4080             break;
4081     }
4082 
4083     return handled;
4084 }
4085 
stateEntered()4086 void ACodec::ExecutingToIdleState::stateEntered() {
4087     ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
4088 
4089     mComponentNowIdle = false;
4090     mCodec->mSentFormat = false;
4091 }
4092 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)4093 bool ACodec::ExecutingToIdleState::onOMXEvent(
4094         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4095     switch (event) {
4096         case OMX_EventCmdComplete:
4097         {
4098             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4099             CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4100 
4101             mComponentNowIdle = true;
4102 
4103             changeStateIfWeOwnAllBuffers();
4104 
4105             return true;
4106         }
4107 
4108         case OMX_EventPortSettingsChanged:
4109         case OMX_EventBufferFlag:
4110         {
4111             // We're shutting down and don't care about this anymore.
4112             return true;
4113         }
4114 
4115         default:
4116             return BaseState::onOMXEvent(event, data1, data2);
4117     }
4118 }
4119 
changeStateIfWeOwnAllBuffers()4120 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
4121     if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4122         CHECK_EQ(mCodec->mOMX->sendCommand(
4123                     mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4124                  (status_t)OK);
4125 
4126         CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4127         CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4128 
4129         if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4130             // We push enough 1x1 blank buffers to ensure that one of
4131             // them has made it to the display.  This allows the OMX
4132             // component teardown to zero out any protected buffers
4133             // without the risk of scanning out one of those buffers.
4134             mCodec->pushBlankBuffersToNativeWindow();
4135         }
4136 
4137         mCodec->changeState(mCodec->mIdleToLoadedState);
4138     }
4139 }
4140 
onInputBufferFilled(const sp<AMessage> & msg)4141 void ACodec::ExecutingToIdleState::onInputBufferFilled(
4142         const sp<AMessage> &msg) {
4143     BaseState::onInputBufferFilled(msg);
4144 
4145     changeStateIfWeOwnAllBuffers();
4146 }
4147 
onOutputBufferDrained(const sp<AMessage> & msg)4148 void ACodec::ExecutingToIdleState::onOutputBufferDrained(
4149         const sp<AMessage> &msg) {
4150     BaseState::onOutputBufferDrained(msg);
4151 
4152     changeStateIfWeOwnAllBuffers();
4153 }
4154 
4155 ////////////////////////////////////////////////////////////////////////////////
4156 
IdleToLoadedState(ACodec * codec)4157 ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4158     : BaseState(codec) {
4159 }
4160 
onMessageReceived(const sp<AMessage> & msg)4161 bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4162     bool handled = false;
4163 
4164     switch (msg->what()) {
4165         case kWhatShutdown:
4166         {
4167             // We're already doing that...
4168 
4169             handled = true;
4170             break;
4171         }
4172 
4173         case kWhatFlush:
4174         {
4175             // Don't send me a flush request if you previously wanted me
4176             // to shutdown.
4177             TRESPASS();
4178             break;
4179         }
4180 
4181         default:
4182             handled = BaseState::onMessageReceived(msg);
4183             break;
4184     }
4185 
4186     return handled;
4187 }
4188 
stateEntered()4189 void ACodec::IdleToLoadedState::stateEntered() {
4190     ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4191 }
4192 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)4193 bool ACodec::IdleToLoadedState::onOMXEvent(
4194         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4195     switch (event) {
4196         case OMX_EventCmdComplete:
4197         {
4198             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4199             CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4200 
4201             mCodec->changeState(mCodec->mLoadedState);
4202 
4203             return true;
4204         }
4205 
4206         default:
4207             return BaseState::onOMXEvent(event, data1, data2);
4208     }
4209 }
4210 
4211 ////////////////////////////////////////////////////////////////////////////////
4212 
FlushingState(ACodec * codec)4213 ACodec::FlushingState::FlushingState(ACodec *codec)
4214     : BaseState(codec) {
4215 }
4216 
stateEntered()4217 void ACodec::FlushingState::stateEntered() {
4218     ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4219 
4220     mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4221 }
4222 
onMessageReceived(const sp<AMessage> & msg)4223 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4224     bool handled = false;
4225 
4226     switch (msg->what()) {
4227         case kWhatShutdown:
4228         {
4229             mCodec->deferMessage(msg);
4230             break;
4231         }
4232 
4233         case kWhatFlush:
4234         {
4235             // We're already doing this right now.
4236             handled = true;
4237             break;
4238         }
4239 
4240         default:
4241             handled = BaseState::onMessageReceived(msg);
4242             break;
4243     }
4244 
4245     return handled;
4246 }
4247 
onOMXEvent(OMX_EVENTTYPE event,OMX_U32 data1,OMX_U32 data2)4248 bool ACodec::FlushingState::onOMXEvent(
4249         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4250     ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4251             mCodec->mComponentName.c_str(), event, data1);
4252 
4253     switch (event) {
4254         case OMX_EventCmdComplete:
4255         {
4256             CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4257 
4258             if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4259                 CHECK(!mFlushComplete[data2]);
4260                 mFlushComplete[data2] = true;
4261 
4262                 if (mFlushComplete[kPortIndexInput]
4263                         && mFlushComplete[kPortIndexOutput]) {
4264                     changeStateIfWeOwnAllBuffers();
4265                 }
4266             } else {
4267                 CHECK_EQ(data2, OMX_ALL);
4268                 CHECK(mFlushComplete[kPortIndexInput]);
4269                 CHECK(mFlushComplete[kPortIndexOutput]);
4270 
4271                 changeStateIfWeOwnAllBuffers();
4272             }
4273 
4274             return true;
4275         }
4276 
4277         case OMX_EventPortSettingsChanged:
4278         {
4279             sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4280             msg->setInt32("type", omx_message::EVENT);
4281             msg->setPointer("node", mCodec->mNode);
4282             msg->setInt32("event", event);
4283             msg->setInt32("data1", data1);
4284             msg->setInt32("data2", data2);
4285 
4286             ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4287                  mCodec->mComponentName.c_str());
4288 
4289             mCodec->deferMessage(msg);
4290 
4291             return true;
4292         }
4293 
4294         default:
4295             return BaseState::onOMXEvent(event, data1, data2);
4296     }
4297 
4298     return true;
4299 }
4300 
onOutputBufferDrained(const sp<AMessage> & msg)4301 void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4302     BaseState::onOutputBufferDrained(msg);
4303 
4304     changeStateIfWeOwnAllBuffers();
4305 }
4306 
onInputBufferFilled(const sp<AMessage> & msg)4307 void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4308     BaseState::onInputBufferFilled(msg);
4309 
4310     changeStateIfWeOwnAllBuffers();
4311 }
4312 
changeStateIfWeOwnAllBuffers()4313 void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4314     if (mFlushComplete[kPortIndexInput]
4315             && mFlushComplete[kPortIndexOutput]
4316             && mCodec->allYourBuffersAreBelongToUs()) {
4317         // We now own all buffers except possibly those still queued with
4318         // the native window for rendering. Let's get those back as well.
4319         mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
4320 
4321         sp<AMessage> notify = mCodec->mNotify->dup();
4322         notify->setInt32("what", ACodec::kWhatFlushCompleted);
4323         notify->post();
4324 
4325         mCodec->mPortEOS[kPortIndexInput] =
4326             mCodec->mPortEOS[kPortIndexOutput] = false;
4327 
4328         mCodec->mInputEOSResult = OK;
4329 
4330         if (mCodec->mSkipCutBuffer != NULL) {
4331             mCodec->mSkipCutBuffer->clear();
4332         }
4333 
4334         mCodec->changeState(mCodec->mExecutingState);
4335     }
4336 }
4337 
4338 }  // namespace android
4339