/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MEDIA_CODEC_LIST_H_

#define MEDIA_CODEC_LIST_H_

#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>
#include <media/IMediaCodecList.h>
#include <media/IOMX.h>
#include <media/MediaCodecInfo.h>

#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/Vector.h>
#include <utils/StrongPointer.h>

namespace android {

extern const char *kMaxEncoderInputBuffers;

struct AMessage;

struct MediaCodecList : public BnMediaCodecList {
    static sp<IMediaCodecList> getInstance();

    virtual ssize_t findCodecByType(
            const char *type, bool encoder, size_t startIndex = 0) const;

    virtual ssize_t findCodecByName(const char *name) const;

    virtual size_t countCodecs() const;

    virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const {
        if (index >= mCodecInfos.size()) {
            ALOGE("b/24445127");
            return NULL;
        }
        return mCodecInfos.itemAt(index);
    }

    virtual const sp<AMessage> getGlobalSettings() const;

    // to be used by MediaPlayerService alone
    static sp<IMediaCodecList> getLocalInstance();

    // only to be used by getLocalInstance
    static void *profilerThreadWrapper(void * /*arg*/);

    // only to be used by MediaPlayerService
    void parseTopLevelXMLFile(const char *path, bool ignore_errors = false);

    enum Flags {
        kPreferSoftwareCodecs   = 1,
        kHardwareCodecsOnly     = 2,
    };

    static void findMatchingCodecs(
            const char *mime,
            bool createEncoder,
            uint32_t flags,
            Vector<AString> *matching);

    static uint32_t getQuirksFor(const char *mComponentName);

    static bool isSoftwareCodec(const AString &componentName);


private:
    class BinderDeathObserver : public IBinder::DeathRecipient {
        void binderDied(const wp<IBinder> &the_late_who __unused);
    };

    static sp<BinderDeathObserver> sBinderDeathObserver;

    enum Section {
        SECTION_TOPLEVEL,
        SECTION_SETTINGS,
        SECTION_DECODERS,
        SECTION_DECODER,
        SECTION_DECODER_TYPE,
        SECTION_ENCODERS,
        SECTION_ENCODER,
        SECTION_ENCODER_TYPE,
        SECTION_INCLUDE,
    };

    static sp<IMediaCodecList> sCodecList;
    static sp<IMediaCodecList> sRemoteList;

    status_t mInitCheck;
    Section mCurrentSection;
    bool mUpdate;
    Vector<Section> mPastSections;
    int32_t mDepth;
    AString mHrefBase;

    sp<AMessage> mGlobalSettings;
    KeyedVector<AString, CodecSettings> mOverrides;

    Vector<sp<MediaCodecInfo> > mCodecInfos;
    sp<MediaCodecInfo> mCurrentInfo;
    sp<IOMX> mOMX;

    MediaCodecList();
    ~MediaCodecList();

    status_t initCheck() const;
    void parseXMLFile(const char *path);

    static void StartElementHandlerWrapper(
            void *me, const char *name, const char **attrs);

    static void EndElementHandlerWrapper(void *me, const char *name);

    void startElementHandler(const char *name, const char **attrs);
    void endElementHandler(const char *name);

    status_t includeXMLFile(const char **attrs);
    status_t addSettingFromAttributes(const char **attrs);
    status_t addMediaCodecFromAttributes(bool encoder, const char **attrs);
    void addMediaCodec(bool encoder, const char *name, const char *type = NULL);

    void setCurrentCodecInfo(bool encoder, const char *name, const char *type);

    status_t addQuirk(const char **attrs);
    status_t addTypeFromAttributes(const char **attrs);
    status_t addLimit(const char **attrs);
    status_t addFeature(const char **attrs);
    void addType(const char *name);

    status_t initializeCapabilities(const char *type);

    DISALLOW_EVIL_CONSTRUCTORS(MediaCodecList);
};

}  // namespace android

#endif  // MEDIA_CODEC_LIST_H_

