自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(24)
  • 收藏
  • 关注

原创 Android12 显示框架之Transaction----server端

上篇讲完了在client端Transaction的内容,最后调用setTransactionState()把所有的参数都交给了surfaceflinger,那么任务就交给server来完成了。本节我们一起接着看看下面的内容。

2024-08-22 13:36:49 1060

原创 Android12 显示框架之Transaction----client端

Transaction的作用是提供给应用统一设置所有需要设置的layer或者display的状态值,以原子操作的形式发送给surfacefinger进行处理,如果应用设置了回调,那么surfacefinger在处理完transaction后会将消息回调到上层。

2024-08-19 16:49:05 940

原创 Android12 显示框架之getSurface

通过本节内容,应用程序搭建完成了生产者消费者模型,获取到了Surface接口端,下面就可以生产buffer送显了。但是在这之前还要设置surface的各项属性,通过Transaction来达成目的,这个在下节讲解,这里提一嘴。老规矩,还是通过框架图的形式总结下本节的内容,注意这里没有再去画出来surfaceflinger内部生成的内容了,因为上篇文章已经展示过了。

2024-08-02 10:54:36 641

原创 Android12 显示框架之createSurface

应用程序调用createSurface()实际上是先在surfaceflinger内创建了一个Layer,在其自身内部还没有创建真正的surface,而且这个Layer还是一个parentLayer。至于为什么,请看下篇文章。

2024-08-01 17:16:11 944

原创 Android12 显示框架之SurfaceComposerClient创建

SurfaceComposerClient是应用程序与SurfaceFlinger交互的客户端接口,在SurfaceFlinger服务端与之对应的名叫Client。SurfaceComposerClient和Client构成了应用程序和SurfaceFlinger之间进行交互的桥梁。每个SurfaceComposerClient在SurfaceFlinger都有一个Client实例一一对应,大概就如下面图里的样子。

2024-07-30 16:58:04 554

原创 Android12 显示框架之SurfaceFlinger启动(六)

而且,mVsyncModulator的成员mTransactionSchedule的初始值也为TransactionSchedule::Late,所以,函数执行到最后一个if()条件的时候,schedule == mTransactionSchedule是成立的,故而直接返回std::nullopt,下面的updateVsyncConfigLocked()执行不到。通过传入的参数可以发现:除了刚刚创建的名叫displays的Vector,其他的参数要么是空值要么就是false,没几个实质行的参数传入。

2024-07-29 14:39:42 995

原创 Android12 MultiMedia框架之NuPlayer Surface

APP会创建一层SurfaceView来显示视频层,同时内部会创建一个BLASTBufferQueue,它的生产者会挂载到我们的Decoder,枢纽就是BpGraphicBufferProducer,它的消费者是SurfaceFlinger,会把这个APP的Layer(SurfaceView在SurfaceFlinger中的对应概念)同其他APP的图层一起合成送显上屏。答案是Surface,而且Surface是NuPlayer创建Decoder的条件。

2024-07-16 14:32:08 289

原创 Android12 MultiMedia框架之GenericSource extractor

onPrepareAsync() 函数到这里结束,主要内容基本都过了一遍,暂时还缺少了MediaBuffer的部分没有涉及到。下面还是老规矩,以图的方式总结下本节的内容:图一 onPrepareAsync()执行流程图二 MP4 extractor关系架构图看代码感觉还没那么强烈,但是从图二的架构图来看,就可以看出设计NuPlayer这个架构的架构师太牛了。图中绿色方框框起来的是MP4 extractor自己实现的内容,其他extractor也是按照这种方式去替换方框中的实现即可。

2024-07-11 09:08:40 988

原创 Android12 MultiMedia框架之MediaExtractorService

上节学到setDataSource()时会创建各种Source,source用来读取音视频源文件,读取到之后需要demux出音、视频、字幕数据流,然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的?这里暂时不考虑APP创建的情况,以前面学过的GenericSource为例,它是在prepare阶段被创建的。本节暂时不分析GenericSource创建extractor的流程,先来看看MediaExtractorService的启动过程。

2024-07-01 17:32:30 996

原创 Android12 显示框架之SurfaceFlinger启动(五)

到此,processDisplayAdded()方法讲完了,返回到processDisplayChangesLocked()中,末尾会将mCurrentState.displays的内容更新到mDrawingState.displays中,这里也是mDrawingState的首次更新内容。上节看完了initScheduler(),本节将看看processDisplayHotplugEventsLocked()中的最后一个方法:processDisplayChangesLocked()。

2024-06-27 09:20:01 974

原创 Android12 MultiMedia框架之NuPlayer Source

NuPlayer主要包含三大组件:Source、Decoder和Render。这些组件都是在接口调用时逐步创建的。本节先来记录下Source相关的内容。从code可以看出,NuPlayer的Source:GenericSource/HTTPLiveSource/RTPSource/RTSPSource/StreamingSource。这些source都是在JAVA层或者NATIVE层调用MediaPlyaer的不同类型的setDataSource()接口来创建的。

2024-06-17 17:55:40 759

原创 Android12 显示框架之SurfaceFlinger启动(四)

在处理onHotplugConnect()时,由于初始状态mDisplayData中是没有任何内容的,所以isConnected()直接返回false。这段code做了很多事,还是比较复杂的,我没有去详细讲解了,后面有时间的话再另起一篇文章来仔细讲一讲。这个需要回到上节中的内容,上节我们没有对这个变量做展开分析直接选择了忽视,其实是因为放在这里分析契合度比较高。我们终于把initScheduler()的内容分析完了,本节的新内容非常多,我们需要经常来回顾一下,以放忘得太快。

2024-06-14 13:44:09 796 1

原创 Android12 MultiMedia框架之NuPlayer状态机

其中最主要的状态分别是:IDLE/UNPREPARED/PREPARED/RUNNING/PAUSED/STOPPED,其他的状态都是中间的过度态。通过这些状态形成一个状态机来控制上层的接口调用的正确顺序,来让NuPlayer正常的运转。

2024-06-11 14:49:29 307

原创 Android12 MultiMedia框架之ALooper/AHandler/AMessage

最后,还有一个gLooperRoster,它是一个全局变量,通过调用ALooper的registerHandler()方法将ALooper和AHandler注册到它内部。全局搜索整个变量可以知道,它没啥功能行的作用,只是debug的时候为dump()提供打印信息。总结一下:当看到(new AMessage(kWhatXXXX, AHandler))->post()语句的时候,直接去到AHandler中的onMessageReceived()方法中,去看对应的kWhatXXXX的分支处理就好了。

2024-06-07 11:15:02 902

原创 Android12 MultiMedia框架之NuPlayerDriver

而这两个Factory都没有实现本地播放类型的scoreFactory()方法,所以它的返回值就是父类的初始实现的值:0.0。接下来进入setDataSource_post()了,它的第二个参数传入的是NuPlayerDriver的setDataSource()的执行结果,这个函数就是在创建source了,我们后面的章节再看,这里跳过。本来想把所有的模块画在一起,但是因为连线的原因不好处理,连接的乱七八糟,怎么调整都不好看,所以干脆就分割成了几个小块,也就是图中的3个小方框。设计这个宏的人估计喜欢打球。

2024-06-07 09:58:58 773

原创 Android12 MultiMedia框架之MediaPlayerService::Client

内部直接new了一个Client,再通过binder回传到MediaPlayer,MediaPlayer持有Client的Bp端。同时MediaPlayerService本地也保存一份Client。MediaPlayerService中的Client和MediaPlayer之间的关系有点类似于SurfaceFLinger中的Client和SurfaceComposerClient之间的关系。本篇讲的是Client的创建,所以暂时只看create(),setDataSource()方法后面再看。

2024-06-06 17:49:27 312

原创 Android12 MultiMedia框架

Android MultiMedia框架学习笔记:1. Android12 MultiMedia框架之MediaPlayerService

2024-06-06 16:33:34 418 2

原创 Android12 MultiMedia框架之MediaPlayerService

MediaPlayerService 是 Android 媒体框架中的核心服务之一,是负责媒体播放管理的服务,提供了管理和控制媒体播放的功能,支持音频和视频文件的播放。它通过 IPC 与应用程序交互,处理媒体播放器实例的创建和管理,并确保媒体资源的正确使用和协调。再回到上面,这些都创建和记录完了之后,将MediaPlayerService注册到service manager中,所有步骤完成。到这里,MediaPlayerService启动就结束了,哈哈,如此的纯粹。

2024-06-06 16:26:32 418 2

原创 Android12 显示框架之SurfaceFlinger启动(三)

对于我们只有一个屏且没有热插拔另一个屏的情况下,init()里的processDisplayHotplugEventsLocked()就是空运行了一下,没有做任何事情。do while循环体中通过getHwComposer().getModes()来获取底层支持的所有Display Mode,再通过getHwComposer().getActiveMode()来获取底层当前在用的Display Mode。总结一下,onHotplug()的作用就是为所有的物理屏幕创建对应的Display实例。

2024-06-06 11:30:13 1053 2

原创 Android12 显示框架之SurfaceFlinger启动(二)

Surfaceflinger调用HWC的接口有些是通过ComposerClientImpl客户端直接调用,还有一些则是先将参数及接口对应的command打包放入command buffer(messagequeue)中并执行execute(),然后进入ComposerCommandEngine中从command buffer中取出参数,最后调用HWC对应的接口。首先,获取IComposer对应的名字为“default”的service,为什么要名字为“default”的service呢?

2024-05-31 17:59:35 880

原创 Android12 显示框架之SurfaceFlinger启动(一)

我们注意到create传入的参数是一个CreateInstanceFactory ,它实际上就是一个std::function函数封装器,它代表的就是传入的lambda表达式(关于std::function和lambda表达式会在附录中讲解),而这个lambda表达式的作用就是创建一个SkiaGLRenderEngine。SurfaceFlinger的实例创建用到了工厂设计模式的概念,关于设计模式的知识点推荐大家去学习下《Head First Design Pattern》这本书,讲得很棒。

2024-05-30 11:16:53 1026

原创 Android显示终极宝典

一直以来都想把Android显示相关的内容给总结起来同大家一起学习和探讨,但由于懒惰以及其他原因迟迟没有着手去做这件事。然而。千里之行始于足下,不积跬步无以至千里,不积小流无以成江海。想做就行动起来吧。文章的名字起得很大、很狂,既然flag立得很大那就努力去实现吧,为了面子也得拼一拼呀,至于结果怎么样,就不去考虑那么多了。畏首畏尾永远做不好事情。这篇文章是后续文章的目录,以便后续的检索。内容会涉及很多,我个人的时间及能力是有限的,如果哪位小伙伴有兴趣的话,欢迎投稿和推荐,我们一起创作。这里的Android版

2024-05-23 09:32:18 410 1

原创 Android12 AIDL native层实现

本文主要是讲解如何实现一个完整的AIDL HAL层的例子,包括aidl文件的编写、service的实现、测试用例的实现、开机启动以及编译过程中和运行时的错误如何解决。此文不讲解AIDL的原理,具体原理的了解请参考官方资料:https://source.android.com/docs/core/architecture/aidl?hl=zh-cn。

2024-05-20 10:50:17 1419 4

原创 批量创建字符设备的设备节点

目录摘要简单示例摘要对于使用register_chrdev()去注册字符设备的driver,在insmod加载完driver后还需要通过mknod去创建对应的设备节点,否则应用程序或调用库无法去open设备。但是,当一个driver需要创建非常多的设备节点时,通过在rc文件中去逐个mknod显然不合理。因此,较合理的做法就是通过程序或脚本去批量创建设备节点。简单示例头文件定义自定义一个结构体将设备节点名称、设备类别(字符设备、块设备)、主设备号、次设备号以及节点操作权限。自定义一个在

2021-06-17 16:03:20 138

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除