OMXCodec.cpp revision 1d2acaffde56ad79e6e96f228d7857863462397c
1/*
2 * Copyright (C) 2009 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 "OMXCodec"
19#include <utils/Log.h>
20
21#include "include/AACEncoder.h"
22#include "include/AMRNBEncoder.h"
23#include "include/AMRWBEncoder.h"
24#include "include/AVCEncoder.h"
25#include "include/M4vH263Encoder.h"
26
27#include "include/ESDS.h"
28
29#include <binder/IServiceManager.h>
30#include <binder/MemoryDealer.h>
31#include <binder/ProcessState.h>
32#include <media/stagefright/foundation/ADebug.h>
33#include <media/IMediaPlayerService.h>
34#include <media/stagefright/HardwareAPI.h>
35#include <media/stagefright/MediaBuffer.h>
36#include <media/stagefright/MediaBufferGroup.h>
37#include <media/stagefright/MediaDefs.h>
38#include <media/stagefright/MediaExtractor.h>
39#include <media/stagefright/MetaData.h>
40#include <media/stagefright/OMXCodec.h>
41#include <media/stagefright/Utils.h>
42#include <utils/Vector.h>
43
44#include <OMX_Audio.h>
45#include <OMX_Component.h>
46
47#include "include/avc_utils.h"
48
49namespace android {
50
51// Treat time out as an error if we have not received any output
52// buffers after 3 seconds.
53const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
54
55// OMX Spec defines less than 50 color formats. If the query for
56// color format is executed for more than kMaxColorFormatSupported,
57// the query will fail to avoid looping forever.
58// 1000 is more than enough for us to tell whether the omx
59// component in question is buggy or not.
60const static uint32_t kMaxColorFormatSupported = 1000;
61
62struct CodecInfo {
63    const char *mime;
64    const char *codec;
65};
66
67#define FACTORY_CREATE_ENCODER(name) \
68static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
69    return new name(source, meta); \
70}
71
72#define FACTORY_REF(name) { #name, Make##name },
73
74FACTORY_CREATE_ENCODER(AMRNBEncoder)
75FACTORY_CREATE_ENCODER(AMRWBEncoder)
76FACTORY_CREATE_ENCODER(AACEncoder)
77FACTORY_CREATE_ENCODER(AVCEncoder)
78FACTORY_CREATE_ENCODER(M4vH263Encoder)
79
80static sp<MediaSource> InstantiateSoftwareEncoder(
81        const char *name, const sp<MediaSource> &source,
82        const sp<MetaData> &meta) {
83    struct FactoryInfo {
84        const char *name;
85        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
86    };
87
88    static const FactoryInfo kFactoryInfo[] = {
89        FACTORY_REF(AMRNBEncoder)
90        FACTORY_REF(AMRWBEncoder)
91        FACTORY_REF(AACEncoder)
92        FACTORY_REF(AVCEncoder)
93        FACTORY_REF(M4vH263Encoder)
94    };
95    for (size_t i = 0;
96         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
97        if (!strcmp(name, kFactoryInfo[i].name)) {
98            return (*kFactoryInfo[i].CreateFunc)(source, meta);
99        }
100    }
101
102    return NULL;
103}
104
105#undef FACTORY_REF
106#undef FACTORY_CREATE
107
108static const CodecInfo kDecoderInfo[] = {
109    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
110//    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
111    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.google.mp3.decoder" },
112    { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, "OMX.Nvidia.mp2.decoder" },
113//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
114//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" },
115    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.google.amrnb.decoder" },
116//    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" },
117    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
118    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.google.amrwb.decoder" },
119//    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" },
120    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
121    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.google.aac.decoder" },
122    { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "OMX.google.g711.alaw.decoder" },
123    { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "OMX.google.g711.mlaw.decoder" },
124    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.DECODER" },
125    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" },
126    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" },
127    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
128    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
129    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" },
130    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.google.mpeg4.decoder" },
131    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.DECODER" },
132    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" },
133    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" },
134    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
135    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" },
136    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.google.h263.decoder" },
137    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.DECODER" },
138    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" },
139    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" },
140    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
141    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
142    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" },
143    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.h264.decoder" },
144    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.google.avc.decoder" },
145    { MEDIA_MIMETYPE_AUDIO_VORBIS, "OMX.google.vorbis.decoder" },
146    { MEDIA_MIMETYPE_VIDEO_VPX, "OMX.google.vpx.decoder" },
147    { MEDIA_MIMETYPE_VIDEO_MPEG2, "OMX.Nvidia.mpeg2v.decode" },
148};
149
150static const CodecInfo kEncoderInfo[] = {
151    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
152    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" },
153    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
154    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" },
155    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
156    { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" },
157    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.MPEG4E" },
158    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" },
159    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
160    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
161    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.encoder" },
162    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" },
163    { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" },
164    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.MPEG4E" },
165    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" },
166    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
167    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
168    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.encoder" },
169    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" },
170    { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" },
171    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.H264E" },
172    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" },
173    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" },
174    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
175    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" },
176    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" },
177    { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" },
178};
179
180#undef OPTIONAL
181
182#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
183#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
184#define CODEC_LOGE(x, ...) LOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
185
186struct OMXCodecObserver : public BnOMXObserver {
187    OMXCodecObserver() {
188    }
189
190    void setCodec(const sp<OMXCodec> &target) {
191        mTarget = target;
192    }
193
194    // from IOMXObserver
195    virtual void onMessage(const omx_message &msg) {
196        sp<OMXCodec> codec = mTarget.promote();
197
198        if (codec.get() != NULL) {
199            Mutex::Autolock autoLock(codec->mLock);
200            codec->on_message(msg);
201            codec.clear();
202        }
203    }
204
205protected:
206    virtual ~OMXCodecObserver() {}
207
208private:
209    wp<OMXCodec> mTarget;
210
211    OMXCodecObserver(const OMXCodecObserver &);
212    OMXCodecObserver &operator=(const OMXCodecObserver &);
213};
214
215static const char *GetCodec(const CodecInfo *info, size_t numInfos,
216                            const char *mime, int index) {
217    CHECK(index >= 0);
218    for(size_t i = 0; i < numInfos; ++i) {
219        if (!strcasecmp(mime, info[i].mime)) {
220            if (index == 0) {
221                return info[i].codec;
222            }
223
224            --index;
225        }
226    }
227
228    return NULL;
229}
230
231template<class T>
232static void InitOMXParams(T *params) {
233    params->nSize = sizeof(T);
234    params->nVersion.s.nVersionMajor = 1;
235    params->nVersion.s.nVersionMinor = 0;
236    params->nVersion.s.nRevision = 0;
237    params->nVersion.s.nStep = 0;
238}
239
240static bool IsSoftwareCodec(const char *componentName) {
241    if (!strncmp("OMX.google.", componentName, 11)) {
242        return true;
243    }
244
245    if (!strncmp("OMX.", componentName, 4)) {
246        return false;
247    }
248
249    return true;
250}
251
252// A sort order in which OMX software codecs are first, followed
253// by other (non-OMX) software codecs, followed by everything else.
254static int CompareSoftwareCodecsFirst(
255        const String8 *elem1, const String8 *elem2) {
256    bool isOMX1 = !strncmp(elem1->string(), "OMX.", 4);
257    bool isOMX2 = !strncmp(elem2->string(), "OMX.", 4);
258
259    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
260    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
261
262    if (isSoftwareCodec1) {
263        if (!isSoftwareCodec2) { return -1; }
264
265        if (isOMX1) {
266            if (isOMX2) { return 0; }
267
268            return -1;
269        } else {
270            if (isOMX2) { return 0; }
271
272            return 1;
273        }
274
275        return -1;
276    }
277
278    if (isSoftwareCodec2) {
279        return 1;
280    }
281
282    return 0;
283}
284
285// static
286uint32_t OMXCodec::getComponentQuirks(
287        const char *componentName, bool isEncoder) {
288    uint32_t quirks = 0;
289
290    if (!strcmp(componentName, "OMX.Nvidia.amr.decoder") ||
291         !strcmp(componentName, "OMX.Nvidia.amrwb.decoder") ||
292         !strcmp(componentName, "OMX.Nvidia.aac.decoder") ||
293         !strcmp(componentName, "OMX.Nvidia.mp3.decoder")) {
294        quirks |= kDecoderLiesAboutNumberOfChannels;
295    }
296
297    if (!strcmp(componentName, "OMX.TI.MP3.decode")) {
298        quirks |= kNeedsFlushBeforeDisable;
299        quirks |= kDecoderLiesAboutNumberOfChannels;
300    }
301    if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
302        quirks |= kNeedsFlushBeforeDisable;
303        quirks |= kRequiresFlushCompleteEmulation;
304        quirks |= kSupportsMultipleFramesPerInputBuffer;
305    }
306    if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
307        quirks |= kRequiresLoadedToIdleAfterAllocation;
308        quirks |= kRequiresAllocateBufferOnInputPorts;
309        quirks |= kRequiresAllocateBufferOnOutputPorts;
310        if (!strncmp(componentName, "OMX.qcom.video.encoder.avc", 26)) {
311
312            // The AVC encoder advertises the size of output buffers
313            // based on the input video resolution and assumes
314            // the worst/least compression ratio is 0.5. It is found that
315            // sometimes, the output buffer size is larger than
316            // size advertised by the encoder.
317            quirks |= kRequiresLargerEncoderOutputBuffer;
318        }
319    }
320    if (!strncmp(componentName, "OMX.qcom.7x30.video.encoder.", 28)) {
321    }
322    if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
323        quirks |= kRequiresAllocateBufferOnOutputPorts;
324        quirks |= kDefersOutputBufferAllocation;
325    }
326    if (!strncmp(componentName, "OMX.qcom.7x30.video.decoder.", 28)) {
327        quirks |= kRequiresAllocateBufferOnInputPorts;
328        quirks |= kRequiresAllocateBufferOnOutputPorts;
329        quirks |= kDefersOutputBufferAllocation;
330    }
331
332    if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.DECODER")) {
333        quirks |= kRequiresAllocateBufferOnInputPorts;
334        quirks |= kRequiresAllocateBufferOnOutputPorts;
335    }
336
337    // FIXME:
338    // Remove the quirks after the work is done.
339    else if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.MPEG4E") ||
340             !strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.H264E")) {
341
342        quirks |= kRequiresAllocateBufferOnInputPorts;
343        quirks |= kRequiresAllocateBufferOnOutputPorts;
344    }
345    else if (!strncmp(componentName, "OMX.TI.", 7)) {
346        // Apparently I must not use OMX_UseBuffer on either input or
347        // output ports on any of the TI components or quote:
348        // "(I) may have unexpected problem (sic) which can be timing related
349        //  and hard to reproduce."
350
351        quirks |= kRequiresAllocateBufferOnInputPorts;
352        quirks |= kRequiresAllocateBufferOnOutputPorts;
353        if (!strncmp(componentName, "OMX.TI.Video.encoder", 20)) {
354            quirks |= kAvoidMemcopyInputRecordingFrames;
355        }
356    }
357
358    if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
359        quirks |= kInputBufferSizesAreBogus;
360    }
361
362    if (!strncmp(componentName, "OMX.SEC.", 8) && !isEncoder) {
363        // These output buffers contain no video data, just some
364        // opaque information that allows the overlay to display their
365        // contents.
366        quirks |= kOutputBuffersAreUnreadable;
367    }
368
369    return quirks;
370}
371
372// static
373void OMXCodec::findMatchingCodecs(
374        const char *mime,
375        bool createEncoder, const char *matchComponentName,
376        uint32_t flags,
377        Vector<String8> *matchingCodecs) {
378    matchingCodecs->clear();
379
380    for (int index = 0;; ++index) {
381        const char *componentName;
382
383        if (createEncoder) {
384            componentName = GetCodec(
385                    kEncoderInfo,
386                    sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
387                    mime, index);
388        } else {
389            componentName = GetCodec(
390                    kDecoderInfo,
391                    sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
392                    mime, index);
393        }
394
395        if (!componentName) {
396            break;
397        }
398
399        // If a specific codec is requested, skip the non-matching ones.
400        if (matchComponentName && strcmp(componentName, matchComponentName)) {
401            continue;
402        }
403
404        // When requesting software-only codecs, only push software codecs
405        // When requesting hardware-only codecs, only push hardware codecs
406        // When there is request neither for software-only nor for
407        // hardware-only codecs, push all codecs
408        if (((flags & kSoftwareCodecsOnly) &&   IsSoftwareCodec(componentName)) ||
409            ((flags & kHardwareCodecsOnly) &&  !IsSoftwareCodec(componentName)) ||
410            (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
411
412            matchingCodecs->push(String8(componentName));
413        }
414    }
415
416    if (flags & kPreferSoftwareCodecs) {
417        matchingCodecs->sort(CompareSoftwareCodecsFirst);
418    }
419}
420
421// static
422sp<MediaSource> OMXCodec::Create(
423        const sp<IOMX> &omx,
424        const sp<MetaData> &meta, bool createEncoder,
425        const sp<MediaSource> &source,
426        const char *matchComponentName,
427        uint32_t flags,
428        const sp<ANativeWindow> &nativeWindow) {
429    int32_t requiresSecureBuffers;
430    if (source->getFormat()->findInt32(
431                kKeyRequiresSecureBuffers,
432                &requiresSecureBuffers)
433            && requiresSecureBuffers) {
434        flags |= kIgnoreCodecSpecificData;
435        flags |= kUseSecureInputBuffers;
436    }
437
438    const char *mime;
439    bool success = meta->findCString(kKeyMIMEType, &mime);
440    CHECK(success);
441
442    Vector<String8> matchingCodecs;
443    findMatchingCodecs(
444            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
445
446    if (matchingCodecs.isEmpty()) {
447        return NULL;
448    }
449
450    sp<OMXCodecObserver> observer = new OMXCodecObserver;
451    IOMX::node_id node = 0;
452
453    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
454        const char *componentNameBase = matchingCodecs[i].string();
455        const char *componentName = componentNameBase;
456
457        AString tmp;
458        if (flags & kUseSecureInputBuffers) {
459            tmp = componentNameBase;
460            tmp.append(".secure");
461
462            componentName = tmp.c_str();
463        }
464
465        if (createEncoder) {
466            sp<MediaSource> softwareCodec =
467                InstantiateSoftwareEncoder(componentName, source, meta);
468
469            if (softwareCodec != NULL) {
470                LOGV("Successfully allocated software codec '%s'", componentName);
471
472                return softwareCodec;
473            }
474        }
475
476        LOGV("Attempting to allocate OMX node '%s'", componentName);
477
478        uint32_t quirks = getComponentQuirks(componentNameBase, createEncoder);
479
480        if (!createEncoder
481                && (quirks & kOutputBuffersAreUnreadable)
482                && (flags & kClientNeedsFramebuffer)) {
483            if (strncmp(componentName, "OMX.SEC.", 8)) {
484                // For OMX.SEC.* decoders we can enable a special mode that
485                // gives the client access to the framebuffer contents.
486
487                LOGW("Component '%s' does not give the client access to "
488                     "the framebuffer contents. Skipping.",
489                     componentName);
490
491                continue;
492            }
493        }
494
495        status_t err = omx->allocateNode(componentName, observer, &node);
496        if (err == OK) {
497            LOGV("Successfully allocated OMX node '%s'", componentName);
498
499            sp<OMXCodec> codec = new OMXCodec(
500                    omx, node, quirks, flags,
501                    createEncoder, mime, componentName,
502                    source, nativeWindow);
503
504            observer->setCodec(codec);
505
506            err = codec->configureCodec(meta);
507
508            if (err == OK) {
509                if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) {
510                    codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime;
511                }
512
513                return codec;
514            }
515
516            LOGV("Failed to configure codec '%s'", componentName);
517        }
518    }
519
520    return NULL;
521}
522
523status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
524    LOGV("configureCodec protected=%d",
525         (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
526
527    if (!(mFlags & kIgnoreCodecSpecificData)) {
528        uint32_t type;
529        const void *data;
530        size_t size;
531        if (meta->findData(kKeyESDS, &type, &data, &size)) {
532            ESDS esds((const char *)data, size);
533            CHECK_EQ(esds.InitCheck(), (status_t)OK);
534
535            const void *codec_specific_data;
536            size_t codec_specific_data_size;
537            esds.getCodecSpecificInfo(
538                    &codec_specific_data, &codec_specific_data_size);
539
540            addCodecSpecificData(
541                    codec_specific_data, codec_specific_data_size);
542        } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
543            // Parse the AVCDecoderConfigurationRecord
544
545            const uint8_t *ptr = (const uint8_t *)data;
546
547            CHECK(size >= 7);
548            CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
549            uint8_t profile = ptr[1];
550            uint8_t level = ptr[3];
551
552            // There is decodable content out there that fails the following
553            // assertion, let's be lenient for now...
554            // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
555
556            size_t lengthSize = 1 + (ptr[4] & 3);
557
558            // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
559            // violates it...
560            // CHECK((ptr[5] >> 5) == 7);  // reserved
561
562            size_t numSeqParameterSets = ptr[5] & 31;
563
564            ptr += 6;
565            size -= 6;
566
567            for (size_t i = 0; i < numSeqParameterSets; ++i) {
568                CHECK(size >= 2);
569                size_t length = U16_AT(ptr);
570
571                ptr += 2;
572                size -= 2;
573
574                CHECK(size >= length);
575
576                addCodecSpecificData(ptr, length);
577
578                ptr += length;
579                size -= length;
580            }
581
582            CHECK(size >= 1);
583            size_t numPictureParameterSets = *ptr;
584            ++ptr;
585            --size;
586
587            for (size_t i = 0; i < numPictureParameterSets; ++i) {
588                CHECK(size >= 2);
589                size_t length = U16_AT(ptr);
590
591                ptr += 2;
592                size -= 2;
593
594                CHECK(size >= length);
595
596                addCodecSpecificData(ptr, length);
597
598                ptr += length;
599                size -= length;
600            }
601
602            CODEC_LOGI(
603                    "AVC profile = %d (%s), level = %d",
604                    (int)profile, AVCProfileToString(profile), level);
605
606            if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
607                && (profile != kAVCProfileBaseline || level > 30)) {
608                // This stream exceeds the decoder's capabilities. The decoder
609                // does not handle this gracefully and would clobber the heap
610                // and wreak havoc instead...
611
612                LOGE("Profile and/or level exceed the decoder's capabilities.");
613                return ERROR_UNSUPPORTED;
614            }
615        } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
616            addCodecSpecificData(data, size);
617
618            CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
619            addCodecSpecificData(data, size);
620        }
621    }
622
623    int32_t bitRate = 0;
624    if (mIsEncoder) {
625        CHECK(meta->findInt32(kKeyBitRate, &bitRate));
626    }
627    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
628        setAMRFormat(false /* isWAMR */, bitRate);
629    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
630        setAMRFormat(true /* isWAMR */, bitRate);
631    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
632        int32_t numChannels, sampleRate;
633        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
634        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
635
636        status_t err = setAACFormat(numChannels, sampleRate, bitRate);
637        if (err != OK) {
638            CODEC_LOGE("setAACFormat() failed (err = %d)", err);
639            return err;
640        }
641    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
642            || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
643        // These are PCM-like formats with a fixed sample rate but
644        // a variable number of channels.
645
646        int32_t numChannels;
647        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
648
649        setG711Format(numChannels);
650    }
651
652    if (!strncasecmp(mMIME, "video/", 6)) {
653
654        if (mIsEncoder) {
655            setVideoInputFormat(mMIME, meta);
656        } else {
657            int32_t width, height;
658            bool success = meta->findInt32(kKeyWidth, &width);
659            success = success && meta->findInt32(kKeyHeight, &height);
660            CHECK(success);
661            status_t err = setVideoOutputFormat(
662                    mMIME, width, height);
663
664            if (err != OK) {
665                return err;
666            }
667        }
668    }
669
670    if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
671        && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
672        OMX_COLOR_FORMATTYPE format =
673            OMX_COLOR_Format32bitARGB8888;
674            // OMX_COLOR_FormatYUV420PackedPlanar;
675            // OMX_COLOR_FormatCbYCrY;
676            // OMX_COLOR_FormatYUV411Planar;
677
678        int32_t width, height;
679        bool success = meta->findInt32(kKeyWidth, &width);
680        success = success && meta->findInt32(kKeyHeight, &height);
681
682        int32_t compressedSize;
683        success = success && meta->findInt32(
684                kKeyMaxInputSize, &compressedSize);
685
686        CHECK(success);
687        CHECK(compressedSize > 0);
688
689        setImageOutputFormat(format, width, height);
690        setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
691    }
692
693    int32_t maxInputSize;
694    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
695        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
696    }
697
698    if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
699        || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")
700        || !strcmp(mComponentName, "OMX.TI.AAC.encode")) {
701        setMinBufferSize(kPortIndexOutput, 8192);  // XXX
702    }
703
704    initOutputFormat(meta);
705
706    if ((mFlags & kClientNeedsFramebuffer)
707            && !strncmp(mComponentName, "OMX.SEC.", 8)) {
708        OMX_INDEXTYPE index;
709
710        status_t err =
711            mOMX->getExtensionIndex(
712                    mNode,
713                    "OMX.SEC.index.ThumbnailMode",
714                    &index);
715
716        if (err != OK) {
717            return err;
718        }
719
720        OMX_BOOL enable = OMX_TRUE;
721        err = mOMX->setConfig(mNode, index, &enable, sizeof(enable));
722
723        if (err != OK) {
724            CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') "
725                       "returned error 0x%08x", err);
726
727            return err;
728        }
729
730        mQuirks &= ~kOutputBuffersAreUnreadable;
731    }
732
733    if (mNativeWindow != NULL
734        && !mIsEncoder
735        && !strncasecmp(mMIME, "video/", 6)
736        && !strncmp(mComponentName, "OMX.", 4)) {
737        status_t err = initNativeWindow();
738        if (err != OK) {
739            return err;
740        }
741    }
742
743    return OK;
744}
745
746void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
747    OMX_PARAM_PORTDEFINITIONTYPE def;
748    InitOMXParams(&def);
749    def.nPortIndex = portIndex;
750
751    status_t err = mOMX->getParameter(
752            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
753    CHECK_EQ(err, (status_t)OK);
754
755    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
756        || (def.nBufferSize < size)) {
757        def.nBufferSize = size;
758    }
759
760    err = mOMX->setParameter(
761            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
762    CHECK_EQ(err, (status_t)OK);
763
764    err = mOMX->getParameter(
765            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
766    CHECK_EQ(err, (status_t)OK);
767
768    // Make sure the setting actually stuck.
769    if (portIndex == kPortIndexInput
770            && (mQuirks & kInputBufferSizesAreBogus)) {
771        CHECK_EQ(def.nBufferSize, size);
772    } else {
773        CHECK(def.nBufferSize >= size);
774    }
775}
776
777status_t OMXCodec::setVideoPortFormatType(
778        OMX_U32 portIndex,
779        OMX_VIDEO_CODINGTYPE compressionFormat,
780        OMX_COLOR_FORMATTYPE colorFormat) {
781    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
782    InitOMXParams(&format);
783    format.nPortIndex = portIndex;
784    format.nIndex = 0;
785    bool found = false;
786
787    OMX_U32 index = 0;
788    for (;;) {
789        format.nIndex = index;
790        status_t err = mOMX->getParameter(
791                mNode, OMX_IndexParamVideoPortFormat,
792                &format, sizeof(format));
793
794        if (err != OK) {
795            return err;
796        }
797
798        // The following assertion is violated by TI's video decoder.
799        // CHECK_EQ(format.nIndex, index);
800
801#if 1
802        CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
803             portIndex,
804             index, format.eCompressionFormat, format.eColorFormat);
805#endif
806
807        if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
808            if (portIndex == kPortIndexInput
809                    && colorFormat == format.eColorFormat) {
810                // eCompressionFormat does not seem right.
811                found = true;
812                break;
813            }
814            if (portIndex == kPortIndexOutput
815                    && compressionFormat == format.eCompressionFormat) {
816                // eColorFormat does not seem right.
817                found = true;
818                break;
819            }
820        }
821
822        if (format.eCompressionFormat == compressionFormat
823                && format.eColorFormat == colorFormat) {
824            found = true;
825            break;
826        }
827
828        ++index;
829        if (index >= kMaxColorFormatSupported) {
830            CODEC_LOGE("color format %d or compression format %d is not supported",
831                colorFormat, compressionFormat);
832            return UNKNOWN_ERROR;
833        }
834    }
835
836    if (!found) {
837        return UNKNOWN_ERROR;
838    }
839
840    CODEC_LOGV("found a match.");
841    status_t err = mOMX->setParameter(
842            mNode, OMX_IndexParamVideoPortFormat,
843            &format, sizeof(format));
844
845    return err;
846}
847
848static size_t getFrameSize(
849        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
850    switch (colorFormat) {
851        case OMX_COLOR_FormatYCbYCr:
852        case OMX_COLOR_FormatCbYCrY:
853            return width * height * 2;
854
855        case OMX_COLOR_FormatYUV420Planar:
856        case OMX_COLOR_FormatYUV420SemiPlanar:
857        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
858        /*
859        * FIXME: For the Opaque color format, the frame size does not
860        * need to be (w*h*3)/2. It just needs to
861        * be larger than certain minimum buffer size. However,
862        * currently, this opaque foramt has been tested only on
863        * YUV420 formats. If that is changed, then we need to revisit
864        * this part in the future
865        */
866        case OMX_COLOR_FormatAndroidOpaque:
867            return (width * height * 3) / 2;
868
869        default:
870            CHECK(!"Should not be here. Unsupported color format.");
871            break;
872    }
873}
874
875status_t OMXCodec::findTargetColorFormat(
876        const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) {
877    LOGV("findTargetColorFormat");
878    CHECK(mIsEncoder);
879
880    *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
881    int32_t targetColorFormat;
882    if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) {
883        *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat;
884    } else {
885        if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) {
886            *colorFormat = OMX_COLOR_FormatYCbYCr;
887        }
888    }
889
890
891    // Check whether the target color format is supported.
892    return isColorFormatSupported(*colorFormat, kPortIndexInput);
893}
894
895status_t OMXCodec::isColorFormatSupported(
896        OMX_COLOR_FORMATTYPE colorFormat, int portIndex) {
897    LOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat));
898
899    // Enumerate all the color formats supported by
900    // the omx component to see whether the given
901    // color format is supported.
902    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
903    InitOMXParams(&portFormat);
904    portFormat.nPortIndex = portIndex;
905    OMX_U32 index = 0;
906    portFormat.nIndex = index;
907    while (true) {
908        if (OMX_ErrorNone != mOMX->getParameter(
909                mNode, OMX_IndexParamVideoPortFormat,
910                &portFormat, sizeof(portFormat))) {
911            break;
912        }
913        // Make sure that omx component does not overwrite
914        // the incremented index (bug 2897413).
915        CHECK_EQ(index, portFormat.nIndex);
916        if (portFormat.eColorFormat == colorFormat) {
917            CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat);
918            return OK;  // colorFormat is supported!
919        }
920        ++index;
921        portFormat.nIndex = index;
922
923        if (index >= kMaxColorFormatSupported) {
924            CODEC_LOGE("More than %ld color formats are supported???", index);
925            break;
926        }
927    }
928
929    CODEC_LOGE("color format %d is not supported", colorFormat);
930    return UNKNOWN_ERROR;
931}
932
933void OMXCodec::setVideoInputFormat(
934        const char *mime, const sp<MetaData>& meta) {
935
936    int32_t width, height, frameRate, bitRate, stride, sliceHeight;
937    bool success = meta->findInt32(kKeyWidth, &width);
938    success = success && meta->findInt32(kKeyHeight, &height);
939    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
940    success = success && meta->findInt32(kKeyBitRate, &bitRate);
941    success = success && meta->findInt32(kKeyStride, &stride);
942    success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
943    CHECK(success);
944    CHECK(stride != 0);
945
946    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
947    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
948        compressionFormat = OMX_VIDEO_CodingAVC;
949    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
950        compressionFormat = OMX_VIDEO_CodingMPEG4;
951    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
952        compressionFormat = OMX_VIDEO_CodingH263;
953    } else {
954        LOGE("Not a supported video mime type: %s", mime);
955        CHECK(!"Should not be here. Not a supported video mime type.");
956    }
957
958    OMX_COLOR_FORMATTYPE colorFormat;
959    CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat));
960
961    status_t err;
962    OMX_PARAM_PORTDEFINITIONTYPE def;
963    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
964
965    //////////////////////// Input port /////////////////////////
966    CHECK_EQ(setVideoPortFormatType(
967            kPortIndexInput, OMX_VIDEO_CodingUnused,
968            colorFormat), (status_t)OK);
969
970    InitOMXParams(&def);
971    def.nPortIndex = kPortIndexInput;
972
973    err = mOMX->getParameter(
974            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
975    CHECK_EQ(err, (status_t)OK);
976
977    def.nBufferSize = getFrameSize(colorFormat,
978            stride > 0? stride: -stride, sliceHeight);
979
980    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
981
982    video_def->nFrameWidth = width;
983    video_def->nFrameHeight = height;
984    video_def->nStride = stride;
985    video_def->nSliceHeight = sliceHeight;
986    video_def->xFramerate = (frameRate << 16);  // Q16 format
987    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
988    video_def->eColorFormat = colorFormat;
989
990    err = mOMX->setParameter(
991            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
992    CHECK_EQ(err, (status_t)OK);
993
994    //////////////////////// Output port /////////////////////////
995    CHECK_EQ(setVideoPortFormatType(
996            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
997            (status_t)OK);
998    InitOMXParams(&def);
999    def.nPortIndex = kPortIndexOutput;
1000
1001    err = mOMX->getParameter(
1002            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1003
1004    CHECK_EQ(err, (status_t)OK);
1005    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1006
1007    video_def->nFrameWidth = width;
1008    video_def->nFrameHeight = height;
1009    video_def->xFramerate = 0;      // No need for output port
1010    video_def->nBitrate = bitRate;  // Q16 format
1011    video_def->eCompressionFormat = compressionFormat;
1012    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1013    if (mQuirks & kRequiresLargerEncoderOutputBuffer) {
1014        // Increases the output buffer size
1015        def.nBufferSize = ((def.nBufferSize * 3) >> 1);
1016    }
1017
1018    err = mOMX->setParameter(
1019            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1020    CHECK_EQ(err, (status_t)OK);
1021
1022    /////////////////// Codec-specific ////////////////////////
1023    switch (compressionFormat) {
1024        case OMX_VIDEO_CodingMPEG4:
1025        {
1026            CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK);
1027            break;
1028        }
1029
1030        case OMX_VIDEO_CodingH263:
1031            CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK);
1032            break;
1033
1034        case OMX_VIDEO_CodingAVC:
1035        {
1036            CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK);
1037            break;
1038        }
1039
1040        default:
1041            CHECK(!"Support for this compressionFormat to be implemented.");
1042            break;
1043    }
1044}
1045
1046static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
1047    if (iFramesInterval < 0) {
1048        return 0xFFFFFFFF;
1049    } else if (iFramesInterval == 0) {
1050        return 0;
1051    }
1052    OMX_U32 ret = frameRate * iFramesInterval;
1053    CHECK(ret > 1);
1054    return ret;
1055}
1056
1057status_t OMXCodec::setupErrorCorrectionParameters() {
1058    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
1059    InitOMXParams(&errorCorrectionType);
1060    errorCorrectionType.nPortIndex = kPortIndexOutput;
1061
1062    status_t err = mOMX->getParameter(
1063            mNode, OMX_IndexParamVideoErrorCorrection,
1064            &errorCorrectionType, sizeof(errorCorrectionType));
1065    if (err != OK) {
1066        LOGW("Error correction param query is not supported");
1067        return OK;  // Optional feature. Ignore this failure
1068    }
1069
1070    errorCorrectionType.bEnableHEC = OMX_FALSE;
1071    errorCorrectionType.bEnableResync = OMX_TRUE;
1072    errorCorrectionType.nResynchMarkerSpacing = 256;
1073    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
1074    errorCorrectionType.bEnableRVLC = OMX_FALSE;
1075
1076    err = mOMX->setParameter(
1077            mNode, OMX_IndexParamVideoErrorCorrection,
1078            &errorCorrectionType, sizeof(errorCorrectionType));
1079    if (err != OK) {
1080        LOGW("Error correction param configuration is not supported");
1081    }
1082
1083    // Optional feature. Ignore the failure.
1084    return OK;
1085}
1086
1087status_t OMXCodec::setupBitRate(int32_t bitRate) {
1088    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
1089    InitOMXParams(&bitrateType);
1090    bitrateType.nPortIndex = kPortIndexOutput;
1091
1092    status_t err = mOMX->getParameter(
1093            mNode, OMX_IndexParamVideoBitrate,
1094            &bitrateType, sizeof(bitrateType));
1095    CHECK_EQ(err, (status_t)OK);
1096
1097    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
1098    bitrateType.nTargetBitrate = bitRate;
1099
1100    err = mOMX->setParameter(
1101            mNode, OMX_IndexParamVideoBitrate,
1102            &bitrateType, sizeof(bitrateType));
1103    CHECK_EQ(err, (status_t)OK);
1104    return OK;
1105}
1106
1107status_t OMXCodec::getVideoProfileLevel(
1108        const sp<MetaData>& meta,
1109        const CodecProfileLevel& defaultProfileLevel,
1110        CodecProfileLevel &profileLevel) {
1111    CODEC_LOGV("Default profile: %ld, level %ld",
1112            defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
1113
1114    // Are the default profile and level overwriten?
1115    int32_t profile, level;
1116    if (!meta->findInt32(kKeyVideoProfile, &profile)) {
1117        profile = defaultProfileLevel.mProfile;
1118    }
1119    if (!meta->findInt32(kKeyVideoLevel, &level)) {
1120        level = defaultProfileLevel.mLevel;
1121    }
1122    CODEC_LOGV("Target profile: %d, level: %d", profile, level);
1123
1124    // Are the target profile and level supported by the encoder?
1125    OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
1126    InitOMXParams(&param);
1127    param.nPortIndex = kPortIndexOutput;
1128    for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
1129        status_t err = mOMX->getParameter(
1130                mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
1131                &param, sizeof(param));
1132
1133        if (err != OK) break;
1134
1135        int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
1136        int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
1137        CODEC_LOGV("Supported profile: %d, level %d",
1138            supportedProfile, supportedLevel);
1139
1140        if (profile == supportedProfile &&
1141            level <= supportedLevel) {
1142            // We can further check whether the level is a valid
1143            // value; but we will leave that to the omx encoder component
1144            // via OMX_SetParameter call.
1145            profileLevel.mProfile = profile;
1146            profileLevel.mLevel = level;
1147            return OK;
1148        }
1149    }
1150
1151    CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
1152            profile, level);
1153    return BAD_VALUE;
1154}
1155
1156status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
1157    int32_t iFramesInterval, frameRate, bitRate;
1158    bool success = meta->findInt32(kKeyBitRate, &bitRate);
1159    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1160    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1161    CHECK(success);
1162    OMX_VIDEO_PARAM_H263TYPE h263type;
1163    InitOMXParams(&h263type);
1164    h263type.nPortIndex = kPortIndexOutput;
1165
1166    status_t err = mOMX->getParameter(
1167            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1168    CHECK_EQ(err, (status_t)OK);
1169
1170    h263type.nAllowedPictureTypes =
1171        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1172
1173    h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1174    if (h263type.nPFrames == 0) {
1175        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1176    }
1177    h263type.nBFrames = 0;
1178
1179    // Check profile and level parameters
1180    CodecProfileLevel defaultProfileLevel, profileLevel;
1181    defaultProfileLevel.mProfile = h263type.eProfile;
1182    defaultProfileLevel.mLevel = h263type.eLevel;
1183    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1184    if (err != OK) return err;
1185    h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
1186    h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
1187
1188    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
1189    h263type.bForceRoundingTypeToZero = OMX_FALSE;
1190    h263type.nPictureHeaderRepetition = 0;
1191    h263type.nGOBHeaderInterval = 0;
1192
1193    err = mOMX->setParameter(
1194            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
1195    CHECK_EQ(err, (status_t)OK);
1196
1197    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1198    CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
1199
1200    return OK;
1201}
1202
1203status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
1204    int32_t iFramesInterval, frameRate, bitRate;
1205    bool success = meta->findInt32(kKeyBitRate, &bitRate);
1206    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1207    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1208    CHECK(success);
1209    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
1210    InitOMXParams(&mpeg4type);
1211    mpeg4type.nPortIndex = kPortIndexOutput;
1212
1213    status_t err = mOMX->getParameter(
1214            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1215    CHECK_EQ(err, (status_t)OK);
1216
1217    mpeg4type.nSliceHeaderSpacing = 0;
1218    mpeg4type.bSVH = OMX_FALSE;
1219    mpeg4type.bGov = OMX_FALSE;
1220
1221    mpeg4type.nAllowedPictureTypes =
1222        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1223
1224    mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1225    if (mpeg4type.nPFrames == 0) {
1226        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1227    }
1228    mpeg4type.nBFrames = 0;
1229    mpeg4type.nIDCVLCThreshold = 0;
1230    mpeg4type.bACPred = OMX_TRUE;
1231    mpeg4type.nMaxPacketSize = 256;
1232    mpeg4type.nTimeIncRes = 1000;
1233    mpeg4type.nHeaderExtension = 0;
1234    mpeg4type.bReversibleVLC = OMX_FALSE;
1235
1236    // Check profile and level parameters
1237    CodecProfileLevel defaultProfileLevel, profileLevel;
1238    defaultProfileLevel.mProfile = mpeg4type.eProfile;
1239    defaultProfileLevel.mLevel = mpeg4type.eLevel;
1240    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1241    if (err != OK) return err;
1242    mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
1243    mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
1244
1245    err = mOMX->setParameter(
1246            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
1247    CHECK_EQ(err, (status_t)OK);
1248
1249    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1250    CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
1251
1252    return OK;
1253}
1254
1255status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
1256    int32_t iFramesInterval, frameRate, bitRate;
1257    bool success = meta->findInt32(kKeyBitRate, &bitRate);
1258    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
1259    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
1260    CHECK(success);
1261
1262    OMX_VIDEO_PARAM_AVCTYPE h264type;
1263    InitOMXParams(&h264type);
1264    h264type.nPortIndex = kPortIndexOutput;
1265
1266    status_t err = mOMX->getParameter(
1267            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1268    CHECK_EQ(err, (status_t)OK);
1269
1270    h264type.nAllowedPictureTypes =
1271        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
1272
1273    // Check profile and level parameters
1274    CodecProfileLevel defaultProfileLevel, profileLevel;
1275    defaultProfileLevel.mProfile = h264type.eProfile;
1276    defaultProfileLevel.mLevel = h264type.eLevel;
1277    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
1278    if (err != OK) return err;
1279    h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
1280    h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
1281
1282    // FIXME:
1283    // Remove the workaround after the work in done.
1284    if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) {
1285        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
1286    }
1287
1288    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
1289        h264type.nSliceHeaderSpacing = 0;
1290        h264type.bUseHadamard = OMX_TRUE;
1291        h264type.nRefFrames = 1;
1292        h264type.nBFrames = 0;
1293        h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
1294        if (h264type.nPFrames == 0) {
1295            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
1296        }
1297        h264type.nRefIdx10ActiveMinus1 = 0;
1298        h264type.nRefIdx11ActiveMinus1 = 0;
1299        h264type.bEntropyCodingCABAC = OMX_FALSE;
1300        h264type.bWeightedPPrediction = OMX_FALSE;
1301        h264type.bconstIpred = OMX_FALSE;
1302        h264type.bDirect8x8Inference = OMX_FALSE;
1303        h264type.bDirectSpatialTemporal = OMX_FALSE;
1304        h264type.nCabacInitIdc = 0;
1305    }
1306
1307    if (h264type.nBFrames != 0) {
1308        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
1309    }
1310
1311    h264type.bEnableUEP = OMX_FALSE;
1312    h264type.bEnableFMO = OMX_FALSE;
1313    h264type.bEnableASO = OMX_FALSE;
1314    h264type.bEnableRS = OMX_FALSE;
1315    h264type.bFrameMBsOnly = OMX_TRUE;
1316    h264type.bMBAFF = OMX_FALSE;
1317    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
1318
1319    if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName)) {
1320        h264type.eLevel = OMX_VIDEO_AVCLevelMax;
1321    }
1322
1323    err = mOMX->setParameter(
1324            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
1325    CHECK_EQ(err, (status_t)OK);
1326
1327    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
1328
1329    return OK;
1330}
1331
1332status_t OMXCodec::setVideoOutputFormat(
1333        const char *mime, OMX_U32 width, OMX_U32 height) {
1334    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
1335
1336    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
1337    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
1338        compressionFormat = OMX_VIDEO_CodingAVC;
1339    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
1340        compressionFormat = OMX_VIDEO_CodingMPEG4;
1341    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
1342        compressionFormat = OMX_VIDEO_CodingH263;
1343    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
1344        compressionFormat = OMX_VIDEO_CodingVPX;
1345    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
1346        compressionFormat = OMX_VIDEO_CodingMPEG2;
1347    } else {
1348        LOGE("Not a supported video mime type: %s", mime);
1349        CHECK(!"Should not be here. Not a supported video mime type.");
1350    }
1351
1352    status_t err = setVideoPortFormatType(
1353            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1354
1355    if (err != OK) {
1356        return err;
1357    }
1358
1359#if 1
1360    {
1361        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1362        InitOMXParams(&format);
1363        format.nPortIndex = kPortIndexOutput;
1364        format.nIndex = 0;
1365
1366        status_t err = mOMX->getParameter(
1367                mNode, OMX_IndexParamVideoPortFormat,
1368                &format, sizeof(format));
1369        CHECK_EQ(err, (status_t)OK);
1370        CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1371
1372        CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1373               || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1374               || format.eColorFormat == OMX_COLOR_FormatCbYCrY
1375               || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
1376               || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
1377
1378        err = mOMX->setParameter(
1379                mNode, OMX_IndexParamVideoPortFormat,
1380                &format, sizeof(format));
1381
1382        if (err != OK) {
1383            return err;
1384        }
1385    }
1386#endif
1387
1388    OMX_PARAM_PORTDEFINITIONTYPE def;
1389    InitOMXParams(&def);
1390    def.nPortIndex = kPortIndexInput;
1391
1392    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1393
1394    err = mOMX->getParameter(
1395            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1396
1397    CHECK_EQ(err, (status_t)OK);
1398
1399#if 1
1400    // XXX Need a (much) better heuristic to compute input buffer sizes.
1401    const size_t X = 64 * 1024;
1402    if (def.nBufferSize < X) {
1403        def.nBufferSize = X;
1404    }
1405#endif
1406
1407    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1408
1409    video_def->nFrameWidth = width;
1410    video_def->nFrameHeight = height;
1411
1412    video_def->eCompressionFormat = compressionFormat;
1413    video_def->eColorFormat = OMX_COLOR_FormatUnused;
1414
1415    err = mOMX->setParameter(
1416            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1417
1418    if (err != OK) {
1419        return err;
1420    }
1421
1422    ////////////////////////////////////////////////////////////////////////////
1423
1424    InitOMXParams(&def);
1425    def.nPortIndex = kPortIndexOutput;
1426
1427    err = mOMX->getParameter(
1428            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1429    CHECK_EQ(err, (status_t)OK);
1430    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1431
1432#if 0
1433    def.nBufferSize =
1434        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
1435#endif
1436
1437    video_def->nFrameWidth = width;
1438    video_def->nFrameHeight = height;
1439
1440    err = mOMX->setParameter(
1441            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1442
1443    return err;
1444}
1445
1446OMXCodec::OMXCodec(
1447        const sp<IOMX> &omx, IOMX::node_id node,
1448        uint32_t quirks, uint32_t flags,
1449        bool isEncoder,
1450        const char *mime,
1451        const char *componentName,
1452        const sp<MediaSource> &source,
1453        const sp<ANativeWindow> &nativeWindow)
1454    : mOMX(omx),
1455      mOMXLivesLocally(omx->livesLocally(getpid())),
1456      mNode(node),
1457      mQuirks(quirks),
1458      mFlags(flags),
1459      mIsEncoder(isEncoder),
1460      mMIME(strdup(mime)),
1461      mComponentName(strdup(componentName)),
1462      mSource(source),
1463      mCodecSpecificDataIndex(0),
1464      mState(LOADED),
1465      mInitialBufferSubmit(true),
1466      mSignalledEOS(false),
1467      mNoMoreOutputData(false),
1468      mOutputPortSettingsHaveChanged(false),
1469      mSeekTimeUs(-1),
1470      mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
1471      mTargetTimeUs(-1),
1472      mOutputPortSettingsChangedPending(false),
1473      mLeftOverBuffer(NULL),
1474      mPaused(false),
1475      mNativeWindow(
1476              (!strncmp(componentName, "OMX.google.", 11)
1477              || !strcmp(componentName, "OMX.Nvidia.mpeg2v.decode"))
1478                        ? NULL : nativeWindow) {
1479    mPortStatus[kPortIndexInput] = ENABLED;
1480    mPortStatus[kPortIndexOutput] = ENABLED;
1481
1482    setComponentRole();
1483}
1484
1485// static
1486void OMXCodec::setComponentRole(
1487        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
1488        const char *mime) {
1489    struct MimeToRole {
1490        const char *mime;
1491        const char *decoderRole;
1492        const char *encoderRole;
1493    };
1494
1495    static const MimeToRole kMimeToRole[] = {
1496        { MEDIA_MIMETYPE_AUDIO_MPEG,
1497            "audio_decoder.mp3", "audio_encoder.mp3" },
1498        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
1499            "audio_decoder.mp1", "audio_encoder.mp1" },
1500        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
1501            "audio_decoder.mp2", "audio_encoder.mp2" },
1502        { MEDIA_MIMETYPE_AUDIO_MPEG,
1503            "audio_decoder.mp3", "audio_encoder.mp3" },
1504        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1505            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1506        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1507            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1508        { MEDIA_MIMETYPE_AUDIO_AAC,
1509            "audio_decoder.aac", "audio_encoder.aac" },
1510        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1511            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1512        { MEDIA_MIMETYPE_VIDEO_AVC,
1513            "video_decoder.avc", "video_encoder.avc" },
1514        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1515            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1516        { MEDIA_MIMETYPE_VIDEO_H263,
1517            "video_decoder.h263", "video_encoder.h263" },
1518    };
1519
1520    static const size_t kNumMimeToRole =
1521        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1522
1523    size_t i;
1524    for (i = 0; i < kNumMimeToRole; ++i) {
1525        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1526            break;
1527        }
1528    }
1529
1530    if (i == kNumMimeToRole) {
1531        return;
1532    }
1533
1534    const char *role =
1535        isEncoder ? kMimeToRole[i].encoderRole
1536                  : kMimeToRole[i].decoderRole;
1537
1538    if (role != NULL) {
1539        OMX_PARAM_COMPONENTROLETYPE roleParams;
1540        InitOMXParams(&roleParams);
1541
1542        strncpy((char *)roleParams.cRole,
1543                role, OMX_MAX_STRINGNAME_SIZE - 1);
1544
1545        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1546
1547        status_t err = omx->setParameter(
1548                node, OMX_IndexParamStandardComponentRole,
1549                &roleParams, sizeof(roleParams));
1550
1551        if (err != OK) {
1552            LOGW("Failed to set standard component role '%s'.", role);
1553        }
1554    }
1555}
1556
1557void OMXCodec::setComponentRole() {
1558    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
1559}
1560
1561OMXCodec::~OMXCodec() {
1562    mSource.clear();
1563
1564    CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE);
1565
1566    status_t err = mOMX->freeNode(mNode);
1567    CHECK_EQ(err, (status_t)OK);
1568
1569    mNode = NULL;
1570    setState(DEAD);
1571
1572    clearCodecSpecificData();
1573
1574    free(mComponentName);
1575    mComponentName = NULL;
1576
1577    free(mMIME);
1578    mMIME = NULL;
1579}
1580
1581status_t OMXCodec::init() {
1582    // mLock is held.
1583
1584    CHECK_EQ((int)mState, (int)LOADED);
1585
1586    status_t err;
1587    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
1588        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1589        CHECK_EQ(err, (status_t)OK);
1590        setState(LOADED_TO_IDLE);
1591    }
1592
1593    err = allocateBuffers();
1594    if (err != (status_t)OK) {
1595        return err;
1596    }
1597
1598    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
1599        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
1600        CHECK_EQ(err, (status_t)OK);
1601
1602        setState(LOADED_TO_IDLE);
1603    }
1604
1605    while (mState != EXECUTING && mState != ERROR) {
1606        mAsyncCompletion.wait(mLock);
1607    }
1608
1609    return mState == ERROR ? UNKNOWN_ERROR : OK;
1610}
1611
1612// static
1613bool OMXCodec::isIntermediateState(State state) {
1614    return state == LOADED_TO_IDLE
1615        || state == IDLE_TO_EXECUTING
1616        || state == EXECUTING_TO_IDLE
1617        || state == IDLE_TO_LOADED
1618        || state == RECONFIGURING;
1619}
1620
1621status_t OMXCodec::allocateBuffers() {
1622    status_t err = allocateBuffersOnPort(kPortIndexInput);
1623
1624    if (err != OK) {
1625        return err;
1626    }
1627
1628    return allocateBuffersOnPort(kPortIndexOutput);
1629}
1630
1631status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
1632    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
1633        return allocateOutputBuffersFromNativeWindow();
1634    }
1635
1636    if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
1637        LOGE("protected output buffers must be stent to an ANativeWindow");
1638        return PERMISSION_DENIED;
1639    }
1640
1641    status_t err = OK;
1642    if ((mFlags & kStoreMetaDataInVideoBuffers)
1643            && portIndex == kPortIndexInput) {
1644        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1645        if (err != OK) {
1646            LOGE("Storing meta data in video buffers is not supported");
1647            return err;
1648        }
1649    }
1650
1651    OMX_PARAM_PORTDEFINITIONTYPE def;
1652    InitOMXParams(&def);
1653    def.nPortIndex = portIndex;
1654
1655    err = mOMX->getParameter(
1656            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1657
1658    if (err != OK) {
1659        return err;
1660    }
1661
1662    CODEC_LOGV("allocating %lu buffers of size %lu on %s port",
1663            def.nBufferCountActual, def.nBufferSize,
1664            portIndex == kPortIndexInput ? "input" : "output");
1665
1666    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
1667    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
1668
1669    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
1670        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
1671        CHECK(mem.get() != NULL);
1672
1673        BufferInfo info;
1674        info.mData = NULL;
1675        info.mSize = def.nBufferSize;
1676
1677        IOMX::buffer_id buffer;
1678        if (portIndex == kPortIndexInput
1679                && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
1680                    || (mFlags & kUseSecureInputBuffers))) {
1681            if (mOMXLivesLocally) {
1682                mem.clear();
1683
1684                err = mOMX->allocateBuffer(
1685                        mNode, portIndex, def.nBufferSize, &buffer,
1686                        &info.mData);
1687            } else {
1688                err = mOMX->allocateBufferWithBackup(
1689                        mNode, portIndex, mem, &buffer);
1690            }
1691        } else if (portIndex == kPortIndexOutput
1692                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
1693            if (mOMXLivesLocally) {
1694                mem.clear();
1695
1696                err = mOMX->allocateBuffer(
1697                        mNode, portIndex, def.nBufferSize, &buffer,
1698                        &info.mData);
1699            } else {
1700                err = mOMX->allocateBufferWithBackup(
1701                        mNode, portIndex, mem, &buffer);
1702            }
1703        } else {
1704            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
1705        }
1706
1707        if (err != OK) {
1708            LOGE("allocate_buffer_with_backup failed");
1709            return err;
1710        }
1711
1712        if (mem != NULL) {
1713            info.mData = mem->pointer();
1714        }
1715
1716        info.mBuffer = buffer;
1717        info.mStatus = OWNED_BY_US;
1718        info.mMem = mem;
1719        info.mMediaBuffer = NULL;
1720
1721        if (portIndex == kPortIndexOutput) {
1722            if (!(mOMXLivesLocally
1723                        && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
1724                        && (mQuirks & kDefersOutputBufferAllocation))) {
1725                // If the node does not fill in the buffer ptr at this time,
1726                // we will defer creating the MediaBuffer until receiving
1727                // the first FILL_BUFFER_DONE notification instead.
1728                info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
1729                info.mMediaBuffer->setObserver(this);
1730            }
1731        }
1732
1733        mPortBuffers[portIndex].push(info);
1734
1735        CODEC_LOGV("allocated buffer %p on %s port", buffer,
1736             portIndex == kPortIndexInput ? "input" : "output");
1737    }
1738
1739    // dumpPortStatus(portIndex);
1740
1741    if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
1742        Vector<MediaBuffer *> buffers;
1743        for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1744            const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
1745
1746            MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
1747            buffers.push(mbuf);
1748        }
1749
1750        status_t err = mSource->setBuffers(buffers);
1751
1752        if (err != OK) {
1753            for (size_t i = 0; i < def.nBufferCountActual; ++i) {
1754                buffers.editItemAt(i)->release();
1755            }
1756            buffers.clear();
1757
1758            CODEC_LOGE(
1759                    "Codec requested to use secure input buffers but "
1760                    "upstream source didn't support that.");
1761
1762            return err;
1763        }
1764    }
1765
1766    return OK;
1767}
1768
1769status_t OMXCodec::applyRotation() {
1770    sp<MetaData> meta = mSource->getFormat();
1771
1772    int32_t rotationDegrees;
1773    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
1774        rotationDegrees = 0;
1775    }
1776
1777    uint32_t transform;
1778    switch (rotationDegrees) {
1779        case 0: transform = 0; break;
1780        case 90: transform = HAL_TRANSFORM_ROT_90; break;
1781        case 180: transform = HAL_TRANSFORM_ROT_180; break;
1782        case 270: transform = HAL_TRANSFORM_ROT_270; break;
1783        default: transform = 0; break;
1784    }
1785
1786    status_t err = OK;
1787
1788    if (transform) {
1789        err = native_window_set_buffers_transform(
1790                mNativeWindow.get(), transform);
1791    }
1792
1793    return err;
1794}
1795
1796status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
1797    // Get the number of buffers needed.
1798    OMX_PARAM_PORTDEFINITIONTYPE def;
1799    InitOMXParams(&def);
1800    def.nPortIndex = kPortIndexOutput;
1801
1802    status_t err = mOMX->getParameter(
1803            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1804    if (err != OK) {
1805        return err;
1806    }
1807
1808    err = native_window_set_scaling_mode(mNativeWindow.get(),
1809            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1810
1811    if (err != OK) {
1812        return err;
1813    }
1814
1815    err = native_window_set_buffers_geometry(
1816            mNativeWindow.get(),
1817            def.format.video.nFrameWidth,
1818            def.format.video.nFrameHeight,
1819            def.format.video.eColorFormat);
1820
1821    if (err != 0) {
1822        LOGE("native_window_set_buffers_geometry failed: %s (%d)",
1823                strerror(-err), -err);
1824        return err;
1825    }
1826
1827    err = applyRotation();
1828    if (err != OK) {
1829        return err;
1830    }
1831
1832    // Set up the native window.
1833    OMX_U32 usage = 0;
1834    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
1835    if (err != 0) {
1836        LOGW("querying usage flags from OMX IL component failed: %d", err);
1837        // XXX: Currently this error is logged, but not fatal.
1838        usage = 0;
1839    }
1840    if (mFlags & kEnableGrallocUsageProtected) {
1841        usage |= GRALLOC_USAGE_PROTECTED;
1842    }
1843
1844    // Make sure to check whether either Stagefright or the video decoder
1845    // requested protected buffers.
1846    if (usage & GRALLOC_USAGE_PROTECTED) {
1847        // Verify that the ANativeWindow sends images directly to
1848        // SurfaceFlinger.
1849        int queuesToNativeWindow = 0;
1850        err = mNativeWindow->query(
1851                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1852                &queuesToNativeWindow);
1853        if (err != 0) {
1854            LOGE("error authenticating native window: %d", err);
1855            return err;
1856        }
1857        if (queuesToNativeWindow != 1) {
1858            LOGE("native window could not be authenticated");
1859            return PERMISSION_DENIED;
1860        }
1861    }
1862
1863    LOGV("native_window_set_usage usage=0x%lx", usage);
1864    err = native_window_set_usage(
1865            mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
1866    if (err != 0) {
1867        LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
1868        return err;
1869    }
1870
1871    int minUndequeuedBufs = 0;
1872    err = mNativeWindow->query(mNativeWindow.get(),
1873            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
1874    if (err != 0) {
1875        LOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1876                strerror(-err), -err);
1877        return err;
1878    }
1879
1880    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
1881    // buffer counts refer to - how do they account for the renderer holding on
1882    // to buffers?
1883    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
1884        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
1885        def.nBufferCountActual = newBufferCount;
1886        err = mOMX->setParameter(
1887                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1888        if (err != OK) {
1889            CODEC_LOGE("setting nBufferCountActual to %lu failed: %d",
1890                    newBufferCount, err);
1891            return err;
1892        }
1893    }
1894
1895    err = native_window_set_buffer_count(
1896            mNativeWindow.get(), def.nBufferCountActual);
1897    if (err != 0) {
1898        LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1899                -err);
1900        return err;
1901    }
1902
1903    CODEC_LOGV("allocating %lu buffers from a native window of size %lu on "
1904            "output port", def.nBufferCountActual, def.nBufferSize);
1905
1906    // Dequeue buffers and send them to OMX
1907    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
1908        ANativeWindowBuffer* buf;
1909        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
1910        if (err != 0) {
1911            LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1912            break;
1913        }
1914
1915        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1916        BufferInfo info;
1917        info.mData = NULL;
1918        info.mSize = def.nBufferSize;
1919        info.mStatus = OWNED_BY_US;
1920        info.mMem = NULL;
1921        info.mMediaBuffer = new MediaBuffer(graphicBuffer);
1922        info.mMediaBuffer->setObserver(this);
1923        mPortBuffers[kPortIndexOutput].push(info);
1924
1925        IOMX::buffer_id bufferId;
1926        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1927                &bufferId);
1928        if (err != 0) {
1929            CODEC_LOGE("registering GraphicBuffer with OMX IL component "
1930                    "failed: %d", err);
1931            break;
1932        }
1933
1934        mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
1935
1936        CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)",
1937                bufferId, graphicBuffer.get());
1938    }
1939
1940    OMX_U32 cancelStart;
1941    OMX_U32 cancelEnd;
1942    if (err != 0) {
1943        // If an error occurred while dequeuing we need to cancel any buffers
1944        // that were dequeued.
1945        cancelStart = 0;
1946        cancelEnd = mPortBuffers[kPortIndexOutput].size();
1947    } else {
1948        // Return the last two buffers to the native window.
1949        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
1950        cancelEnd = def.nBufferCountActual;
1951    }
1952
1953    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1954        BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i);
1955        cancelBufferToNativeWindow(info);
1956    }
1957
1958    return err;
1959}
1960
1961status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
1962    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
1963    CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
1964    int err = mNativeWindow->cancelBuffer(
1965        mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get());
1966    if (err != 0) {
1967      CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
1968
1969      setState(ERROR);
1970      return err;
1971    }
1972    info->mStatus = OWNED_BY_NATIVE_WINDOW;
1973    return OK;
1974}
1975
1976OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
1977    // Dequeue the next buffer from the native window.
1978    ANativeWindowBuffer* buf;
1979    int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
1980    if (err != 0) {
1981      CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
1982
1983      setState(ERROR);
1984      return 0;
1985    }
1986
1987    // Determine which buffer we just dequeued.
1988    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
1989    BufferInfo *bufInfo = 0;
1990    for (size_t i = 0; i < buffers->size(); i++) {
1991      sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i).
1992          mMediaBuffer->graphicBuffer();
1993      if (graphicBuffer->handle == buf->handle) {
1994        bufInfo = &buffers->editItemAt(i);
1995        break;
1996      }
1997    }
1998
1999    if (bufInfo == 0) {
2000        CODEC_LOGE("dequeued unrecognized buffer: %p", buf);
2001
2002        setState(ERROR);
2003        return 0;
2004    }
2005
2006    // The native window no longer owns the buffer.
2007    CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW);
2008    bufInfo->mStatus = OWNED_BY_US;
2009
2010    return bufInfo;
2011}
2012
2013int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) {
2014    CHECK(mIsEncoder);
2015
2016    if (mDecodingTimeList.empty()) {
2017        CHECK(mSignalledEOS || mNoMoreOutputData);
2018        // No corresponding input frame available.
2019        // This could happen when EOS is reached.
2020        return 0;
2021    }
2022
2023    List<int64_t>::iterator it = mDecodingTimeList.begin();
2024    int64_t timeUs = *it;
2025
2026    // If the output buffer is codec specific configuration,
2027    // do not remove the decoding time from the list.
2028    if (!isCodecSpecific) {
2029        mDecodingTimeList.erase(it);
2030    }
2031    return timeUs;
2032}
2033
2034void OMXCodec::on_message(const omx_message &msg) {
2035    if (mState == ERROR) {
2036        LOGW("Dropping OMX message - we're in ERROR state.");
2037        return;
2038    }
2039
2040    switch (msg.type) {
2041        case omx_message::EVENT:
2042        {
2043            onEvent(
2044                 msg.u.event_data.event, msg.u.event_data.data1,
2045                 msg.u.event_data.data2);
2046
2047            break;
2048        }
2049
2050        case omx_message::EMPTY_BUFFER_DONE:
2051        {
2052            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
2053
2054            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
2055
2056            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2057            size_t i = 0;
2058            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
2059                ++i;
2060            }
2061
2062            CHECK(i < buffers->size());
2063            if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) {
2064                LOGW("We already own input buffer %p, yet received "
2065                     "an EMPTY_BUFFER_DONE.", buffer);
2066            }
2067
2068            BufferInfo* info = &buffers->editItemAt(i);
2069            info->mStatus = OWNED_BY_US;
2070
2071            // Buffer could not be released until empty buffer done is called.
2072            if (info->mMediaBuffer != NULL) {
2073                if (mIsEncoder &&
2074                    (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
2075                    // If zero-copy mode is enabled this will send the
2076                    // input buffer back to the upstream source.
2077                    restorePatchedDataPointer(info);
2078                }
2079
2080                info->mMediaBuffer->release();
2081                info->mMediaBuffer = NULL;
2082            }
2083
2084            if (mPortStatus[kPortIndexInput] == DISABLING) {
2085                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
2086
2087                status_t err = freeBuffer(kPortIndexInput, i);
2088                CHECK_EQ(err, (status_t)OK);
2089            } else if (mState != ERROR
2090                    && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
2091                CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
2092
2093                if (mFlags & kUseSecureInputBuffers) {
2094                    drainAnyInputBuffer();
2095                } else {
2096                    drainInputBuffer(&buffers->editItemAt(i));
2097                }
2098            }
2099            break;
2100        }
2101
2102        case omx_message::FILL_BUFFER_DONE:
2103        {
2104            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
2105            OMX_U32 flags = msg.u.extended_buffer_data.flags;
2106
2107            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
2108                 buffer,
2109                 msg.u.extended_buffer_data.range_length,
2110                 flags,
2111                 msg.u.extended_buffer_data.timestamp,
2112                 msg.u.extended_buffer_data.timestamp / 1E6);
2113
2114            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2115            size_t i = 0;
2116            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
2117                ++i;
2118            }
2119
2120            CHECK(i < buffers->size());
2121            BufferInfo *info = &buffers->editItemAt(i);
2122
2123            if (info->mStatus != OWNED_BY_COMPONENT) {
2124                LOGW("We already own output buffer %p, yet received "
2125                     "a FILL_BUFFER_DONE.", buffer);
2126            }
2127
2128            info->mStatus = OWNED_BY_US;
2129
2130            if (mPortStatus[kPortIndexOutput] == DISABLING) {
2131                CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
2132
2133                status_t err = freeBuffer(kPortIndexOutput, i);
2134                CHECK_EQ(err, (status_t)OK);
2135
2136#if 0
2137            } else if (mPortStatus[kPortIndexOutput] == ENABLED
2138                       && (flags & OMX_BUFFERFLAG_EOS)) {
2139                CODEC_LOGV("No more output data.");
2140                mNoMoreOutputData = true;
2141                mBufferFilled.signal();
2142#endif
2143            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
2144                CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
2145
2146                if (info->mMediaBuffer == NULL) {
2147                    CHECK(mOMXLivesLocally);
2148                    CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
2149                    CHECK(mQuirks & kDefersOutputBufferAllocation);
2150
2151                    // The qcom video decoders on Nexus don't actually allocate
2152                    // output buffer memory on a call to OMX_AllocateBuffer
2153                    // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
2154                    // structure is only filled in later.
2155
2156                    info->mMediaBuffer = new MediaBuffer(
2157                            msg.u.extended_buffer_data.data_ptr,
2158                            info->mSize);
2159                    info->mMediaBuffer->setObserver(this);
2160                }
2161
2162                MediaBuffer *buffer = info->mMediaBuffer;
2163                bool isGraphicBuffer = buffer->graphicBuffer() != NULL;
2164
2165                if (!isGraphicBuffer
2166                    && msg.u.extended_buffer_data.range_offset
2167                        + msg.u.extended_buffer_data.range_length
2168                            > buffer->size()) {
2169                    CODEC_LOGE(
2170                            "Codec lied about its buffer size requirements, "
2171                            "sending a buffer larger than the originally "
2172                            "advertised size in FILL_BUFFER_DONE!");
2173                }
2174                buffer->set_range(
2175                        msg.u.extended_buffer_data.range_offset,
2176                        msg.u.extended_buffer_data.range_length);
2177
2178                buffer->meta_data()->clear();
2179
2180                buffer->meta_data()->setInt64(
2181                        kKeyTime, msg.u.extended_buffer_data.timestamp);
2182
2183                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
2184                    buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
2185                }
2186                bool isCodecSpecific = false;
2187                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
2188                    buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
2189                    isCodecSpecific = true;
2190                }
2191
2192                if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) {
2193                    buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
2194                }
2195
2196                buffer->meta_data()->setPointer(
2197                        kKeyPlatformPrivate,
2198                        msg.u.extended_buffer_data.platform_private);
2199
2200                buffer->meta_data()->setPointer(
2201                        kKeyBufferID,
2202                        msg.u.extended_buffer_data.buffer);
2203
2204                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
2205                    CODEC_LOGV("No more output data.");
2206                    mNoMoreOutputData = true;
2207                }
2208
2209                if (mIsEncoder) {
2210                    int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific);
2211                    buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
2212                }
2213
2214                if (mTargetTimeUs >= 0) {
2215                    CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
2216
2217                    if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) {
2218                        CODEC_LOGV(
2219                                "skipping output buffer at timestamp %lld us",
2220                                msg.u.extended_buffer_data.timestamp);
2221
2222                        fillOutputBuffer(info);
2223                        break;
2224                    }
2225
2226                    CODEC_LOGV(
2227                            "returning output buffer at target timestamp "
2228                            "%lld us",
2229                            msg.u.extended_buffer_data.timestamp);
2230
2231                    mTargetTimeUs = -1;
2232                }
2233
2234                mFilledBuffers.push_back(i);
2235                mBufferFilled.signal();
2236                if (mIsEncoder) {
2237                    sched_yield();
2238                }
2239            }
2240
2241            break;
2242        }
2243
2244        default:
2245        {
2246            CHECK(!"should not be here.");
2247            break;
2248        }
2249    }
2250}
2251
2252// Has the format changed in any way that the client would have to be aware of?
2253static bool formatHasNotablyChanged(
2254        const sp<MetaData> &from, const sp<MetaData> &to) {
2255    if (from.get() == NULL && to.get() == NULL) {
2256        return false;
2257    }
2258
2259    if ((from.get() == NULL && to.get() != NULL)
2260        || (from.get() != NULL && to.get() == NULL)) {
2261        return true;
2262    }
2263
2264    const char *mime_from, *mime_to;
2265    CHECK(from->findCString(kKeyMIMEType, &mime_from));
2266    CHECK(to->findCString(kKeyMIMEType, &mime_to));
2267
2268    if (strcasecmp(mime_from, mime_to)) {
2269        return true;
2270    }
2271
2272    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
2273        int32_t colorFormat_from, colorFormat_to;
2274        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
2275        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
2276
2277        if (colorFormat_from != colorFormat_to) {
2278            return true;
2279        }
2280
2281        int32_t width_from, width_to;
2282        CHECK(from->findInt32(kKeyWidth, &width_from));
2283        CHECK(to->findInt32(kKeyWidth, &width_to));
2284
2285        if (width_from != width_to) {
2286            return true;
2287        }
2288
2289        int32_t height_from, height_to;
2290        CHECK(from->findInt32(kKeyHeight, &height_from));
2291        CHECK(to->findInt32(kKeyHeight, &height_to));
2292
2293        if (height_from != height_to) {
2294            return true;
2295        }
2296
2297        int32_t left_from, top_from, right_from, bottom_from;
2298        CHECK(from->findRect(
2299                    kKeyCropRect,
2300                    &left_from, &top_from, &right_from, &bottom_from));
2301
2302        int32_t left_to, top_to, right_to, bottom_to;
2303        CHECK(to->findRect(
2304                    kKeyCropRect,
2305                    &left_to, &top_to, &right_to, &bottom_to));
2306
2307        if (left_to != left_from || top_to != top_from
2308                || right_to != right_from || bottom_to != bottom_from) {
2309            return true;
2310        }
2311    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
2312        int32_t numChannels_from, numChannels_to;
2313        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
2314        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
2315
2316        if (numChannels_from != numChannels_to) {
2317            return true;
2318        }
2319
2320        int32_t sampleRate_from, sampleRate_to;
2321        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
2322        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
2323
2324        if (sampleRate_from != sampleRate_to) {
2325            return true;
2326        }
2327    }
2328
2329    return false;
2330}
2331
2332void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2333    switch (event) {
2334        case OMX_EventCmdComplete:
2335        {
2336            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
2337            break;
2338        }
2339
2340        case OMX_EventError:
2341        {
2342            CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2);
2343
2344            setState(ERROR);
2345            break;
2346        }
2347
2348        case OMX_EventPortSettingsChanged:
2349        {
2350            CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
2351                       data1, data2);
2352
2353            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
2354                // There is no need to check whether mFilledBuffers is empty or not
2355                // when the OMX_EventPortSettingsChanged is not meant for reallocating
2356                // the output buffers.
2357                if (data1 == kPortIndexOutput) {
2358                    CHECK(mFilledBuffers.empty());
2359                }
2360                onPortSettingsChanged(data1);
2361            } else if (data1 == kPortIndexOutput &&
2362                        (data2 == OMX_IndexConfigCommonOutputCrop ||
2363                         data2 == OMX_IndexConfigCommonScale)) {
2364
2365                sp<MetaData> oldOutputFormat = mOutputFormat;
2366                initOutputFormat(mSource->getFormat());
2367
2368                if (data2 == OMX_IndexConfigCommonOutputCrop &&
2369                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
2370                    mOutputPortSettingsHaveChanged = true;
2371
2372                } else if (data2 == OMX_IndexConfigCommonScale) {
2373                    OMX_CONFIG_SCALEFACTORTYPE scale;
2374                    InitOMXParams(&scale);
2375                    scale.nPortIndex = kPortIndexOutput;
2376
2377                    // Change display dimension only when necessary.
2378                    if (OK == mOMX->getConfig(
2379                                        mNode,
2380                                        OMX_IndexConfigCommonScale,
2381                                        &scale, sizeof(scale))) {
2382                        int32_t left, top, right, bottom;
2383                        CHECK(mOutputFormat->findRect(kKeyCropRect,
2384                                                      &left, &top,
2385                                                      &right, &bottom));
2386
2387                        // The scale is in 16.16 format.
2388                        // scale 1.0 = 0x010000. When there is no
2389                        // need to change the display, skip it.
2390                        LOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx",
2391                                scale.xWidth, scale.xHeight);
2392
2393                        if (scale.xWidth != 0x010000) {
2394                            mOutputFormat->setInt32(kKeyDisplayWidth,
2395                                    ((right - left +  1) * scale.xWidth)  >> 16);
2396                            mOutputPortSettingsHaveChanged = true;
2397                        }
2398
2399                        if (scale.xHeight != 0x010000) {
2400                            mOutputFormat->setInt32(kKeyDisplayHeight,
2401                                    ((bottom  - top + 1) * scale.xHeight) >> 16);
2402                            mOutputPortSettingsHaveChanged = true;
2403                        }
2404                    }
2405                }
2406            }
2407            break;
2408        }
2409
2410#if 0
2411        case OMX_EventBufferFlag:
2412        {
2413            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
2414
2415            if (data1 == kPortIndexOutput) {
2416                mNoMoreOutputData = true;
2417            }
2418            break;
2419        }
2420#endif
2421
2422        default:
2423        {
2424            CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
2425            break;
2426        }
2427    }
2428}
2429
2430void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
2431    switch (cmd) {
2432        case OMX_CommandStateSet:
2433        {
2434            onStateChange((OMX_STATETYPE)data);
2435            break;
2436        }
2437
2438        case OMX_CommandPortDisable:
2439        {
2440            OMX_U32 portIndex = data;
2441            CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
2442
2443            CHECK(mState == EXECUTING || mState == RECONFIGURING);
2444            CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING);
2445            CHECK_EQ(mPortBuffers[portIndex].size(), 0u);
2446
2447            mPortStatus[portIndex] = DISABLED;
2448
2449            if (mState == RECONFIGURING) {
2450                CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2451
2452                sp<MetaData> oldOutputFormat = mOutputFormat;
2453                initOutputFormat(mSource->getFormat());
2454
2455                // Don't notify clients if the output port settings change
2456                // wasn't of importance to them, i.e. it may be that just the
2457                // number of buffers has changed and nothing else.
2458                bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
2459                if (!mOutputPortSettingsHaveChanged) {
2460                    mOutputPortSettingsHaveChanged = formatChanged;
2461                }
2462
2463                status_t err = enablePortAsync(portIndex);
2464                if (err != OK) {
2465                    CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err);
2466                    setState(ERROR);
2467                } else {
2468                    err = allocateBuffersOnPort(portIndex);
2469                    if (err != OK) {
2470                        CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
2471                        setState(ERROR);
2472                    }
2473                }
2474            }
2475            break;
2476        }
2477
2478        case OMX_CommandPortEnable:
2479        {
2480            OMX_U32 portIndex = data;
2481            CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
2482
2483            CHECK(mState == EXECUTING || mState == RECONFIGURING);
2484            CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING);
2485
2486            mPortStatus[portIndex] = ENABLED;
2487
2488            if (mState == RECONFIGURING) {
2489                CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2490
2491                setState(EXECUTING);
2492
2493                fillOutputBuffers();
2494            }
2495            break;
2496        }
2497
2498        case OMX_CommandFlush:
2499        {
2500            OMX_U32 portIndex = data;
2501
2502            CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
2503
2504            CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN);
2505            mPortStatus[portIndex] = ENABLED;
2506
2507            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
2508                     mPortBuffers[portIndex].size());
2509
2510            if (mState == RECONFIGURING) {
2511                CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2512
2513                disablePortAsync(portIndex);
2514            } else if (mState == EXECUTING_TO_IDLE) {
2515                if (mPortStatus[kPortIndexInput] == ENABLED
2516                    && mPortStatus[kPortIndexOutput] == ENABLED) {
2517                    CODEC_LOGV("Finished flushing both ports, now completing "
2518                         "transition from EXECUTING to IDLE.");
2519
2520                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
2521                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
2522
2523                    status_t err =
2524                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
2525                    CHECK_EQ(err, (status_t)OK);
2526                }
2527            } else {
2528                // We're flushing both ports in preparation for seeking.
2529
2530                if (mPortStatus[kPortIndexInput] == ENABLED
2531                    && mPortStatus[kPortIndexOutput] == ENABLED) {
2532                    CODEC_LOGV("Finished flushing both ports, now continuing from"
2533                         " seek-time.");
2534
2535                    // We implicitly resume pulling on our upstream source.
2536                    mPaused = false;
2537
2538                    drainInputBuffers();
2539                    fillOutputBuffers();
2540                }
2541
2542                if (mOutputPortSettingsChangedPending) {
2543                    CODEC_LOGV(
2544                            "Honoring deferred output port settings change.");
2545
2546                    mOutputPortSettingsChangedPending = false;
2547                    onPortSettingsChanged(kPortIndexOutput);
2548                }
2549            }
2550
2551            break;
2552        }
2553
2554        default:
2555        {
2556            CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
2557            break;
2558        }
2559    }
2560}
2561
2562void OMXCodec::onStateChange(OMX_STATETYPE newState) {
2563    CODEC_LOGV("onStateChange %d", newState);
2564
2565    switch (newState) {
2566        case OMX_StateIdle:
2567        {
2568            CODEC_LOGV("Now Idle.");
2569            if (mState == LOADED_TO_IDLE) {
2570                status_t err = mOMX->sendCommand(
2571                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
2572
2573                CHECK_EQ(err, (status_t)OK);
2574
2575                setState(IDLE_TO_EXECUTING);
2576            } else {
2577                CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE);
2578
2579                CHECK_EQ(
2580                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
2581                    mPortBuffers[kPortIndexInput].size());
2582
2583                CHECK_EQ(
2584                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
2585                    mPortBuffers[kPortIndexOutput].size());
2586
2587                status_t err = mOMX->sendCommand(
2588                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
2589
2590                CHECK_EQ(err, (status_t)OK);
2591
2592                err = freeBuffersOnPort(kPortIndexInput);
2593                CHECK_EQ(err, (status_t)OK);
2594
2595                err = freeBuffersOnPort(kPortIndexOutput);
2596                CHECK_EQ(err, (status_t)OK);
2597
2598                mPortStatus[kPortIndexInput] = ENABLED;
2599                mPortStatus[kPortIndexOutput] = ENABLED;
2600
2601                setState(IDLE_TO_LOADED);
2602            }
2603            break;
2604        }
2605
2606        case OMX_StateExecuting:
2607        {
2608            CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING);
2609
2610            CODEC_LOGV("Now Executing.");
2611
2612            mOutputPortSettingsChangedPending = false;
2613
2614            setState(EXECUTING);
2615
2616            // Buffers will be submitted to the component in the first
2617            // call to OMXCodec::read as mInitialBufferSubmit is true at
2618            // this point. This ensures that this on_message call returns,
2619            // releases the lock and ::init can notice the state change and
2620            // itself return.
2621            break;
2622        }
2623
2624        case OMX_StateLoaded:
2625        {
2626            CHECK_EQ((int)mState, (int)IDLE_TO_LOADED);
2627
2628            CODEC_LOGV("Now Loaded.");
2629
2630            setState(LOADED);
2631            break;
2632        }
2633
2634        case OMX_StateInvalid:
2635        {
2636            setState(ERROR);
2637            break;
2638        }
2639
2640        default:
2641        {
2642            CHECK(!"should not be here.");
2643            break;
2644        }
2645    }
2646}
2647
2648// static
2649size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
2650    size_t n = 0;
2651    for (size_t i = 0; i < buffers.size(); ++i) {
2652        if (buffers[i].mStatus != OWNED_BY_COMPONENT) {
2653            ++n;
2654        }
2655    }
2656
2657    return n;
2658}
2659
2660status_t OMXCodec::freeBuffersOnPort(
2661        OMX_U32 portIndex, bool onlyThoseWeOwn) {
2662    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
2663
2664    status_t stickyErr = OK;
2665
2666    for (size_t i = buffers->size(); i-- > 0;) {
2667        BufferInfo *info = &buffers->editItemAt(i);
2668
2669        if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) {
2670            continue;
2671        }
2672
2673        CHECK(info->mStatus == OWNED_BY_US
2674                || info->mStatus == OWNED_BY_NATIVE_WINDOW);
2675
2676        CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
2677
2678        status_t err = freeBuffer(portIndex, i);
2679
2680        if (err != OK) {
2681            stickyErr = err;
2682        }
2683
2684    }
2685
2686    CHECK(onlyThoseWeOwn || buffers->isEmpty());
2687
2688    return stickyErr;
2689}
2690
2691status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
2692    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
2693
2694    BufferInfo *info = &buffers->editItemAt(bufIndex);
2695
2696    status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
2697
2698    if (err == OK && info->mMediaBuffer != NULL) {
2699        CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2700        info->mMediaBuffer->setObserver(NULL);
2701
2702        // Make sure nobody but us owns this buffer at this point.
2703        CHECK_EQ(info->mMediaBuffer->refcount(), 0);
2704
2705        // Cancel the buffer if it belongs to an ANativeWindow.
2706        sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
2707        if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) {
2708            err = cancelBufferToNativeWindow(info);
2709        }
2710
2711        info->mMediaBuffer->release();
2712        info->mMediaBuffer = NULL;
2713    }
2714
2715    if (err == OK) {
2716        buffers->removeAt(bufIndex);
2717    }
2718
2719    return err;
2720}
2721
2722void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
2723    CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
2724
2725    CHECK_EQ((int)mState, (int)EXECUTING);
2726    CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
2727    CHECK(!mOutputPortSettingsChangedPending);
2728
2729    if (mPortStatus[kPortIndexOutput] != ENABLED) {
2730        CODEC_LOGV("Deferring output port settings change.");
2731        mOutputPortSettingsChangedPending = true;
2732        return;
2733    }
2734
2735    setState(RECONFIGURING);
2736
2737    if (mQuirks & kNeedsFlushBeforeDisable) {
2738        if (!flushPortAsync(portIndex)) {
2739            onCmdComplete(OMX_CommandFlush, portIndex);
2740        }
2741    } else {
2742        disablePortAsync(portIndex);
2743    }
2744}
2745
2746bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
2747    CHECK(mState == EXECUTING || mState == RECONFIGURING
2748            || mState == EXECUTING_TO_IDLE);
2749
2750    CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
2751         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
2752         mPortBuffers[portIndex].size());
2753
2754    CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
2755    mPortStatus[portIndex] = SHUTTING_DOWN;
2756
2757    if ((mQuirks & kRequiresFlushCompleteEmulation)
2758        && countBuffersWeOwn(mPortBuffers[portIndex])
2759                == mPortBuffers[portIndex].size()) {
2760        // No flush is necessary and this component fails to send a
2761        // flush-complete event in this case.
2762
2763        return false;
2764    }
2765
2766    status_t err =
2767        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
2768    CHECK_EQ(err, (status_t)OK);
2769
2770    return true;
2771}
2772
2773void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
2774    CHECK(mState == EXECUTING || mState == RECONFIGURING);
2775
2776    CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
2777    mPortStatus[portIndex] = DISABLING;
2778
2779    CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex);
2780    status_t err =
2781        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
2782    CHECK_EQ(err, (status_t)OK);
2783
2784    freeBuffersOnPort(portIndex, true);
2785}
2786
2787status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
2788    CHECK(mState == EXECUTING || mState == RECONFIGURING);
2789
2790    CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
2791    mPortStatus[portIndex] = ENABLING;
2792
2793    CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex);
2794    return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
2795}
2796
2797void OMXCodec::fillOutputBuffers() {
2798    CHECK_EQ((int)mState, (int)EXECUTING);
2799
2800    // This is a workaround for some decoders not properly reporting
2801    // end-of-output-stream. If we own all input buffers and also own
2802    // all output buffers and we already signalled end-of-input-stream,
2803    // the end-of-output-stream is implied.
2804    if (mSignalledEOS
2805            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
2806                == mPortBuffers[kPortIndexInput].size()
2807            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
2808                == mPortBuffers[kPortIndexOutput].size()) {
2809        mNoMoreOutputData = true;
2810        mBufferFilled.signal();
2811
2812        return;
2813    }
2814
2815    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
2816    for (size_t i = 0; i < buffers->size(); ++i) {
2817        BufferInfo *info = &buffers->editItemAt(i);
2818        if (info->mStatus == OWNED_BY_US) {
2819            fillOutputBuffer(&buffers->editItemAt(i));
2820        }
2821    }
2822}
2823
2824void OMXCodec::drainInputBuffers() {
2825    CHECK(mState == EXECUTING || mState == RECONFIGURING);
2826
2827    if (mFlags & kUseSecureInputBuffers) {
2828        Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2829        for (size_t i = 0; i < buffers->size(); ++i) {
2830            if (!drainAnyInputBuffer()
2831                    || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
2832                break;
2833            }
2834        }
2835    } else {
2836        Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
2837        for (size_t i = 0; i < buffers->size(); ++i) {
2838            BufferInfo *info = &buffers->editItemAt(i);
2839
2840            if (info->mStatus != OWNED_BY_US) {
2841                continue;
2842            }
2843
2844            if (!drainInputBuffer(info)) {
2845                break;
2846            }
2847
2848            if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
2849                break;
2850            }
2851        }
2852    }
2853}
2854
2855bool OMXCodec::drainAnyInputBuffer() {
2856    return drainInputBuffer((BufferInfo *)NULL);
2857}
2858
2859OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
2860    Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
2861    for (size_t i = 0; i < infos->size(); ++i) {
2862        BufferInfo *info = &infos->editItemAt(i);
2863
2864        if (info->mData == ptr) {
2865            CODEC_LOGV(
2866                    "input buffer data ptr = %p, buffer_id = %p",
2867                    ptr,
2868                    info->mBuffer);
2869
2870            return info;
2871        }
2872    }
2873
2874    TRESPASS();
2875}
2876
2877OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
2878    Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
2879    for (size_t i = 0; i < infos->size(); ++i) {
2880        BufferInfo *info = &infos->editItemAt(i);
2881
2882        if (info->mStatus == OWNED_BY_US) {
2883            return info;
2884        }
2885    }
2886
2887    TRESPASS();
2888}
2889
2890bool OMXCodec::drainInputBuffer(BufferInfo *info) {
2891    if (info != NULL) {
2892        CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
2893    }
2894
2895    if (mSignalledEOS) {
2896        return false;
2897    }
2898
2899    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
2900        CHECK(!(mFlags & kUseSecureInputBuffers));
2901
2902        const CodecSpecificData *specific =
2903            mCodecSpecificData[mCodecSpecificDataIndex];
2904
2905        size_t size = specific->mSize;
2906
2907        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
2908                && !(mQuirks & kWantsNALFragments)) {
2909            static const uint8_t kNALStartCode[4] =
2910                    { 0x00, 0x00, 0x00, 0x01 };
2911
2912            CHECK(info->mSize >= specific->mSize + 4);
2913
2914            size += 4;
2915
2916            memcpy(info->mData, kNALStartCode, 4);
2917            memcpy((uint8_t *)info->mData + 4,
2918                   specific->mData, specific->mSize);
2919        } else {
2920            CHECK(info->mSize >= specific->mSize);
2921            memcpy(info->mData, specific->mData, specific->mSize);
2922        }
2923
2924        mNoMoreOutputData = false;
2925
2926        CODEC_LOGV("calling emptyBuffer with codec specific data");
2927
2928        status_t err = mOMX->emptyBuffer(
2929                mNode, info->mBuffer, 0, size,
2930                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
2931                0);
2932        CHECK_EQ(err, (status_t)OK);
2933
2934        info->mStatus = OWNED_BY_COMPONENT;
2935
2936        ++mCodecSpecificDataIndex;
2937        return true;
2938    }
2939
2940    if (mPaused) {
2941        return false;
2942    }
2943
2944    status_t err;
2945
2946    bool signalEOS = false;
2947    int64_t timestampUs = 0;
2948
2949    size_t offset = 0;
2950    int32_t n = 0;
2951
2952
2953    for (;;) {
2954        MediaBuffer *srcBuffer;
2955        if (mSeekTimeUs >= 0) {
2956            if (mLeftOverBuffer) {
2957                mLeftOverBuffer->release();
2958                mLeftOverBuffer = NULL;
2959            }
2960
2961            MediaSource::ReadOptions options;
2962            options.setSeekTo(mSeekTimeUs, mSeekMode);
2963
2964            mSeekTimeUs = -1;
2965            mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
2966            mBufferFilled.signal();
2967
2968            err = mSource->read(&srcBuffer, &options);
2969
2970            if (err == OK) {
2971                int64_t targetTimeUs;
2972                if (srcBuffer->meta_data()->findInt64(
2973                            kKeyTargetTime, &targetTimeUs)
2974                        && targetTimeUs >= 0) {
2975                    CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs);
2976                    mTargetTimeUs = targetTimeUs;
2977                } else {
2978                    mTargetTimeUs = -1;
2979                }
2980            }
2981        } else if (mLeftOverBuffer) {
2982            srcBuffer = mLeftOverBuffer;
2983            mLeftOverBuffer = NULL;
2984
2985            err = OK;
2986        } else {
2987            err = mSource->read(&srcBuffer);
2988        }
2989
2990        if (err != OK) {
2991            signalEOS = true;
2992            mFinalStatus = err;
2993            mSignalledEOS = true;
2994            mBufferFilled.signal();
2995            break;
2996        }
2997
2998        if (mFlags & kUseSecureInputBuffers) {
2999            info = findInputBufferByDataPointer(srcBuffer->data());
3000            CHECK(info != NULL);
3001        }
3002
3003        size_t remainingBytes = info->mSize - offset;
3004
3005        if (srcBuffer->range_length() > remainingBytes) {
3006            if (offset == 0) {
3007                CODEC_LOGE(
3008                     "Codec's input buffers are too small to accomodate "
3009                     "buffer read from source (info->mSize = %d, srcLength = %d)",
3010                     info->mSize, srcBuffer->range_length());
3011
3012                srcBuffer->release();
3013                srcBuffer = NULL;
3014
3015                setState(ERROR);
3016                return false;
3017            }
3018
3019            mLeftOverBuffer = srcBuffer;
3020            break;
3021        }
3022
3023        bool releaseBuffer = true;
3024        if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
3025            CHECK(mOMXLivesLocally && offset == 0);
3026
3027            OMX_BUFFERHEADERTYPE *header =
3028                (OMX_BUFFERHEADERTYPE *)info->mBuffer;
3029
3030            CHECK(header->pBuffer == info->mData);
3031
3032            header->pBuffer =
3033                (OMX_U8 *)srcBuffer->data() + srcBuffer->range_offset();
3034
3035            releaseBuffer = false;
3036            info->mMediaBuffer = srcBuffer;
3037        } else {
3038            if (mFlags & kStoreMetaDataInVideoBuffers) {
3039                releaseBuffer = false;
3040                info->mMediaBuffer = srcBuffer;
3041            }
3042
3043            if (mFlags & kUseSecureInputBuffers) {
3044                // Data in "info" is already provided at this time.
3045
3046                releaseBuffer = false;
3047
3048                CHECK(info->mMediaBuffer == NULL);
3049                info->mMediaBuffer = srcBuffer;
3050            } else {
3051                CHECK(srcBuffer->data() != NULL) ;
3052                memcpy((uint8_t *)info->mData + offset,
3053                        (const uint8_t *)srcBuffer->data()
3054                            + srcBuffer->range_offset(),
3055                        srcBuffer->range_length());
3056            }
3057        }
3058
3059        int64_t lastBufferTimeUs;
3060        CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
3061        CHECK(lastBufferTimeUs >= 0);
3062        if (mIsEncoder) {
3063            mDecodingTimeList.push_back(lastBufferTimeUs);
3064        }
3065
3066        if (offset == 0) {
3067            timestampUs = lastBufferTimeUs;
3068        }
3069
3070        offset += srcBuffer->range_length();
3071
3072        if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) {
3073            CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer));
3074            CHECK_GE(info->mSize, offset + sizeof(int32_t));
3075
3076            int32_t numPageSamples;
3077            if (!srcBuffer->meta_data()->findInt32(
3078                        kKeyValidSamples, &numPageSamples)) {
3079                numPageSamples = -1;
3080            }
3081
3082            memcpy((uint8_t *)info->mData + offset,
3083                   &numPageSamples,
3084                   sizeof(numPageSamples));
3085
3086            offset += sizeof(numPageSamples);
3087        }
3088
3089        if (releaseBuffer) {
3090            srcBuffer->release();
3091            srcBuffer = NULL;
3092        }
3093
3094        ++n;
3095
3096        if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
3097            break;
3098        }
3099
3100        int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
3101
3102        if (coalescedDurationUs > 250000ll) {
3103            // Don't coalesce more than 250ms worth of encoded data at once.
3104            break;
3105        }
3106    }
3107
3108    if (n > 1) {
3109        LOGV("coalesced %d frames into one input buffer", n);
3110    }
3111
3112    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3113
3114    if (signalEOS) {
3115        flags |= OMX_BUFFERFLAG_EOS;
3116    } else {
3117        mNoMoreOutputData = false;
3118    }
3119
3120    CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
3121               "timestamp %lld us (%.2f secs)",
3122               info->mBuffer, offset,
3123               timestampUs, timestampUs / 1E6);
3124
3125    if (info == NULL) {
3126        CHECK(mFlags & kUseSecureInputBuffers);
3127        CHECK(signalEOS);
3128
3129        // This is fishy, there's still a MediaBuffer corresponding to this
3130        // info available to the source at this point even though we're going
3131        // to use it to signal EOS to the codec.
3132        info = findEmptyInputBuffer();
3133    }
3134
3135    err = mOMX->emptyBuffer(
3136            mNode, info->mBuffer, 0, offset,
3137            flags, timestampUs);
3138
3139    if (err != OK) {
3140        setState(ERROR);
3141        return false;
3142    }
3143
3144    info->mStatus = OWNED_BY_COMPONENT;
3145
3146    // This component does not ever signal the EOS flag on output buffers,
3147    // Thanks for nothing.
3148    if (mSignalledEOS && !strcmp(mComponentName, "OMX.TI.Video.encoder")) {
3149        mNoMoreOutputData = true;
3150        mBufferFilled.signal();
3151    }
3152
3153    return true;
3154}
3155
3156void OMXCodec::fillOutputBuffer(BufferInfo *info) {
3157    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3158
3159    if (mNoMoreOutputData) {
3160        CODEC_LOGV("There is no more output data available, not "
3161             "calling fillOutputBuffer");
3162        return;
3163    }
3164
3165    if (info->mMediaBuffer != NULL) {
3166        sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
3167        if (graphicBuffer != 0) {
3168            // When using a native buffer we need to lock the buffer before
3169            // giving it to OMX.
3170            CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer);
3171            int err = mNativeWindow->lockBuffer(mNativeWindow.get(),
3172                    graphicBuffer.get());
3173            if (err != 0) {
3174                CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err);
3175
3176                setState(ERROR);
3177                return;
3178            }
3179        }
3180    }
3181
3182    CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
3183    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
3184
3185    if (err != OK) {
3186        CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
3187
3188        setState(ERROR);
3189        return;
3190    }
3191
3192    info->mStatus = OWNED_BY_COMPONENT;
3193}
3194
3195bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
3196    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
3197    for (size_t i = 0; i < buffers->size(); ++i) {
3198        if ((*buffers)[i].mBuffer == buffer) {
3199            return drainInputBuffer(&buffers->editItemAt(i));
3200        }
3201    }
3202
3203    CHECK(!"should not be here.");
3204
3205    return false;
3206}
3207
3208void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
3209    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
3210    for (size_t i = 0; i < buffers->size(); ++i) {
3211        if ((*buffers)[i].mBuffer == buffer) {
3212            fillOutputBuffer(&buffers->editItemAt(i));
3213            return;
3214        }
3215    }
3216
3217    CHECK(!"should not be here.");
3218}
3219
3220void OMXCodec::setState(State newState) {
3221    mState = newState;
3222    mAsyncCompletion.signal();
3223
3224    // This may cause some spurious wakeups but is necessary to
3225    // unblock the reader if we enter ERROR state.
3226    mBufferFilled.signal();
3227}
3228
3229status_t OMXCodec::waitForBufferFilled_l() {
3230
3231    if (mIsEncoder) {
3232        // For timelapse video recording, the timelapse video recording may
3233        // not send an input frame for a _long_ time. Do not use timeout
3234        // for video encoding.
3235        return mBufferFilled.wait(mLock);
3236    }
3237    status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
3238    if (err != OK) {
3239        CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
3240            countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
3241            countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
3242    }
3243    return err;
3244}
3245
3246void OMXCodec::setRawAudioFormat(
3247        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
3248
3249    // port definition
3250    OMX_PARAM_PORTDEFINITIONTYPE def;
3251    InitOMXParams(&def);
3252    def.nPortIndex = portIndex;
3253    status_t err = mOMX->getParameter(
3254            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3255    CHECK_EQ(err, (status_t)OK);
3256    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
3257    CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
3258            &def, sizeof(def)), (status_t)OK);
3259
3260    // pcm param
3261    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
3262    InitOMXParams(&pcmParams);
3263    pcmParams.nPortIndex = portIndex;
3264
3265    err = mOMX->getParameter(
3266            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3267
3268    CHECK_EQ(err, (status_t)OK);
3269
3270    pcmParams.nChannels = numChannels;
3271    pcmParams.eNumData = OMX_NumericalDataSigned;
3272    pcmParams.bInterleaved = OMX_TRUE;
3273    pcmParams.nBitPerSample = 16;
3274    pcmParams.nSamplingRate = sampleRate;
3275    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3276
3277    if (numChannels == 1) {
3278        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
3279    } else {
3280        CHECK_EQ(numChannels, 2);
3281
3282        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
3283        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
3284    }
3285
3286    err = mOMX->setParameter(
3287            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3288
3289    CHECK_EQ(err, (status_t)OK);
3290}
3291
3292static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
3293    if (isAMRWB) {
3294        if (bps <= 6600) {
3295            return OMX_AUDIO_AMRBandModeWB0;
3296        } else if (bps <= 8850) {
3297            return OMX_AUDIO_AMRBandModeWB1;
3298        } else if (bps <= 12650) {
3299            return OMX_AUDIO_AMRBandModeWB2;
3300        } else if (bps <= 14250) {
3301            return OMX_AUDIO_AMRBandModeWB3;
3302        } else if (bps <= 15850) {
3303            return OMX_AUDIO_AMRBandModeWB4;
3304        } else if (bps <= 18250) {
3305            return OMX_AUDIO_AMRBandModeWB5;
3306        } else if (bps <= 19850) {
3307            return OMX_AUDIO_AMRBandModeWB6;
3308        } else if (bps <= 23050) {
3309            return OMX_AUDIO_AMRBandModeWB7;
3310        }
3311
3312        // 23850 bps
3313        return OMX_AUDIO_AMRBandModeWB8;
3314    } else {  // AMRNB
3315        if (bps <= 4750) {
3316            return OMX_AUDIO_AMRBandModeNB0;
3317        } else if (bps <= 5150) {
3318            return OMX_AUDIO_AMRBandModeNB1;
3319        } else if (bps <= 5900) {
3320            return OMX_AUDIO_AMRBandModeNB2;
3321        } else if (bps <= 6700) {
3322            return OMX_AUDIO_AMRBandModeNB3;
3323        } else if (bps <= 7400) {
3324            return OMX_AUDIO_AMRBandModeNB4;
3325        } else if (bps <= 7950) {
3326            return OMX_AUDIO_AMRBandModeNB5;
3327        } else if (bps <= 10200) {
3328            return OMX_AUDIO_AMRBandModeNB6;
3329        }
3330
3331        // 12200 bps
3332        return OMX_AUDIO_AMRBandModeNB7;
3333    }
3334}
3335
3336void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) {
3337    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
3338
3339    OMX_AUDIO_PARAM_AMRTYPE def;
3340    InitOMXParams(&def);
3341    def.nPortIndex = portIndex;
3342
3343    status_t err =
3344        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
3345
3346    CHECK_EQ(err, (status_t)OK);
3347
3348    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
3349
3350    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate);
3351    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
3352    CHECK_EQ(err, (status_t)OK);
3353
3354    ////////////////////////
3355
3356    if (mIsEncoder) {
3357        sp<MetaData> format = mSource->getFormat();
3358        int32_t sampleRate;
3359        int32_t numChannels;
3360        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
3361        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
3362
3363        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
3364    }
3365}
3366
3367status_t OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
3368    if (numChannels > 2)
3369        LOGW("Number of channels: (%d) \n", numChannels);
3370
3371    if (mIsEncoder) {
3372        //////////////// input port ////////////////////
3373        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
3374
3375        //////////////// output port ////////////////////
3376        // format
3377        OMX_AUDIO_PARAM_PORTFORMATTYPE format;
3378        format.nPortIndex = kPortIndexOutput;
3379        format.nIndex = 0;
3380        status_t err = OMX_ErrorNone;
3381        while (OMX_ErrorNone == err) {
3382            CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat,
3383                    &format, sizeof(format)), (status_t)OK);
3384            if (format.eEncoding == OMX_AUDIO_CodingAAC) {
3385                break;
3386            }
3387            format.nIndex++;
3388        }
3389        CHECK_EQ((status_t)OK, err);
3390        CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat,
3391                &format, sizeof(format)), (status_t)OK);
3392
3393        // port definition
3394        OMX_PARAM_PORTDEFINITIONTYPE def;
3395        InitOMXParams(&def);
3396        def.nPortIndex = kPortIndexOutput;
3397        CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition,
3398                &def, sizeof(def)), (status_t)OK);
3399        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
3400        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
3401        CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
3402                &def, sizeof(def)), (status_t)OK);
3403
3404        // profile
3405        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3406        InitOMXParams(&profile);
3407        profile.nPortIndex = kPortIndexOutput;
3408        CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac,
3409                &profile, sizeof(profile)), (status_t)OK);
3410        profile.nChannels = numChannels;
3411        profile.eChannelMode = (numChannels == 1?
3412                OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo);
3413        profile.nSampleRate = sampleRate;
3414        profile.nBitRate = bitRate;
3415        profile.nAudioBandWidth = 0;
3416        profile.nFrameLength = 0;
3417        profile.nAACtools = OMX_AUDIO_AACToolAll;
3418        profile.nAACERtools = OMX_AUDIO_AACERNone;
3419        profile.eAACProfile = OMX_AUDIO_AACObjectLC;
3420        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
3421        err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
3422                &profile, sizeof(profile));
3423
3424        if (err != OK) {
3425            CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err);
3426            return err;
3427        }
3428    } else {
3429        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
3430        InitOMXParams(&profile);
3431        profile.nPortIndex = kPortIndexInput;
3432
3433        status_t err = mOMX->getParameter(
3434                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
3435        CHECK_EQ(err, (status_t)OK);
3436
3437        profile.nChannels = numChannels;
3438        profile.nSampleRate = sampleRate;
3439        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
3440
3441        err = mOMX->setParameter(
3442                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
3443
3444        if (err != OK) {
3445            CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err);
3446            return err;
3447        }
3448    }
3449
3450    return OK;
3451}
3452
3453void OMXCodec::setG711Format(int32_t numChannels) {
3454    CHECK(!mIsEncoder);
3455    setRawAudioFormat(kPortIndexInput, 8000, numChannels);
3456}
3457
3458void OMXCodec::setImageOutputFormat(
3459        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
3460    CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
3461
3462#if 0
3463    OMX_INDEXTYPE index;
3464    status_t err = mOMX->get_extension_index(
3465            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
3466    CHECK_EQ(err, (status_t)OK);
3467
3468    err = mOMX->set_config(mNode, index, &format, sizeof(format));
3469    CHECK_EQ(err, (status_t)OK);
3470#endif
3471
3472    OMX_PARAM_PORTDEFINITIONTYPE def;
3473    InitOMXParams(&def);
3474    def.nPortIndex = kPortIndexOutput;
3475
3476    status_t err = mOMX->getParameter(
3477            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3478    CHECK_EQ(err, (status_t)OK);
3479
3480    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3481
3482    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3483
3484    CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused);
3485    imageDef->eColorFormat = format;
3486    imageDef->nFrameWidth = width;
3487    imageDef->nFrameHeight = height;
3488
3489    switch (format) {
3490        case OMX_COLOR_FormatYUV420PackedPlanar:
3491        case OMX_COLOR_FormatYUV411Planar:
3492        {
3493            def.nBufferSize = (width * height * 3) / 2;
3494            break;
3495        }
3496
3497        case OMX_COLOR_FormatCbYCrY:
3498        {
3499            def.nBufferSize = width * height * 2;
3500            break;
3501        }
3502
3503        case OMX_COLOR_Format32bitARGB8888:
3504        {
3505            def.nBufferSize = width * height * 4;
3506            break;
3507        }
3508
3509        case OMX_COLOR_Format16bitARGB4444:
3510        case OMX_COLOR_Format16bitARGB1555:
3511        case OMX_COLOR_Format16bitRGB565:
3512        case OMX_COLOR_Format16bitBGR565:
3513        {
3514            def.nBufferSize = width * height * 2;
3515            break;
3516        }
3517
3518        default:
3519            CHECK(!"Should not be here. Unknown color format.");
3520            break;
3521    }
3522
3523    def.nBufferCountActual = def.nBufferCountMin;
3524
3525    err = mOMX->setParameter(
3526            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3527    CHECK_EQ(err, (status_t)OK);
3528}
3529
3530void OMXCodec::setJPEGInputFormat(
3531        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
3532    OMX_PARAM_PORTDEFINITIONTYPE def;
3533    InitOMXParams(&def);
3534    def.nPortIndex = kPortIndexInput;
3535
3536    status_t err = mOMX->getParameter(
3537            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3538    CHECK_EQ(err, (status_t)OK);
3539
3540    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
3541    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
3542
3543    CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG);
3544    imageDef->nFrameWidth = width;
3545    imageDef->nFrameHeight = height;
3546
3547    def.nBufferSize = compressedSize;
3548    def.nBufferCountActual = def.nBufferCountMin;
3549
3550    err = mOMX->setParameter(
3551            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3552    CHECK_EQ(err, (status_t)OK);
3553}
3554
3555void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
3556    CodecSpecificData *specific =
3557        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) + size - 1);
3558
3559    specific->mSize = size;
3560    memcpy(specific->mData, data, size);
3561
3562    mCodecSpecificData.push(specific);
3563}
3564
3565void OMXCodec::clearCodecSpecificData() {
3566    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
3567        free(mCodecSpecificData.editItemAt(i));
3568    }
3569    mCodecSpecificData.clear();
3570    mCodecSpecificDataIndex = 0;
3571}
3572
3573status_t OMXCodec::start(MetaData *meta) {
3574    Mutex::Autolock autoLock(mLock);
3575
3576    if (mState != LOADED) {
3577        return UNKNOWN_ERROR;
3578    }
3579
3580    sp<MetaData> params = new MetaData;
3581    if (mQuirks & kWantsNALFragments) {
3582        params->setInt32(kKeyWantsNALFragments, true);
3583    }
3584    if (meta) {
3585        int64_t startTimeUs = 0;
3586        int64_t timeUs;
3587        if (meta->findInt64(kKeyTime, &timeUs)) {
3588            startTimeUs = timeUs;
3589        }
3590        params->setInt64(kKeyTime, startTimeUs);
3591    }
3592    status_t err = mSource->start(params.get());
3593
3594    if (err != OK) {
3595        return err;
3596    }
3597
3598    mCodecSpecificDataIndex = 0;
3599    mInitialBufferSubmit = true;
3600    mSignalledEOS = false;
3601    mNoMoreOutputData = false;
3602    mOutputPortSettingsHaveChanged = false;
3603    mSeekTimeUs = -1;
3604    mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
3605    mTargetTimeUs = -1;
3606    mFilledBuffers.clear();
3607    mPaused = false;
3608
3609    return init();
3610}
3611
3612status_t OMXCodec::stop() {
3613    CODEC_LOGV("stop mState=%d", mState);
3614
3615    Mutex::Autolock autoLock(mLock);
3616
3617    while (isIntermediateState(mState)) {
3618        mAsyncCompletion.wait(mLock);
3619    }
3620
3621    bool isError = false;
3622    switch (mState) {
3623        case LOADED:
3624            break;
3625
3626        case ERROR:
3627        {
3628            OMX_STATETYPE state = OMX_StateInvalid;
3629            status_t err = mOMX->getState(mNode, &state);
3630            CHECK_EQ(err, (status_t)OK);
3631
3632            if (state != OMX_StateExecuting) {
3633                break;
3634            }
3635            // else fall through to the idling code
3636            isError = true;
3637        }
3638
3639        case EXECUTING:
3640        {
3641            setState(EXECUTING_TO_IDLE);
3642
3643            if (mQuirks & kRequiresFlushBeforeShutdown) {
3644                CODEC_LOGV("This component requires a flush before transitioning "
3645                     "from EXECUTING to IDLE...");
3646
3647                bool emulateInputFlushCompletion =
3648                    !flushPortAsync(kPortIndexInput);
3649
3650                bool emulateOutputFlushCompletion =
3651                    !flushPortAsync(kPortIndexOutput);
3652
3653                if (emulateInputFlushCompletion) {
3654                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3655                }
3656
3657                if (emulateOutputFlushCompletion) {
3658                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3659                }
3660            } else {
3661                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
3662                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
3663
3664                status_t err =
3665                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
3666                CHECK_EQ(err, (status_t)OK);
3667            }
3668
3669            while (mState != LOADED && mState != ERROR) {
3670                mAsyncCompletion.wait(mLock);
3671            }
3672
3673            if (isError) {
3674                // We were in the ERROR state coming in, so restore that now
3675                // that we've idled the OMX component.
3676                setState(ERROR);
3677            }
3678
3679            break;
3680        }
3681
3682        default:
3683        {
3684            CHECK(!"should not be here.");
3685            break;
3686        }
3687    }
3688
3689    if (mLeftOverBuffer) {
3690        mLeftOverBuffer->release();
3691        mLeftOverBuffer = NULL;
3692    }
3693
3694    mSource->stop();
3695
3696    CODEC_LOGV("stopped in state %d", mState);
3697
3698    return OK;
3699}
3700
3701sp<MetaData> OMXCodec::getFormat() {
3702    Mutex::Autolock autoLock(mLock);
3703
3704    return mOutputFormat;
3705}
3706
3707status_t OMXCodec::read(
3708        MediaBuffer **buffer, const ReadOptions *options) {
3709    status_t err = OK;
3710    *buffer = NULL;
3711
3712    Mutex::Autolock autoLock(mLock);
3713
3714    if (mState != EXECUTING && mState != RECONFIGURING) {
3715        return UNKNOWN_ERROR;
3716    }
3717
3718    bool seeking = false;
3719    int64_t seekTimeUs;
3720    ReadOptions::SeekMode seekMode;
3721    if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
3722        seeking = true;
3723    }
3724
3725    if (mInitialBufferSubmit) {
3726        mInitialBufferSubmit = false;
3727
3728        if (seeking) {
3729            CHECK(seekTimeUs >= 0);
3730            mSeekTimeUs = seekTimeUs;
3731            mSeekMode = seekMode;
3732
3733            // There's no reason to trigger the code below, there's
3734            // nothing to flush yet.
3735            seeking = false;
3736            mPaused = false;
3737        }
3738
3739        drainInputBuffers();
3740
3741        if (mState == EXECUTING) {
3742            // Otherwise mState == RECONFIGURING and this code will trigger
3743            // after the output port is reenabled.
3744            fillOutputBuffers();
3745        }
3746    }
3747
3748    if (seeking) {
3749        while (mState == RECONFIGURING) {
3750            if ((err = waitForBufferFilled_l()) != OK) {
3751                return err;
3752            }
3753        }
3754
3755        if (mState != EXECUTING) {
3756            return UNKNOWN_ERROR;
3757        }
3758
3759        CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
3760
3761        mSignalledEOS = false;
3762
3763        CHECK(seekTimeUs >= 0);
3764        mSeekTimeUs = seekTimeUs;
3765        mSeekMode = seekMode;
3766
3767        mFilledBuffers.clear();
3768
3769        CHECK_EQ((int)mState, (int)EXECUTING);
3770
3771        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
3772        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
3773
3774        if (emulateInputFlushCompletion) {
3775            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
3776        }
3777
3778        if (emulateOutputFlushCompletion) {
3779            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
3780        }
3781
3782        while (mSeekTimeUs >= 0) {
3783            if ((err = waitForBufferFilled_l()) != OK) {
3784                return err;
3785            }
3786        }
3787    }
3788
3789    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
3790        if ((err = waitForBufferFilled_l()) != OK) {
3791            return err;
3792        }
3793    }
3794
3795    if (mState == ERROR) {
3796        return UNKNOWN_ERROR;
3797    }
3798
3799    if (mFilledBuffers.empty()) {
3800        return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
3801    }
3802
3803    if (mOutputPortSettingsHaveChanged) {
3804        mOutputPortSettingsHaveChanged = false;
3805
3806        return INFO_FORMAT_CHANGED;
3807    }
3808
3809    size_t index = *mFilledBuffers.begin();
3810    mFilledBuffers.erase(mFilledBuffers.begin());
3811
3812    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
3813    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
3814    info->mStatus = OWNED_BY_CLIENT;
3815
3816    info->mMediaBuffer->add_ref();
3817    *buffer = info->mMediaBuffer;
3818
3819    return OK;
3820}
3821
3822void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
3823    Mutex::Autolock autoLock(mLock);
3824
3825    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
3826    for (size_t i = 0; i < buffers->size(); ++i) {
3827        BufferInfo *info = &buffers->editItemAt(i);
3828
3829        if (info->mMediaBuffer == buffer) {
3830            CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
3831            CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT);
3832
3833            info->mStatus = OWNED_BY_US;
3834
3835            if (buffer->graphicBuffer() == 0) {
3836                fillOutputBuffer(info);
3837            } else {
3838                sp<MetaData> metaData = info->mMediaBuffer->meta_data();
3839                int32_t rendered = 0;
3840                if (!metaData->findInt32(kKeyRendered, &rendered)) {
3841                    rendered = 0;
3842                }
3843                if (!rendered) {
3844                    status_t err = cancelBufferToNativeWindow(info);
3845                    if (err < 0) {
3846                        return;
3847                    }
3848                }
3849
3850                info->mStatus = OWNED_BY_NATIVE_WINDOW;
3851
3852                // Dequeue the next buffer from the native window.
3853                BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow();
3854                if (nextBufInfo == 0) {
3855                    return;
3856                }
3857
3858                // Give the buffer to the OMX node to fill.
3859                fillOutputBuffer(nextBufInfo);
3860            }
3861            return;
3862        }
3863    }
3864
3865    CHECK(!"should not be here.");
3866}
3867
3868static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
3869    static const char *kNames[] = {
3870        "OMX_IMAGE_CodingUnused",
3871        "OMX_IMAGE_CodingAutoDetect",
3872        "OMX_IMAGE_CodingJPEG",
3873        "OMX_IMAGE_CodingJPEG2K",
3874        "OMX_IMAGE_CodingEXIF",
3875        "OMX_IMAGE_CodingTIFF",
3876        "OMX_IMAGE_CodingGIF",
3877        "OMX_IMAGE_CodingPNG",
3878        "OMX_IMAGE_CodingLZW",
3879        "OMX_IMAGE_CodingBMP",
3880    };
3881
3882    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
3883
3884    if (type < 0 || (size_t)type >= numNames) {
3885        return "UNKNOWN";
3886    } else {
3887        return kNames[type];
3888    }
3889}
3890
3891static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
3892    static const char *kNames[] = {
3893        "OMX_COLOR_FormatUnused",
3894        "OMX_COLOR_FormatMonochrome",
3895        "OMX_COLOR_Format8bitRGB332",
3896        "OMX_COLOR_Format12bitRGB444",
3897        "OMX_COLOR_Format16bitARGB4444",
3898        "OMX_COLOR_Format16bitARGB1555",
3899        "OMX_COLOR_Format16bitRGB565",
3900        "OMX_COLOR_Format16bitBGR565",
3901        "OMX_COLOR_Format18bitRGB666",
3902        "OMX_COLOR_Format18bitARGB1665",
3903        "OMX_COLOR_Format19bitARGB1666",
3904        "OMX_COLOR_Format24bitRGB888",
3905        "OMX_COLOR_Format24bitBGR888",
3906        "OMX_COLOR_Format24bitARGB1887",
3907        "OMX_COLOR_Format25bitARGB1888",
3908        "OMX_COLOR_Format32bitBGRA8888",
3909        "OMX_COLOR_Format32bitARGB8888",
3910        "OMX_COLOR_FormatYUV411Planar",
3911        "OMX_COLOR_FormatYUV411PackedPlanar",
3912        "OMX_COLOR_FormatYUV420Planar",
3913        "OMX_COLOR_FormatYUV420PackedPlanar",
3914        "OMX_COLOR_FormatYUV420SemiPlanar",
3915        "OMX_COLOR_FormatYUV422Planar",
3916        "OMX_COLOR_FormatYUV422PackedPlanar",
3917        "OMX_COLOR_FormatYUV422SemiPlanar",
3918        "OMX_COLOR_FormatYCbYCr",
3919        "OMX_COLOR_FormatYCrYCb",
3920        "OMX_COLOR_FormatCbYCrY",
3921        "OMX_COLOR_FormatCrYCbY",
3922        "OMX_COLOR_FormatYUV444Interleaved",
3923        "OMX_COLOR_FormatRawBayer8bit",
3924        "OMX_COLOR_FormatRawBayer10bit",
3925        "OMX_COLOR_FormatRawBayer8bitcompressed",
3926        "OMX_COLOR_FormatL2",
3927        "OMX_COLOR_FormatL4",
3928        "OMX_COLOR_FormatL8",
3929        "OMX_COLOR_FormatL16",
3930        "OMX_COLOR_FormatL24",
3931        "OMX_COLOR_FormatL32",
3932        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
3933        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
3934        "OMX_COLOR_Format18BitBGR666",
3935        "OMX_COLOR_Format24BitARGB6666",
3936        "OMX_COLOR_Format24BitABGR6666",
3937    };
3938
3939    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
3940
3941    if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
3942        return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
3943    } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
3944        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
3945    } else if (type < 0 || (size_t)type >= numNames) {
3946        return "UNKNOWN";
3947    } else {
3948        return kNames[type];
3949    }
3950}
3951
3952static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
3953    static const char *kNames[] = {
3954        "OMX_VIDEO_CodingUnused",
3955        "OMX_VIDEO_CodingAutoDetect",
3956        "OMX_VIDEO_CodingMPEG2",
3957        "OMX_VIDEO_CodingH263",
3958        "OMX_VIDEO_CodingMPEG4",
3959        "OMX_VIDEO_CodingWMV",
3960        "OMX_VIDEO_CodingRV",
3961        "OMX_VIDEO_CodingAVC",
3962        "OMX_VIDEO_CodingMJPEG",
3963    };
3964
3965    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
3966
3967    if (type < 0 || (size_t)type >= numNames) {
3968        return "UNKNOWN";
3969    } else {
3970        return kNames[type];
3971    }
3972}
3973
3974static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
3975    static const char *kNames[] = {
3976        "OMX_AUDIO_CodingUnused",
3977        "OMX_AUDIO_CodingAutoDetect",
3978        "OMX_AUDIO_CodingPCM",
3979        "OMX_AUDIO_CodingADPCM",
3980        "OMX_AUDIO_CodingAMR",
3981        "OMX_AUDIO_CodingGSMFR",
3982        "OMX_AUDIO_CodingGSMEFR",
3983        "OMX_AUDIO_CodingGSMHR",
3984        "OMX_AUDIO_CodingPDCFR",
3985        "OMX_AUDIO_CodingPDCEFR",
3986        "OMX_AUDIO_CodingPDCHR",
3987        "OMX_AUDIO_CodingTDMAFR",
3988        "OMX_AUDIO_CodingTDMAEFR",
3989        "OMX_AUDIO_CodingQCELP8",
3990        "OMX_AUDIO_CodingQCELP13",
3991        "OMX_AUDIO_CodingEVRC",
3992        "OMX_AUDIO_CodingSMV",
3993        "OMX_AUDIO_CodingG711",
3994        "OMX_AUDIO_CodingG723",
3995        "OMX_AUDIO_CodingG726",
3996        "OMX_AUDIO_CodingG729",
3997        "OMX_AUDIO_CodingAAC",
3998        "OMX_AUDIO_CodingMP3",
3999        "OMX_AUDIO_CodingSBC",
4000        "OMX_AUDIO_CodingVORBIS",
4001        "OMX_AUDIO_CodingWMA",
4002        "OMX_AUDIO_CodingRA",
4003        "OMX_AUDIO_CodingMIDI",
4004    };
4005
4006    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4007
4008    if (type < 0 || (size_t)type >= numNames) {
4009        return "UNKNOWN";
4010    } else {
4011        return kNames[type];
4012    }
4013}
4014
4015static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
4016    static const char *kNames[] = {
4017        "OMX_AUDIO_PCMModeLinear",
4018        "OMX_AUDIO_PCMModeALaw",
4019        "OMX_AUDIO_PCMModeMULaw",
4020    };
4021
4022    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4023
4024    if (type < 0 || (size_t)type >= numNames) {
4025        return "UNKNOWN";
4026    } else {
4027        return kNames[type];
4028    }
4029}
4030
4031static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
4032    static const char *kNames[] = {
4033        "OMX_AUDIO_AMRBandModeUnused",
4034        "OMX_AUDIO_AMRBandModeNB0",
4035        "OMX_AUDIO_AMRBandModeNB1",
4036        "OMX_AUDIO_AMRBandModeNB2",
4037        "OMX_AUDIO_AMRBandModeNB3",
4038        "OMX_AUDIO_AMRBandModeNB4",
4039        "OMX_AUDIO_AMRBandModeNB5",
4040        "OMX_AUDIO_AMRBandModeNB6",
4041        "OMX_AUDIO_AMRBandModeNB7",
4042        "OMX_AUDIO_AMRBandModeWB0",
4043        "OMX_AUDIO_AMRBandModeWB1",
4044        "OMX_AUDIO_AMRBandModeWB2",
4045        "OMX_AUDIO_AMRBandModeWB3",
4046        "OMX_AUDIO_AMRBandModeWB4",
4047        "OMX_AUDIO_AMRBandModeWB5",
4048        "OMX_AUDIO_AMRBandModeWB6",
4049        "OMX_AUDIO_AMRBandModeWB7",
4050        "OMX_AUDIO_AMRBandModeWB8",
4051    };
4052
4053    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4054
4055    if (type < 0 || (size_t)type >= numNames) {
4056        return "UNKNOWN";
4057    } else {
4058        return kNames[type];
4059    }
4060}
4061
4062static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
4063    static const char *kNames[] = {
4064        "OMX_AUDIO_AMRFrameFormatConformance",
4065        "OMX_AUDIO_AMRFrameFormatIF1",
4066        "OMX_AUDIO_AMRFrameFormatIF2",
4067        "OMX_AUDIO_AMRFrameFormatFSF",
4068        "OMX_AUDIO_AMRFrameFormatRTPPayload",
4069        "OMX_AUDIO_AMRFrameFormatITU",
4070    };
4071
4072    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
4073
4074    if (type < 0 || (size_t)type >= numNames) {
4075        return "UNKNOWN";
4076    } else {
4077        return kNames[type];
4078    }
4079}
4080
4081void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
4082    OMX_PARAM_PORTDEFINITIONTYPE def;
4083    InitOMXParams(&def);
4084    def.nPortIndex = portIndex;
4085
4086    status_t err = mOMX->getParameter(
4087            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4088    CHECK_EQ(err, (status_t)OK);
4089
4090    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
4091
4092    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
4093          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
4094
4095    printf("  nBufferCountActual = %ld\n", def.nBufferCountActual);
4096    printf("  nBufferCountMin = %ld\n", def.nBufferCountMin);
4097    printf("  nBufferSize = %ld\n", def.nBufferSize);
4098
4099    switch (def.eDomain) {
4100        case OMX_PortDomainImage:
4101        {
4102            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4103
4104            printf("\n");
4105            printf("  // Image\n");
4106            printf("  nFrameWidth = %ld\n", imageDef->nFrameWidth);
4107            printf("  nFrameHeight = %ld\n", imageDef->nFrameHeight);
4108            printf("  nStride = %ld\n", imageDef->nStride);
4109
4110            printf("  eCompressionFormat = %s\n",
4111                   imageCompressionFormatString(imageDef->eCompressionFormat));
4112
4113            printf("  eColorFormat = %s\n",
4114                   colorFormatString(imageDef->eColorFormat));
4115
4116            break;
4117        }
4118
4119        case OMX_PortDomainVideo:
4120        {
4121            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4122
4123            printf("\n");
4124            printf("  // Video\n");
4125            printf("  nFrameWidth = %ld\n", videoDef->nFrameWidth);
4126            printf("  nFrameHeight = %ld\n", videoDef->nFrameHeight);
4127            printf("  nStride = %ld\n", videoDef->nStride);
4128
4129            printf("  eCompressionFormat = %s\n",
4130                   videoCompressionFormatString(videoDef->eCompressionFormat));
4131
4132            printf("  eColorFormat = %s\n",
4133                   colorFormatString(videoDef->eColorFormat));
4134
4135            break;
4136        }
4137
4138        case OMX_PortDomainAudio:
4139        {
4140            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4141
4142            printf("\n");
4143            printf("  // Audio\n");
4144            printf("  eEncoding = %s\n",
4145                   audioCodingTypeString(audioDef->eEncoding));
4146
4147            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
4148                OMX_AUDIO_PARAM_PCMMODETYPE params;
4149                InitOMXParams(&params);
4150                params.nPortIndex = portIndex;
4151
4152                err = mOMX->getParameter(
4153                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4154                CHECK_EQ(err, (status_t)OK);
4155
4156                printf("  nSamplingRate = %ld\n", params.nSamplingRate);
4157                printf("  nChannels = %ld\n", params.nChannels);
4158                printf("  bInterleaved = %d\n", params.bInterleaved);
4159                printf("  nBitPerSample = %ld\n", params.nBitPerSample);
4160
4161                printf("  eNumData = %s\n",
4162                       params.eNumData == OMX_NumericalDataSigned
4163                        ? "signed" : "unsigned");
4164
4165                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
4166            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
4167                OMX_AUDIO_PARAM_AMRTYPE amr;
4168                InitOMXParams(&amr);
4169                amr.nPortIndex = portIndex;
4170
4171                err = mOMX->getParameter(
4172                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4173                CHECK_EQ(err, (status_t)OK);
4174
4175                printf("  nChannels = %ld\n", amr.nChannels);
4176                printf("  eAMRBandMode = %s\n",
4177                        amrBandModeString(amr.eAMRBandMode));
4178                printf("  eAMRFrameFormat = %s\n",
4179                        amrFrameFormatString(amr.eAMRFrameFormat));
4180            }
4181
4182            break;
4183        }
4184
4185        default:
4186        {
4187            printf("  // Unknown\n");
4188            break;
4189        }
4190    }
4191
4192    printf("}\n");
4193}
4194
4195status_t OMXCodec::initNativeWindow() {
4196    // Enable use of a GraphicBuffer as the output for this node.  This must
4197    // happen before getting the IndexParamPortDefinition parameter because it
4198    // will affect the pixel format that the node reports.
4199    status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
4200    if (err != 0) {
4201        return err;
4202    }
4203
4204    return OK;
4205}
4206
4207void OMXCodec::initNativeWindowCrop() {
4208    int32_t left, top, right, bottom;
4209
4210    CHECK(mOutputFormat->findRect(
4211                        kKeyCropRect,
4212                        &left, &top, &right, &bottom));
4213
4214    android_native_rect_t crop;
4215    crop.left = left;
4216    crop.top = top;
4217    crop.right = right + 1;
4218    crop.bottom = bottom + 1;
4219
4220    // We'll ignore any errors here, if the surface is
4221    // already invalid, we'll know soon enough.
4222    native_window_set_crop(mNativeWindow.get(), &crop);
4223}
4224
4225void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
4226    mOutputFormat = new MetaData;
4227    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
4228    if (mIsEncoder) {
4229        int32_t timeScale;
4230        if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
4231            mOutputFormat->setInt32(kKeyTimeScale, timeScale);
4232        }
4233    }
4234
4235    OMX_PARAM_PORTDEFINITIONTYPE def;
4236    InitOMXParams(&def);
4237    def.nPortIndex = kPortIndexOutput;
4238
4239    status_t err = mOMX->getParameter(
4240            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4241    CHECK_EQ(err, (status_t)OK);
4242
4243    switch (def.eDomain) {
4244        case OMX_PortDomainImage:
4245        {
4246            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
4247            CHECK_EQ((int)imageDef->eCompressionFormat,
4248                     (int)OMX_IMAGE_CodingUnused);
4249
4250            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4251            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
4252            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
4253            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
4254            break;
4255        }
4256
4257        case OMX_PortDomainAudio:
4258        {
4259            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
4260
4261            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
4262                OMX_AUDIO_PARAM_PCMMODETYPE params;
4263                InitOMXParams(&params);
4264                params.nPortIndex = kPortIndexOutput;
4265
4266                err = mOMX->getParameter(
4267                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4268                CHECK_EQ(err, (status_t)OK);
4269
4270                CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
4271                CHECK_EQ(params.nBitPerSample, 16u);
4272                CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
4273
4274                int32_t numChannels, sampleRate;
4275                inputFormat->findInt32(kKeyChannelCount, &numChannels);
4276                inputFormat->findInt32(kKeySampleRate, &sampleRate);
4277
4278                if ((OMX_U32)numChannels != params.nChannels) {
4279                    LOGV("Codec outputs a different number of channels than "
4280                         "the input stream contains (contains %d channels, "
4281                         "codec outputs %ld channels).",
4282                         numChannels, params.nChannels);
4283                }
4284
4285                if (sampleRate != (int32_t)params.nSamplingRate) {
4286                    LOGV("Codec outputs at different sampling rate than "
4287                         "what the input stream contains (contains data at "
4288                         "%d Hz, codec outputs %lu Hz)",
4289                         sampleRate, params.nSamplingRate);
4290                }
4291
4292                mOutputFormat->setCString(
4293                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
4294
4295                // Use the codec-advertised number of channels, as some
4296                // codecs appear to output stereo even if the input data is
4297                // mono. If we know the codec lies about this information,
4298                // use the actual number of channels instead.
4299                mOutputFormat->setInt32(
4300                        kKeyChannelCount,
4301                        (mQuirks & kDecoderLiesAboutNumberOfChannels)
4302                            ? numChannels : params.nChannels);
4303
4304                mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
4305            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
4306                OMX_AUDIO_PARAM_AMRTYPE amr;
4307                InitOMXParams(&amr);
4308                amr.nPortIndex = kPortIndexOutput;
4309
4310                err = mOMX->getParameter(
4311                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
4312                CHECK_EQ(err, (status_t)OK);
4313
4314                CHECK_EQ(amr.nChannels, 1u);
4315                mOutputFormat->setInt32(kKeyChannelCount, 1);
4316
4317                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
4318                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
4319                    mOutputFormat->setCString(
4320                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
4321                    mOutputFormat->setInt32(kKeySampleRate, 8000);
4322                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
4323                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
4324                    mOutputFormat->setCString(
4325                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
4326                    mOutputFormat->setInt32(kKeySampleRate, 16000);
4327                } else {
4328                    CHECK(!"Unknown AMR band mode.");
4329                }
4330            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
4331                mOutputFormat->setCString(
4332                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
4333                int32_t numChannels, sampleRate, bitRate;
4334                inputFormat->findInt32(kKeyChannelCount, &numChannels);
4335                inputFormat->findInt32(kKeySampleRate, &sampleRate);
4336                inputFormat->findInt32(kKeyBitRate, &bitRate);
4337                mOutputFormat->setInt32(kKeyChannelCount, numChannels);
4338                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
4339                mOutputFormat->setInt32(kKeyBitRate, bitRate);
4340            } else {
4341                CHECK(!"Should not be here. Unknown audio encoding.");
4342            }
4343            break;
4344        }
4345
4346        case OMX_PortDomainVideo:
4347        {
4348            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4349
4350            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
4351                mOutputFormat->setCString(
4352                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
4353            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
4354                mOutputFormat->setCString(
4355                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
4356            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
4357                mOutputFormat->setCString(
4358                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
4359            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
4360                mOutputFormat->setCString(
4361                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
4362            } else {
4363                CHECK(!"Unknown compression format.");
4364            }
4365
4366            mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
4367            mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
4368            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
4369
4370            if (!mIsEncoder) {
4371                OMX_CONFIG_RECTTYPE rect;
4372                InitOMXParams(&rect);
4373                rect.nPortIndex = kPortIndexOutput;
4374                status_t err =
4375                        mOMX->getConfig(
4376                            mNode, OMX_IndexConfigCommonOutputCrop,
4377                            &rect, sizeof(rect));
4378
4379                CODEC_LOGI(
4380                        "video dimensions are %ld x %ld",
4381                        video_def->nFrameWidth, video_def->nFrameHeight);
4382
4383                if (err == OK) {
4384                    CHECK_GE(rect.nLeft, 0);
4385                    CHECK_GE(rect.nTop, 0);
4386                    CHECK_GE(rect.nWidth, 0u);
4387                    CHECK_GE(rect.nHeight, 0u);
4388                    CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
4389                    CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
4390
4391                    mOutputFormat->setRect(
4392                            kKeyCropRect,
4393                            rect.nLeft,
4394                            rect.nTop,
4395                            rect.nLeft + rect.nWidth - 1,
4396                            rect.nTop + rect.nHeight - 1);
4397
4398                    CODEC_LOGI(
4399                            "Crop rect is %ld x %ld @ (%ld, %ld)",
4400                            rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
4401                } else {
4402                    mOutputFormat->setRect(
4403                            kKeyCropRect,
4404                            0, 0,
4405                            video_def->nFrameWidth - 1,
4406                            video_def->nFrameHeight - 1);
4407                }
4408
4409                if (mNativeWindow != NULL) {
4410                     initNativeWindowCrop();
4411                }
4412            }
4413            break;
4414        }
4415
4416        default:
4417        {
4418            CHECK(!"should not be here, neither audio nor video.");
4419            break;
4420        }
4421    }
4422
4423    // If the input format contains rotation information, flag the output
4424    // format accordingly.
4425
4426    int32_t rotationDegrees;
4427    if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
4428        mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
4429    }
4430}
4431
4432status_t OMXCodec::pause() {
4433    Mutex::Autolock autoLock(mLock);
4434
4435    mPaused = true;
4436
4437    return OK;
4438}
4439
4440////////////////////////////////////////////////////////////////////////////////
4441
4442status_t QueryCodecs(
4443        const sp<IOMX> &omx,
4444        const char *mime, bool queryDecoders, bool hwCodecOnly,
4445        Vector<CodecCapabilities> *results) {
4446    Vector<String8> matchingCodecs;
4447    results->clear();
4448
4449    OMXCodec::findMatchingCodecs(mime,
4450            !queryDecoders /*createEncoder*/,
4451            NULL /*matchComponentName*/,
4452            hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
4453            &matchingCodecs);
4454
4455    for (size_t c = 0; c < matchingCodecs.size(); c++) {
4456        const char *componentName = matchingCodecs.itemAt(c).string();
4457
4458        if (strncmp(componentName, "OMX.", 4)) {
4459            // Not an OpenMax component but a software codec.
4460
4461            results->push();
4462            CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
4463            caps->mComponentName = componentName;
4464            continue;
4465        }
4466
4467        sp<OMXCodecObserver> observer = new OMXCodecObserver;
4468        IOMX::node_id node;
4469        status_t err = omx->allocateNode(componentName, observer, &node);
4470
4471        if (err != OK) {
4472            continue;
4473        }
4474
4475        OMXCodec::setComponentRole(omx, node, !queryDecoders, mime);
4476
4477        results->push();
4478        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
4479        caps->mComponentName = componentName;
4480
4481        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
4482        InitOMXParams(&param);
4483
4484        param.nPortIndex = queryDecoders ? 0 : 1;
4485
4486        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
4487            err = omx->getParameter(
4488                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
4489                    &param, sizeof(param));
4490
4491            if (err != OK) {
4492                break;
4493            }
4494
4495            CodecProfileLevel profileLevel;
4496            profileLevel.mProfile = param.eProfile;
4497            profileLevel.mLevel = param.eLevel;
4498
4499            caps->mProfileLevels.push(profileLevel);
4500        }
4501
4502        // Color format query
4503        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
4504        InitOMXParams(&portFormat);
4505        portFormat.nPortIndex = queryDecoders ? 1 : 0;
4506        for (portFormat.nIndex = 0;; ++portFormat.nIndex)  {
4507            err = omx->getParameter(
4508                    node, OMX_IndexParamVideoPortFormat,
4509                    &portFormat, sizeof(portFormat));
4510            if (err != OK) {
4511                break;
4512            }
4513            caps->mColorFormats.push(portFormat.eColorFormat);
4514        }
4515
4516        CHECK_EQ(omx->freeNode(node), (status_t)OK);
4517    }
4518
4519    return OK;
4520}
4521
4522status_t QueryCodecs(
4523        const sp<IOMX> &omx,
4524        const char *mimeType, bool queryDecoders,
4525        Vector<CodecCapabilities> *results) {
4526    return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
4527}
4528
4529void OMXCodec::restorePatchedDataPointer(BufferInfo *info) {
4530    CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames));
4531    CHECK(mOMXLivesLocally);
4532
4533    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer;
4534    header->pBuffer = (OMX_U8 *)info->mData;
4535}
4536
4537}  // namespace android
4538