自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Android常用C++特性之std::chrono

是 C++11 中提供的时间库,用于处理时间点和时间间隔。通过duration表示时间间隔,time_point表示时间点。支持不同精度的时间单位,如纳秒、毫秒、秒等。和。提供精确的时间测量和单位转换功能。

2024-09-27 19:58:59 678

原创 Android常用C++特性之std::abs

std::abs主要用于计算整数的绝对值。对于浮点数类型,应使用std::fabs进行绝对值计算。支持不同的数值类型重载,如intlonglong longfloatdouble等。

2024-09-27 19:54:46 456

原创 Android常用C++特性之std::none_of

也可以用于容器中的自定义对象。下面是一个例子,检查是否所有对象的某个成员都不满足条件。int age;// 检查是否所有人都不超过 40 岁// 谓词:检查年龄是否超过 40});检查范围内的所有元素是否都不满足给定的条件。如果所有元素都不满足条件,返回true;如果至少有一个元素满足条件,返回false。可用于数组、向量或其他支持迭代器的容器。

2024-09-27 19:51:12 500

原创 Android常用C++特性之std::unique

你可以通过提供自定义的谓词来定义 "相等" 的标准。// 使用自定义谓词来移除相邻绝对值相等的元素});// 使用 erase 减少容器大小// 打印结果return 0;是一个用于移除相邻重复元素的算法。它通过重新排列容器中的元素,将不需要的重复元素移动到末尾,并返回新的末尾位置。如果想要实际移除元素,需要结合erase函数。如果容器中存在非相邻的重复元素,通常需要先使用std::sort对容器进行排序。

2024-09-27 19:46:50 448

原创 Android常用C++特性之std::sort

/ 使用自定义的降序排序return 0;你可以提供自己的比较函数或 Lambda 表达式,用于定义排序规则。// 比较个位数// 使用自定义的比较函数return 0;std::sort是 C++ 中的高效排序函数,默认使用快速排序或类似算法。支持默认升序排序和自定义比较规则(如降序、自定义函数等)。适用于随机访问迭代器,如数组和等容器。

2024-09-27 19:42:07 413

原创 Android常用C++特性之std::find_if

int age;// 查找年龄大于 30 的人});if (it!是一个灵活的算法,用于在容器中查找满足特定条件的元素。它支持自定义条件,使其适用于多种类型和查找需求。适合用于数组、向量、列表等容器的元素查找。

2024-09-26 14:08:28 468

原创 Android常用C++特性之std::equal

/ 比较最后一位数字// 使用自定义比较函数} else {return 0;std::equal是用于比较两个范围内元素是否相等的标准算法。支持自定义比较逻辑,使其适用于不同的数据类型和比较需求。适合用于检查数组、向量、列表等容器的内容是否一致。

2024-09-26 13:45:26 510

原创 Android常用C++特性之std::any_of

是一个便捷的算法,用于快速检查范围内是否存在满足特定条件的元素。适用于各种容器,如数组、向量、列表等,具有简洁的语法和高效的执行。通过传递不同的谓词,可以灵活地处理各种条件检查。

2024-09-26 11:25:26 414

原创 Android常用C++特性之std::move

std::move用于将对象转换为右值引用,允许其资源被移动而不是复制。使用std::move可以避免不必要的深拷贝,提升程序效率,尤其在处理大对象时。配合移动构造函数和移动赋值运算符,可以实现高效的资源转移。一旦对象被移动,它通常会进入“空”或“无效”的状态,因此应避免在移动后继续使用该对象。

2024-09-26 10:52:14 644

原创 Android常用C++特性之std::optional

int age;} else {// 找不到人} else {return 0;是 C++17 中引入的,用于表示可选值。它提供了一种类型安全的方式来处理缺失值,避免了使用指针或特殊值的复杂性。适用于函数返回值、配置选项等场景,可以提高代码的可读性和安全性。

2024-09-26 09:58:39 428

原创 Android常用C++特性之std::this_thread

获取当前线程的唯一 ID。:让当前线程暂停执行指定时长。:让当前线程暂停执行,直到指定的时间点。:让出当前线程的 CPU 时间片,允许其他线程运行。通过,可以灵活地控制当前线程的行为,尤其在多线程编程中,能有效地控制线程的执行顺序和时机。

2024-09-25 11:09:32 612

原创 Android常用C++特性之std::unique_lock

提供了一个灵活的互斥锁管理工具,支持延迟锁定、手动解锁和尝试锁定等高级功能。与相比,在锁管理方面有更多的控制权,适用于更复杂的同步场景。在多线程编程中,适合那些需要在特定时刻手动锁定或解锁的场景,而则更适合简单、固定的锁管理。

2024-09-25 10:40:19 473

原创 Android常用C++特性之std::make_unique

提供了一种更简洁和安全的方式来创建,避免了手动管理内存的麻烦。提供独占的所有权,确保对象在不再使用时自动释放资源。使用可以减少使用new和delete时的出错风险。

2024-09-25 10:18:05 636

原创 Android常用C++特性之std::lock_guard

提供了一种简单且安全的机制来管理互斥锁,自动加锁和解锁,防止手动管理时的各种问题(如死锁、忘记解锁)。适合在简单场景中使用,主要用于确保在作用域结束时互斥锁能够安全释放。

2024-09-25 09:53:20 461

原创 Android常用C++特性之std::thread

提供了一种简单的多线程并发模型,能够启动、管理并行执行的任务。通过join()可以确保主线程等待子线程完成,通过detach()可以使线程独立运行。当多个线程访问共享资源时,需要使用同步机制(如std::mutex)来防止数据竞争。

2024-09-24 16:21:43 576

原创 Android常用C++特性之lambda表达式

捕获方式:通过捕获列表[ ]指定捕获外部变量的方式。简洁性:可以用 lambda 表达式代替简单的函数或函数对象,简化代码。应用场景:适合临时、匿名的可调用对象,特别是在回调、算法、事件处理中广泛应用。

2024-09-24 15:56:31 915

原创 Android常用C++特性之std::function

声明:本文内容生成自ChatGPT,为方便大家了解学习作为引用到其他文章中。是 C++ 标准库中的一个,用于存储、复制、调用任何可以调用的目标(如普通函数、lambda 表达式、函数对象、成员函数等)。它提供了一种通用的方式来处理不同类型的可调用对象。

2024-09-24 15:04:43 321

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

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

2024-08-22 13:36:49 1086

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

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

2024-08-19 16:49:05 972

原创 Android12 显示框架之getSurface

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

2024-08-02 10:54:36 653

原创 Android12 显示框架之createSurface

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

2024-08-01 17:16:11 966

原创 Android12 显示框架之SurfaceComposerClient创建

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

2024-07-30 16:58:04 577

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

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

2024-07-29 14:39:42 1025

原创 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 307

原创 Android12 MultiMedia框架之GenericSource extractor

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

2024-07-11 09:08:40 995

原创 Android12 MultiMedia框架之MediaExtractorService

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

2024-07-01 17:32:30 1010

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

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

2024-06-27 09:20:01 989

原创 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 768

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

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

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

原创 Android12 MultiMedia框架之NuPlayer状态机

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

2024-06-11 14:49:29 319

原创 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 914

原创 Android12 MultiMedia框架之NuPlayerDriver

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

2024-06-07 09:58:58 791

原创 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 320

原创 Android12 MultiMedia框架

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

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

原创 Android12 MultiMedia框架之MediaPlayerService

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

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

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

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

2024-06-06 11:30:13 1112 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 917

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

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

2024-05-30 11:16:53 1072

原创 Android显示终极宝典

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

2024-05-23 09:32:18 449 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 1468 4

空空如也

空空如也

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

TA关注的人

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