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