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