160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar/*
260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * Copyright (C) 2014, The Android Open Source Project
360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *
460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * you may not use this file except in compliance with the License.
660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * You may obtain a copy of the License at
760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *
860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar *
1060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * Unless required by applicable law or agreed to in writing, software
1160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * See the License for the specific language governing permissions and
1460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar * limitations under the License.
1560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar */
1660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
1760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <stdint.h>
1860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <sys/types.h>
1960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <binder/Parcel.h>
2160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/stagefright/MediaCodecList.h>
2260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/IMediaCodecList.h>
2360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <media/MediaCodecInfo.h>
2460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar#include <utils/Errors.h>  // for status_t
2660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarnamespace android {
2860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
2960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarenum {
3060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    CREATE = IBinder::FIRST_CALL_TRANSACTION,
3160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    COUNT_CODECS,
3260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    GET_CODEC_INFO,
339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    GET_GLOBAL_SETTINGS,
3460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    FIND_CODEC_BY_TYPE,
3560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    FIND_CODEC_BY_NAME,
3660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar};
3760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
3860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarclass BpMediaCodecList: public BpInterface<IMediaCodecList>
3960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar{
4060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarpublic:
4160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    BpMediaCodecList(const sp<IBinder>& impl)
4260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        : BpInterface<IMediaCodecList>(impl)
4360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    {
4460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
4560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
4660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    virtual size_t countCodecs() const
4760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    {
4860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        Parcel data, reply;
4960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
5060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        remote()->transact(COUNT_CODECS, data, &reply);
5160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        return static_cast<size_t>(reply.readInt32());
5260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
5360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
5460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const
5560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    {
5660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        Parcel data, reply;
5760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
5860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInt32(index);
5960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        remote()->transact(GET_CODEC_INFO, data, &reply);
6060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        status_t err = reply.readInt32();
6160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        if (err == OK) {
6260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return MediaCodecInfo::FromParcel(reply);
6360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        } else {
6460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return NULL;
6560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
6660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
6760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
689e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    virtual const sp<AMessage> getGlobalSettings() const
699e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    {
709e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        Parcel data, reply;
719e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
729e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        remote()->transact(GET_GLOBAL_SETTINGS, data, &reply);
739e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        status_t err = reply.readInt32();
749e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        if (err == OK) {
759e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            return AMessage::FromParcel(reply);
769e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        } else {
779e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            return NULL;
789e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        }
799e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
809e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
8160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    virtual ssize_t findCodecByType(
8260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const char *type, bool encoder, size_t startIndex = 0) const
8360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    {
8460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        if (startIndex > INT32_MAX) {
8560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return NAME_NOT_FOUND;
8660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
8760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
8860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        Parcel data, reply;
8960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
9060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeCString(type);
9160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInt32(encoder);
9260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInt32(startIndex);
9360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        remote()->transact(FIND_CODEC_BY_TYPE, data, &reply);
9460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        return static_cast<ssize_t>(reply.readInt32());
9560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
9660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
9760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    virtual ssize_t findCodecByName(const char *name) const
9860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    {
9960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        Parcel data, reply;
10060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
10160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        data.writeCString(name);
10260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        remote()->transact(FIND_CODEC_BY_NAME, data, &reply);
10360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        return static_cast<ssize_t>(reply.readInt32());
10460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
10560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar};
10660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
10760b1c0e79d12a1c70758bc8d060156924635f8baLajos MolnarIMPLEMENT_META_INTERFACE(MediaCodecList, "android.media.IMediaCodecList");
10860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
10960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// ----------------------------------------------------------------------
11060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
11160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnarstatus_t BnMediaCodecList::onTransact(
11260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
11360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar{
11460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    switch (code) {
11560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        case COUNT_CODECS:
11660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        {
11760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            CHECK_INTERFACE(IMediaCodecList, data, reply);
11860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            size_t count = countCodecs();
11960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            if (count > INT32_MAX) {
12060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                count = INT32_MAX;
12160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            }
12260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            reply->writeInt32(count);
12360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return NO_ERROR;
12460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
12560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        break;
12660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
12760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        case GET_CODEC_INFO:
12860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        {
12960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            CHECK_INTERFACE(IMediaCodecList, data, reply);
13060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            size_t index = static_cast<size_t>(data.readInt32());
13160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = getCodecInfo(index);
13260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            if (info != NULL) {
13360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                reply->writeInt32(OK);
13460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                info->writeToParcel(reply);
13560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            } else {
13660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                reply->writeInt32(-ERANGE);
13760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            }
13860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return NO_ERROR;
13960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
14060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        break;
14160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
1429e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        case GET_GLOBAL_SETTINGS:
1439e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        {
1449e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            CHECK_INTERFACE(IMediaCodecList, data, reply);
1459e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            const sp<AMessage> info = getGlobalSettings();
1469e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            if (info != NULL) {
1479e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu                reply->writeInt32(OK);
1489e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu                info->writeToParcel(reply);
1499e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            } else {
1509e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu                reply->writeInt32(-ERANGE);
1519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            }
1529e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            return NO_ERROR;
1539e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        }
1549e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        break;
1559e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
15660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        case FIND_CODEC_BY_TYPE:
15760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        {
15860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            CHECK_INTERFACE(IMediaCodecList, data, reply);
15960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const char *type = data.readCString();
1602afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            if (type == NULL) {
1612afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                reply->writeInt32(NAME_NOT_FOUND);
1622afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                return NO_ERROR;
1632afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            }
16460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            bool isEncoder = static_cast<bool>(data.readInt32());
16560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            size_t startIndex = static_cast<size_t>(data.readInt32());
16660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            ssize_t index = findCodecByType(type, isEncoder, startIndex);
16760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            if (index > INT32_MAX || index < 0) {
16860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                index = NAME_NOT_FOUND;
16960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            }
17060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            reply->writeInt32(index);
17160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return NO_ERROR;
17260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
17360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        break;
17460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
17560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        case FIND_CODEC_BY_NAME:
17660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        {
17760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            CHECK_INTERFACE(IMediaCodecList, data, reply);
17860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const char *name = data.readCString();
1792afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            if (name == NULL) {
1802afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                reply->writeInt32(NAME_NOT_FOUND);
1812afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                return NO_ERROR;
1822afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            }
18360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            ssize_t index = findCodecByName(name);
18460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            if (index > INT32_MAX || index < 0) {
18560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                index = NAME_NOT_FOUND;
18660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            }
18760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            reply->writeInt32(index);
18860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return NO_ERROR;
18960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        }
19060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        break;
19160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
19260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        default:
19360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            return BBinder::onTransact(code, data, reply, flags);
19460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar    }
19560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar}
19660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
19760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar// ----------------------------------------------------------------------------
19860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar
19940bc906252974d0b389ae4a147232d0c9a97193fGlenn Kasten} // namespace android
200