三、Libmedia层介绍
在文件/framework/base/media/libmedia/MediaProfiles.cpp中实现了MediaProfiles的getInstance()和getImageEncodingQualityLevels(),其code如下:
/*static*/ MediaProfiles*
MediaProfiles::getInstance()
{
LOGV("getInstance");
Mutex::Autolock lock(sLock);
if (!sIsInitialized) {
char value[PROPERTY_VALUE_MAX];
if (property_get("media.settings.xml", value, NULL) <= 0) {
const char *defaultXmlFile = "/etc/media_profiles.xml";
FILE *fp = fopen(defaultXmlFile, "r");
if (fp == NULL) {
LOGW("could not find media config xml file");
sInstance = createDefaultInstance();
} else {
fclose(fp); // close the file first.
sInstance = createInstanceFromXmlFile(defaultXmlFile);
}
} else {
sInstance = createInstanceFromXmlFile(value);
}
}
return sInstance;
}
该函数中判断,如果"/etc/media_profiles.xml"存在就调用函数
createInstanceFromXmlFile()去解析该xml文件,否则调用createDefaultInstance()创建默认的数值。
函数createDefaultInstance()的实现如下:
/*static*/ MediaProfiles*
MediaProfiles::createDefaultInstance()
{
MediaProfiles *profiles = new MediaProfiles;
createDefaultCamcorderProfiles(profiles);
createDefaultVideoEncoders(profiles);
createDefaultAudioEncoders(profiles);
createDefaultVideoDecoders(profiles);
createDefaultAudioDecoders(profiles);
createDefaultEncoderOutputFileFormats(profiles);
createDefaultImageEncodingQualityLevels(profiles);
sIsInitialized = true;
return profiles;
}
函数createDefaultImageEncodingQualityLevels()实现如下:
/*static*/ void
MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles)
{
profiles->mImageEncodingQualityLevels.add(70);
profiles->mImageEncodingQualityLevels.add(80);
profiles->mImageEncodingQualityLevels.add(90);
}
由此,可以看出,默认情况下,会将70,80,90做为jpeg quality的三个quality等级对应的数值。
如果xml文件存在,就需要看看函数createInstanceFromXmlFile()了,其定义为:
/*static*/ MediaProfiles*
MediaProfiles::createInstanceFromXmlFile(const char *xml)
{
FILE *fp = NULL;
CHECK((fp = fopen(xml, "r")));
XML_Parser parser = ::XML_ParserCreate(NULL);
CHECK(parser != NULL);
MediaProfiles *profiles = new MediaProfiles();
::XML_SetUserData(parser, profiles);
::XML_SetElementHandler(parser, startElementHandler, NULL);
/*
FIXME:
expat is not compiled with -DXML_DTD. We don't have DTD parsing support.
if (!::XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)) {
LOGE("failed to enable DTD support in the xml file");
return UNKNOWN_ERROR;
}
*/
const int BUFF_SIZE = 512;
for (;;) {
void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
if (buff == NULL) {
LOGE("failed to in call to XML_GetBuffer()");
delete profiles;
profiles = NULL;
goto exit;
}
int bytes_read = ::fread(buff, 1, BUFF_SIZE, fp);
if (bytes_read < 0) {
LOGE("failed in call to read");
delete profiles;
profiles = NULL;
goto exit;
}
CHECK(::XML_ParseBuffer(parser, bytes_read, bytes_read == 0));
if (bytes_read == 0) break; // done parsing the xml file
}
exit:
::XML_ParserFree(parser);
::fclose(fp);
if (profiles) {
sIsInitialized = true;
}
return profiles;
}
函数getImageEncodingQualityLevels()的定义为:
Vector<int> MediaProfiles::getImageEncodingQualityLevels() const
{
return mImageEncodingQualityLevels; // copy out
}
只需返回存储了jpeg quality数值的数组mImageEncodingQualityLevels就行了。
四、小结
通过研究jpeg quality的菜单,简单了解了JNI接口的注册和实现流程。虽然里面还有不少不大清楚地地方,但此记录可以帮助日后使用JNI接口时使用。
E-mail:wxiaozhe@163.com
QQ:1226062415
Date:2011/5/14
Blog:http://blog.csdn.net/wxzking
欢迎交流,欢迎转载,转载时请保留以上信息。
转自:http://blog.csdn.net/wxzking/article/details/6425959
pdf格式:http://211.100.26.59/data/myspace/49/245368/bbs/2011-05-17/1305644407_5b9b9dd5.pdf