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