当前位置:网站首页>Camera Hal(Hal3)层修改Preview流
Camera Hal(Hal3)层修改Preview流
2022-08-02 14:02:00 【程序猫 猫小白】
问题描述
在Camera的Hal层修改数据流,系统相机应用获取到的数据会改变,除此之外,调用相机服务的第三方应用获取到的数据也会得到改变。比如Oppo手机 ColorOS 12 OMOJI功能:微信视频通话的时候可以使用3D表情功能。
如果在相机的Hal层对数据流进行修改,第三方使用相机服务的应用得到的数据也会改变。
具体怎样对Camera Hal层的数据进行修改?
解决问题思路
1.找到Camera Hal层的数据流
2.了解数据流格式,对其进行修改
问题解决
找到Preview数据流:
hardware\qcom\camera\QCamera2\HAL3
QCamera2HardwareInterface::preview_stream_cb_routinemm_camera_super_buf_t *super_frame, QCameraStream * stream, void userdata)
//了解下 mm_camera_super_buf_t数据结构
typedef struct {
uint32_t camera_handle;
uint32_t ch_id;
uint32_t num_bufs;
uint8_t bUnlockAEC;
uint8_t bReadyForPrepareSnapshot;
mm_camera_buf_def_t bufs[MAX_STREAM_NUM_IN_BUNDLE]; //各种数据流
} mm_camera_super_buf_t;
其中super_frame->bufs[0]的就是Preview流,继续了解mm_camera_buf_def_t的数据结构:
typedef struct mm_camera_buf_def {
uint32_t stream_id;
cam_stream_type_t stream_type;
cam_stream_buf_type buf_type;
uint32_t buf_idx;
uint8_t is_uv_subsampled;
struct timespec ts;
uint32_t frame_idx;
union {
mm_camera_plane_buf_def_t planes_buf;
mm_camera_user_buf_def_t user_buf;
};
int fd;
void *buffer; //真正数据
size_t frame_len;
void *mem_info;
uint32_t flags;
uint32_t cache_flags;
} mm_camera_buf_def_t;
preview流真正的数据:super_frame->bufs[0]->buffer;
数据修改:
preview流的数据是YUV,格式为nv21。
以一个44的小图来解释格式nv21
一共有的数据个数为 443/2,其中44是Y(明亮度),44/2为UV(色彩)
Y Y Y Y
Y Y Y Y
Y Y Y Y
Y Y Y Y
V U V U
V U V U
如果我把想把44这个小图设置为灰色图,即色彩值为128(色彩黑,色彩值为0;色彩白,色彩值为255;色彩灰,色彩之为128(0x80))
可以写一个灰色滤镜函数:
void GrayFilter(unsigned char* yuvsrc, int width, int height)
{
int Y_len=widthheight;
int VU_len=Y_len/2;
unsigned char p=yuvsrc+Y_len;
memset(p,0x80,(size_t)VU_len);
}
其中 for(int i=0;i<VU_len;i++)
*p=0x80;
代码和 memset(p,0x80,(size_t)VU_len); 实现效果一致,但是使用memset(p,0x80,(size_t)VU_len)效率更高。这句话的含义就是把YUV途中色彩部分(VU_len)赋值为0x80(即十进制的128,灰色)。
在Camera Hal2中进行调用这个函数
voidQCamera2HardwareInterface::preview_stream_cb_routine
(mm_camera_super_buf_t *super_frame, QCameraStream * stream, void userdata)
{
//获取YUV数据地址
++ unsigned char yuvsrc = (unsigned char *)super_frame->bufs[0]->buffer;
++ cam_frame_len_offset_t offset;
++ stream->getFrameOffset(offset);
//其中offset.mp[0].stride为对齐后的宽
//offset.mp[0].scanline为对齐后的高
//调用灰色滤镜函数
++ GrayFilter(yuvsrc,offset.mp[0].stride,offset.mp[0].scanline);
}
效果
编译之后,刷机,相机的预览后面相当于加了个灰色滤镜的效果,第三方调用相机服务的预览画面也是加了个灰色滤镜的效果。
本来想做个黑白滤镜的效果,即把色彩VU的值都复制为0;但是测试的时候,发现画面都是绿色,不知道是不是相机底层加了颜色纠正的功能,如果有人知道这个问题,不吝赐教~~~
写在最后的话
今天周日对之前的学习进行了个小总结~~~写了这篇博客,如果觉得这篇文章对你有点帮忙,就点个赞吧~~~~
边栏推荐
- Flask框架
- Object detection scene SSD-Mobilenetv1-FPN
- Interview | with questions to learn, Apache DolphinScheduler Wang Fuzheng
- Some impressions of the 519 plummet 2021-05-21
- Minio文件上传
- Supervision strikes again, what about the market outlook?2021-05-22
- Linux: CentOS 7 install MySQL5.7
- run yolov5
- Unit 13 Mixing in View Base Classes
- redis延时队列
猜你喜欢
随机推荐
EasyExcel 的使用
How to solve 1045 cannot log in to mysql server
Unit 6 meet ORM
8576 顺序线性表的基本操作
第五单元 保持状态
Unit 13 Mixing in View Base Classes
8581 线性链表逆置
Audio processing: floating point data stream to PCM file
第七单元 ORM表关系及操作
deal!It's July 30th!
yolov5,yolov4,yolov3 mess
window10 lower semi-automatic labeling
Minio文件上传
瑞吉外卖笔记——第05讲Redis入门
MarkDown语法汇总
What are the file encryption software?Keep your files safe
Swagger 的使用
Cloin 控制台乱码
redis分布式锁和看门狗的实现
drf路由组件Routers