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