您的位置:首页 > 移动开发 > Android开发

Android平台上从Camera的jpegquality菜单研究JNI接口(三)

2011-05-17 08:47 465 查看
三、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
欢迎交流,欢迎转载,转载时请保留以上信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: