zoukankan      html  css  js  c++  java
  • 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的框架图。
    下面是代码片段

    http://blogold.chinaunix.net/u2/61880/showart_2330325.html

  • 相关阅读:
    pgspider sqlite mysql docker 镜像
    pgspider docker 镜像
    pgspider基于pg 的高性能数据可视化sql 集群引擎
    diesel rust orm 框架试用
    golang 条件编译
    Performance Profiling Zeebe
    bazel 学习一 简单java 项目运行
    一个好用node http keeplive agnet
    gox 简单灵活的golang 跨平台编译工具
    mailhog 作为smtp server mock工具
  • 原文地址:https://www.cnblogs.com/eustoma/p/2415826.html
Copyright © 2011-2022 走看看