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