Как MediaCodec находит кодек внутри фреймворка в Android?

Я пытаюсь понять, как MediaCodec используется для аппаратного декодирования.

Мои знания в области Android очень ограничены.

Вот мои выводы:

Существует XML-файл, который представляет детали кодека в системе Android.

 device/ti/omap3evm/media_codecs.xml for an example. 

Это означает, что если мы создадим кодек из Java-приложения с Media Codec

MediaCodec codec = MediaCodec.createDecoderByType(type);

Нужно выяснить соответствующий кодер с помощью файла xml.

Что я делаю?

Я пытаюсь выяснить, какая часть кода читает xml, и найти кодек, основанный на заданном типе.

1) прикладной уровень:

   MediaCodec codec = MediaCodec.createDecoderByType(type);

2) MediaCodec.java -> [ frameworks / base / media / java / android / media / MediaCodec.java ]

     public static MediaCodec createDecoderByType(String type) {

    return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
}

3)

private MediaCodec(
        String name, boolean nameIsType, boolean encoder) {
    native_setup(name, nameIsType, encoder);    --> JNI Call.
}

4) Реализация JNI -> [ frameworks/base/media/jni/android_media_MediaCodec.cpp ]

static void android_media_MediaCodec_native_setup (..) {
        .......
    const char *tmp = env->GetStringUTFChars(name, NULL);
    sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder);     ---> Here
}

из frameworks/base/media/jni/android_media_MediaCodec.cpp

    JMediaCodec::JMediaCodec( ..) { 
         .... 
          mCodec = MediaCodec::CreateByType(mLooper, name, encoder); //Call goes to libstagefright 
          .... }


    sp<MediaCodec> MediaCodec::CreateByType(
            const sp<ALooper> &looper, const char *mime, bool encoder) {
        sp<MediaCodec> codec = new MediaCodec(looper);
        if (codec->init(mime, true /* nameIsType */, encoder) != OK) {  --> HERE.
            return NULL;
        }    
    return codec;
   }



    status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
           // MediaCodec
    }

Я поражен этим потоком. Если кто-то укажет, как продвигаться вперед, это очень поможет.

Благодарю.

1 ответ

Решение

Давайте рассмотрим шаг за шагом.

  1. MediaCodec::CreateByType создаст новый MediaCodec объект

  2. MediaCodec конструктор создаст новый ACodec возразить и сохранить его как mCodec

  3. когда MediaCodec::init вызывается, он внутренне инструктирует ACodec выделить OMX компонент через mCodec->initiateAllocateComponent,

  4. ACodec::initiateAllocateComponent будет ссылаться onAllocateComponent

  5. ACodec::UninitializedState::onAllocateComponent будет ссылаться OMXCodec::findMatchingCodecs найти кодеки, соответствующие MIME Тип передан от звонящего.

  6. В OMXCodec::findMatchingCodecs, есть вызов, чтобы получить экземпляр MediaCodecList как MediaCodecList::getInstance(),

  7. В MediaCodecList::getInstance, есть проверка, если есть MediaCodecList или новый объект MediaCodecList создан.

  8. В конструкторе MediaCodecList есть звонок в parseXMLFile с именем файла как /etc/media_codecs.xml,

  9. parseXMLFile читает содержимое и сохраняет различные имена компонентов и т. д. в MediaCodecList который также может быть использован для любого другого экземпляра кодека. Вспомогательная функция, используемая для анализа startElementHandler, Функция интереса может быть addMediaCodec,

Благодаря этим шагам XML содержимое файла переводится в список, который может использоваться любым другим модулем. MediaCodecList выставляется на уровне Java тоже, как можно сослаться отсюда.

Я пропустил несколько прыжков, где MediaCodec а также ACodec использовать сообщения для фактического общения и вызова методов, но представленный поток должен дать хорошее представление о базовом механизме.

Другие вопросы по тегам