自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 16字节对齐算法

最后将 23 与 15的取反结果 进行 &(与)操作,&(与)的规则是:都是1为1,反之为0,最后的结果为 16,即内存的大小是以16的倍数增加的。原理为 首先若x=8 将原始的内存 8 与 size_t(15)相加,得到 8 + 15 = 23。将 size_t(15) 即 15进行~(取反)操作,~(取反)的规则是:1变为0,0变为1。类似 (8 + 15 ) >> 4 << 4 16字节对齐。

2024-06-12 14:25:33 395

原创 Android中native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface的关系

native_handle/native_handle_t只是定义了一个描述buffer的结构体原型,这个原型是和平台无关的,方便buffer在各个进程之间传递,注意成员data是一个大小为0的数组,这意味着data指向紧挨着numInts后面的一个地址.我们可以把native_handle_t看成是一个纯虚的基类.一般来说,我们描述一块buffer,需要知道它在kernel中对应的fd,虚拟地址/物理地址,offset,size等等信息,后面我们在private_handle_t中就可以看到这些字段.

2024-05-30 20:09:17 952

原创 从handle得到GraphicBuffer

【代码】从handle得到GraphicBuffer。

2024-05-30 17:27:40 386

原创 Android 系统中AHardwareBuffer、ANativeWindowBuffer和GraphicBuffer的关系

Android Camera软件系统中,每路Stream的Buffer都是DMA-BUF,这种Buffer通常对外暴露的结构是ANativeWindowBuffer或GraphicBuffer(跨进程传递时用的native_handle_t),本文介绍Android系统中AHardwareBuffer、ANativeWindowBuffer和GraphicBuffer的关系。

2024-05-30 16:41:52 1192

原创 条件变量(Conditional variable)要注意的点

与互斥锁的关系:虽然条件变量与互斥锁都是同步工具,但它们的用途是不同的。条件变量是用于线程同步的另一种工具,特别是当线程需要等待某个条件成立(或者说满足)时。唤醒:线程可以使用pthread_cond_signal来唤醒一个等待的线程,或使用pthread_cond_broadcast来唤醒所有等待的线程。目的:条件变量的主要目的是允许一个或多个线程在某些条件成立之前等待。总的来说,条件变量提供了一种方式,允许线程在某些条件成立前休眠,并在条件成立后被唤醒,从而实现复杂的同步需求。

2024-05-30 14:48:53 190

原创 博客摘录「 Nuplayer 音视频同步学习笔记」2024年4月9日

所以理论上,我们可以根据锚点, 计算出任意一点的媒体时间对应的系统时间(Buffer应该播放的时间). AVsync 的进本机理就是通过Audio每隔一段时间更新锚点, Video的Buffer根据锚点和媒体时间计算出应该播放的时(系统时间)AVsync的目的是获得Buffer显示的时间(buffer的系统时间).我们可以根据媒体时间和系统时间的线性关系计算出显示的时间。当前正在播放的媒体时间 = 正在写入的媒体时间 - 已经写入但是没有播放的数据需要播放的时间。

2024-05-30 14:42:51 577

原创 dumpsys media.camera

可以看到很多信息。

2024-05-30 14:38:22 184

原创 Android systrace抓取工具atrace、perfetto的使用

systrace主要用来分析析能问题:应用响应速度慢、动画播放不流畅、卡顿或耗电量过高表示应用存在性能问题。共有三种方法,一是android studio、二是、三是prefetto。

2024-05-30 14:37:34 950

原创 C++ 多重继承的内存布局和指针偏移

在 C++ 程序里,在有多重继承的类里面。偏移的大小,等于派生类的继承顺序表里面,排在该类前面的所有的类的数据成员(含虚表指针)所占的空间大小总和。注意:在 D 的继承关系链里面,只有基类 B 有虚函数,因此对于 D 对象而言,总体只有一个虚表指针,也就是(B)基类对象中的虚表指针。D 继承自A, B, C,它的大小等于 A, B, C 的所有数据成员的大小,加上其自身的数据成员和虚表指针的总的大小:4(b) + 4(c) + 4(d) + 8(vptr) = 20 字节。我们首先来分析这四个类的大小。

2024-05-30 13:58:30 396

原创 android sp指针的cast

对于c++原生的智能指针,有static_pointer_cast之类的操作方法。可以看cppreference。

2024-05-24 15:09:08 120

原创 Camera相关目录

注意这个目录应该是废弃了的HIDL方式的CameraService:frameworks/hardware/interfaces/cameraservice。frameworks/av/services/camera/libcameraservice是CameraService的实现目录。hardware/interfaces/camera是HAL进程即CameraProvider进程的代码目录。frameworks/av/camera/aidl是CameraService的aidl接口定义目录。

2024-05-14 15:10:08 254

原创 三种binder

【代码】三种binder。

2024-05-08 16:23:54 143

原创 PRId64的正确用法

/ 在PRId64前保留一个空格。// 将PRId64换成其它宏,情况相同。

2024-05-06 14:08:50 297

原创 Android CallStack使用

代码里添加:android::CallStack stack("Debug info");Android12 亲测有效。

2024-04-30 11:01:06 340

原创 Android12之如何查看hidl服务

本篇目的:在Android源码中提供了cmd、service、dumpsys来获取Binder服务的工具,但是Android8.0以后推出HIDL服务, 前边三个工具是无法获取到的,下面我们如何获取HIDL服务呢?HIDL向hwservicemanager(/dev/hwbinder)注册binder服务。Google为我们提供了一个脚lshal的工具,下面来看下它的用法。<4>.查看HIDL服务名、线程数量和客户端梳理。<2>.service和lshal命令对比。<2>.查看系统所有HIDL服务。

2024-04-23 14:26:50 568

转载 Android ServiceManager进阶

在新版中,getService、checkService、addService、listServices四个方法和旧版在使用上基本相同,新增了一个新方法 waitForService ,这个方法会先去 getService ,如果无法获取到对应的服务,则向ServiceManager 注册一个 IServiceCallback 并开始等待,当对应的服务被add到 ServiceManager 中时,这个服务被注册的信息会通过 onRegistration 回调到当前进程,解锁等待后再getService。

2024-04-23 14:15:42 49

原创 User-defined conversion function

operator bool就是User-defined conversion function。

2024-04-07 20:33:29 248

原创 一些奇怪的函数指针转换

话不多说,自己看代码编译运行体会。

2024-02-26 15:08:09 390

原创 AIDL实践

以上三个文件写完以后就可以运行mm先处理aidl文件了。会提示你运行m android.hardware.demo-update-api来自动生成(更新)aidl/aidl_api文件夹。android.hardware.demo-service.xml:(最后要push到/vendor/etc/vintf/manifest目录下)Android.bp:(里面可能很多库是不需要的)

2024-01-29 12:04:13 724

转载 ARMV8 用户态DMA cache一致性问题和解决

原因:dma和cpu都有操作内存的能力,dma操作内存不通过cpu和cache,即cpu cache感知不到dma对内存的操作因此cpu和dma合作时,就会存在cpu cache和内存的一致性问题,原因是dma对内存操作无法被cache感知。当然如果给dma的内存是no cache的,cpu不会使用cache,也就不存在相关问题。如果给dma的是带cache内存,那么cpu访问的时候就需要注意。armv8提供了cache相关指令解决上述问题,比如下面2条:dc civac Data or un

2021-08-25 18:40:09 1680

转载 Linux C/C++调试之三:性能分析工具callgrind的使用

callgrind是valgrind工具套件中用于分析程序性能的一个工具,它能够得到粒度为函数、代码行和指令级别的性能数据,具体来说,我们可以得到某个函数、某行代码、某条指令处累计执行了多少条指令。我们看一个实例:// foo.cppint accumulate(int begin, int end){ int result = 0; for (int i = begin; i < end; i++) { result += i; }}...

2021-08-05 10:59:58 1255

原创 变长数组(variable-length array)

C语言中,直到C99标准出现之前,声明数组时在方括号内只能使用整数常量表达式。而C99做了很大改进,允许数组的[ ]中的值是整形变量或是整形表达式。这就解释了下面的情况:int n;scanf ("%d", &n);int array[n];虽然n确实是需要运行时动态确定的变量,但是在C99中,以这种变量作为数组大小的形式已经是允许的了。这样的数组就被称之为“变长数组”。注意:变长数组是指用整型变量或表达式声明或定义的数组,而不是说数组的长度会随时变化,变长数组在其生存期内的长

2021-08-05 10:10:40 1650

转载 C++的性能优化实践

内容目录:1 Gprof 2. gprof使用步骤 1.初始化大对象耗时 2.Map使用不当优化准则:1. 二八法则:在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%的尽管是多数,却是次要的;在优化实践中,我们将精力集中在优化那20%最耗时的代码上,整体性能将有显著的提升;这个很好理解。函数A虽然代码量大,但在一次正常执行流程中,只调用了一次。而另一个函数B代码量比A小很多,但被调用了1000次。显然,我们更应关注B的优化。2. 编完代码,再优化;编码的时候总是考虑最佳性能

2021-07-28 10:44:31 386

转载 【日常杂记】for(int i=1;i<n;i=2*i)的时间复杂度

问题:求如下代码的时间复杂度for(int i=1;i<n;i=2*i){ cout<<"Hello!"<<endl;}解:第一次循环:i=1第二次循环:i=2i=2第三次循环:i=2i=2*2=22…第k次循环(最后一次):i=2k-1最后一次决定了2k-1<n<2k,两边取2的对数,得到:k-1<log2n<k,也就是:log2n<k<log2n+1因此:这段代码执行了k次基本操作(打印字符串),即:...

2021-07-28 10:03:16 2656

转载 (数据结构)十分钟搞定时间复杂度(算法的时间复杂度)

我们假设计算机运行一行基础代码需要执行一次运算。int aFunc(void) { printf("Hello, World!\n"); // 需要执行 1 次 return 0; // 需要执行 1 次}那么上面这个方法需要执行 2 次运算int aFunc(int n) { for(int i = 0; i<n; i++) { // 需要执行 (n + 1) 次 printf("Hello,

2021-07-28 09:13:31 310

转载 计算机编码问题解析(反码,补码等)

本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法.书中关于原码、反码、补码和移码的定义如下(n是机器字长):原码:反码:补码:移码:一. 机器数和真值在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.1、机器数一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, .

2021-07-21 18:04:06 566

原创 vulkan tutorial

#define GLFW_INCLUDE_VULKAN#include <GLFW/glfw3.h>#include <iostream>#include <stdexcept>#include <cstdlib>#include <vector>#include <cstring>#include <optional>#include <set>const uint32_t WIDTH =.

2021-07-17 11:54:50 284

转载 什么是拓扑排序(Topological Sorting)

(文章引用于http://songlee24.github.io/2015/05/07/topological-sorting/)一、什么是拓扑排序在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:每个顶点出现且只出现一次。 若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。有向无环图(DAG)才有拓扑排序,非DAG图没有

2021-07-06 15:48:29 5891

原创 questions

GLContext: Can a process have not only one context? what's the index of the context?100 floors, two eggs.check whether the binary tree is a BSTwhat is VBO?float in the computertextureview and surfaceviewthe pipeline of opengles

2021-06-25 10:00:11 128

转载 SurfaceView及TextureView区别

1、SurfaceView是什么它继承自类View,因此它本质上是一个View。但与普通View不同的是,它有自己的Surface。有自己的Surface,在WMS中有对应的WindowState,在SurfaceFlinger中有Layer。我们知道,一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DecorView,也就是根结点视图,才是对WMS可见的。这个DecorView在WMS中有一个对应的WindowState。相应地,在SF中对应的Layer

2021-06-25 09:51:36 5330

转载 认真分析mmap:是什么 为什么 怎么用

mmap基础概念mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现了文件磁盘地址和进程虚拟地址的映射关系。实现映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。如下图所示:由上图可以看出,进程的虚拟地址空间,由多个虚拟内存区域构成。虚拟内存区域是进程的虚拟地址.

2021-06-23 10:55:29 302

原创 rvalue reference

template<class T>void swap(T& a, T& b)// "perfect swap" (almost){T tmp {static_cast<T&&>(a)}; // the initialization may write to aa = static_cast<T&&>(b);// the assignment may write to bb = static_cast<T.

2021-06-14 17:46:07 207

原创 Lvalues and Rvalues

To complement the notion of an lvalue, we have the notion of an rvalue. Roughly, rvalue means ‘‘avalue that is not an lvalue,’’ such as a temporary value (e.g., the value returned by a function).If you need to be more technical (say, because you want to

2021-06-14 17:22:08 169

原创 packaged_task & future & async

packaged_task:double accum(double∗ beg, double ∗ end, double init)// compute the sum of [beg:end) starting with the initial value init{return accumulate(beg,end,init);}double comp2(vector<double>& v){using Task_type = double(double∗,dou

2021-06-14 17:04:08 96

原创 Passing Arguments to thread function

void f(vector<double>& v);// function do something with vstruct F {// function object: do something with vvector<double>& v;F(vector<double>& vv) :v{vv} { }void operator()();// application operator ; §3.4.3};int main(

2021-06-14 17:00:42 191

原创 thread using

void f(); // functionstruct F {void operator()();}; // function object// F’s call operator (§3.4.3)void user(){thread t1 {f};thread t2 {F()};t1.join();t2.join();// f() executes in separate thread// F()() executes in separate thread// wait for

2021-06-14 16:58:17 190

转载 移动构造函数和移动赋值运算符

如果第二个对象是在复制或赋值结束后被销毁的临时对象,则调用移动构造函数和移动赋值运算符,这样的好处是避免深度复制,提高效率。为了直观地观察移动构造函数和移动赋值运算符的运行方式,编写一个类Pointer,该类的对象会在堆动态创建一个数组。代码如下:class Pointer{public: Pointer(const int i,const string &n) { mptr = new int[i]; length = i;...

2021-06-14 16:47:49 367

转载 引用返回左值及其判断引用有效性的方法

被调函数的返回类型决定返回的是左值还是右值,当被调函数的返回类型是引用时,返回的是左值,其余情况下返回的是右值,被调函数返回的左值有着与其他左值类型同样的运算特性,需要特别指出的是,我们能为返回类型是非常量引用的函数的结果赋值,但是需要注意的是,进行运算的前提是确保返回的引用是有效的,返回与局部对象绑定的引用是无效的,因为被调函数运行结束时,局部对象的存储空间已经释放,返回与局部对象绑定的引用将会产生错误的结果,要想确保返回值的安全,我们不妨自问:引用绑定的是被调函数运行前的哪一个对象?然而,在...

2021-06-14 11:21:47 381

原创 初始化列表的初始化顺序

构造函数初始化列表仅用于初始化成员的值,并不指定这些初始化执行的次序。成员被初始化的次序就是定义成员的次序。第一个被定义的成员先被初始化,依次类推。一般,初始化的顺序无关紧要,然而,如果一个成员是根据其他成员而初始化,则成员的初始化顺序是至关重要的。class x {  int i;//声明顺序是先i,后j,故初始化列表中,会先初始化i,在初始化j  int j;public:  x(inttem): j(tem),i(j){}//看起来是先初始化j,然后初始化i,其实恰恰相反,先用...

2021-06-14 10:55:40 1707

原创 how to get the size new‘ed

如果你用的是glibc的话,里面有个malloc_usable_size的函数,可以拿到malloc的大小。类似free,指针得是原始申请出来的指针,不能有偏移。#include "malloc.h"#include <iostream>void get_malloc_size(void* p) { size_t size = malloc_usable_size(p); std::cout << "malloc size is: " << size

2021-06-14 10:50:35 115

空空如也

空空如也

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

TA关注的人

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