Android Camera预览过程数据流浅析

硬件平台:Atmel SAMA5D3 SoC + OV2640 Camera Sensor

Android版本:4.2.2

mediaserver进程是Camera Service的容器进程,它会动态加载Camera HAL和Gralloc HAL。

视频数据帧首先必须从Camera驱动程序到达Camera硬件抽象层。

在Camera硬件抽象层,视频数据帧被从video capture buffer拷贝到gralloc buffer。

surfaceflinger进程作为显示服务器会动态加载HWComposer HAL和Gralloc HAL。

在HWComposer硬件抽象层,会把数据帧从gralloc buffer拷贝到video output buffer。

经过上述过程,Camera Sensor采集的图像最终通过LCDC HEO显示在显示屏上。

图中红色实线为视频数据帧流向,不带箭头的红线连接的两端为同一块内存。

涉及三块内存,分别如下:

video capture buffer /dev/video1

gralloc buffer       匿名共享内存 mediaserver进程和surfacelinger进程都可以访问这块内存

video output buffer /dev/video0

进行了两次数据拷贝操作,如下:

media server进程

Camera HAL    video capture buffer -> gralloc buffer

surfaceflinger进程

HWCompser HAL   gralloc buffer -> video output buffer

video capture buffer的分配与内存映射

https://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/camera/CameraHardwareSam.cpp

https://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/camera/V4L2Camera.cpp

申请video capture buffer

CameraHardwareSam::startPreviewInternal
-> V4L2Camera::startPreview
-> isi_v4l2_reqbufs

    ret = ioctl(fp, VIDIOC_REQBUFS, &req);

内存映射

CameraHardwareSam::startPreviewInternal

    mPreviewHeap = mGetMemoryCb((int)mV4L2Camera->getCameraFd(),
                                aligned_buffer_size,
                                kBufferCount,
                                0);

获得gralloc buffer以及视频数据帧从video capture buffer到gralloc buffer的拷贝

https://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/camera/CameraHardwareSam.cpp

CameraHardwareSam::previewThread

    if (mPreviewWindow && mGrallocHal) {
        buffer_handle_t *buf_handle;
        int stride;
        if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &buf_handle, &stride)) {
            ALOGE("Could not dequeue gralloc buffer!\n");
            goto callbacks;
        }

        void *vaddr;
        if (!mGrallocHal->lock(mGrallocHal,
                               *buf_handle,
                               GRALLOC_USAGE_SW_WRITE_OFTEN,
                               0, 0, width, height, &vaddr)) {
            char *frame = ((char *)mPreviewHeap->data) + offset;

            // the code below assumes YUV, not RGB
            {
                int h;
                char *src = frame;
                char *ptr = (char *)vaddr;
                memcpy(ptr, src, frame_size);
                //YUY2toYV12(frame, vaddr, width, height);
            }
            mGrallocHal->unlock(mGrallocHal, *buf_handle);
        }
        else
            ALOGE("%s: could not obtain gralloc buffer", __func__);

        if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, buf_handle)) {
            ALOGE("Could not enqueue gralloc buffer!\n");
            goto callbacks;
        }
    }

video output buffer的分配与内存映射

https://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/hwcomposer/hwcomposer.cpp

https://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/hwcomposer/v4l2_utils.cpp

申请video ouput buffer

hwc_prepare -> assign_heo_overlay_window
-> v4l2_overlay_req_buf

    ret = ioctl(win->fd, VIDIOC_REQBUFS, &reqbuf);

内存映射

hwc_prepare -> assign_heo_overlay_window
-> v4l2_overlay_map_buf

    *len = buf.length;
    *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
            fd, buf.m.offset);

视频数据帧从gralloc buffer到video output buffer的拷贝

hwc_set ->  copy_heo_src_content

    for (unsigned int i = 0; i < cur_layer->visibleRegionScreen.numRects; i++) {
        uint8_t *cur_dst_addr = dst_addr;
        uint8_t *cur_src_addr = src_addr;

        for (int j = 0; j < h ; j++) {
            memcpy(cur_dst_addr, cur_src_addr, cpy_size);
            cur_dst_addr = &cur_dst_addr[cpy_size];
            cur_src_addr = &cur_src_addr[(cur_layer->displayFrame.right - cur_layer->displayFrame.left) * (prev_handle->uiBpp / 8)];
        }
        cur_rect++;
    }

Android Camera预览过程数据流浅析

时间: 2024-08-11 03:36:29

Android Camera预览过程数据流浅析的相关文章

Android 5.0 Camera系统源码分析(5):Camera预览3A流程

1. 前言 本文分析的是Android Hal层的源码,硬件平台基于mt6735.之前几篇讲的预览流程中3A相关的环节都忽略了,现在重新整理下. 3A指的是Auto Exposure,Auto Focus,Auto White Balance.这三个一起放上来代码实在太多了,这里将重点记录AF的代码.AF的部分工作是由ISP完成的,而ISP的大部分代码mtk都没有开放给我们,比如ISP是如何计算得到对焦位置信息的,但得到对焦位置之后怎么操作对焦马达的代码我们是看得到的,所以涉及到ISP的一些代码

Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用(转)

原文地址:http://blog.csdn.net/yanzi1225627/article/details/8605061# 很多时候,android摄像头模块不仅预览,拍照这么简单,而是需要在预览视频的时候,能够做出一些检测,比如最常见的人脸检测.在未按下拍照按钮前,就检测出人脸然后矩形框标示出来,再按拍照.那么如何获得预览帧视频么? 只需要在Activity里继承PreviewCallback这个接口就行了.示例如下: public class RectPhoto extends Acti

Android手势识别 Camera 预览界面上显示文字 布局注意事项(merge布局)

通常在Surfaceview作为预览视频帧的载体,有时需在上面显示提示文字.以前我弄的都好好的,今天忽然发现叠加的TextView不管咋弄都出不来文字了,跟Surfaceview一起放在FrameLayout也不行,后来想到merge布局,发现也不行.大爷的,奇了怪了,最后发现了原因,原来是顺序问题.也即无论是在RelativeLayout里还是merge布局里,View是逐个叠加上去的,一层一层铺上去的.如果你先放TextView在最前面,那肯定被后面的全屏Surfaceview覆盖了.用常规

android相机预览

android访问相机使用的是Camera.open 来返回一个Camera对象,设置好显示的视图后,调用Camera的预览功能函数 startPreview,停止预览函数是 stopPreview! activity_mail.xml布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/too

camera预览是闪退的问题

使用ov8825 sensor时,如果是摄像预览可以点亮,如果切换到拍照预览时,apk闪退.log如下: [email protected]:/ # logcat logcat --------- beginning of /dev/log/main D/AudioHardware( 1340): AudioHardware pcm playback is exiting standby. D/AudioHardware( 1340): openPcmOut_l() mPcmOpenCnt: 0

4412开发板 DVFS camera预览性能测试

内核:3.8.13 ARM: IBOX 4412 camera分辨率 640x480 160000(1.6G)时4核全开, echo Peformance > scaling_governor Mem: 58220K used, 969844K free, 0K shrd, 268K buff, 2524K cached CPU: 49.7% usr 1.4% sys 0.0% nic 48.7% idle 0.0% io 0.0% irq 0.0% sirq Load average: 1.0

android xml预览问题

1.当加入EditText组件后不能预览 ,android sdk的platform版本可能是4.4,4.4是不支持EditText控件的,更新sdk的platform 2.选择的版本与sdk版本  不对应.

上传多张照片并实现预览过程

function selectImage(imgFile){ //上传的多张图片 var allFiles = imgFile.files; var imgArr = []; for(var i=0;i<allFiles.length;i++){ var file = allFiles[i]; //添加一层过滤 var rFilter = /^(image\/bmp|image\/gif|image\/jpeg|image\/png|image\/tiff)$/i; if(!rFilter.te

玩转Android Camera开发(四):预览界面四周暗中间亮,仅仅拍摄矩形区域图片(附完整源代码)

杂家前文曾写过一篇关于仅仅拍摄特定区域图片的demo.仅仅是比較简陋.在坐标的换算上不是非常严谨,并且没有完毕预览界面四周暗中间亮的效果,深以为憾.今天把这个补齐了. 在上代码之前首先交代下,这里面存在着换算的两种模式.第一种,是以屏幕上的矩形区域为基准进行换算.举个样例.屏幕中间一个 矩形框为100dip*100dip.这里一定要使用dip为单位,否则在不同的手机上屏幕呈现的矩形框大小不一样. 先将这个dip换算成px.然后依据屏幕的宽和高的像素计算出矩形区域,传给Surfaceview上铺的