1693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber/*
2693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
4693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * you may not use this file except in compliance with the License.
6693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * You may obtain a copy of the License at
7693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
8693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber *
10693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * Unless required by applicable law or agreed to in writing, software
11693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * See the License for the specific language governing permissions and
14693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber * limitations under the License.
15693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber */
16693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
17693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber//#define LOG_NDEBUG 0
18693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#define LOG_TAG "OMXCodec"
19693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Log.h>
20693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
21c71f6e2392bf55cc85ee7c1a376441e9b9aae4c8James Dong#include "include/AACEncoder.h"
2292616b5655b7aef260480f60f2aabf98e821c8f3Andreas Huber
2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/ESDS.h"
2489e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
25693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/IServiceManager.h>
26693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/MemoryDealer.h>
27693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <binder/ProcessState.h>
286c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong#include <HardwareAPI.h>
29f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h>
30693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/IMediaPlayerService.h>
31693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBuffer.h>
32693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
3318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
34afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
35693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaExtractor.h>
36693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MetaData.h>
37693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h>
38bde3caae211e215e4bbfef1a267f8d680efa4764Andreas Huber#include <media/stagefright/Utils.h>
39a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <media/stagefright/SkipCutBuffer.h>
40693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <utils/Vector.h>
41693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
42693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Audio.h>
43693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <OMX_Component.h>
44693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
45bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber#include "include/avc_utils.h"
46aae3516293e58c0b015d4109bde58c11d503433cAndreas Huber
47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubernamespace android {
48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
49a57a9a491272aa884494b2ec7854960827a73742James Dong// Treat time out as an error if we have not received any output
50a57a9a491272aa884494b2ec7854960827a73742James Dong// buffers after 3 seconds.
518edb8e82fa886564ee8e72178a1969e2437dd525James Dongconst static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
52a57a9a491272aa884494b2ec7854960827a73742James Dong
535e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dong// OMX Spec defines less than 50 color formats. If the query for
545e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dong// color format is executed for more than kMaxColorFormatSupported,
555e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dong// the query will fail to avoid looping forever.
565e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dong// 1000 is more than enough for us to tell whether the omx
575e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dong// component in question is buggy or not.
585e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dongconst static uint32_t kMaxColorFormatSupported = 1000;
595e69eb97b0e5e70919f61099bcc5bdbb1db0861cJames Dong
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define FACTORY_CREATE_ENCODER(name) \
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return new name(source, meta); \
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
651af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#define FACTORY_REF(name) { #name, Make##name },
661af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
67c71f6e2392bf55cc85ee7c1a376441e9b9aae4c8James DongFACTORY_CREATE_ENCODER(AACEncoder)
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic sp<MediaSource> InstantiateSoftwareEncoder(
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        const char *name, const sp<MediaSource> &source,
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        const sp<MetaData> &meta) {
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    struct FactoryInfo {
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        const char *name;
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    };
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    static const FactoryInfo kFactoryInfo[] = {
78c71f6e2392bf55cc85ee7c1a376441e9b9aae4c8James Dong        FACTORY_REF(AACEncoder)
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    };
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (size_t i = 0;
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (!strcmp(name, kFactoryInfo[i].name)) {
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            return (*kFactoryInfo[i].CreateFunc)(source, meta);
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return NULL;
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
891af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
90afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#undef FACTORY_CREATE_ENCODER
911af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber#undef FACTORY_REF
921af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
93df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block#define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block#define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
9529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block#define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
967a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
97693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstruct OMXCodecObserver : public BnOMXObserver {
98318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXCodecObserver() {
99318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
100318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
101318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void setCodec(const sp<OMXCodec> &target) {
102318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mTarget = target;
103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
104693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
105693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    // from IOMXObserver
106318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    virtual void onMessage(const omx_message &msg) {
107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        sp<OMXCodec> codec = mTarget.promote();
108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
109693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (codec.get() != NULL) {
11014c858e80dfe2030c9f343dc0c6e2048e030731bJames Dong            Mutex::Autolock autoLock(codec->mLock);
111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            codec->on_message(msg);
11214c858e80dfe2030c9f343dc0c6e2048e030731bJames Dong            codec.clear();
113693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        }
114693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
115693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
116693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
117693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~OMXCodecObserver() {}
118693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
119693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprivate:
120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    wp<OMXCodec> mTarget;
121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
122693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver(const OMXCodecObserver &);
123693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    OMXCodecObserver &operator=(const OMXCodecObserver &);
124693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber};
125693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1267a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Hubertemplate<class T>
1277a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huberstatic void InitOMXParams(T *params) {
1287a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nSize = sizeof(T);
1297a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMajor = 1;
1307a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nVersionMinor = 0;
1317a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nRevision = 0;
1327a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber    params->nVersion.s.nStep = 0;
1337a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber}
1347a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber
135ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic bool IsSoftwareCodec(const char *componentName) {
136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!strncmp("OMX.google.", componentName, 11)) {
137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return true;
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
140c810b75fd04eef8af509bb42aa8837566a374b32James Dong    if (!strncmp("OMX.", componentName, 4)) {
141c810b75fd04eef8af509bb42aa8837566a374b32James Dong        return false;
142ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
143693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
144c810b75fd04eef8af509bb42aa8837566a374b32James Dong    return true;
145ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
146693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber// A sort order in which OMX software codecs are first, followed
148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber// by other (non-OMX) software codecs, followed by everything else.
149ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huberstatic int CompareSoftwareCodecsFirst(
150e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        const OMXCodec::CodecNameAndQuirks *elem1,
151e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        const OMXCodec::CodecNameAndQuirks *elem2) {
152e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4);
153e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4);
1541af80bc3fefb999756ef4847e72b2dcfd0b88a4aAndreas Huber
155e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string());
156e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string());
157693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
158ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec1) {
159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!isSoftwareCodec2) { return -1; }
160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (isOMX1) {
162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (isOMX2) { return 0; }
163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return -1;
165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        } else {
166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (isOMX2) { return 0; }
167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return 1;
169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
171ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return -1;
172ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
174ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (isSoftwareCodec2) {
175ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return 1;
176693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
178ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    return 0;
179ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
180ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
181ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
182ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Hubervoid OMXCodec::findMatchingCodecs(
183ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *mime,
184ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        bool createEncoder, const char *matchComponentName,
185ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        uint32_t flags,
186e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        Vector<CodecNameAndQuirks> *matchingCodecs) {
187ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    matchingCodecs->clear();
188ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
189afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const MediaCodecList *list = MediaCodecList::getInstance();
190afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (list == NULL) {
191afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return;
192afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
193afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
194afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    size_t index = 0;
195afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    for (;;) {
196afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        ssize_t matchIndex =
197afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            list->findCodecByType(mime, createEncoder, index);
198ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (matchIndex < 0) {
200ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            break;
201ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
202ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
203afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        index = matchIndex + 1;
204afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
205afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const char *componentName = list->getCodecName(matchIndex);
206afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
207ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        // If a specific codec is requested, skip the non-matching ones.
208ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        if (matchComponentName && strcmp(componentName, matchComponentName)) {
209ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber            continue;
210ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        }
211ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
212d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong        // When requesting software-only codecs, only push software codecs
213d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong        // When requesting hardware-only codecs, only push hardware codecs
214d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong        // When there is request neither for software-only nor for
215d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong        // hardware-only codecs, push all codecs
216d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong        if (((flags & kSoftwareCodecsOnly) &&   IsSoftwareCodec(componentName)) ||
217d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong            ((flags & kHardwareCodecsOnly) &&  !IsSoftwareCodec(componentName)) ||
218d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong            (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
219d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong
220e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            ssize_t index = matchingCodecs->add();
221e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index);
222e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mName = String8(componentName);
223e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = getComponentQuirks(list, matchIndex);
224afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
225e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            ALOGV("matching '%s' quirks 0x%08x",
226e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                  entry->mName.string(), entry->mQuirks);
227d332a72e8f71caea0d3dc898db6a9d7a929fad32James Dong        }
228ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
229ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
230ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (flags & kPreferSoftwareCodecs) {
231ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        matchingCodecs->sort(CompareSoftwareCodecsFirst);
232ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
233ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber}
234ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
235ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber// static
236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberuint32_t OMXCodec::getComponentQuirks(
237afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        const MediaCodecList *list, size_t index) {
238afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t quirks = 0;
239afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (list->codecHasQuirk(
240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                index, "requires-allocate-on-input-ports")) {
241afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        quirks |= kRequiresAllocateBufferOnInputPorts;
242afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
243afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (list->codecHasQuirk(
244afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                index, "requires-allocate-on-output-ports")) {
245afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        quirks |= kRequiresAllocateBufferOnOutputPorts;
246afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
247afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (list->codecHasQuirk(
248afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                index, "output-buffers-are-unreadable")) {
249afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        quirks |= kOutputBuffersAreUnreadable;
250afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
251afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
252afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return quirks;
253afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
254afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
255afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
256afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberbool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) {
257afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    const MediaCodecList *list = MediaCodecList::getInstance();
258afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
259afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (list == NULL) {
260afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return false;
261afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
262afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ssize_t index = list->findCodecByName(componentName);
264afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
265afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    if (index < 0) {
266afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        return false;
267afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
268afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
269afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    *quirks = getComponentQuirks(list, index);
270afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
271afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    return true;
272afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
273afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
274afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber// static
275bf697e37550d9e8376089b0b5e498613bede798cAndreas Hubersp<MediaSource> OMXCodec::Create(
276ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<IOMX> &omx,
277ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MetaData> &meta, bool createEncoder,
278ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const sp<MediaSource> &source,
279ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        const char *matchComponentName,
2806a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        uint32_t flags,
2816a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        const sp<ANativeWindow> &nativeWindow) {
2820bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber    int32_t requiresSecureBuffers;
2830bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber    if (source->getFormat()->findInt32(
2840bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber                kKeyRequiresSecureBuffers,
2850bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber                &requiresSecureBuffers)
2860bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber            && requiresSecureBuffers) {
2870bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber        flags |= kIgnoreCodecSpecificData;
2880bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber        flags |= kUseSecureInputBuffers;
2890bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber    }
2900bb6b4c5da2451ee0973372b0a3858b15c742689Andreas Huber
291ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    const char *mime;
292ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    bool success = meta->findCString(kKeyMIMEType, &mime);
293ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    CHECK(success);
294ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
295e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<CodecNameAndQuirks> matchingCodecs;
296ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    findMatchingCodecs(
297e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
298ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
299ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    if (matchingCodecs.isEmpty()) {
300bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala        ALOGV("No matching codecs! (mime: %s, createEncoder: %s, "
301bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala                "matchComponentName: %s, flags: 0x%x)",
302bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala                mime, createEncoder ? "true" : "false", matchComponentName, flags);
303ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber        return NULL;
304ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    }
305ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
306ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    sp<OMXCodecObserver> observer = new OMXCodecObserver;
307ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    IOMX::node_id node = 0;
308ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber
309ba229b3faa98b3bb6567cf95040062be2d9c2b3fAndreas Huber    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
310e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        const char *componentNameBase = matchingCodecs[i].mName.string();
311e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        uint32_t quirks = matchingCodecs[i].mQuirks;
312c4847184f0d351ca2587ca66dc5ab8eab4dbe207Andreas Huber        const char *componentName = componentNameBase;
313c4847184f0d351ca2587ca66dc5ab8eab4dbe207Andreas Huber
314c4847184f0d351ca2587ca66dc5ab8eab4dbe207Andreas Huber        AString tmp;
315c4847184f0d351ca2587ca66dc5ab8eab4dbe207Andreas Huber        if (flags & kUseSecureInputBuffers) {
316c4847184f0d351ca2587ca66dc5ab8eab4dbe207Andreas Huber            tmp = componentNameBase;
317c4847184f0d351ca2587ca66dc5ab8eab4dbe207Andreas Huber            tmp.append(".secure"