I am trying to understanding how MediaCodec is used for hardware decoding.
My knowledge in android internal is very limited.
Here is my findings:
There is a xml file which represents the codec details in the android system .
device/ti/omap3evm/media_codecs.xml for an example.
Which means, that If we create a codec from the Java Application with Media Codec
MediaCodec codec = MediaCodec.createDecoderByType(type);
It should be finding out respective coder with the help of xml file.
What am I doing?
I am trying to figure our which part of the code is reading xml and find the codec based on given 'type'.
1) Application Layer :
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 Implementation -> [ 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
}
from 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
}
I am struck with this flow. If someone points out how to take it forward would help a lot.
thanks.
Let's take the flow step by step.
MediaCodec::CreateByType
will create a newMediaCodec
objectMediaCodec
constructor would create a newACodec
object and store it asmCodec
When
MediaCodec::init
is invoked, it internally instructs the underlyingACodec
to allocate theOMX
component throughmCodec->initiateAllocateComponent
.ACodec::initiateAllocateComponent
would invokeonAllocateComponent
ACodec::UninitializedState::onAllocateComponent
would invokeOMXCodec::findMatchingCodecs
to find the codecs matching theMIME
type passed from the caller.In
OMXCodec::findMatchingCodecs
, there is a call to retrieve an instance ofMediaCodecList
asMediaCodecList::getInstance()
.In
MediaCodecList::getInstance
, there is a check if there is an existingMediaCodecList
or else a new object ofMediaCodecList
is created.In the constructor of
MediaCodecList
, there is a call toparseXMLFile
with the file name as/etc/media_codecs.xml
.parseXMLFile
reads the contents and stores the different component names etc intoMediaCodecList
which can be used for any other codec instance too. The helper function employed for the parsing isstartElementHandler
. A function of interest could beaddMediaCodec
.Through these steps, the
XML
file contents are translated into a list which can be employed by any other module.MediaCodecList
is exposed at Java layer too as can be referred from here.I have skipped a few hops wherein
MediaCodec
andACodec
employ messages to actually communicate and invoke methods, but the flow presented should give a good idea about the underlying mechanism.