¿Cómo MediaCodec encuentra el códec dentro del framework en Android?
Estoy tratando de entender cómo MediaCodec se utiliza para la decodificación de hardware.
Mi conocimiento en android interno es muy limitado.
- MediaPlayer Framework en GingerBread y soporte de streaming en vivo HTTP de Apple
- FFmpeg en Android
- ¿Por qué estoy recibiendo errores de "formato no admitido", leyendo flujos de rtsp codificados con H.264 con el MediaPlayer de Android?
- FFMpeg Android Stagefright SIGSEGV error (decodificación h264)
- Cómo utilizar Stagefright en Android?
Aquí están mis conclusiones:
Hay un archivo xml que representa los detalles del códec en el sistema android.
device/ti/omap3evm/media_codecs.xml for an example.
Lo que significa que si creamos un códec desde la aplicación Java con Media Codec
MediaCodec codec = MediaCodec.createDecoderByType(type);
Debería encontrar el codificador respectivo con la ayuda del archivo xml.
¿Qué estoy haciendo?
Estoy tratando de calcular nuestra parte del código que está leyendo xml y encontrar el códec basado en el 'tipo' dado.
1) Capa de aplicación:
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) Implementación de 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 }
Desde 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 }
Estoy impresionado con este flujo. Si alguien señala cómo llevarlo adelante ayudaría mucho.
Gracias.
- Android: incluye funciones nativas de StageFright en mi propio proyecto
- Integración de un codec a un marco multimedia de Android
- Decodificador de vídeo acelerado por hardware para H264
- Arquitectura de Stagefright
- Cómo invocar mi decodificador personalizado en el código fuente de Android
- ¿Para utilizar el decodificador de HW en android a través de libstagefright, qué establecer para kKeyAVCC en metadatos para la descodificación de base de trama en lugar de la reproducción de MP4?
- Función de ventana de ventana nativa Función de búfer que no produce la salida del decodificador Stagefright
- H264 HW Decodificación en Android con FFmpeg-10
Tomemos el flujo paso a paso.
-
MediaCodec::CreateByType
creará un nuevo objetoMediaCodec
-
MediaCodec
constructor deMediaCodec
crearía un nuevo objetoACodec
y lo almacenaría comomCodec
-
Cuando se invoca a
MediaCodec::init
, instruye internamente que elACodec
subyacente asigne el componenteOMX
través demCodec->initiateAllocateComponent
. -
ACodec::initiateAllocateComponent
invocaráonAllocateComponent
-
ACodec::UninitializedState::onAllocateComponent
invocaráOMXCodec::findMatchingCodecs
para encontrar los códecs que coincidan con el tipoMIME
pasado de la persona que llama. -
En
OMXCodec::findMatchingCodecs
, hay una llamada para recuperar una instancia deMediaCodecList
comoMediaCodecList::getInstance()
. -
En
MediaCodecList::getInstance
, hay una comprobación si hay unaMediaCodecList
existente o bien se crea un nuevo objeto deMediaCodecList
. -
En el constructor de
MediaCodecList
, hay una llamada aparseXMLFile
con el nombre de archivo como/etc/media_codecs.xml
. -
parseXMLFile
lee el contenido y almacena los diferentes nombres de componentes, etc enMediaCodecList
que se puede utilizar para cualquier otra instancia de codec también. La función auxiliar empleada para el análisis esstartElementHandler
. Una función de interés podría seraddMediaCodec
.
A través de estos pasos, el contenido del archivo XML
se convierte en una lista que puede ser utilizada por cualquier otro módulo. MediaCodecList
se expone en la capa de Java también como puede ser referido desde aquí .
He omitido algunos saltos en los que MediaCodec
y ACodec
emplean mensajes para comunicar e invocar realmente métodos, pero el flujo presentado debería dar una buena idea sobre el mecanismo subyacente.
- Fijación GPS más rápida en Android
- Cómo crear Android La vista de cuadrícula de Google Play como Widget con imágenes de diferentes tamaños cargadas dinámicamente