StageFright_Video Buffer传输流程
Kommander 软件使用手册说明书
Kommander软件使用手册V4.9适用于:T0、T1、T3、F1、F2服务热线:400-159-0808官方网址:目录1.简介 (1)1.1.概述 (1)1.2.软件运行环境 (1)1.3.产品线差异表 (2)2.软件安装与卸载 (3)3.Kommander界面介绍 (6)3.1.菜单栏 (6)3.1.1.文件菜单 (6)3.1.2.画布菜单 (7)3.1.3.多联机菜单 (7)3.1.4.资源菜单 (8)3.1.5.窗口菜单 (8)3.1.6.设置菜单 (8)3.1.7.锁屏 (9)3.1.8.帮助 (10)3.2.媒体资源库 (10)3.2.1.媒体资源管理 (11)3.2.2.小工具 (11)3.2.3.播放列表 (12)3.2.4.特效库 (13)3.3.播控区 (13)3.3.1.屏幕管理 (14)3.3.2.画布编辑 (15)3.3.3.播放状态 (15)3.3.4.黑屏 (16)3.3.5.画布上素材设置 (16)3.4.参数设置栏 (17)3.4.1.层级调整 (17)3.4.4.文件透明通道 (18)3.4.5.启用Y/C伸张 (18)3.4.6.裁剪 (18)3.4.7.效果设置 (18)3.4.8.时间裁剪 (19)3.4.9.蒙层 (19)3.4.10.抠像 (19)3.4.11.声道映射 (20)3.5.播放进度 (20)3.6.播放预案区 (21)3.6.1.预案分组 (21)3.6.2.预案 (21)3.6.3.主KV (22)3.7.输出区 (23)3.8.更新 (24)3.9.时间码 (24)3.10.音频列表 (25)4.工程编辑流程 (26)4.1.切换电脑显示模式 (26)4.2.运行软件 (26)4.3.新建工程 (26)4.4.添加素材 (27)4.5.进行屏幕管理配置 (27)4.5.1.添加显示口 (28)4.5.2.新建和编辑屏 (28)4.6.画布编辑和输出 (28)5.素材支持 (29)5.1.本地媒体 (29)5.2.播放列表 (30)5.3.字幕 (30)5.4.Office文件 (31)5.7.截屏 (32)5.8.网站 (33)5.9.小工具 (34)5.9.1.字幕 (34)5.9.2.数字时钟 (34)5.9.3.模拟时钟 (34)5.9.4.表格 (34)5.9.5.正计时 (34)5.9.6.倒计时 (35)5.9.7.天气 (35)5.9.8.抽奖 (35)5.9.9.幻彩字 (36)5.9.10.箱体图 (37)5.10.NDI采集 (38)5.11.序列帧 (39)5.12.添加spout (39)6.其他功能 (40)6.1.软件系统设置 (40)6.2.工程打包 (41)6.3.在线更新软件 (42)6.4.图片优化 (42)6.5.自动保存与恢复 (43)6.6.预编布局与实时布局的使用 (43)6.7.云控 (43)6.8.定时任务 (43)6.9.NDI发送 (44)6.10.多联机 (44)6.11.声光电一体化支持 (45)6.12.直播推流-rtmp.....................................................错误!未定义书签。
Android_ics_stagefright框架数据流向分析 - xww810319的专栏
Android_ics_stagefright框架数据流向分析2014-01-03 10:15 78人阅读评论(0) 收藏举报原文:Android_ics_stagefright框架数据流向分析——1,待解码的原始数据从何而来链接:/mci2004/article/details/7629146先明确一点,stagefright框架是典型的事件驱动型,数据的流向也受到事件驱动(driven by event)的影响,在awesomePlayer中主要的驱动事件有:onPrepareAsyncEvent,onVideoEvent,onStreamDone......这些event会在awesomeplayer中维护的TimedEventQueue mQueue中按照时间的顺序被放入这个队列中。
然后TimedEventQueue根据时间顺序来调度事件。
这样做的目的是:因为,按照mQueue中事件的是按事件排序的,所以,在视频数据到来时,可以根据视频的时间戳来进行音视频同步的调节。
AwesomePlayer中音视频的同步处理就是在onVideoEvent()回调中来做的。
当应用层调用mediaplayer.prepare()的时候,在框架内最终对应的是AwesomePlayer::prepareAsync_l(),这个函数的实现很简单,看下主要的实现部分:status_t AwesomePlayer::prepareAsync_l() {…mAsyncPrepareEvent = new AwesomeEvent(this,&AwesomePlayer::onPrepareAsyncEvent);mQueue.postEvent(mAsyncPrepareEvent); //向mQueue中投递一个事件}那么当mQueue在进行事件调度的时候,会执行到事件对应的回调函数,例如上面 mAsyncPrepareEvent对应的回调函数就是 onPrepareAsyncEvent。
LibStageFright
图2 LibStageFright与外部接口调用关系图图3 MediaPlayer框架图4 MediaRecorder框架libmedia和libmediaplayerservice分析1)libmedia目录在frameworks/base/media/libmedia,为多媒体底层库,这里面的内容被编译成libmedia.so在整个MediaPlayer运行中属于Client部分1.libmedia.so处于核心位置,主要实现对上层以及下层的接口类。
对上层主要提供MediaPlayer类的接口,类libmedia_jni.so通过调用MediaPlayer类,提供对JAVA的接口。
2.另外一部分则通过Binder机制和libmediaplayerservice.so进行通讯。
3.对stagefright,则定义了标准的IOMX接口。
Stagefirght通过该接口调用OpenMax插件。
2)libmeidaplayerservice目录在frameworks/base/media/libmediaplayerservice为多媒体服务部分,文件为mediaplayerservice.h和mediaplayerservice.cpp,这部分内容被编译成libmediaplayerservice.so在整个MediaPlayer运行中处于Server部分这部分通过继承libmedia.so的类,实现服务器的功能。
对mediaplayer整个流程进行管理调度。
通过stagefrightPlayer和stagefrightRecorder,调用到stagefirght框架中的音视频播放与录制功能。
图5 MediaPlayer各个库之间结构图图6 整个Media库调用关系图LibStageFright主要工作流程videoDecode1创建playerengine// 设置数据源,以及audio sinkMediaPlayer::SetDataSource(PATH_TO_FILE)->MediaPlayerService::create->MediaPlayerService::Client::setDataSource->MediaPlayerService:: Client:: GetPlayerType->MediaPlayerService:: Client::CreatePlayer->StagefrightPlayer:: setAudioSink->StagefrightPlayer:: setDataSource->Create MediaPlayerImpl(AwesomePlayer)->MediaPlayerImpl:: MediaPlayerImplPlayerType:PV_PLAYER--------------------(已经不使用,原本为创建OpenCore中的PVPlayer) SONIVOX_PLAYER----------- MidiFile()(MIDI 格式)STAGEFRIGHT_PLAYER----- StagefrightPlayerNU_PLAYER---------------------NuPlayer(流媒体播放器)TEST_PLAYER------------------- TestPlayerStub (only for ‘test’ and ‘eng’build)//以下为与openMax插件的初始化连接。
网易视频云:Android多媒体框架opencore和stagefright分析
网易视频云:Android多媒体框架opencore和stagefright分析Android 系统整体架构:我们先看一下多媒体框架在整个Android系统所处的位置从框架图可以看出Media Framework处于Libraries这一层,这层的Library不是用Java 实现,一般是C/C++实现,它们通过Java的JNI方式调用。
Android 系统的多媒体业务:多媒体框架变动:Android froyo版本多媒体引擎做了变动,新添加了stagefright框架,并且默认情况android选择stagefright,弃用之前的opencore,仅仅对opencore中的omx-component 部分做了引用。
Stagefright自android2.0后才添加,其稳定性有待商榷,是否存在bug 也未知,opencore自android诞生起便存在,稳定性有保障。
Opencore上的开发较stagefright上要复杂耗时些。
不过,从目前android代码看,opencore 有被stagefright取代的趋势,从Android2.3 (Gingerbread) 开始,预设的多媒体框架为Stagefright。
以MediaPlayer为例,我们先看一下多媒体的简单框架。
上图可知,stagefright是在MediaPlayerService这一层加入的,和opencore是并列的,在选用opencore还是stagefright的代码切换上也非常容易。
OpenCore框架介绍:Open Core是Android 多媒体框架的核心,所有Android平台的音视频采集,播放的操作都是通过它来实现。
它也被称为PV(Packet Video), Packet Video是一家专门提供多媒体解决方案的公司。
通过Open Core程序员可以方便快速的开发出想要的多媒体应用程序,例如:音视频的采集,回放,视频会议,实时的流媒体播放等等应用。
SmaartLive的基本操作技巧攻略
SIA的基本操作攻略进几年,在现场的SR作业里,总是会携带一些各人的装备,如手提电脑或者是一些处理器啦,或是一些你善用的效果器。
早期,一般条件好些的硬件系统在架设完后,都会有一些校准的动作,当然会使用到一些仪测的设备,通常有的就是Gold Line,或是audio control这类的频谱分析仪,这些工具虽然只是简单的LED灯光排列显示信息,不过却能给人信赖与放心。
最近看了一些朋友同行们,出门携带设备在旁的,几乎是场场必见手提电脑,也大致上看了大家在使用的平台是什幺,不管大家用什么东东出现在计算机里,最重要的是它要能工作!而且是准确的,不是打开在那儿突显自己控场子有用计算机哦!水准哦!好啦。
频谱分析工具,它们的单位离不开分贝dB、音压值SPL、等响加权,为何要介绍它呢?使用的环境国际化嘛,支持的厂商多嘛,还有它的前身就是JBL 那一套软件,然后老板们买得起。
SmaartLive 5是一套双信道,采用FFT数学运算转换为基础的量测软件,它可以实时分析音场频谱设备,或是声音档案的相位、时间等工具,也可遥控调整有支持软件的喇叭处理器,算是在数字软件仪表里,属于便宜又准确的东东。
批注:FFT ( Fast Fourier Transform 快速傅立叶转换or傅氏转换)法国数学、物理学家。
1768年3月21日生于欧塞尔,1830年5月16日卒于巴黎。
9岁父母双亡,被当地教堂收养,12岁由一主教送入地方军事学校读书。
17岁(1785 )回乡教数学,1794到巴黎,成为高等师范学校的首批学员,次年到巴黎综合工科学校执教。
1798年随拿破仑远征埃及时任军中文书和埃及研究院秘书,1801年回国后任伊泽尔省地方长官。
1817年当选为科学院院士,1822年任该院终身秘书,又任法兰西学院终身秘书和理工科大学校务委员会主席。
主要贡献是在研究热的传播时创立了一套数学理论。
1807年向巴黎科学院呈交《热的传播》论文,推导出著名的热传导方程,并在求解该方程时发现解函数可以由三角函数构成的级数形式表示,从而提出任一函数都可以展成三角函数的无穷级数。
stagefright缓存机制
保存所有#EXT-X-STREAM-INF的bandwidth属性 并拼接保存住对应的URI
4. 完成m3u8的parse过程回到LiveSource.loadPlayList 检查m3u8是否为variantPlayList类型的播放列表 如果是则遍历获得所有的带宽值,都保存到mBandwidthItems : Vector中 按照升序排列
prepare 过程
1. 2. 3. 4.
AwesomePlayer内部mQueue(TimedEventQueue)是一个事件队列 mQueue单独有自己的线程(pthread)随时监视队列是否为空 通过异步的方式处理从Proxy进程传入Native进程上的事件 通过 onPrepareAsyncEvent 方法来响应prepare事件
M3UParser.mItems保存着#行中 需要继续构造URI获取数据的项目 包括获取不同带宽的.m3u8文件的URI 即#EXT-X-STREAM-INF(key=―bandwidth‖) 还有获取具体编码数据.ts文件的URI 即#EXTINF(―key=duration‖) 在完成m3u8的parse后要检查mItems 继续尝试连接服务器获取数据
fetchM3U把index.m3u8文件缓冲到 buffer对象上后就直接把指针给了out参数
接之前 loadPlayList的序列图,在完成fetchM3U之后构建M3UParser对.m3u8文件进行解析
prepare 过程—建立liveSource对象,解析m3u8文件
第一行必须是标准m3u8行头:
Android Binder 机制 Proxy进程与Native进程上的AwesomePlayer通信—prepare, start, stop等操作
framebuffer设备原理
framebuffer设备原理FrameBuffer是一种用于图形显示的设备,它作为计算机系统中的一个重要组成部分,用于控制显示器显示图像。
在现代计算机体系结构中,FrameBuffer被广泛应用于图像处理、计算机游戏和图形用户界面等领域。
FrameBuffer设备原理涉及到了显示器、图像数据存储和显示控制等多个方面。
让我们逐步来了解FrameBuffer设备的原理。
首先,我们需要了解FrameBuffer是什么。
FrameBuffer实际上是指一块内存区域,用于存储和管理图像数据。
这块内存被分割成一系列的单元,每个单元都对应屏幕上的一个像素点。
每个像素点的颜色信息都会被存储在FrameBuffer中。
FrameBuffer设备通过显示控制器来控制图像在显示器上的显示。
显示控制器连接着FrameBuffer设备和显示器,负责将FrameBuffer中的图像数据转换成电子信号发送给显示器。
实际上,显示控制器将FrameBuffer中的二进制图像数据转换为模拟信号,通过显示器上的像素点来显示图像。
在显示控制器中,最关键的部分是时序控制电路。
时序控制电路负责生成与显示器参数匹配的时钟信号,以确保每个像素点按照正确的时间顺序接收到正确的图像数据。
时序控制电路还会根据显示器的分辨率和刷新率等参数来确定显示图像的频率。
为了保证图像的质量和平滑度,FrameBuffer设备通常会具备高的色彩深度,即每个像素点可以表示的颜色种类数量。
常见的色彩深度有16位、24位和32位。
高色彩深度可以更精确地表示颜色,使得图像更加真实和细腻。
当用户在计算机上进行图形操作时,如打开应用程序、拖动窗口或者播放视频,操作系统会将相应的图像数据传输到FrameBuffer设备中。
操作系统通过设备驱动程序来控制FrameBuffer设备。
设备驱动程序是连接操作系统和硬件设备的桥梁,它将图像数据传输到FrameBuffer,并通知显示控制器开始显示图像。
V4l2驱动的流程说明
V4l2 基础知识,附图说明 时间:2011-05-17 作者:网络编辑:hawk 点击:176 [ 评论]V4l2 基础知识,附图说明,易于理解Video for Linux two(Video4Linux2)简称V4L2,是V4L的改进版。
V4L2是linux 操作系统下用于采集图片、视频和音频数据的API接口,配合适当的视频采集设备和相应的驱动程序,可以实现图片、视频、音频等的采集。
在远程会议、可视电话、视频监控系统和嵌入式多媒体终端中都有广泛的应用。
一、Video for Linux two在Linux下,所有外设都被看成一种特殊的文件,成为“设备文件”,可以象访问普通文件一样对其进行读写。
一般来说,采用V4L2驱动的摄像头设备文件是/dev/v4l/video0。
为了通用,可以建立一个到/dev/video0的链接。
V4L2支持两种方式来采集图像:内存映射方式(mmap)和直接读取方式(read)。
V4L2在include/linux/videodev.h文件中定义了一些重要的数据结构,在采集图像的过程中,就是通过对这些数据的操作来获得最终的图像数据。
Linux系统V4L2的能力可在Linux内核编译阶段配置,默认情况下都有此开发接口。
V4L2从Linux 2.5.x版本的内核中开始出现。
V4L2规范中不仅定义了通用API元素(Common API Elements),图像的格式(Image Formats),输入/输出方法(Input/Output),还定义了Linux内核驱动处理视频信息的一系列接口(Interfaces),这些接口主要有:视频采集接口——Video Capture Interface;视频输出接口——Video Output Interface;视频覆盖/预览接口——Video Overlay Interface;视频输出覆盖接口——Video Output Overlay Interface;编解码接口——Codec Interface。
framebuffer设备原理
framebuffer设备原理Framebuffer是一种在计算机图形处理中常见的设备,它用于存储显示屏上每个像素的颜色信息。
Framebuffer设备是计算机系统中的一种虚拟设备,它提供了一种机制,使得操作系统和应用程序能够与显示硬件进行高效地交互。
本文将介绍Framebuffer设备的基本原理,并提供相关参考内容供读者进一步学习。
Framebuffer设备的基本原理是将每个显示屏上的像素映射到内存中的一块连续区域,称为帧缓冲区。
帧缓冲区是一个二维数组,每个元素表示一个像素的颜色值。
操作系统和应用程序可以直接读取和写入帧缓冲区中的数据,从而实现图形的显示和更新。
Framebuffer设备的工作流程如下:1. 操作系统初始化:在系统启动过程中,操作系统会检测并初始化Framebuffer设备。
这通常涉及分配内存空间,设置设备参数等操作。
2. 应用程序与Framebuffer设备交互:应用程序可以通过操作系统的API或系统调用与Framebuffer设备进行交互。
例如,应用程序可以请求读取或写入帧缓冲区的数据。
3. 显示控制器更新显示:当帧缓冲区中的数据发生变化时,显示控制器会将新的数据发送到显示设备上,从而更新屏幕上的图像。
Framebuffer设备的设计有以下一些关键要点:1. 缓冲区管理:Framebuffer设备需要分配一块连续的内存作为帧缓冲区,用于存储图像数据。
操作系统需要设计合理的算法来管理帧缓冲区的分配和释放,以实现高效的图像操作。
2. 像素格式:不同的显示设备支持不同的像素格式,例如RGB、RGBA等。
Framebuffer设备需要灵活支持各种不同的像素格式,并能够进行格式转换以适应不同的应用需求。
3. 双缓冲技术:为了避免图像闪烁和撕裂等问题,Framebuffer 设备通常采用双缓冲技术。
双缓冲技术使用两个帧缓冲区,一个用于显示当前的图像,另一个用于更新下一帧的图像。
这样,在切换帧缓冲区时,可以实现无闪烁的图像更新。
stable video diffusion原理
stable video diffusion原理
稳定视频扩散是一种视频传播的原理,旨在通过有效的策略和技术,确保视频
的广泛传播和良好的稳定性。
稳定视频扩散的原理主要包括以下几个方面:
1. 强大的服务器基础设施:稳定视频扩散需要有高度可靠和强大的服务器基础
设施来支持大量视频内容的存储和传输。
这些服务器可以分布在世界各地,以提供全球范围的视频扩散服务。
2. 内容传输网络(CDN):内容传输网络是实现稳定视频扩散的关键要素之一。
CDN通过将视频内容分发到位于不同地理位置的边缘服务器,可以缓解网络拥塞
问题,并提高视频的播放速度和质量。
3. 视频编码和压缩技术:稳定视频扩散还依赖于先进的视频编码和压缩技术。
这些技术可以将视频文件的大小减小到适合互联网传输的程度,同时保持较高的视觉质量,以确保视频的快速加载和流畅播放。
4. 高效的内容识别和推荐算法:稳定视频扩散需要利用先进的内容识别和推荐
算法来自动分析和推荐用户感兴趣的视频内容。
这些算法可以根据用户的历史观看记录、喜好和行为模式,提供相应的视频推荐,从而增加视频的曝光和传播。
5. 社交媒体和用户互动:稳定视频扩散还依赖于社交媒体平台和用户的互动。
通过在社交媒体上分享和评论视频,用户可以扩大视频的传播范围,并带动更多用户的注意和参与。
综上所述,稳定视频扩散的原理涉及服务器基础设施、内容传输网络、视频编
码和压缩技术、内容识别和推荐算法,以及社交媒体和用户互动等方面。
通过合理运用这些原理,可以实现视频的广泛传播和稳定的用户体验。
Stagefright (1) - Video Playback的流程
Stagefright (1) - Video Playback的流程在Android上,預設的多媒體框架(multimedia framework)是OpenCORE。
OpenCORE的優點是兼顧了跨平台的移植性,而且已經過多方驗證,所以相對來說較為穩定;但是其缺點是過於龐大複雜,需要耗費相當多的時間去維護。
從Android 2.0開始,Google引進了架構稍為簡潔的Stagefright,並且有逐漸取代OpenCORE 的趨勢(註1)。
[圖1] Stagefright在Android多媒體架構中的位置。
[圖2] Stagefright所涵蓋的模組(註2)。
以下我們就先來看看Stagefright是如何播放一個影片檔。
Stagefright在Android中是以shared library的形式存在(libstagefright.so),其中的module -- AwesomePlayer可用來播放video/audio (註3)。
AwesomePlayer提供許多API,可以讓上層的應用程式(Java/JNI)來呼叫,我們以一個簡單的程式來說明video playback的流程。
在Java中,若要播放一個影片檔,我們會這樣寫:MediaPlayer mp = new MediaPlayer();mp.setDataSource(PATH_TO_FILE); (1)mp.prepare(); ........................ (2)、(3)mp.start(); (4)在Stagefright中,則會看到相對應的處理;(1) 將檔案的絕對路徑指定給mUristatus_t AwesomePlayer::setDataSource(const char* uri, ...) {return setDataSource_l(uri, ...);}status_t AwesomePlayer::setDataSource_l(const char* uri, ...) {mUri = uri;}(2) 啟動mQueue,作為event handlerstatus_t AwesomePlayer::prepare(){return prepare_l(); => mFlag|= PREPARING}status_t AwesomePlayer::prepare_l(){prepareAsync_l();while (mFlags & PREPARING){mPreparedCondition.wait(mLock);}}status_t AwesomePlayer::prepareAsync_l(){mQueue.start();mFlags |= PREPARING;mAsyncPrepareEvent = new AwesomeEvent(this&AwesomePlayer::onPrepareAsyncEvent);mQueue.postEvent(mAsyncPrepareEvent);}(3) onPrepareAsyncEvent被觸發void AwesomePlayer::onPrepareAsyncEvent(){finishSetDataSource_l();=> dataSource -> extractor-> mVideoTrackinitVideoDecoder(); ...... (3.3) 找Codec and DecoderinitAudioDecoder();}status_t AwesomePlayer::finishSetDataSource_l(){dataSource = DataSource::CreateFromURI(mUri.string(), ...);sp<MediaExtractor> extractor =MediaExtractor::Create(dataSource); ..... (3.1)return setDataSource_l(extractor); ...... (3.2) 分離A/V}PS. dataSource有3種(http://, rtsp://, FD)(3.1) 解析mUri所指定的檔案,並且根據其header來選擇對應的extractorsp<MediaExtractor> MediaExtractor::Create(const sp<DataSource>&source, ...){source->sniff(&tmp, ...);mime = tmp.string();if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4){return new MPEG4Extractor(source);}else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)){return new MP3Extractor(source);}else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB){return new AMRExtractor(source);}}(3.2) 使用extractor對檔案做A/V的分離(mVideoTrack/mAudioTrack)status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor){for (size_t i = 0; i < extractor->countTracks(); ++i){sp<MetaData> meta = extractor->getTrackMetaData(i);CHECK(meta->findCString(kKeyMIMEType, &mime));if (!haveVideo && !strncasecmp(mime, "video/", 6)){setVideoSource(extractor->getTrack(i));haveVideo = true;}else if (!haveAudio && !strncasecmp(mime, "audio/", 6)){setAudioSource(extractor->getTrack(i));haveAudio = true;}}}void AwesomePlayer::setVideoSource(sp<MediaSource> source){mVideoTrack = source;}(3.3) 根據mVideoTrack中的編碼類型來選擇video decoder (mVideoSource)status_t AwesomePlayer::initVideoDecoder(){mVideoSource = OMXCodec::Create(mClient.interface(),mVideoTrack->getFormat(),false,mVideoTrack);}(4) 將mVideoEvent放入mQueue中,開始解碼播放,並交由mVideoRenderer 來畫出status_t AwesomePlayer::play(){return play_l();}status_t AwesomePlayer::play_l(){postVideoEvent_l();}void AwesomePlayer::postVideoEvent_l(int64_t delayUs){mQueue.postEventWithDelay(mVideoEvent, delayUs);}void AwesomePlayer::onVideoEvent(){mVideoSource->read(&mVideoBuffer, &options);[Check Timestamp]mVideoRenderer->render(mVideoBuffer);postVideoEvent_l();}(註1) 從Android2.3 (Gingerbread) 開始,預設的多媒體框架為Stagefright。
video工作原理
video工作原理
视频的工作原理可以被简单描述为以下几个步骤:
1. 采集:通过摄像设备或其他图像传感器,将现实中的场景转换成电信号。
这些信号可以是模拟信号或数字信号。
2. 压缩编码:将采集到的信号进行压缩编码,以减少数据量并提高传输效率。
常用的视频编码标准包括H.264、H.265等。
3. 存储/传输:压缩编码后的视频信号可以被存储到本地设备(如硬盘、存储卡等)或通过网络传输到其他设备。
4. 解码:接收者设备在收到视频信号后,对其进行解码。
解码过程将压缩后的信号恢复为原始的图像和音频数据。
5. 显示:解码后的图像数据将被传递给显示设备,如显示器或电视屏幕。
这些设备通过将图像分为像素并根据像素颜色和亮度值来呈现图像。
整个过程涉及了多个技术和算法,以确保视频的高质量传输和呈现。
Android底层开发技术实战详解:内核、移植和驱动
目 录前言第1章 Android底层开发基础1.1 什么是驱动1.1.1 驱动程序的魅力1.1.2 电脑中的驱动1.1.3 手机中的驱动程序1.2 开源还是不开源的问题1.2.1 雾里看花的开源1.2.2 从为什么选择Java谈为什么不开源驱动程序1.2.3 对驱动开发者来说是一把双刃剑1.3 Android和Linux1.3.1 Linux简介1.3.2 Android和Linux的关系1.4 简析Linux内核1.4.1 内核的体系结构1.4.2 和Android密切相关的Linux内核知识1.5 分析Linux内核源代码很有必要1.5.1 源代码目录结构1.5.2 浏览源代码的工具1.5.3 为什么用汇编语言编写内核代码1.5.4 Linux内核的显著特性1.5.5 学习Linux内核的方法第2章 分析Android源代码2.1 搭建Linux开发环境和工具2.1.1 搭建Linux开发环境2.1.2 设置环境变量2.1.3 安装编译工具2.2 获取Android源代码2.3 分析并编译Android源代码2.3.1 Android源代码的结构2.3.2 编译Android源代码2.3.3 运行Android源代码2.3.4 实践演练——演示编译Android程序的两种方法2.4 编译Android Kernel2.4.1 获取Goldfish内核代码2.4.2 获取MSM内核代码2.4.3 获取OMAP内核代码2.4.4 编译Android的Linux内核2.5 运行模拟器2.5.1 Linux环境下运行模拟器的方法2.5.2 模拟器辅助工具——adb第3章 驱动需要移植3.1 驱动开发需要做的工作3.2 Android移植3.2.1 移植的任务3.2.2 移植的内容3.2.3 驱动开发的任务3.3 Android对Linux的改造3.3.1 Android对Linux内核文件的改动3.3.2 为Android构建Linux的操作系统3.4 内核空间和用户空间接口是一个媒介3.4.1 内核空间和用户空间的相互作用3.4.2 系统和硬件之间的交互3.4.3 使用Relay实现内核到用户空间的数据传输3.5 三类驱动程序3.5.1 字符设备驱动程序3.5.2 块设备驱动程序3.5.3 网络设备驱动程序第4章 HAL层深入分析4.1 认识HAL层4.1.1 HAL层的发展4.1.2 过去和现在的区别4.2 分析HAL层源代码4.2.1 分析HAL moudle4.2.2 分析mokoid工程4.3 总结HAL层的使用方法4.4 传感器在HAL层的表现4.4.1 HAL层的Sensor代码4.4.2 总结Sensor编程的流程4.4.3 分析Sensor源代码看Android API与硬件平台的衔接4.5 移植总结4.5.1 移植各个Android部件的方式4.5.2 移植技巧之一——不得不说的辅助工作第5章 Goldfish下的驱动解析5.1 staging驱动5.1.1 staging驱动概述5.1.2 Binder驱动程序5.1.3 Logger驱动程序5.1.4 Lowmemorykiller组件5.1.5 Timed Output驱动程序5.1.6 Timed Gpio驱动程序5.1.7 Ram Console驱动程序5.2 wakelock和early_suspend5.2.1 wakelock和early_suspend的原理5.2.2 Android休眠5.2.3 Android唤醒5.3 Ashmem驱动程序5.4 Pmem驱动程序5.5 Alarm驱动程序5.5.1 Alarm简析5.5.2 Alarm驱动程序的实现5.6 USB Gadget驱动程序5.7 Android Paranoid驱动程序5.8 Goldfish设备驱动5.8.1 FrameBuffer驱动5.8.2 键盘驱动5.8.3 实时时钟驱动程序5.8.4 TTY终端驱动程序5.8.5 NandFlash驱动程序5.8.6 MMC驱动程序5.8.7 电池驱动程序第6章 MSM内核和驱动解析6.1 MSM基础6.1.1 常见MSM处理器产品6.1.2 Snapdragon内核介绍6.2 移植MSM内核简介6.3 移植MSM6.3.1 Makefile文件6.3.2 驱动和组件6.3.3 设备驱动6.3.4 高通特有的组件第7章 OMAP内核和驱动解析7.1 OMAP基础7.1.1 OMAP简析7.1.2 常见OMAP处理器产品7.1.3 开发平台7.2 OMAP内核7.3 移植OMAP体系结构7.3.1 移植OMAP平台7.3.2 移植OMAP处理器7.4 移植Android专用驱动和组件7.5 OMAP的设备驱动第8章 显示系统驱动应用8.1 显示系统介绍8.1.1 Android的版本8.1.2 不同版本的显示系统8.2 移植和调试前的准备8.2.1 FrameBuffer驱动程序8.2.2 硬件抽象层8.3 实现显示系统的驱动程序8.3.1 Goldfish中的FrameBuffer驱动程序8.3.2 使用Gralloc模块的驱动程序8.4 MSM高通处理器中的显示驱动实现8.4.1 MSM中的FrameBuffer驱动程序8.4.2 MSM中的Gralloc驱动程序8.5 OMAP处理器中的显示驱动实现第9章 输入系统驱动应用9.1 输入系统介绍9.1.1 Android输入系统结构元素介绍9.1.2 移植Android输入系统时的工作9.2 Input(输入)驱动9.3 模拟器的输入驱动9.4 MSM高通处理器中的输入驱动实现9.4.1 触摸屏驱动9.4.2 按键和轨迹球驱动9.5 OMAP处理器平台中的输入驱动实现9.5.1 触摸屏驱动9.5.2 键盘驱动第10章 振动器系统驱动10.1 振动器系统结构10.1.1 硬件抽象层10.1.2 JNI框架部分10.2 开始移植10.2.1 移植振动器驱动程序10.2.2 实现硬件抽象层10.3 在MSM平台实现振动器驱动第11章 音频系统驱动11.1 音频系统结构11.2 分析音频系统的层次11.2.1 层次说明11.2.2 Media库中的Audio框架11.2.3 本地代码11.2.4 JNI代码11.2.5 Java代码11.3 移植Audio系统的必备技术11.3.1 移植Audio系统所要做的工作11.3.2 分析硬件抽象层11.3.3 分析AudioFlinger中的Audio硬件抽象层的实现11.4 真正实现Audio硬件抽象层11.5 MSM平台实现Audio驱动系统11.5.1 实现Audio驱动程序11.5.2 实现硬件抽象层11.6 OSS平台实现Audio驱动系统11.6.1 OSS驱动程序介绍11.6.2 mixer11.7 ALSA平台实现Audio系统11.7.1 注册音频设备和音频驱动11.7.2 在Android中使用ALSA声卡11.7.3 在OMAP平台移植Android的ALSA声卡驱动第12章 视频输出系统驱动12.1 视频输出系统结构12.2 需要移植的部分12.3 分析硬件抽象层12.3.1 Overlay系统硬件抽象层的接口12.3.2 实现Overlay系统的硬件抽象层12.3.3 实现接口12.4 实现Overlay硬件抽象层12.5 在OMAP平台实现Overlay系统12.5.1 实现输出视频驱动程序12.5.2 实现Overlay硬件抽象层12.6 系统层调用Overlay HAL的架构12.6.1 调用Overlay HAL的架构的流程12.6.2 S3C6410 Android Overlay的测试代码第13章 OpenMax多媒体框架13.1 OpenMax基本层次结构13.2 分析OpenMax框架构成13.2.1 OpenMax总体层次结构13.2.2 OpenMax IL层的结构13.2.3 Android中的OpenMax13.3 实现OpenMax IL层接口13.3.1 OpenMax IL层的接口13.3.2 在OpenMax IL层中需要做什么13.3.3 研究Android中的OpenMax适配层13.4 在OMAP平台实现OpenMax IL13.4.1 实现文件13.4.2 分析TI OpenMax IL的核心13.4.3 实现TI OpenMax IL组件实例第14章 多媒体插件框架14.1 Android多媒体插件14.2 需要移植的内容14.3 OpenCore引擎14.3.1 OpenCore层次结构14.3.2 OpenCore代码结构14.3.3 OpenCore编译结构14.3.4 OpenCore OSCL14.3.5 实现OpenCore中的OpenMax部分14.3.6 OpenCore的扩展14.4 Stagefright引擎14.4.1 Stagefright代码结构14.4.2 Stagefright实现OpenMax接口14.4.3 Video Buffer传输流程第15章 传感器系统15.1 传感器系统的结构15.2 需要移植的内容15.2.1 移植驱动程序15.2.2 移植硬件抽象层15.2.3 实现上层部分15.3 在模拟器中实现传感器第16章 照相机系统16.1 Camera系统的结构16.2 需要移植的内容16.3 移植和调试16.3.1 V4L2驱动程序16.3.2 硬件抽象层16.4 实现Camera系统的硬件抽象层16.4.1 Java程序部分16.4.2 Camera的Java本地调用部分16.4.3 Camera的本地库libui.so16.4.4 Camera服务libcameraservice.so16.5 MSM平台实现Camera系统16.6 OMAP平台实现Camera系统第17章 Wi-Fi系统、蓝牙系统和GPS系统17.1 Wi-Fi系统17.1.1 Wi-Fi系统的结构17.1.2 需要移植的内容17.1.3 移植和调试17.1.4 OMAP平台实现Wi-Fi17.1.5 配置Wi-Fi的流程17.1.6 具体演练——在Android下实现Ethernet 17.2 蓝牙系统17.2.1 蓝牙系统的结构17.2.2 需要移植的内容17.2.3 具体移植17.2.4 MSM平台的蓝牙驱动17.3 定位系统17.3.1 定位系统的结构17.3.2 需要移植的内容17.3.3 移植和调试第18章 电话系统18.1 电话系统基础18.1.1 电话系统简介18.1.2 电话系统结构18.2 需要移植的内容18.3 移植和调试18.3.1 驱动程序18.3.2 RIL接口18.4 电话系统实现流程分析18.4.1 初始启动流程18.4.2 request流程18.4.3 response流程第19章 其他系统19.1 Alarm警报器系统19.1.1 Alarm系统的结构19.1.2 需要移植的内容19.1.3 移植和调试19.1.4 模拟器环境的具体实现19.1.5 MSM平台实现Alarm19.2 Lights光系统19.2.1 Lights光系统的结构19.2.2 需要移植的内容19.2.3 移植和调试19.2.4 MSM平台实现光系统19.3 Battery电池系统19.3.1 Battery系统的结构19.3.2 需要移植的内容19.3.3 移植和调试19.3.4 在模拟器中实现电池系统Android移动开发技术丛书Android底层开发技术实战详解——内核、移植和驱动王振丽编著電子工業出版社Publishing House of Electronics Industry北京·BEIJING内容简介本书从底层原理开始讲起,结合真实的案例向读者详细介绍了Android内核、移植和驱动开发的整个流程。
stagefright简介
1、StageFright介绍Android froyo版本多媒体引擎做了变动,新添加了stagefright框架,并且默认情况android 选择stagefright,并没有完全抛弃opencore,主要是做了一个OMX层,仅仅是对opencore 的omx-component部分做了引用。
stagefright是在MediaPlayerService这一层加入的,和opencore是并列的。
Stagefright在Android中是以shared library的形式存在(libstagefright.so),其中的module -- AwesomePlayer可用来播放video/audio。
AwesomePlayer提供许多API,可以让上层的应用程序(Java/JNI)来调用。
2、StageFright数据流封装2.1》由数据源DataSource生成MediaExtractor。
通过MediaExtractor::Create(dataSource)来实现。
Create方法通过两步来生成相应的MediaExtractor(MediaExtractor.cpp):通过dataSource-λ>sniff来探测数据类型生成相应的Extractor:λif (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)|| !strcasecmp(mime, "audio/mp4")) {return new MPEG4Extractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {return new MP3Extractor(source, meta);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {return new AMRExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {return new WAVExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {return new OggExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {return new MatroskaExtractor(source);} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {return new MPEG2TSExtractor(source);}2.2》把音视频轨道分离,生成mVideoTrack和mAudioTrack两个MediaSource。
叙述影音剪辑的8个流程
叙述影音剪辑的8个流程英文回答:1. Concept and Storyboarding:Define the project's purpose and message.Create a storyboard to visualize the sequence of shots.2. Footage Acquisition and Selection:Capture or gather the necessary footage.Select the most relevant and visually appealing shots.3. Synchronization and Assembly:Align the audio and video tracks to create acohesive flow.Assemble the selected shots into a rough cut.4. Trimming and Adjustment:Trim unnecessary footage to refine the length and pacing.Adjust color, contrast, and other visual settings to enhance the footage.5. Transitions and Effects:Add transitions between shots for smooth or dramatic effects.Utilize visual effects (e.g., motion graphics, filters) to enhance the visual appeal.6. Music and Sound Design:Select background music that complements the mood and tone.Add sound effects to create ambiance or emphasize key moments.7. Narration and Commentary:Write and record a narrative or commentary to provide context or additional depth.Edit the narration to ensure a seamless integration into the video.8. Final Cut and Export:Review the final cut to make any necessary adjustments.Export the video in the desired file format and resolution.中文回答:1. 确定概念并绘制分镜头脚本:定义项目的目的是信息。
stable video diffusion原理 -回复
stable video diffusion原理-回复稳定的视频扩散是一种技术,它旨在通过优化视频传输过程中的各个环节,提供更高质量的视频内容。
该技术的原理是通过减少网络延迟、提高带宽利用率和优化数据传输方式来实现。
在理解稳定的视频扩散原理之前,我们需要先知道视频扩散的概念。
视频扩散是指将视频内容从一个源端传输到多个接收端的过程。
在传统的视频扩散中,数据通常通过广播或点对点方式传输,但由于网络延迟、带宽限制和数据包丢失等问题,导致视频质量下降,甚至无法正常观看。
稳定的视频扩散通过对传输过程进行优化来解决这些问题,从而提供更好的用户体验。
稳定的视频扩散的原理主要有以下几个方面:1. 优化编码算法:视频编码是指将原始视频数据转换为数字数据的过程。
稳定的视频扩散通过优化编码算法,减少视频数据的冗余信息,并提高编码的效率。
这样可以降低数据的传输量,减少网络延迟,并提高视频传输的质量。
2. 使用自适应流媒体传输协议:自适应流媒体传输协议可以根据网络环境的实际情况,调整视频的码率和分辨率。
当网络带宽较低时,可以自动降低视频的码率和分辨率,以减少数据传输量,并避免视频卡顿和缓冲。
当网络带宽较高时,可以自动提高视频的码率和分辨率,以提供更清晰的视频质量。
这样可以提高视频流的稳定性和可靠性。
3. 实时监测网络情况:稳定的视频扩散需要实时监测网络的带宽、延迟和丢包率等参数。
通过对这些参数的监测和分析,可以及时调整视频的传输参数和发送策略。
例如,当网络延迟较高时,可以采用前向纠错和重传机制,以提高视频的可靠性;当网络带宽较低时,可以降低视频的码率和分辨率,以保证视频的流畅传输。
4. 使用缓存技术:为了降低视频的延迟和提高观看体验,稳定的视频扩散还可以利用缓存技术。
缓存技术可以将视频的部分数据提前下载到接收端的缓存中,并在播放时从缓存中读取数据。
这样可以解决网络延迟问题,并提高视频的响应速度和流畅度。
综上所述,稳定的视频扩散通过优化编码算法、使用自适应流媒体传输协议、实时监测网络情况和使用缓存技术等方式,提供了更高质量的视频内容。
stable video diffusion原理 -回复
stable video diffusion原理-回复稳定的视频传输亦称为稳定的视频扩散,是指在视频传输过程中保持画质和帧率稳定的技术。
这项技术在实时视频传输、视频会议以及流媒体等领域具有重要的应用价值。
稳定的视频传输可以通过多种技术来实现,其中包括分层编码、帧间编码以及错误修复等。
一、分层编码分层编码是实现稳定视频传输的一种常用方法。
该方法包括将视频数据划分为多个层,不同层次的数据对于画质和帧率的重要性不同。
在传输过程中,可以根据网络带宽和传输条件的变化,灵活地选择不同的层次进行传输,从而实现画质和帧率的稳定。
具体来说,分层编码将视频数据划分为基本层和增强层。
基本层包含了视频的基本信息,对于保证视频的基本质量起着重要作用。
增强层包含了视频的细节信息,对于提高视频的清晰度和细节展示具有重要作用。
在传输过程中,可以根据网络带宽和传输条件的变化,选择性地传输基本层和增强层,以达到稳定的视频传输效果。
二、帧间编码帧间编码是实现稳定视频传输的另一种常用方法。
该方法利用视频中相邻帧之间的相关性,通过压缩和预测来减少传输数据量。
帧间编码将视频帧划分为关键帧和预测帧。
关键帧是完整的帧,不依赖于其他帧进行解码。
预测帧则是根据前一帧或多帧来进行预测和重建。
在传输过程中,可以选择性地传输关键帧和预测帧,以适应网络带宽和传输条件的变化。
这样可以减少传输数据量,并提高整个系统的稳定性。
帧间编码在视频会议和流媒体等实时传输场景中具有广泛应用。
三、错误修复错误修复是保证稳定视频传输的另一个重要技术。
在视频传输过程中,由于网络干扰、传输错误或丢包等原因,传输数据可能会发生错误。
为了减少错误对视频画质和帧率的影响,可以采用错误修复技术来进行恢复。
一种常用的错误修复技术是冗余编码。
该技术通过在传输数据中增加冗余信息,以实现错误的检测和修复。
当传输数据出现错误时,接收端可以利用冗余信息对错误进行检测,并利用冗余信息进行数据恢复。
这样可以有效提高视频传输的稳定性。
stagefright多媒体框架处理流程GB
Stagefright多媒体框架处理流程MM-CODEC2011-11-16目录1. MediaPlayer调用流程图 (2)1.1. Media player state value (3)1.2. MediaPlayer::decode (3)2. StagefrightPlayer类所处的位置 (4)2.1. StagefrightPlayer类 (4)2.2. MediaPlayerBase::AudioSink的子类 (4)3. 创建StagefrightPlayer播放器 (5)4. 播放器类型 (5)5. DataSource类 (6)5.1. DataSource类介绍 (6)5.2. DataSource的派生类 (7)6. AwesomePlayer::setDataSource的处理流程 (7)7. OpenMax插件的初始化过程 (8)8. 流媒体创建Extractor的过程 (9)8.1. finishSetDataSource_l的调用过程 (10)8.2. 流媒体创建MediaExtractor的处理流程 (10)9. MediaExtractor的处理流程 (11)9.1. Stagefright的MediaExtractor的Extractor类型 (11)9.2. QCom的MediaExtractor的Extractor类型 (11)10. 初始化video和audio解码器 (12)10.1. 初始化video解码器的过程 (13)10.2. 初始化audio解码器的过程 (16)10.3. MediaSource的子类和struct (16)11. start的处理流程 (17)11.1. AwesomePlayer::play_l() (18)11.2. AudioPlayer::start (19)12. seekTo的处理流程 (20)12.1. MediaPlayer::seekTo( int msec) (20)12.2. AwesomePlayer::seekTo(int64_t timeUs) (21)12.3. AudioPlayer::seekTo(int64_t time_us) (22)13. 流媒体的处理流程 (22)13.1. HTTP 流媒体的处理 (22)13.2. RTSP流媒体的处理 (24)14. MediaScanner处理流程 (26)14.1. StagefrightMediaScanner的处理流程 (26)15. MediaMetadataRetriever处理流程 (27)15.1. StagefrightMetadataRetriever的处理流程 (28)16. MediaRecorder处理流程 (29)16.1. StagefrightRecorder处理流程 (30)17. Android Supported Media Formats (31)1.MediaPlayer调用流程图多媒体框架无论是Stagefright还是OpenCore ,都是遵循MediaPlayer播放流程的。
Android 系统下Stagefright Player框架介绍
gComponentList
prepare
Prepare -组件加载
Openmax 适配层 Openmax IL 实现
AwesomePlayer
OMXCodec
OMXLeabharlann OMXMasterSECOMXPlugin
OMX core (libvmc_omx_core.so)
OMX component (/system/etc/ vmcomxreg.cfg)
初始化状态:在OMXCodec::read函数中,会把所有的输入输出buffer都
传递给OMXComponent;之后等待有输出buffer可用。 输入buffer操作:当OMXComponent使用完一个输入buffer时,通过回调 函数通知上层;在上层的对应处理函数中,继续填充该buffer,并传递 给OMXComponent。如此循环。 输出buffer操作:当OMXComponent使用完一个输出buffer时,通过回调 函数通知上层;在上层的对应处理函数中,唤醒OMXCodec::read函数。 OMXCodec::read函数将获取到buffer送给render去显示,并记录该buffer 信息。再次,调用OMXCodec::read函数获取一个输出buffer,送给render 去显示。之后,调用OMXCodec::signalBufferReturned函数,将上一个 buffer传递给OMXComponent使用。
connect new OMX new OMXMaster new SECOMXPlugin SEC_OMX_Init VMC_OMX_COMPONENT _Library_Register
enumerateComponents
SEC_OMX_ComponentNameEnum
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Stagefright (4) - Video Buffer 傳輸流程
這篇文章將介紹Stagefright 中是如何和OMX video decoder 傳遞buffer 。
(1) OMXCodec 會在一開始的時候透過read 函式來傳送未解碼的data 給decoder ,並且要求decoder 將解碼後的data 傳回來
status_t OMXCodec::read(...) {
if (mInitialBufferSubmit) {
mInitialBufferSubmit = false;
drainInputBuffers(); <----- OMX_EmptyThisBuffer
fillOutputBuffers(); <----- OMX_FillThisBuffer } ... }
void OMXCodec::drainInputBuffers() { Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
for (i = 0; i < buffers->size(); ++i)
{ drainInputBuffer(&buffers->editItemAt(i));
} } void OMXCodec::drainInputBuffer(BufferInfo *info)
{
mOMX->emptyBuffer(...); }
void OMXCodec::fillOutputBuffers() {
Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
for (i = 0; i < buffers->size(); ++i) {
fillOutputBuffer(&buffers->editItemAt(i)); }
h t
t p
:/
/z
h a
i x
i s
h a
n .
c u
b l
o g
.c
n
void OMXCodec::fillOutputBuffer(BufferInfo *info) {
mOMX->fillBuffer(...); }
(2) Decoder 從input port 讀取資料後,開始進行解碼,並且回傳EmptyBufferDone 通知OMXCodec
void OMXCodec::on_message(const omx_message &msg) {
switch (msg.type)
{
case omx_message::EMPTY_BUFFER_DONE: { IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
drainInputBuffer(&buffers->editItemAt(i));
} } }
OMXCodec 收到EMPTY_BUFFER_DONE 之後,繼續傳送下一個未解碼的資料給decoder 。
(3) Decoder 將解碼完的資料送到output port ,並回傳FillBufferDone 通知OMXCodec
void OMXCodec::on_message(const omx_message &msg)
{ switch (msg.type)
{
case omx_message::FILL_BUFFER_DONE: {
IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; fillOutputBuffer(info);
mFilledBuffers.push_back(i); mBufferFilled.signal(); } } }
h t
t p
:/
/z
h a
i x
i s
h a
n .
c u
b l
o g
.c
n
OMXCodec 收到FILL_BUFFER_DONE 之後,將解碼後的資料放入
mFilledBuffers ,發出mBufferFilled 信號,並且要求decoder 繼續送出資料。
(4) read 函式在後段等待mBufferFilled 信號。
當mFilledBuffers 被填入資料後,read 函式將其指定給buffer 指標,並回傳給AwesomePlayer
status_t OMXCodec::read(MediaBuffer **buffer, ...) { ...
while (mFilledBuffers.empty()) { mBufferFilled.wait(mLock);
}
BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
info->mMediaBuffer->add_ref(); *buffer = info->mMediaBuffer; }
h t
t p
:/
/z
h a
i x
i s
h a
n .
c u
b l
o g
.c
n。