当前位置:  编程技术>移动开发
本页文章导读:
    ▪opencore内部部署        opencore内部调度 1 引言 多媒体框架是非常重要而又令人关心的模块,尤其在 android 的系统上,多媒体播放效果如何,对其框架了解是非常必要的。 多媒体中的调度问题,是个背后的故.........
    ▪ 【转】NSString+NSMutableString+NSValue+NSAraay用法集锦        【转】NSString+NSMutableString+NSValue+NSAraay用法汇总 [经验分享] NSString+NSMutableString+NSValue+NSAraay用法汇总   开发过程中难免遇到字符串操作,下面是CocoaChina为您总结的NSString+NSMutableString+NSValue+NSAr.........
    ▪ VGA WVGA QVGA HVGE XGA差别       VGA WVGA QVGA HVGE XGA区别 对于准备换新手机的朋友,可能会参考一些参数,比如手机屏幕的分辨率。今天就来看看手机屏幕VGA QVGA HVGA WVGA区别,一般手机液晶屏幕都是TFT材质,VGA WVGA QVGA HVGE XGA.........

[1]opencore内部部署
    来源: 互联网  发布时间: 2014-02-18
opencore内部调度
1 引言

多媒体框架是非常重要而又令人关心的模块,尤其在 android 的系统上,多媒体播放效果如何,对其框架了解是非常必要的。

多媒体中的调度问题,是个背后的故事,但却对性能影响至关重要,本文并非全面分析多媒体框架,旨在探讨媒体框架调度方面与传统的多线程应用间的差异。  

2 基本知识

1.        多媒体框架:

宏观上看多媒体框架一般包含: engine 、 parser 、 codec 、 output , engine 为控制部分, parser 为文件解析及读取部分, codec 就是音视频编解码, output 包含音视频输出。针对不同文件类型及编解码器,会有多种 parser 及 codec 。

2.        Linux 线程:

       一般来讲 linux 都会定义最大线程为 1024 ,不过还没有看到哪个系统运行起来有如此之多的线程存在,也有网评说创建到 382 个线程时返回失败。最大线程数目会受到系统资源的影响。

       多线程在管理调度上也会影响系统性能,影响的是 kernel 部分。

       多线程应用设计中,数据共享是个问题,线程 A 和线程 B 间共享数据,为确保数据访问有效,会引入锁,比如信号量。多个线程中,信号量等待是很重要的,有时线程 A 的数据准备 OK 了,但线程 B 没有用完,那么接下来线程 A 只能死等或是空转。

       多线程中,还要避免线程死锁。  

3 调度对比

在此我们拿传统 while 循环、多线程模式、 opencore 调度模式作对比,如下图示。

 

模式一:

      顺序执行,有新模块加入就挨着添加。

模式二:

      不论有限与否, ABCD 四个模块都在独立运行,即使浪费也要空转。

模式三:

      由统一调度器调度,优先者优先调度, ABCD 四个模块都注册到调度器上,通过状态机切换触发下一次调度,谁着急被再次调用谁就去触发调度器执行,相对公平。 Opencore 采用该模式, PlayerDriver 创建后进入 OSCL 线程来处理消息, engine 创建完各个 node 节点并将其连接起来,剩下的就是 node 间的通讯问题,各 node 状态变化会触发 oscl 对其下一次调度,参与到oscl调度中的模块都必须提供一个Run函数,oscl会去call这个函数。

 

4     opencore 为何不用多线程

因为有人曾疑问,为什么opencore不去创建大量线程来调度,那样不是更快,事实上opencore是采用上述模式三来解决调度问题的。附上一张oscl调度相关的类图。

 

opencore 中为何不大量去创建线程来完成各个模块,暂时没有看到 opencore 的官方设计文档来讲述其设计思路,只能通过代码去分析,下述也仅一家之言供参考。

1.        从模块化去看, opencore 有很多模块,包含 engine 、 player 、 author 、 parser 、 omx 、 codec 、 output 、 audio 、 video 等,并且 opencore 抽象出来个概念叫 node , parser/codec/omx 都被封装成 node , engine 负责把各个 node 节点创建并连接起来后,剩下的就是各个 node 节点之间的通讯,它们由统一调度器来调度。试想,如果每个 node (或者说模块)都去创建一个线程去执行,如何管理是个问题,也有悖软件工程的模块化思想。

2.        从模块化再看,假如把多媒体缩减到 engine 、 parser 、 decoder 三个模块,如果多线程去做,会有三个线程,这是其一,其二,文件类型识别及解码器识别需要事先完成,必然由 engine 去完成,从而决定用哪个 parser 和 decoder 。 Opencore 里分的很清楚,各个模块干各自的事情,一个线程统一调度完成。

3.        从 CS 模型去看, android 中多媒体采用服务器客户端架构来实现,客户端是 jiava 程序,仅用于一些 API 的封装、控制指令的下放等;核心的媒体播放控制都在服务器端实现,它们之间通过 binder 调用衔接。当有客户端发起媒体请求时,服务器就创建一个 client 去对应它,如果有第二个媒体请求,就会创建第二个 client 来对应。如此一来,服务器端可能会存在多个 client ,每个 client 都是一个媒体引擎的实例,假如 opencore 采用了多线程模式,又假如引擎总共涉及 6 个线程,倘若有五个客户端发起请求,系统就会增加 30 个线程,如此一来显然增加 kernel 的调度时间,影响系统性能。而采用 opencore 的统一调度,五个客户端也就呼起五个线程,这是可以接受的。

4.        从多媒体的应用场景来看,视频播放、短信铃声、彩信铃声、电话铃声、闹钟铃声是会同时出现的,这样就触发了上述多种客户端的情况。

5.        从可移植看, opencore 采用的统一调度器叫 oscl ,它是一个抽象封装,基于 oscl 之上可以看做纯软件模块,如此一来 opencore 可以很容易的移植到各个平台,且保持一致性。

6.        从扩展性看, opencore 现有框架添加一个模块很容易,比如添加 rmvb 的支持,只要添加一个 rmvb 的 parser-node 即可,对系统框架没有任何影响。如果采用多线程, rmvb 的 parser 肯定要实现, engine 中要添加 rmvb 识别部分,也会添加创建 rmvb-parser 线程部分。

7.        多线程肯定是最快的,但复杂系统考虑自身架构设计及可扩展性,势必在多线程的应用上采取谨慎态度。关键的问题,应该还是落在系统性能上,拿 200M 主频和 1G 主频作对比,在 200M 主频处理器上再怎么优化,也赶不上 1G 处理器,换句话说, 1G 处理器上即使框架再烂,系统运行的也不会太差。

8.        DirectX 中也有一个 filter 的概念(类似 opencore 中的 node 节点),应用 directx 开发中,只要把各个 filter 连接起来即可,剩下的是 filter 间的事情。  

5 附录

附录两张图,均来自网络。

一张 opencore 的框架图。

 

 

下面是代码片段


    
[2] 【转】NSString+NSMutableString+NSValue+NSAraay用法集锦
    来源: 互联网  发布时间: 2014-02-18
【转】NSString+NSMutableString+NSValue+NSAraay用法汇总

[经验分享] NSString+NSMutableString+NSValue+NSAraay用法汇总

 

开发过程中难免遇到字符串操作,下面是CocoaChina为您总结的NSString+NSMutableString+NSValue+NSAraay用法汇总,帮您应对各种字符串操作。

 

//一、NSString    

    /*----------------创建字符串的方法----------------*/

 

    //1、创建常量字符串。

    NSString *astring = @"This is a String!";

 

 

    //2、创建空字符串,给予赋值。

 

    NSString *astring = [[NSString alloc] init];

    astring = @"This is a String!";

    NSLog(@"astring:%@",astring);

  [astring release];

 

 

 

 

    //3、在以上方法中,提升速度:initWithString方法

 

    NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];

    NSLog(@"astring:%@",astring);

    [astring release];

 

 

 

    //4、用标准c创建字符串:initWithCString方法

 

    char *Cstring = "This is a String!";

    NSString *astring = [[NSString alloc] initWithCString:Cstring];

    NSLog(@"astring:%@",astring);

    [astring release];

 

 

 

    //5、创建格式化字符串:占位符(由一个%加一个字符组成)

 

    int i = 1;

    int j = 2;

    NSString *astring = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%d.This is %i string!",i,j]];

    NSLog(@"astring:%@",astring);

    [astring release];

 

 

 

    //6、创建临时字符串

 

    NSString *astring;

    astring = [NSString stringWithCString:"This is a temporary string"];

    NSLog(@"astring:%@",astring);

 

 

 

 

    /*----------------从文件读取字符串:initWithContentsOfFile方法 ----------------*/    

 

    NSString *path = @"astring.text";

    NSString *astring = [[NSString alloc] initWithContentsOfFile:path];

    NSLog(@"astring:%@",astring);

    [astring release];

 

 

    /*----------------写字符串到文件:writeToFile方法 ----------------*/    

 

 

    NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];

    NSLog(@"astring:%@",astring);

    NSString *path = @"astring.text";    

    [astring writeToFile: path atomically: YES];

    [astring release];    

 

 

 

 

    /*---------------- 比较两个字符串----------------*/        

 

    //用C比较:strcmp函数

 

    char string1[] = "string!";

    char string2[] = "string!";

    if(strcmp(string1, string2) = = 0)

    {

        NSLog(@"1");

    }

 

 

 

    //isEqualToString方法    

    NSString *astring01 = @"This is a String!";

    NSString *astring02 = @"This is a String!";

    BOOL result = [astring01 isEqualToString:astring02];

    NSLog(@"result:%d",result);

 

 

 

 

    //compare方法(comparer返回的三种值)    

    NSString *astring01 = @"This is a String!";

    NSString *astring02 = @"This is a String!";    

    BOOL result = [astring01 compare:astring02] = = NSOrderedSame;    

    NSLog(@"result:%d",result);    

    //NSOrderedSame 判断两者内容是否相同

 

 

 

 

    NSString *astring01 = @"This is a String!";

    NSString *astring02 = @"this is a String!";

    BOOL result = [astring01 compare:astring02] = = NSOrderedAscending;    

    NSLog(@"result:%d",result);

    //NSOrderedAscending 判断两对象值的大小(按字母顺序进行比较,astring02大于astring01为真)

 

 

 

    NSString *astring01 = @"this is a String!";

    NSString *astring02 = @"This is a String!";

    BOOL result = [astring01 compare:astring02] = = NSOrderedDescending;    

    NSLog(@"result:%d",result);     

    //NSOrderedDescending 判断两对象值的大小(按字母顺序进行比较,astring02小于astring01为真)

 

 

 

    //不考虑大 小写比较字符串1

    NSString *astring01 = @"this is a String!";

    NSString *astring02 = @"This is a String!";

    BOOL result = [astring01 caseInsensitiveCompare:astring02] = = NSOrderedSame;    

    NSLog(@"result:%d",result);     

    //NSOrderedDescending判断两对象值的大小(按字母顺序进行比较,astring02小于astring01为 真)

 

 

 

    //不考虑大小写比较字符串2

    NSString *astring01 = @"this is a String!";

    NSString *astring02 = @"This is a String!";

    BOOL result = [astring01 compare:astring02

                            options:NSCaseInsensitiveSearch | NSNumericSearch] = = NSOrderedSame;    

    NSLog(@"result:%d",result);     

 

    //NSCaseInsensitiveSearch:不区分大小写比较 NSLiteralSearch:进行完全比较,区分大小写 NSNumericSearch:比较字符串的字符个数,而不是字符值。

 

 

    /*----------------改变字符串的大小写----------------*/    

 

    NSString *string1 = @"A String"; 

    NSString *string2 = @"String"; 

    NSLog(@"string1:%@",[string1 uppercaseString]);//大写

    NSLog(@"string2:%@",[string2 lowercaseString]);//小写

    NSLog(@"string2:%@",[string2 capitalizedString]);//首字母大小

 

 

    /*----------------在串中搜索子串 ----------------*/        

 

    NSString *string1 = @"This is a string";

    NSString *string2 = @"string";

    NSRange range = [string1 rangeOfString:string2];

    int location = range.location;

    int leight = range.length;

    NSString *astring = [[NSString alloc] initWithString:[NSString stringWithFormat:@"Location:%i,Leight:%i",location,leight]];

    NSLog(@"astring:%@",astring);

    [astring release];

 

 

    /*----------------抽取子串 ----------------*/        

 

    //-substringToIndex: 从字符串的开头一直截取到指定的位置,但不包括该位置的字符

    NSString *string1 = @"This is a string";

    NSString *string2 = [string1 substringToIndex:3];

    NSLog(@"string2:%@",string2);

 

 

 

 

    //-substringFromIndex: 以指定位置开始(包括指定位置的字符),并包括之后的全部字符

    NSString *string1 = @"This is a string";

    NSString *string2 = [string1 substringFromIndex:3];

    NSLog(@"string2:%@",string2);

 

 

 

 

    //-substringWithRange: //按照所给出的位置,长度,任意地从字符串中截取子串

    NSString *string1 = @"This is a string";

    NSString *string2 = [string1 substringWithRange:NSMakeRange(0, 4)];

    NSLog(@"string2:%@",string2);

//***************************************************

//扩展路径

 

    NSString *Path = @"~/NSData.txt";

    NSString *absolutePath = [Path stringByExpandingTildeInPath];

    NSLog(@"absolutePath:%@",absolutePath);

    NSLog(@"Path:%@",[absolutePath stringByAbbreviatingWithTildeInPath]);

 

 

 

    //文件扩展名

    NSString *Path = @"~/NSData.txt";

    NSLog(@"Extension:%@",[Path pathExtension]);

 

 

 

 

    /*******************************************************************************************

     NSMutableString

     *******************************************************************************************/    

 

    /*---------------给字符串分配容量----------------*/

    //stringWithCapacity:

    NSMutableString *String;

    String = [NSMutableString stringWithCapacity:40];

 

 

    /*---------------在已有字符串后面添加字符----------------*/    

 

    //appendString: and appendFormat:

 

    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];

    //[String1 appendString:@", I will be adding some character"];

    [String1 appendFormat:[NSString stringWithFormat:@", I will be adding some character"]];

    NSLog(@"String1:%@",String1);

    */

 

 

    /*-------- 在已有字符串中按照所给出范围和长度删除字符------*/    

    /*

     //deleteCharactersInRange:

     NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];

     [String1 deleteCharactersInRange:NSMakeRange(0, 5)];

     NSLog(@"String1:%@",String1);

 

 

 

     /*--------在已有字符串后面在所指定的位置中插入给出的字符串------*/

 

    //-insertString: atIndex:

    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];

    [String1 insertString:@"Hi! " atIndex:0];

    NSLog(@"String1:%@",String1);

 

 

 

    /*--------将已有的空符串换成其它的字符串------*/

 

    //-setString:

    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];

    [String1 setString:@"Hello Word!"];

    NSLog(@"String1:%@",String1);

 

 

 

    /*--------按照所给出的范围,和字符串替换的原有的字符------*/

 

    //-setString:

    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];

    [String1 replaceCharactersInRange:NSMakeRange(0, 4) withString:@"That"];

    NSLog(@"String1:%@",String1);

 

 

 

    /*-------------判断字符串内是否还包含别的字符串(前缀,后缀)-------------*/

    //01: 检查字符串是否以另一个字符串开头- (BOOL) hasPrefix: (NSString *) aString;

    NSString *String1 = @"NSStringInformation.txt";

    [String1 hasPrefix:@"NSString"] = = 1 ?  NSLog(@"YES") : NSLog(@"NO");

    [String1 hasSuffix:@".txt"] = = 1 ?  NSLog(@"YES") : NSLog(@"NO");

 

    //02: 查找字符串某处是否包含其它字符串 - (NSRange) rangeOfString: (NSString *) aString,这一点前面在串中搜索子串用到过;

 

 

 

    /*******************************************************************************************

     NSArray

     *******************************************************************************************/

 

    /*---------------------------创建数组 ------------------------------*/

    //NSArray *array = [[NSArray alloc] initWithObjects:

    @"One",@"Two",@"Three",@"Four",nil];

 

    self.dataArray = array;

    [array release];

 

    //- (unsigned) Count;数组所包含对象个数;

    NSLog(@"self.dataArray cound:%d",[self.dataArray count]);

 

    //- (id) objectAtIndex: (unsigned int) index;获取指定索引处的对象;

    NSLog(@"self.dataArray cound 2:%@",[self.dataArray objectAtIndex:2]);

 

 

    /*-------------------------- 从一个数组拷贝数据到另一数组(可变数级)----------------------------*/    

 

    //arrayWithArray:

    //NSArray *array1 = [[NSArray alloc] init];

    NSMutableArray *MutableArray = [[NSMutableArray alloc] init];

    NSArray *array = [NSArray arrayWithObjects:

                      @"a",@"b",@"c",nil];

    NSLog(@"array:%@",array);

    MutableArray = [NSMutableArray arrayWithArray:array];

    NSLog(@"MutableArray:%@",MutableArray);

 

    array1 = [NSArray arrayWithArray:array];

    NSLog(@"array1:%@",array1);

 

 

    //Copy

 

    //id obj;

    NSMutableArray *newArray = [[NSMutableArray alloc] init];

    NSArray *oldArray = [NSArray arrayWithObjects:

                         @"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",nil];

 

    NSLog(@"oldArray:%@",oldArray);

    for(int i = 0; i 

1 楼 xjg19870111 2011-11-20  
不错,谢谢版主收集

    
[3] VGA WVGA QVGA HVGE XGA差别
    来源: 互联网  发布时间: 2014-02-18
VGA WVGA QVGA HVGE XGA区别

对于准备换新手机的朋友,可能会参考一些参数,比如手机屏幕的分辨率。今天就来看看手机屏幕VGA QVGA HVGA WVGA区别,一般手机液晶屏幕都是TFT材质,VGA WVGA QVGA HVGE XGA只是表示屏幕分辨率只,是个代号和材质没关系。

分辨率对照表:

代号 分辨率 代号 分辨率 QVGA 320*240像素 WQVGA 400*240像素 HVGA 320*480像素 VGA 640*480像素 WVGA 800*480像素 XGA 1024*480像素

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • QVGA 即Quarter VGA。顾名思义即VGA的四分之一尺寸
  • HVGA (Half-size VGA),即VGA(640*480)的一半
  • WVGA 即Wide VGA
  • WQVGA 全称:Wide Quarter Video Graphics Array
  • VGA和XGA(Extended Graphics Array) 详情见百度百科
  • 他们和屏幕大小也没关系,比如 诺基亚N95和诺基亚E71都是QVGA 320*240,N95是2.6英寸 N95 8GB为2.8英寸, 而E71是2.36英寸

    再看,苹果iphone是HVGA 320*480 3.5英寸 而G3(HTC hero)也是HVGA 320*480 屏幕为3.2英寸。

    当然同样的分辨率 屏幕越小 显示越细腻!


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android双击返回键退出程序的实现方法 iis7站长之家
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3