IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 高通msm8937/msm8939平台【备录】 -> 正文阅读

[移动开发]高通msm8937/msm8939平台【备录】

心怀浪漫宇宙,也珍惜人间日常。

这篇文章基于高通msm8937/msm8939平台,分下面几点内容展开:

一、主要硬件模块
二、Camera?预览数据流
三、Android?Camera?软件架构?
四、HAL层dump?Yuv?
五、Jepg Encoder dump YUV

01

主要硬件模块(Major Hardware Blocks Used)

1)Camera Control Interface (CCI)?

Used for dedicated I2C for camera subsystem

2)Video Frontend (VFE4)?

Image processing hardware for processing camera frame data? ? MSM8939 VFE can support up to 21 MP?

VFE4 maximum clock is 320 MHz in Normal mode and 600 MHz in Turbo mode

3)JPEG encoder/decoder?

Hardware block for JPEG encoding?

JPEG encoder maximum clock is 266 MHz in Normal mode?

LIBJPEG software library is used for decoding

4)Camera Postprocessor (CPP)?

Supports flip/rotate, denoise, smooth/sharpen, crop, and upscale features for full-size VFE output frames

--------- 我们经常说的翻转、旋转、降噪、裁剪、按比例缩放等操作就是放在cpp中进行出来。

02

Camera 预览数据量

MDP: (支持16bit总线以上LCD) lcd总线接口类型,支持高速刷屏。

03

Sortware Architechture - Android Camera

MCT :Media Controller

04

HAL层dump Yuv

上面的文档是针对8939平台的,如果在其它平台上,可能有有点差异,具体值以实际代码为准。

我这边是在8937平台上看的调试代码:

persist.vendor.camera.dumpimg

//------ hardware/qcom/camera/QCamera2/HAL3/QCamera3Channel.cpp


void QCamera3Channel::dumpYUV(mm_camera_buf_def_t *frame, cam_dimension_t dim,
        cam_frame_len_offset_t offset, uint8_t dump_type)
{
    char buf[FILENAME_MAX];
    memset(buf, 0, sizeof(buf));
    static int counter = 0;
    char prop[PROPERTY_VALUE_MAX];
    property_get("persist.vendor.camera.dumpimg", prop, "0");
    mYUVDump = (uint32_t)atoi(prop);
    if (mYUVDump & dump_type) {
        mFrmNum = ((mYUVDump & 0xffff0000) >> 16);
        if (mFrmNum == 0) {
            mFrmNum = 10;
        }
        if (mFrmNum > 256) {
            mFrmNum = 256;
        }
        mSkipMode = ((mYUVDump & 0x0000ff00) >> 8);
        if (mSkipMode == 0) {
            mSkipMode = 1;
        }
        if (mDumpSkipCnt == 0) {
            mDumpSkipCnt = 1;
        }
        if (mDumpSkipCnt % mSkipMode == 0) {
            if (mDumpFrmCnt < mFrmNum) {
                /* Note that the image dimension will be the unrotated stream dimension.
                * If you feel that the image would have been rotated during reprocess
                * then swap the dimensions while opening the file
                * */
                switch (dump_type) {
                    case QCAMERA_DUMP_FRM_PREVIEW:
                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"p_%d_%d_%dx%d.yuv",
                            counter, frame->frame_idx, dim.width, dim.height);
                    break;
                    case QCAMERA_DUMP_FRM_VIDEO:
                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"v_%d_%d_%dx%d.yuv",
                            counter, frame->frame_idx, dim.width, dim.height);
                    break;
                    case QCAMERA_DUMP_FRM_INPUT_JPEG:
                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"s_%d_%d_%dx%d.yuv",
                            counter, frame->frame_idx, dim.width, dim.height);
                    break;
                    case QCAMERA_DUMP_FRM_INPUT_REPROCESS:
                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"ir_%d_%d_%dx%d.yuv",
                            counter, frame->frame_idx, dim.width, dim.height);
                    break;
                    case QCAMERA_DUMP_FRM_CALLBACK:
                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"c_%d_%d_%dx%d.yuv",
                            counter, frame->frame_idx, dim.width, dim.height);
                    break;
                    case QCAMERA_DUMP_FRM_OUTPUT_JPEG:
                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"j_%d_%d_%dx%d.jpg",
                            counter, frame->frame_idx, dim.width, dim.height);
                    break;
                    default :
                        LOGE("dumping not enabled for stream type %d",dump_type);
                    break;
                }
                counter++;
                int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
                ssize_t written_len = 0;
                if (file_fd >= 0) {
                    void *data = NULL;
                    fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
                    if( dump_type == QCAMERA_DUMP_FRM_OUTPUT_JPEG ) {
                        written_len = write(file_fd, frame->buffer, frame->frame_len);
                    }
                    else {
                        for (uint32_t i = 0; i < offset.num_planes; i++) {
                            uint32_t index = offset.mp[i].offset;
                            if (i > 0) {
                                index += offset.mp[i-1].len;
                            }
                            for (int j = 0; j < offset.mp[i].height; j++) {
                                data = (void *)((uint8_t *)frame->buffer + index);
                                written_len += write(file_fd, data,
                                        (size_t)offset.mp[i].width);
                                index += (uint32_t)offset.mp[i].stride;
                            }
                        }
                    }
                    LOGH("written number of bytes %ld\n", written_len);
                    mDumpFrmCnt++;
                    frame->cache_flags |= CPU_HAS_READ;
                    close(file_fd);
                } else {
                    LOGE("failed to open file to dump image");
                }
            }
        } else {
            mDumpSkipCnt++;
        }
    }
}

1)setprop persist.vendor.camera.dumping 4

值设为 1<<2,也就是4,这个dump的是送给Jepg Encode之前的yuv数据。如果需要查看拍照前的yuv数据,可以设置这个进行dump。

2) setprop persist.vendor.camera.dumping 8

值设为 1 << 3 也就是4,可以dump callback的yuv。比如第三方app 的hdr算法,拍照的时候,请求了3张不同ev值的yuv,这时就可以把3张yuv dump出来。

下面是使用第三方app,hdr模式下拍照的dump的例子。

下图dump出来的3张yuv图,可以看到亮度是有变化的,也就是上层申请的不同ev值对应的yuv文件。

3)setprop persist.vendor.camera.dumping 32

值设为32,这个dump的是拍照返回的jpeg,这个是Jpeg Encoder处理后返回的,dump出来的格式自然也就是jpeg格式。

05

Jepg Encoder dump YUV

按照文档说明,在mm_jpeg.c文件中添加定义宏?MM_JPEG_DUMP_INPUT即可打开dump。

这里需要注意文件路径读写权限的问题,相应的目录权限需要修改成777,如果文件夹路径不存在,需要手动创建下。

如果需要dump处理后的jpeg数据,则可以添加定义宏?MM_JPEG_DUMP_OUT_BS

推荐阅读:

ITS测试修改备录

哪些坑爹的Android CTS测试

Android Camera2 对焦梳理

Android Camera 测光梳理

一篇文章带你了解Android 最新Camera框架

这可能是介绍Android UvcCamera最详细的文章了

深圳上班,

生活简简单单,

14年开始从事Android Camera相关软件开发工作,

做过车载、手机、执法记录仪......

公众号记录生活和工作的点滴,

点击关注“小驰笔记”,期待和你相遇~

人生不设限,一起加油

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-23 16:48:38  更:2021-08-23 16:50:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:34:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码