- 博客(49)
- 收藏
- 关注
原创 Android12 显示框架之APP到SurfaceFlinger的buffer运转周期
前面几篇文章已经讲完了一个应用从SurfaceComposerClient的创建到Surface的创建再到BLASTBufferQueue的创建以及通过Transaction把Surface的属性同步问SurfaceFlinger的Layer中。这一节就可以开始讲讲应用生产完的buffer是如何送到SurfaceFlinger中去的。
2024-10-23 19:55:22
1259
原创 Android常用C++特性之std::placeholders
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。是 C++ STL 中的一个命名空间,提供了用于std::bind的占位符。它允许你在使用std::bind时指定未绑定参数的位置,以便在调用新创建的可调用对象时传入这些参数。
2024-10-20 17:16:27
348
原创 Android常用C++特性之std::bind
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。std::bind是 C++ STL 中的一个函数模板,用于创建一个新的可调用对象(如函数、成员函数或函数对象),该对象将部分参数绑定到指定的函数上。它允许你预先指定某些参数,从而生成一个新的函数对象。
2024-10-20 16:29:07
416
原创 Android常用C++特性之std::forward_as_tuple
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。是 C++ STL 中的一个函数模板,主要用于创建一个元组,同时能够完美转发其元素。它可以保留传入参数的值类别(如左值或右值),这对于提高性能和避免不必要的拷贝非常重要。
2024-10-20 16:23:50
501
原创 Android常用C++特性之std::make_pair
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。是 C++ 标准库中的一个函数模板,用于创建一个std::pair对象。std::pair是一种可以存储两个不同类型值的简单数据结构,类似于二元组。函数可以自动推导出元素的类型,简化了构造pair对象的过程。
2024-10-10 15:54:55
508
原创 Android常用C++特性之std::future
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。是 C++ 中的一个类模板,表示异步操作的未来结果。它是 C++11 标准库中线程功能的一部分,用于访问异步任务(例如通过线程或异步调用执行的函数)完成后产生的结果。
2024-10-10 15:51:51
472
原创 Android常用C++特性之std::swap
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。std::swap是 C++ 标准库中提供的一个函数,位于<utility>头文件中。它用于交换两个变量的值。
2024-10-08 17:18:02
462
原创 Android常用C++特性之std::chrono
是 C++11 中提供的时间库,用于处理时间点和时间间隔。通过duration表示时间间隔,time_point表示时间点。支持不同精度的时间单位,如纳秒、毫秒、秒等。和。提供精确的时间测量和单位转换功能。
2024-09-27 19:58:59
905
原创 Android常用C++特性之std::abs
std::abs主要用于计算整数的绝对值。对于浮点数类型,应使用std::fabs进行绝对值计算。支持不同的数值类型重载,如intlonglong longfloatdouble等。
2024-09-27 19:54:46
745
原创 Android常用C++特性之std::none_of
也可以用于容器中的自定义对象。下面是一个例子,检查是否所有对象的某个成员都不满足条件。int age;// 检查是否所有人都不超过 40 岁// 谓词:检查年龄是否超过 40});检查范围内的所有元素是否都不满足给定的条件。如果所有元素都不满足条件,返回true;如果至少有一个元素满足条件,返回false。可用于数组、向量或其他支持迭代器的容器。
2024-09-27 19:51:12
575
原创 Android常用C++特性之std::unique
你可以通过提供自定义的谓词来定义 "相等" 的标准。// 使用自定义谓词来移除相邻绝对值相等的元素});// 使用 erase 减少容器大小// 打印结果return 0;是一个用于移除相邻重复元素的算法。它通过重新排列容器中的元素,将不需要的重复元素移动到末尾,并返回新的末尾位置。如果想要实际移除元素,需要结合erase函数。如果容器中存在非相邻的重复元素,通常需要先使用std::sort对容器进行排序。
2024-09-27 19:46:50
617
原创 Android常用C++特性之std::sort
/ 使用自定义的降序排序return 0;你可以提供自己的比较函数或 Lambda 表达式,用于定义排序规则。// 比较个位数// 使用自定义的比较函数return 0;std::sort是 C++ 中的高效排序函数,默认使用快速排序或类似算法。支持默认升序排序和自定义比较规则(如降序、自定义函数等)。适用于随机访问迭代器,如数组和等容器。
2024-09-27 19:42:07
479
原创 Android常用C++特性之std::find_if
int age;// 查找年龄大于 30 的人});if (it!是一个灵活的算法,用于在容器中查找满足特定条件的元素。它支持自定义条件,使其适用于多种类型和查找需求。适合用于数组、向量、列表等容器的元素查找。
2024-09-26 14:08:28
532
原创 Android常用C++特性之std::equal
/ 比较最后一位数字// 使用自定义比较函数} else {return 0;std::equal是用于比较两个范围内元素是否相等的标准算法。支持自定义比较逻辑,使其适用于不同的数据类型和比较需求。适合用于检查数组、向量、列表等容器的内容是否一致。
2024-09-26 13:45:26
605
原创 Android常用C++特性之std::any_of
是一个便捷的算法,用于快速检查范围内是否存在满足特定条件的元素。适用于各种容器,如数组、向量、列表等,具有简洁的语法和高效的执行。通过传递不同的谓词,可以灵活地处理各种条件检查。
2024-09-26 11:25:26
540
原创 Android常用C++特性之std::move
std::move用于将对象转换为右值引用,允许其资源被移动而不是复制。使用std::move可以避免不必要的深拷贝,提升程序效率,尤其在处理大对象时。配合移动构造函数和移动赋值运算符,可以实现高效的资源转移。一旦对象被移动,它通常会进入“空”或“无效”的状态,因此应避免在移动后继续使用该对象。
2024-09-26 10:52:14
705
原创 Android常用C++特性之std::optional
int age;} else {// 找不到人} else {return 0;是 C++17 中引入的,用于表示可选值。它提供了一种类型安全的方式来处理缺失值,避免了使用指针或特殊值的复杂性。适用于函数返回值、配置选项等场景,可以提高代码的可读性和安全性。
2024-09-26 09:58:39
528
原创 Android常用C++特性之std::this_thread
获取当前线程的唯一 ID。:让当前线程暂停执行指定时长。:让当前线程暂停执行,直到指定的时间点。:让出当前线程的 CPU 时间片,允许其他线程运行。通过,可以灵活地控制当前线程的行为,尤其在多线程编程中,能有效地控制线程的执行顺序和时机。
2024-09-25 11:09:32
690
原创 Android常用C++特性之std::unique_lock
提供了一个灵活的互斥锁管理工具,支持延迟锁定、手动解锁和尝试锁定等高级功能。与相比,在锁管理方面有更多的控制权,适用于更复杂的同步场景。在多线程编程中,适合那些需要在特定时刻手动锁定或解锁的场景,而则更适合简单、固定的锁管理。
2024-09-25 10:40:19
618
原创 Android常用C++特性之std::make_unique
提供了一种更简洁和安全的方式来创建,避免了手动管理内存的麻烦。提供独占的所有权,确保对象在不再使用时自动释放资源。使用可以减少使用new和delete时的出错风险。
2024-09-25 10:18:05
792
原创 Android常用C++特性之std::lock_guard
提供了一种简单且安全的机制来管理互斥锁,自动加锁和解锁,防止手动管理时的各种问题(如死锁、忘记解锁)。适合在简单场景中使用,主要用于确保在作用域结束时互斥锁能够安全释放。
2024-09-25 09:53:20
589
原创 Android常用C++特性之std::thread
提供了一种简单的多线程并发模型,能够启动、管理并行执行的任务。通过join()可以确保主线程等待子线程完成,通过detach()可以使线程独立运行。当多个线程访问共享资源时,需要使用同步机制(如std::mutex)来防止数据竞争。
2024-09-24 16:21:43
697
原创 Android常用C++特性之lambda表达式
捕获方式:通过捕获列表[ ]指定捕获外部变量的方式。简洁性:可以用 lambda 表达式代替简单的函数或函数对象,简化代码。应用场景:适合临时、匿名的可调用对象,特别是在回调、算法、事件处理中广泛应用。
2024-09-24 15:56:31
981
原创 Android常用C++特性之std::function
声明:本文内容生成自ChatGPT,为方便大家了解学习作为引用到其他文章中。是 C++ 标准库中的一个,用于存储、复制、调用任何可以调用的目标(如普通函数、lambda 表达式、函数对象、成员函数等)。它提供了一种通用的方式来处理不同类型的可调用对象。
2024-09-24 15:04:43
411
原创 Android12 显示框架之Transaction----server端
上篇讲完了在client端Transaction的内容,最后调用setTransactionState()把所有的参数都交给了surfaceflinger,那么任务就交给server来完成了。本节我们一起接着看看下面的内容。
2024-08-22 13:36:49
1435
原创 Android12 显示框架之Transaction----client端
Transaction的作用是提供给应用统一设置所有需要设置的layer或者display的状态值,以原子操作的形式发送给surfacefinger进行处理,如果应用设置了回调,那么surfacefinger在处理完transaction后会将消息回调到上层。
2024-08-19 16:49:05
1452
原创 Android12 显示框架之getSurface
通过本节内容,应用程序搭建完成了生产者消费者模型,获取到了Surface接口端,下面就可以生产buffer送显了。但是在这之前还要设置surface的各项属性,通过Transaction来达成目的,这个在下节讲解,这里提一嘴。老规矩,还是通过框架图的形式总结下本节的内容,注意这里没有再去画出来surfaceflinger内部生成的内容了,因为上篇文章已经展示过了。
2024-08-02 10:54:36
815
原创 Android12 显示框架之createSurface
应用程序调用createSurface()实际上是先在surfaceflinger内创建了一个Layer,在其自身内部还没有创建真正的surface,而且这个Layer还是一个parentLayer。至于为什么,请看下篇文章。
2024-08-01 17:16:11
1293
原创 Android12 显示框架之SurfaceComposerClient创建
SurfaceComposerClient是应用程序与SurfaceFlinger交互的客户端接口,在SurfaceFlinger服务端与之对应的名叫Client。SurfaceComposerClient和Client构成了应用程序和SurfaceFlinger之间进行交互的桥梁。每个SurfaceComposerClient在SurfaceFlinger都有一个Client实例一一对应,大概就如下面图里的样子。
2024-07-30 16:58:04
1088
原创 Android12 显示框架之SurfaceFlinger启动(六)
而且,mVsyncModulator的成员mTransactionSchedule的初始值也为TransactionSchedule::Late,所以,函数执行到最后一个if()条件的时候,schedule == mTransactionSchedule是成立的,故而直接返回std::nullopt,下面的updateVsyncConfigLocked()执行不到。通过传入的参数可以发现:除了刚刚创建的名叫displays的Vector,其他的参数要么是空值要么就是false,没几个实质行的参数传入。
2024-07-29 14:39:42
1265
原创 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
363
原创 Android12 MultiMedia框架之GenericSource extractor
onPrepareAsync() 函数到这里结束,主要内容基本都过了一遍,暂时还缺少了MediaBuffer的部分没有涉及到。下面还是老规矩,以图的方式总结下本节的内容:图一 onPrepareAsync()执行流程图二 MP4 extractor关系架构图看代码感觉还没那么强烈,但是从图二的架构图来看,就可以看出设计NuPlayer这个架构的架构师太牛了。图中绿色方框框起来的是MP4 extractor自己实现的内容,其他extractor也是按照这种方式去替换方框中的实现即可。
2024-07-11 09:08:40
1103
原创 Android12 MultiMedia框架之MediaExtractorService
上节学到setDataSource()时会创建各种Source,source用来读取音视频源文件,读取到之后需要demux出音、视频、字幕数据流,然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的?这里暂时不考虑APP创建的情况,以前面学过的GenericSource为例,它是在prepare阶段被创建的。本节暂时不分析GenericSource创建extractor的流程,先来看看MediaExtractorService的启动过程。
2024-07-01 17:32:30
1144
1
原创 Android12 显示框架之SurfaceFlinger启动(五)
到此,processDisplayAdded()方法讲完了,返回到processDisplayChangesLocked()中,末尾会将mCurrentState.displays的内容更新到mDrawingState.displays中,这里也是mDrawingState的首次更新内容。上节看完了initScheduler(),本节将看看processDisplayHotplugEventsLocked()中的最后一个方法:processDisplayChangesLocked()。
2024-06-27 09:20:01
1162
原创 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
861
原创 Android12 显示框架之SurfaceFlinger启动(四)
在处理onHotplugConnect()时,由于初始状态mDisplayData中是没有任何内容的,所以isConnected()直接返回false。这段code做了很多事,还是比较复杂的,我没有去详细讲解了,后面有时间的话再另起一篇文章来仔细讲一讲。这个需要回到上节中的内容,上节我们没有对这个变量做展开分析直接选择了忽视,其实是因为放在这里分析契合度比较高。我们终于把initScheduler()的内容分析完了,本节的新内容非常多,我们需要经常来回顾一下,以放忘得太快。
2024-06-14 13:44:09
1111
1
原创 Android12 MultiMedia框架之NuPlayer状态机
其中最主要的状态分别是:IDLE/UNPREPARED/PREPARED/RUNNING/PAUSED/STOPPED,其他的状态都是中间的过度态。通过这些状态形成一个状态机来控制上层的接口调用的正确顺序,来让NuPlayer正常的运转。
2024-06-11 14:49:29
372
原创 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
996
原创 Android12 MultiMedia框架之NuPlayerDriver
而这两个Factory都没有实现本地播放类型的scoreFactory()方法,所以它的返回值就是父类的初始实现的值:0.0。接下来进入setDataSource_post()了,它的第二个参数传入的是NuPlayerDriver的setDataSource()的执行结果,这个函数就是在创建source了,我们后面的章节再看,这里跳过。本来想把所有的模块画在一起,但是因为连线的原因不好处理,连接的乱七八糟,怎么调整都不好看,所以干脆就分割成了几个小块,也就是图中的3个小方框。设计这个宏的人估计喜欢打球。
2024-06-07 09:58:58
909
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人