android_驱动_qcom_【高通SDM660平台】(7) --- Camera onPreview 代码流程


【高通SDM660平台】(1) — Camera 驱动 Bringup Guide
【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析
【高通SDM660平台】(3) — Camera V4L2 驱动层分析
【高通SDM660平台】(4) — Camera Init 初始化流程
【高通SDM660平台】(5) — Camera Open 流程
【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程
【高通SDM660平台】(7) — Camera onPreview 代码流程
【高通SDM660平台】(8) — Camera MetaData介绍
【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析
【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析
《【高通SDM660平台】Camera Capture 流程》
《【高通SDM660平台】Camera mm-qcamera-app 代码分析》


一、Camera onPreview 流程

1. [ Framework ] Camera.java

@ frameworks/base/core/java/android/hardware/Camera.java
@Deprecated
public class Camera {
    private static final String TAG = "Camera";
<span class="token keyword">public</span> <span class="token keyword">native</span> <span class="token keyword">final</span> <span class="token keyword">void</span> <span class="token function">startPreview</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2. [ JNI ] android_hardware_Camera.cpp

可以看出,代码是获取 native 层Camera 对象,调用 Camera::startPreview() 方法

@ frameworks/base/core/jni/android_hardware_Camera.cpp
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
    ALOGV("startPreview");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
<span class="token keyword">if</span> <span class="token punctuation">(</span>camera<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">startPreview</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">jniThrowRuntimeException</span><span class="token punctuation">(</span>env<span class="token punctuation">,</span> <span class="token string">"startPreview failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

//-------------------------------------------------
static const JNINativeMethod camMethods[] = {
{ “startPreview”, “()V”, (void *)android_hardware_Camera_startPreview },
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3. [ Native ] Camera.cpp

@ frameworks/av/camera/Camera.cpp
// start preview mode
status_t Camera::startPreview()
{
    ALOGV("startPreview");
    sp <::android::hardware::ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->startPreview();
    	========>
    	@ frameworks/av/camera/ICamera.cpp
    		status_t startPreview()
		    {
		        ALOGV("startPreview");
		        Parcel data, reply;
		        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
		        remote()->transact(START_PREVIEW, data, &reply);
		        return reply.readInt32();
		    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在 ICamera.cpp 代理对像中远程调用BnCamera的onTransact() 方法

@ frameworks/av/camera/ICamera.cpp
status_t BnCamera::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
    	case START_PREVIEW: {
            ALOGV("START_PREVIEW");
            CHECK_INTERFACE(ICamera, data, reply);
            reply->writeInt32(startPreview());
            return NO_ERROR;
        } break;

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以看出 ,调用的是BnCamera 的中的 startPreview() 方法,但实际上 BnCamera 并没有 实现startPreview() 方法,它是继承于 ICamera 的虚方法。
因此,startPreview() 是由 BnCamera 的子类来实现。

@ frameworks/av/services/camera/libcameraservice/CameraService.h
class CameraService :
    public BinderService<CameraService>,
    public ::android::hardware::BnCameraService,
    public IBinder::DeathRecipient,
    public camera_module_callbacks_t
{
	class Client : public hardware::BnCamera, public BasicClient
    {
    public:
        virtual status_t      startPreview() = 0;
        virtual void          stopPreview() = 0;
	}
}

@ frameworks/av/services/camera/libcameraservice/api1/CameraClient.h
class CameraClient : public CameraService::Client
{
public:
virtual status_t startPreview();
virtual void stopPreview();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

可以看出,CameraService 的内部类 Client 是继承了 BnCamera 的 startPreview() 方法,
接着,CameraClient 继承了 CameraService::Client ,最终 startPreview() 方法 是由 CameraClient 来实现了

4. [ Native ] CameraClient.cpp

@ frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
// start preview mode
status_t CameraClient::startPreview() {
    LOG1("startPreview (pid %d)", getCallingPid());
    // 开始预览
    return startCameraMode(CAMERA_PREVIEW_MODE);
}

// start preview or recording
status_t CameraClient::startCameraMode(camera_mode mode) {
LOG1(“startCameraMode(%d)”, mode);
switch(mode) {
case CAMERA_PREVIEW_MODE:
return startPreviewMode();
case CAMERA_RECORDING_MODE:
return startRecordingMode();
}
}

status_t CameraClient::startPreviewMode() {
LOG1(“startPreviewMode”);
if (mPreviewWindow != 0) {
//根据新的参数,设置所有缓冲区的显示
mHardware->setPreviewScalingMode( NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
mHardware->setPreviewTransform(mOrientation);
}
//设置预览窗口
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
if (result == NO_ERROR) {
mCameraService->updateProxyDeviceState( ICameraServiceProxy::CAMERA_STATE_ACTIVE,
String8::format("%d", mCameraId));
}
return result;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

5. [ Hardware ] CameraClient.cpp

mHardware 对像实现如下, sp<CameraHardwareInterface> mHardware;
可知,mHardware->setPreviewWindow(mPreviewWindow); 实现如下:

@ frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h

class CameraHardwareInterface : public virtual RefBase {
public:
/*** Start preview mode. */
status_t startPreview()
{
ALOGV("%s(%s)", FUNCTION, mName.string());
if (mDevice->ops->start_preview)
return mDevice->ops->start_preview(mDevice);
return INVALID_OPERATION;
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

6. [ Hardware ] camera_device_t

mDevice 定义为 camera_device_t *mDevice;

camera_device_t定义在:

@ hardware/libhardware/include/hardware/camera.h

struct camera_device;
typedef struct camera_device_ops {
/**
* Start preview mode.
/

int (start_preview)(struct camera_device *);
}camera_device_ops_t;

typedef struct camera_device {
/**
* camera_device.common.version must be in the range
* HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is
* recommended.
/

hw_device_t common;
camera_device_ops_t ops;
void *priv;
} camera_device_t;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
@ hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp

camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
.start_preview = QCamera2HardwareInterface::start_preview,
.stop_preview = QCamera2HardwareInterface::stop_preview,
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7. [ Hardware ] QCamera2HWI.cpp

通过 processAPI() 往底层下发 QCAMERA_SM_EVT_START_PREVIEW 事件

@ hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp

int QCamera2HardwareInterface::start_preview(struct camera_device *device)
{
KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW);

QCamera2HardwareInterface <span class="token operator">*</span>hw <span class="token operator">=</span> <span class="token keyword">reinterpret_cast</span><span class="token operator">&lt;</span>QCamera2HardwareInterface <span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>device<span class="token operator">-</span><span class="token operator">&gt;</span>priv<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"[KPI Perf]: E PROFILE_START_PREVIEW camera id %d"</span><span class="token punctuation">,</span> hw<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">getCameraId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

qcamera_sm_evt_enum_t evt <span class="token operator">=</span> QCAMERA_SM_EVT_START_PREVIEW<span class="token punctuation">;</span>
<span class="token keyword">uint32_t</span> cam_type <span class="token operator">=</span> CAM_TYPE_MAIN<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>hw<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">isDualCamera</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    cam_type <span class="token operator">=</span> MM_CAMERA_DUAL_CAM<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>hw<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">isNoDisplayMode</span><span class="token punctuation">(</span>cam_type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    evt <span class="token operator">=</span> QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
ret <span class="token operator">=</span> hw<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">processAPI</span><span class="token punctuation">(</span>evt<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
		@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>HAL<span class="token operator">/</span>QCamera2HWI<span class="token punctuation">.</span>cpp
		QCamera2HardwareInterface <span class="token operator">*</span>hw <span class="token operator">=</span> <span class="token keyword">reinterpret_cast</span><span class="token operator">&lt;</span>QCamera2HardwareInterface <span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>device<span class="token operator">-</span><span class="token operator">&gt;</span>priv<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token keyword">int</span> QCamera2HardwareInterface<span class="token operator">::</span><span class="token function">processAPI</span><span class="token punctuation">(</span>qcamera_sm_evt_enum_t api<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>api_payload<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			ret <span class="token operator">=</span> m_stateMachine<span class="token punctuation">.</span><span class="token function">procAPI</span><span class="token punctuation">(</span>api<span class="token punctuation">,</span> api_payload<span class="token punctuation">)</span><span class="token punctuation">;</span>		
		<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    hw<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">waitAPIResult</span><span class="token punctuation">(</span>evt<span class="token punctuation">,</span> <span class="token operator">&amp;</span>apiResult<span class="token punctuation">)</span><span class="token punctuation">;</span>
    ret <span class="token operator">=</span> apiResult<span class="token punctuation">.</span>status<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
hw<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">unlockAPI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"[KPI Perf]: X ret = %d"</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

经过层层调用,最终跑到了 QCameraStateMachine::procAPI() 中, evt=QCAMERA_SM_EVT_START_PREVIEW
将消息,保存在 class QCameraQueue 中。
node 中包括: QCAMERA_SM_EVT_START_PREVIEW 和 QCAMERA_SM_CMD_TYPE_API 两个消息

@ hardware/qcom/camera/QCamera2/HAL/QCameraStateMachine.cpp
QCameraStateMachine m_stateMachine;

int32_t QCameraStateMachine::procAPI(qcamera_sm_evt_enum_t evt, void api_payload)
{
qcamera_sm_cmd_t node = (qcamera_sm_cmd_t *)malloc(sizeof(qcamera_sm_cmd_t));

<span class="token function">memset</span><span class="token punctuation">(</span>node<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>qcamera_sm_cmd_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
node<span class="token operator">-</span><span class="token operator">&gt;</span>cmd <span class="token operator">=</span> QCAMERA_SM_CMD_TYPE_API<span class="token punctuation">;</span>
node<span class="token operator">-</span><span class="token operator">&gt;</span>evt <span class="token operator">=</span> evt<span class="token punctuation">;</span>
node<span class="token operator">-</span><span class="token operator">&gt;</span>evt_payload <span class="token operator">=</span> api_payload<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>api_queue<span class="token punctuation">.</span><span class="token function">enqueue</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>node<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">cam_sem_post</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>cmd_sem<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> NO_ERROR<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在QCameraQueue::enqueue() 中添加队列

@ hardware/qcom/camera/QCamera2/util/QCameraQueue.cpp
bool QCameraQueue::enqueue(void *data)
{
    bool rc;
    camera_q_node *node = (camera_q_node *)malloc(sizeof(camera_q_node));
<span class="token function">memset</span><span class="token punctuation">(</span>node<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>camera_q_node<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
node<span class="token operator">-</span><span class="token operator">&gt;</span>data <span class="token operator">=</span> data<span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>m_active<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">cam_list_add_tail_node</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>node<span class="token operator">-</span><span class="token operator">&gt;</span>list<span class="token punctuation">,</span> <span class="token operator">&amp;</span>m_head<span class="token punctuation">.</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span>
    m_size<span class="token operator">++</span><span class="token punctuation">;</span>
    rc <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

8. [ HWI ] QCameraStateMachine.cpp

QCameraStateMachine 中创建了一个线程用 于处理evt 事件

@ hardware/qcom/camera/QCamera2/HAL/QCameraStateMachine.cpp

QCameraStateMachine::QCameraStateMachine(QCamera2HardwareInterface *ctrl) :
api_queue(),
evt_queue()
{
pthread_create(&cmd_pid, NULL,smEvtProcRoutine,this);
pthread_setname_np(cmd_pid, “CAM_stMachine”);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在线程 *QCameraStateMachine::smEvtProcRoutine() 中,
因为下发的是 QCAMERA_SM_EVT_START_PREVIEWQCAMERA_SM_CMD_TYPE_API 两个消息 ,
可知跑 case QCAMERA_SM_CMD_TYPE_API

@ hardware/qcom/camera/QCamera2/HAL/QCameraStateMachine.cpp
void *QCameraStateMachine::smEvtProcRoutine(void *data)
{
    int running = 1, ret;
    QCameraStateMachine *pme = (QCameraStateMachine *)data;
<span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"E"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">do</span> <span class="token punctuation">{</span>
    <span class="token keyword">do</span> <span class="token punctuation">{</span>
        ret <span class="token operator">=</span> <span class="token function">cam_sem_wait</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>pme<span class="token operator">-</span><span class="token operator">&gt;</span>cmd_sem<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">// we got notified about new cmd avail in cmd queue</span>
    <span class="token comment">// first check API cmd queue</span>
    qcamera_sm_cmd_t <span class="token operator">*</span>node <span class="token operator">=</span> <span class="token punctuation">(</span>qcamera_sm_cmd_t <span class="token operator">*</span><span class="token punctuation">)</span>pme<span class="token operator">-</span><span class="token operator">&gt;</span>api_queue<span class="token punctuation">.</span><span class="token function">dequeue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>node <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// no API cmd, then check evt cmd queue</span>
        node <span class="token operator">=</span> <span class="token punctuation">(</span>qcamera_sm_cmd_t <span class="token operator">*</span><span class="token punctuation">)</span>pme<span class="token operator">-</span><span class="token operator">&gt;</span>evt_queue<span class="token punctuation">.</span><span class="token function">dequeue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>node <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">switch</span> <span class="token punctuation">(</span>node<span class="token operator">-</span><span class="token operator">&gt;</span>cmd<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">case</span> QCAMERA_SM_CMD_TYPE_API<span class="token operator">:</span>
            pme<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">stateMachine</span><span class="token punctuation">(</span>node<span class="token operator">-</span><span class="token operator">&gt;</span>evt<span class="token punctuation">,</span> node<span class="token operator">-</span><span class="token operator">&gt;</span>evt_payload<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">// API is in a way sync call, so evt_payload is managed by HWI</span>
            <span class="token comment">// no need to free payload for API</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> QCAMERA_SM_CMD_TYPE_EVT<span class="token operator">:</span>
            pme<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">stateMachine</span><span class="token punctuation">(</span>node<span class="token operator">-</span><span class="token operator">&gt;</span>evt<span class="token punctuation">,</span> node<span class="token operator">-</span><span class="token operator">&gt;</span>evt_payload<span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// EVT is async call, so payload need to be free after use</span>
            <span class="token function">free</span><span class="token punctuation">(</span>node<span class="token operator">-</span><span class="token operator">&gt;</span>evt_payload<span class="token punctuation">)</span><span class="token punctuation">;</span>
            node<span class="token operator">-</span><span class="token operator">&gt;</span>evt_payload <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> QCAMERA_SM_CMD_TYPE_EXIT<span class="token operator">:</span>
            running <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>running<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"X"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

QCameraStateMachine::stateMachine() 中,会根据之前的 m_state 状态来决定当前代码怎么走的,
在初始化时 配置 m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
因此我们第一次preview 是走 procEvtPreviewStoppedState

@ hardware/qcom/camera/QCamera2/HAL/QCameraStateMachine.cpp
int32_t QCameraStateMachine::stateMachine(qcamera_sm_evt_enum_t evt, void *payload)
{
    int32_t rc = NO_ERROR;
    LOGL("m_state %d, event (%d)", m_state, evt);
    switch (m_state) {
    case QCAMERA_SM_STATE_PREVIEW_STOPPED:
        rc = procEvtPreviewStoppedState(evt, payload);
        break;
    case QCAMERA_SM_STATE_PREVIEW_READY:
        rc = procEvtPreviewReadyState(evt, payload);
        break;
    case QCAMERA_SM_STATE_PREVIEWING:
        rc = procEvtPreviewingState(evt, payload);
        break;
    case QCAMERA_SM_STATE_PREPARE_SNAPSHOT:
        rc = procEvtPrepareSnapshotState(evt, payload);
        break;
    case QCAMERA_SM_STATE_PIC_TAKING:
        rc = procEvtPicTakingState(evt, payload);
        break;
    case QCAMERA_SM_STATE_RECORDING:
        rc = procEvtRecordingState(evt, payload);
        break;
    case QCAMERA_SM_STATE_VIDEO_PIC_TAKING:
        rc = procEvtVideoPicTakingState(evt, payload);
        break;
    case QCAMERA_SM_STATE_PREVIEW_PIC_TAKING:
        rc = procEvtPreviewPicTakingState(evt, payload);
        break;
    default:
        break;
    }
<span class="token keyword">if</span> <span class="token punctuation">(</span>m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">isDualCamera</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">/* Update the FOVControl dual camera result state based on the current state.
     Update the result only in previewing and recording states */</span>
    <span class="token keyword">bool</span> updateResultState <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>m_state <span class="token operator">==</span> QCAMERA_SM_STATE_PREVIEWING<span class="token punctuation">)</span> <span class="token operator">||</span>
            <span class="token punctuation">(</span>m_state <span class="token operator">==</span> QCAMERA_SM_STATE_RECORDING<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>m_parent<span class="token operator">-</span><span class="token operator">&gt;</span>mActiveAF
            <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>m_parent<span class="token operator">-</span><span class="token operator">&gt;</span>m_bPreparingHardware<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        updateResultState <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    m_parent<span class="token operator">-</span><span class="token operator">&gt;</span>m_pFovControl<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">UpdateFlag</span><span class="token punctuation">(</span>FOVCONTROL_FLAG_UPDATE_RESULT_STATE<span class="token punctuation">,</span>
            <span class="token operator">&amp;</span>updateResultState<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

9. [ HWI ] procEvtPreviewStoppedState

由于,我们下发的 evt 事件为 QCAMERA_SM_EVT_START_PREVIEW
首先调用 m_parent->preparePreview() 准备preview,添加 QCAMERA_CH_TYPE_PREVIEW
完毕后,将状态机,切换为 QCAMERA_SM_STATE_PREVIEW_READY.

@ hardware/qcom/camera/QCamera2/HAL/QCameraStateMachine.cpp

int32_t QCameraStateMachine::procEvtPreviewStoppedState(qcamera_sm_evt_enum_t evt,
void *payload)
{
int32_t rc = NO_ERROR;
qcamera_api_result_t result;
memset(&result, 0, sizeof(qcamera_api_result_t));

<span class="token function">LOGL</span><span class="token punctuation">(</span><span class="token string">"event (%d)"</span><span class="token punctuation">,</span> evt<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>evt<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> QCAMERA_SM_EVT_START_PREVIEW<span class="token operator">:</span>
    <span class="token punctuation">{</span>
        rc <span class="token operator">=</span> m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">waitDeferredWork</span><span class="token punctuation">(</span>m_parent<span class="token operator">-</span><span class="token operator">&gt;</span>mParamInitJob<span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token keyword">if</span> <span class="token punctuation">(</span>m_parent<span class="token operator">-</span><span class="token operator">&gt;</span>mPreviewWindow <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            rc <span class="token operator">=</span> m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">preparePreview</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
            		rc <span class="token operator">=</span> <span class="token function">addChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_PREVIEW<span class="token punctuation">)</span><span class="token punctuation">;</span>
            		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
            			<span class="token function">addPreviewChannel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
     
            <span class="token keyword">if</span><span class="token punctuation">(</span>rc <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token comment">// preview window is not set yet, move to previewReady state</span>
                m_state <span class="token operator">=</span> QCAMERA_SM_STATE_PREVIEW_READY<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
            rc <span class="token operator">=</span> m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">preparePreview</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token function">applyDelayedMsgs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                rc <span class="token operator">=</span> m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">startPreview</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">unpreparePreview</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
                    <span class="token comment">// start preview success, move to previewing state</span>
                    m_state <span class="token operator">=</span> QCAMERA_SM_STATE_PREVIEWING<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        result<span class="token punctuation">.</span>status <span class="token operator">=</span> rc<span class="token punctuation">;</span>
        result<span class="token punctuation">.</span>request_api <span class="token operator">=</span> evt<span class="token punctuation">;</span>
        result<span class="token punctuation">.</span>result_type <span class="token operator">=</span> QCAMERA_API_RESULT_TYPE_DEF<span class="token punctuation">;</span>
        m_parent<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">signalAPIResult</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

9.1 addChannel(QCAMERA_CH_TYPE_PREVIEW)

@ hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp

int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
{
switch (ch_type) {
case QCAMERA_CH_TYPE_PREVIEW:
rc = addPreviewChannel();
break;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在 addPreviewChannel() 中
调用 addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,preview_stream_cb_routine, this); 注册preview_stream 回调函数。
回调函数为 preview_stream_cb_routine()

同时设置同步信号回调函数: pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, synchronous_stream_cb_routine);
回调函数为 synchronous_stream_cb_routine()

如果需要获取 raw yuv 的图,则调用rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW, preview_raw_stream_cb_routine,this);
回调函数为 preview_raw_stream_cb_routine()
在回调函数 中会dump 为 yuv 文件

@ hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp
int32_t QCamera2HardwareInterface::addPreviewChannel()
{
    QCameraChannel *pChannel = NULL;
    char value[PROPERTY_VALUE_MAX];
    bool raw_yuv = false;
<span class="token keyword">uint32_t</span> handle <span class="token operator">=</span> <span class="token function">getCamHandleForChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_PREVIEW<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
		handle <span class="token operator">=</span> mCameraHandle<span class="token operator">-</span><span class="token operator">&gt;</span>camera_handle<span class="token punctuation">;</span>
<span class="token comment">// 初始化 QCameraChannel 对象,传递 mCameraHandle-&gt;ops 操作函数,ops 是在构造函数中初始化 </span>
pChannel <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">QCameraChannel</span><span class="token punctuation">(</span>handle<span class="token punctuation">,</span> mCameraHandle<span class="token operator">-</span><span class="token operator">&gt;</span>ops<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 初始化 Channel ,  preview only channel, don't need bundle attr and cb</span>
rc <span class="token operator">=</span> pChannel<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// meta data stream always coexists with preview if applicable</span>
rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_METADATA<span class="token punctuation">,</span> metadata_stream_cb_routine<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isRdiMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isSecureMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"RDI - secure CB"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_RAW<span class="token punctuation">,</span>
                secure_stream_cb_routine<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"RDI - rdi CB"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_RAW<span class="token punctuation">,</span>
                rdi_mode_stream_cb_routine<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isSecureMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"PREVIEW - secure CB"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_PREVIEW<span class="token punctuation">,</span>
                secure_stream_cb_routine<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"PREVIEW - non-secure CB"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">uint32_t</span> cam_type <span class="token operator">=</span> CAM_TYPE_MAIN<span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isDualCamera</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            cam_type <span class="token operator">=</span> <span class="token punctuation">(</span>CAM_TYPE_MAIN <span class="token operator">|</span> CAM_TYPE_AUX<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isNoDisplayMode</span><span class="token punctuation">(</span>cam_type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_PREVIEW<span class="token punctuation">,</span> nodisplay_preview_stream_cb_routine<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
                rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_PREVIEW<span class="token punctuation">,</span>preview_stream_cb_routine<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
                	
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">needSyncCB</span><span class="token punctuation">(</span>CAM_STREAM_TYPE_PREVIEW<span class="token punctuation">)</span> <span class="token operator">==</span> TRUE<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    pChannel<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">setStreamSyncCB</span><span class="token punctuation">(</span>CAM_STREAM_TYPE_PREVIEW<span class="token punctuation">,</span> synchronous_stream_cb_routine<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>mParameters<span class="token punctuation">.</span><span class="token function">fdModeInVideo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>mParameters<span class="token punctuation">.</span><span class="token function">getDcrf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
        <span class="token operator">||</span> <span class="token punctuation">(</span>mParameters<span class="token punctuation">.</span><span class="token function">getRecordingHintValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isSecureMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span> CAM_STREAM_TYPE_ANALYSIS<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.raw_yuv"</span><span class="token punctuation">,</span> value<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
raw_yuv <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token boolean">true</span> <span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span> raw_yuv <span class="token punctuation">)</span> <span class="token punctuation">{</span>
    rc <span class="token operator">=</span> <span class="token function">addStreamToChannel</span><span class="token punctuation">(</span>pChannel<span class="token punctuation">,</span>CAM_STREAM_TYPE_RAW<span class="token punctuation">,</span> preview_raw_stream_cb_routine<span class="token punctuation">,</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

m_channels<span class="token punctuation">[</span>QCAMERA_CH_TYPE_PREVIEW<span class="token punctuation">]</span> <span class="token operator">=</span> pChannel<span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

10. [ HWI ] procEvtPreviewReadyState

由于将状态机切换为 m_state = QCAMERA_SM_STATE_PREVIEW_READY;,所以代码如下:

@ hardware/qcom/camera/QCamera2/HAL/QCameraStateMachine.cpp
int32_t QCameraStateMachine::procEvtPreviewReadyState(qcamera_sm_evt_enum_t evt, void *payload)
{
    LOGL("event (%d)", evt);
    switch (evt) {
    	case QCAMERA_SM_EVT_START_PREVIEW:
        {
            if (m_parent->mPreviewWindow != NULL) {
                rc = m_parent->startPreview();
                if (rc != NO_ERROR) {
                    m_parent->unpreparePreview();
                    m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
                } else {
                    m_state = QCAMERA_SM_STATE_PREVIEWING;
                }
            }
            // no ops here
            rc = NO_ERROR;
            result.status = rc;
            result.request_api = evt;
            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
            m_parent->signalAPIResult(&result);
        }
        break;

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

开始调用 m_parent->startPreview(),同时将状态切换为 m_state = QCAMERA_SM_STATE_PREVIEWING;
m_parent 定义为 QCamera2HardwareInterface *m_parent; // ptr to HWI

10. [ HWI ] QCamera2HardwareInterface::startPreview()

最终调用 startChannel(QCAMERA_CH_TYPE_PREVIEW);

@ hardware/qcom/camera/QCamera2/HAL/QCamera2HWI.cpp
int QCamera2HardwareInterface::startPreview()
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
    int32_t rc = NO_ERROR;
<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"E ZSL = %d Recording Hint = %d"</span><span class="token punctuation">,</span> mParameters<span class="token punctuation">.</span><span class="token function">isZSLMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> mParameters<span class="token punctuation">.</span><span class="token function">getRecordingHintValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">updateThermalLevel</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>mThermalLevel<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">setDisplayFrameSkip</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// start preview stream</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>mParameters<span class="token punctuation">.</span><span class="token function">isZSLMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> mParameters<span class="token punctuation">.</span><span class="token function">getRecordingHintValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    rc <span class="token operator">=</span> <span class="token function">startChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_ZSL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isSecureMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>mParameters<span class="token punctuation">.</span><span class="token function">getSecureStreamType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> CAM_STREAM_TYPE_RAW <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token function">isRdiMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        rc <span class="token operator">=</span> <span class="token function">startChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_RAW<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span>
        rc <span class="token operator">=</span> <span class="token function">startChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_PREVIEW<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    rc <span class="token operator">=</span> <span class="token function">startChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_PREVIEW<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
    	rc <span class="token operator">=</span> m_channels<span class="token punctuation">[</span>ch_type<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isDualCamera</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        mParameters<span class="token punctuation">.</span><span class="token function">setDCDeferCamera</span><span class="token punctuation">(</span>CAM_DEFER_PROCESS<span class="token punctuation">)</span><span class="token punctuation">;</span>
        mParameters<span class="token punctuation">.</span><span class="token function">setDCLowPowerMode</span><span class="token punctuation">(</span>mActiveCameras<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        mParameters<span class="token punctuation">.</span><span class="token function">setDCDeferCamera</span><span class="token punctuation">(</span>CAM_DEFER_FLUSH<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token function">msgTypeEnabled</span><span class="token punctuation">(</span>CAMERA_MSG_PREVIEW_FRAME<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>m_channels<span class="token punctuation">[</span>QCAMERA_CH_TYPE_CALLBACK<span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    rc <span class="token operator">=</span> <span class="token function">startChannel</span><span class="token punctuation">(</span>QCAMERA_CH_TYPE_CALLBACK<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">updatePostPreviewParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
m_stateMachine<span class="token punctuation">.</span><span class="token function">setPreviewCallbackNeeded</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// if job id is non-zero, that means the postproc init job is already</span>
<span class="token comment">// pending or complete</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>mInitPProcJob <span class="token operator">==</span> <span class="token number">0</span><span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">isSecureMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">isRdiMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mInitPProcJob <span class="token operator">=</span> <span class="token function">deferPPInit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
m_bPreviewStarted <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>

<span class="token comment">//configure snapshot skip for dual camera usecases</span>
<span class="token function">configureSnapshotSkip</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"X rc = %d"</span><span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

11. [ HWI ] QCameraChannel

m_channels[QCAMERA_CH_TYPE_PREVIEW]->start() 中,

int32_t QCameraChannel::start()
{
    // there is more than one stream in the channel
    // we need to notify mctl that all streams in this channel need to be bundled
    for (size_t i = 0; i < mStreams.size(); i++) {
        if ((mStreams[i] != NULL) &&(validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
            mStreams[i]->setBundleInfo();
        }
    }
    for (size_t i = 0; i < mStreams.size(); i++) {
        if ((mStreams[i] != NULL) && (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
            mStreams[i]->start();
        }
    }
    rc = m_camOps->start_channel(m_camHandle, m_handle);
	m_bIsActive <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> mStreams<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>mStreams<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            mStreams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">cond_signal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

可以看到 在代码中对每个stream 进行操作:
mStreams[i]->setBundleInfo();
mStreams[i]->start();
m_camOps->start_channel(m_camHandle, m_handle);
mStreams[i]->cond_signal();

我们先来看下有哪些 stream 。
可以看到 ,我们可能有这三个stream : CAM_STREAM_TYPE_METADATACAM_STREAM_TYPE_PREVIEWCAM_STREAM_TYPE_RAW

rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA, metadata_stream_cb_routine, this);

rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,preview_stream_cb_routine, this);
pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW, synchronous_stream_cb_routine);

rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW, preview_raw_stream_cb_routine,this);

12. mm_camera_ops 定义

@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c

/* camera ops v-table */
static mm_camera_ops_t mm_camera_ops = {
.query_capability = mm_camera_intf_query_capability,
.register_event_notify = mm_camera_intf_register_event_notify,
.close_camera = mm_camera_intf_close,
.set_parms = mm_camera_intf_set_parms,
.get_parms = mm_camera_intf_get_parms,
.do_auto_focus = mm_camera_intf_do_auto_focus,
.cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
.prepare_snapshot = mm_camera_intf_prepare_snapshot,
.start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
.stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
.map_buf = mm_camera_intf_map_buf,
.map_bufs = mm_camera_intf_map_bufs,
.unmap_buf = mm_camera_intf_unmap_buf,
.add_channel = mm_camera_intf_add_channel,
.delete_channel = mm_camera_intf_del_channel,
.get_bundle_info = mm_camera_intf_get_bundle_info,
.add_stream = mm_camera_intf_add_stream,
.link_stream = mm_camera_intf_link_stream,
.delete_stream = mm_camera_intf_del_stream,
.config_stream = mm_camera_intf_config_stream,
.qbuf = mm_camera_intf_qbuf,
.cancel_buffer = mm_camera_intf_cancel_buf,
.get_queued_buf_count = mm_camera_intf_get_queued_buf_count,
.map_stream_buf = mm_camera_intf_map_stream_buf,
.map_stream_bufs = mm_camera_intf_map_stream_bufs,
.unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
.set_stream_parms = mm_camera_intf_set_stream_parms,
.get_stream_parms = mm_camera_intf_get_stream_parms,
.start_channel = mm_camera_intf_start_channel,
.stop_channel = mm_camera_intf_stop_channel,
.request_super_buf = mm_camera_intf_request_super_buf,
.cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
.flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
.configure_notify_mode = mm_camera_intf_configure_notify_mode,
.process_advanced_capture = mm_camera_intf_process_advanced_capture,
.get_session_id = mm_camera_intf_get_session_id,
.set_dual_cam_cmd = mm_camera_intf_set_dual_cam_cmd,
.flush = mm_camera_intf_flush,
.register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb,
.register_frame_sync = mm_camera_intf_reg_frame_sync,
.handle_frame_sync_cb = mm_camera_intf_handle_frame_sync_cb
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

13. [ HWI ] QCameraStream

13.1 mStreams[i]->setBundleInfo()

  1. 检查当前 mCamHandle 是否有绑定 stream
@ hardware/qcom/camera/QCamera2/HAL/QCameraStream.cpp
// set bundle for this stream to MCT
int32_t QCameraStream::setBundleInfo()
{
	cam_stream_parm_buffer_t param, aux_param;
    uint32_t active_handle = get_main_camera_handle(mChannelHandle);
    	=====>
    		@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c
    		return mm_camera_util_get_handle_by_num(0, handle);
<span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>bundleInfo<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>bundleInfo<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>active_handle<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// 1. 检查当前 mCamHandle 是否有绑定 stream </span>
    ret <span class="token operator">=</span> mCamOps<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">get_bundle_info</span><span class="token punctuation">(</span>mCamHandle<span class="token punctuation">,</span> active_handle<span class="token punctuation">,</span><span class="token operator">&amp;</span>bundleInfo<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span> 	@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_interface<span class="token punctuation">.</span>c
	<span class="token operator">+</span>	rc <span class="token operator">=</span> <span class="token function">mm_camera_get_bundle_info</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> m_chid<span class="token punctuation">,</span> bundle_info<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>		@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera<span class="token punctuation">.</span>c
	<span class="token operator">+</span>		rc <span class="token operator">=</span> <span class="token function">mm_channel_fsm_fn</span><span class="token punctuation">(</span>ch_obj<span class="token punctuation">,</span>MM_CHANNEL_EVT_GET_BUNDLE_INFO<span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>bundle_info<span class="token punctuation">,</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>			@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_channel<span class="token punctuation">.</span>c
	<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">mm_channel_fsm_fn_stopped</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> evt<span class="token punctuation">,</span> in_val<span class="token punctuation">,</span> out_val<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>			<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>				@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_channel<span class="token punctuation">.</span>c
	<span class="token operator">+</span>				<span class="token keyword">case</span> MM_CHANNEL_EVT_GET_BUNDLE_INFO<span class="token operator">:</span>
	<span class="token operator">+</span>					cam_bundle_config_t <span class="token operator">*</span>payload <span class="token operator">=</span> <span class="token punctuation">(</span>cam_bundle_config_t <span class="token operator">*</span><span class="token punctuation">)</span>in_val<span class="token punctuation">;</span>
    <span class="token operator">+</span>   				rc <span class="token operator">=</span> <span class="token function">mm_channel_get_bundle_info</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> payload<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>    				<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span>    					@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_channel<span class="token punctuation">.</span>c
    <span class="token operator">+</span>    					s_obj <span class="token operator">=</span> <span class="token function">mm_channel_util_get_stream_by_handler</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>streams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>my_hdl<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>    					<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span>    						@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_channel<span class="token punctuation">.</span>c
	<span class="token operator">+</span>						    <span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> MAX_STREAM_NUM_IN_BUNDLE<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token operator">+</span>						        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>MM_STREAM_STATE_NOTUSED <span class="token operator">!=</span> ch_obj<span class="token operator">-</span><span class="token operator">&gt;</span>streams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>state<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
	<span class="token operator">+</span>						            <span class="token punctuation">(</span>handler <span class="token operator">==</span> ch_obj<span class="token operator">-</span><span class="token operator">&gt;</span>streams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>my_hdl<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token operator">+</span>						            s_obj <span class="token operator">=</span> <span class="token operator">&amp;</span>ch_obj<span class="token operator">-</span><span class="token operator">&gt;</span>streams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>						            <span class="token keyword">break</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>						        <span class="token punctuation">}</span>
	<span class="token operator">+</span>						    <span class="token punctuation">}</span>
	<span class="token operator">+</span>						    <span class="token keyword">return</span> s_obj<span class="token punctuation">;</span>
    <span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>                  
    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>param<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>cam_stream_parm_buffer_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    param<span class="token punctuation">.</span>type <span class="token operator">=</span> CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO<span class="token punctuation">;</span>
    param<span class="token punctuation">.</span>bundleInfo <span class="token operator">=</span> bundleInfo<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
mStreamInfo<span class="token operator">-</span><span class="token operator">&gt;</span>parm_buf <span class="token operator">=</span> param<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>aux_param<span class="token punctuation">.</span>bundleInfo<span class="token punctuation">.</span>num_of_streams <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>mStreamInfo<span class="token operator">-</span><span class="token operator">&gt;</span>aux_str_info <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mStreamInfo<span class="token operator">-</span><span class="token operator">&gt;</span>aux_str_info<span class="token operator">-</span><span class="token operator">&gt;</span>parm_buf <span class="token operator">=</span> aux_param<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>mStreamInfo<span class="token operator">-</span><span class="token operator">&gt;</span>parm_buf<span class="token punctuation">.</span>bundleInfo<span class="token punctuation">.</span>num_of_streams <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">uint32_t</span> channelHdl <span class="token operator">=</span> <span class="token function">get_main_camera_handle</span><span class="token punctuation">(</span>mChannelHandle<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">uint32_t</span> streamHdl <span class="token operator">=</span> <span class="token function">get_main_camera_handle</span><span class="token punctuation">(</span>mHandle<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>mCamType <span class="token operator">==</span> CAM_TYPE_AUX<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        channelHdl <span class="token operator">=</span> mChannelHandle<span class="token punctuation">;</span>
        streamHdl <span class="token operator">=</span> mHandle<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    ret <span class="token operator">=</span> mCamOps<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">set_stream_parms</span><span class="token punctuation">(</span>mCamHandle<span class="token punctuation">,</span> channelHdl<span class="token punctuation">,</span> streamHdl<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mStreamInfo<span class="token operator">-</span><span class="token operator">&gt;</span>parm_buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
   	<span class="token operator">+</span> 	@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_interface<span class="token punctuation">.</span>c
    <span class="token operator">+</span>	rc <span class="token operator">=</span> <span class="token function">mm_camera_set_stream_parms</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> chid<span class="token punctuation">,</span> strid<span class="token punctuation">,</span> parms<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span>		@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera<span class="token punctuation">.</span>c
    <span class="token operator">+</span>		rc <span class="token operator">=</span> <span class="token function">mm_channel_fsm_fn</span><span class="token punctuation">(</span>ch_obj<span class="token punctuation">,</span> MM_CHANNEL_EVT_SET_STREAM_PARM<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>payload<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>       <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>   
    <span class="token operator">+</span>         	@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_channel<span class="token punctuation">.</span>c
    <span class="token operator">+</span>         	rc <span class="token operator">=</span> <span class="token function">mm_channel_fsm_fn_stopped</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> evt<span class="token punctuation">,</span> in_val<span class="token punctuation">,</span> out_val<span class="token punctuation">)</span><span class="token punctuation">;</span>      
    <span class="token operator">+</span> 			<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span> 				    <span class="token keyword">case</span> MM_CHANNEL_EVT_GET_STREAM_PARM<span class="token operator">:</span>
	<span class="token operator">+</span>			        <span class="token punctuation">{</span>
	<span class="token operator">+</span>			            mm_evt_paylod_set_get_stream_parms_t <span class="token operator">*</span>payload <span class="token operator">=</span>
	<span class="token operator">+</span>			                <span class="token punctuation">(</span>mm_evt_paylod_set_get_stream_parms_t <span class="token operator">*</span><span class="token punctuation">)</span>in_val<span class="token punctuation">;</span>
	<span class="token operator">+</span>			            rc <span class="token operator">=</span> <span class="token function">mm_channel_get_stream_parm</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> payload<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>			            <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>			            	rc <span class="token operator">=</span> <span class="token function">mm_stream_fsm_fn</span><span class="token punctuation">(</span>s_obj<span class="token punctuation">,</span> MM_STREAM_EVT_GET_PARM<span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>payload<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>			            	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>			            		rc <span class="token operator">=</span> <span class="token function">mm_stream_fsm_inited</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> evt<span class="token punctuation">,</span> in_val<span class="token punctuation">,</span> out_val<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>			            		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>									@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_stream<span class="token punctuation">.</span>c
	<span class="token operator">+</span>			            			rc <span class="token operator">=</span> <span class="token function">mm_stream_get_parm</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> payload<span class="token operator">-</span><span class="token operator">&gt;</span>parms<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>									<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>										rc <span class="token operator">=</span> <span class="token function">mm_camera_util_g_ctrl</span><span class="token punctuation">(</span>cam_obj<span class="token punctuation">,</span> stream_id<span class="token punctuation">,</span> my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">,</span>
	<span class="token operator">+</span>																			CAM_PRIV_STREAM_PARM<span class="token punctuation">,</span> <span class="token operator">&amp;</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>      									<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span> 											@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera<span class="token punctuation">.</span>c
    <span class="token operator">+</span> 											rc <span class="token operator">=</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> VIDIOC_G_CTRL<span class="token punctuation">,</span> <span class="token operator">&amp;</span>control<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>										    <span class="token function">LOGD</span><span class="token punctuation">(</span><span class="token string">"fd=%d, G_CTRL, id=0x%x, rc = %d\n"</span><span class="token punctuation">,</span> fd<span class="token punctuation">,</span> id<span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>										    <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token operator">+</span>										        <span class="token operator">*</span>value <span class="token operator">=</span> control<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
	<span class="token operator">+</span>										    <span class="token punctuation">}</span>			
	<span class="token operator">+</span>											<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>												@ kernel<span class="token operator">/</span>msm<span class="token operator">-</span><span class="token number">4.4</span><span class="token operator">/</span>drivers<span class="token operator">/</span>media<span class="token operator">/</span>v4l2<span class="token operator">-</span>core<span class="token operator">/</span>v4l2<span class="token operator">-</span>subdev<span class="token punctuation">.</span>c
	<span class="token operator">+</span>												<span class="token keyword">static</span> <span class="token keyword">long</span> <span class="token function">subdev_do_ioctl</span><span class="token punctuation">(</span><span class="token keyword">struct</span> file <span class="token operator">*</span>file<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> cmd<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>arg<span class="token punctuation">)</span>
	<span class="token operator">+</span>												<span class="token punctuation">{</span>
	<span class="token operator">+</span>												<span class="token keyword">case</span> VIDIOC_G_CTRL<span class="token operator">:</span>
	<span class="token operator">+</span>													<span class="token keyword">return</span> <span class="token function">v4l2_g_ctrl</span><span class="token punctuation">(</span>vfh<span class="token operator">-</span><span class="token operator">&gt;</span>ctrl_handler<span class="token punctuation">,</span> arg<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>  
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

13.2 mStreams[i]->start()

初始化 mStreamMetaMemory 。

@ hardware/qcom/camera/QCamera2/HAL/QCameraStream.cpp
int32_t QCameraStream::start()
{
    int32_t rc = 0;
    mDataQ.init();
    =============>
    +	@ hardware/qcom/camera/QCamera2/util/QCameraQueue.cpp
    +	m_active = true;
    <=============	
    // 创建 frame线程 ,函数运行 dataProcRoutine
    rc = mProcTh.launch(dataProcRoutine, this);
    =============>
    +	pthread_create(&cmd_pid, NULL, dataProcRoutine, user_data);
	<=============	
mCurMetaMemory <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
mCurBufIndex <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
mCurMetaIndex <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
mFirstTimeStamp <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
memset <span class="token punctuation">(</span><span class="token operator">&amp;</span>mStreamMetaMemory<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>MetaMemory<span class="token punctuation">)</span> <span class="token operator">*</span> CAMERA_MIN_VIDEO_BATCH_BUFFERS<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
13.2.1 Camera 数据处理线程 及 QCameraStream的 Callbak 调用
void *QCameraStream::dataProcRoutine(void *data)
{
    int running = 1;
    QCameraStream *pme = (QCameraStream *)data;
    QCameraCmdThread *cmdThread = &pme->mProcTh;
    cmdThread->setName("CAM_strmDatProc");
    LOGD("E");
    do {
        do {	// 等待消息到来
            ret = cam_sem_wait(&cmdThread->cmd_sem);
        } while (ret != 0);
    <span class="token comment">// we got notified about new cmd avail in cmd queue</span>
    camera_cmd_type_t cmd <span class="token operator">=</span> cmdThread<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">getCmd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">switch</span> <span class="token punctuation">(</span>cmd<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">case</span> CAMERA_CMD_TYPE_DO_NEXT_JOB<span class="token operator">:</span>
        <span class="token punctuation">{</span>
            <span class="token function">LOGD</span><span class="token punctuation">(</span><span class="token string">"Do next job"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">// 当有数据到来时,调用 QCameraStream的 callback 函数,将 frame 上报</span>
            mm_camera_super_buf_t <span class="token operator">*</span>frame <span class="token operator">=</span> <span class="token punctuation">(</span>mm_camera_super_buf_t <span class="token operator">*</span><span class="token punctuation">)</span>pme<span class="token operator">-</span><span class="token operator">&gt;</span>mDataQ<span class="token punctuation">.</span><span class="token function">dequeue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token constant">NULL</span> <span class="token operator">!=</span> frame<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pme<span class="token operator">-</span><span class="token operator">&gt;</span>mDataCB <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    pme<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">mDataCB</span><span class="token punctuation">(</span>frame<span class="token punctuation">,</span> pme<span class="token punctuation">,</span> pme<span class="token operator">-</span><span class="token operator">&gt;</span>mUserData<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
                    <span class="token comment">// no data cb routine, return buf here</span>
                    pme<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">bufDone</span><span class="token punctuation">(</span>frame<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">free</span><span class="token punctuation">(</span>frame<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> CAMERA_CMD_TYPE_EXIT<span class="token operator">:</span>
        <span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"Exit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">/* flush data buf queue */</span>
        pme<span class="token operator">-</span><span class="token operator">&gt;</span>mDataQ<span class="token punctuation">.</span><span class="token function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        running <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">default</span><span class="token operator">:</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>running<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"X"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

13.3 m_camOps->start_channel(m_camHandle, m_handle)

@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c
/* camera ops v-table */
static mm_camera_ops_t mm_camera_ops = {
	 .start_channel = mm_camera_intf_start_channel,
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c
static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
                                            uint32_t ch_id)
{
    int32_t rc = -1;
    mm_camera_obj_t * my_obj = NULL;
    uint32_t chid = get_main_camera_handle(ch_id);
    uint32_t aux_chid = get_aux_camera_handle(ch_id);
<span class="token keyword">if</span> <span class="token punctuation">(</span>chid<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">uint32_t</span> handle <span class="token operator">=</span> <span class="token function">get_main_camera_handle</span><span class="token punctuation">(</span>camera_handle<span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    my_obj <span class="token operator">=</span> <span class="token function">mm_camera_util_get_camera_by_handler</span><span class="token punctuation">(</span>handle<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    	<span class="token comment">// 启动该 channel 中的所有 stream </span>
        rc <span class="token operator">=</span> <span class="token function">mm_camera_start_channel</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> chid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
        <span class="token operator">+</span>	@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera<span class="token punctuation">.</span>c
        <span class="token operator">+</span>	rc <span class="token operator">=</span> <span class="token function">mm_channel_fsm_fn</span><span class="token punctuation">(</span>ch_obj<span class="token punctuation">,</span> MM_CHANNEL_EVT_START<span class="token punctuation">,</span>   <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">+</span>		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
        <span class="token operator">+</span>		@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera<span class="token punctuation">.</span>c
        <span class="token operator">+</span>		<span class="token keyword">case</span> MM_CHANNEL_STATE_STOPPED<span class="token operator">:</span>
    	<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">mm_channel_fsm_fn_stopped</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> evt<span class="token punctuation">,</span> in_val<span class="token punctuation">,</span> out_val<span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token operator">+</span>			<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
    	<span class="token operator">+</span>				@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>stack<span class="token operator">/</span>mm<span class="token operator">-</span>camera<span class="token operator">-</span>interface<span class="token operator">/</span>src<span class="token operator">/</span>mm_camera_channel<span class="token punctuation">.</span>c
    	<span class="token operator">+</span>				<span class="token keyword">case</span> MM_CHANNEL_EVT_START<span class="token operator">:</span><span class="token punctuation">{</span>
        <span class="token operator">+</span>					rc <span class="token operator">=</span> <span class="token function">mm_channel_start</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">+</span>					<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">==</span> rc<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token operator">+</span>    					my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>state <span class="token operator">=</span> MM_CHANNEL_STATE_ACTIVE<span class="token punctuation">;</span>
        <span class="token operator">+</span>					<span class="token punctuation">}</span>
        <span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"X ch_id = %u rc = %d"</span><span class="token punctuation">,</span> ch_id<span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

mm_camera_channel.cmm_channel_start()

  1. 创建 pthread, 名为 “CAM_SuperBuf”
  2. 创建 pthread, 名为 “CAM_SuperBufCB”, 用于处理 stream buf
  3. 创建 streams 对应的 buff
  4. 注册 streams 对应的 buf
  5. 开始 stream
@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_channel.c
int32_t mm_channel_start(mm_channel_t *my_obj)
{
    int32_t rc = 0;
    int i = 0, j = 0;
    mm_stream_t *s_objs[MAX_STREAM_NUM_IN_BUNDLE] = {NULL};
    uint8_t num_streams_to_start = 0;
    uint8_t num_streams_in_bundle_queue = 0;
    mm_stream_t *s_obj = NULL;
    int meta_stream_idx = 0;
    cam_stream_type_t stream_type = CAM_STREAM_TYPE_DEFAULT;
<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> MAX_STREAM_NUM_IN_BUNDLE<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>streams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>my_hdl <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        s_obj <span class="token operator">=</span> <span class="token function">mm_channel_util_get_stream_by_handler</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">,</span> my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>streams<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>my_hdl<span class="token punctuation">)</span><span class="token punctuation">;</span>
      	
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>meta_stream_idx <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">/* always start meta data stream first, so switch the stream object with the first one */</span>
    s_obj <span class="token operator">=</span> s_objs<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    s_objs<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> s_objs<span class="token punctuation">[</span>meta_stream_idx<span class="token punctuation">]</span><span class="token punctuation">;</span>
    s_objs<span class="token punctuation">[</span>meta_stream_idx<span class="token punctuation">]</span> <span class="token operator">=</span> s_obj<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token constant">NULL</span> <span class="token operator">!=</span> my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>super_buf_notify_cb<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">/* need to send up cb, therefore launch thread */</span>
    <span class="token comment">/* init superbuf queue */</span>
    <span class="token function">mm_channel_superbuf_queue_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">)</span><span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>num_streams <span class="token operator">=</span> num_streams_in_bundle_queue<span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>expected_frame_id <span class="token operator">=</span> my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>attr<span class="token punctuation">.</span>user_expected_frame_id<span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>expected_frame_id_without_led <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>led_off_start_frame_id <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>led_on_start_frame_id <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>led_on_num_frames <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>good_frame_id <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>

    <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> num_streams_to_start<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">/* Only bundle streams that belong to the channel */</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>stream_info<span class="token operator">-</span><span class="token operator">&gt;</span>noFrameExpected<span class="token punctuation">)</span> <span class="token operator">||</span><span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>is_frame_shared <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>ch_obj <span class="token operator">==</span> my_obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>ch_obj <span class="token operator">==</span> my_obj<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token comment">/* set bundled flag to streams */</span>
                s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>is_bundled <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>bundled_streams<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>my_hdl<span class="token punctuation">;</span>

            <span class="token keyword">if</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>is_frame_shared <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>ch_obj <span class="token operator">==</span> my_obj<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                mm_stream_t <span class="token operator">*</span>dst_obj <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>master_str_obj <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    dst_obj <span class="token operator">=</span> s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>master_str_obj<span class="token punctuation">;</span>
                <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>aux_str_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    dst_obj <span class="token operator">=</span> s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>aux_str_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>dst_obj<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>bundled_streams<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token operator">|</span><span class="token operator">=</span> dst_obj<span class="token operator">-</span><span class="token operator">&gt;</span>my_hdl<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            j<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// 创建  pthread, 名为 "CAM_SuperBuf"</span>
    <span class="token comment">/* launch cb thread for dispatching super buf through cb */</span>
    <span class="token function">snprintf</span><span class="token punctuation">(</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>cb_thread<span class="token punctuation">.</span>threadName<span class="token punctuation">,</span> THREAD_NAME_SIZE<span class="token punctuation">,</span> <span class="token string">"CAM_SuperBuf"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">mm_camera_cmd_thread_launch</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>cb_thread<span class="token punctuation">,</span> mm_channel_dispatch_super_buf<span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span>my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">// 创建  pthread, 名为 "CAM_SuperBufCB", 用于处理 stream buf</span>
    <span class="token comment">/* launch cmd thread for super buf dataCB */</span>
    <span class="token function">snprintf</span><span class="token punctuation">(</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>cmd_thread<span class="token punctuation">.</span>threadName<span class="token punctuation">,</span> THREAD_NAME_SIZE<span class="token punctuation">,</span> <span class="token string">"CAM_SuperBufCB"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">mm_camera_cmd_thread_launch</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>cmd_thread<span class="token punctuation">,</span> mm_channel_process_stream_buf<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span>my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
    		<span class="token function">pthread_create</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>cmd_thread<span class="token operator">-</span><span class="token operator">&gt;</span>cmd_pid<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> mm_channel_process_stream_buf<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>cmd_thread<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* set flag to TRUE */</span>
    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>is_active <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/* link any streams first before starting the rest of the streams */</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> num_streams_to_start<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>ch_obj <span class="token operator">!=</span> my_obj<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>is_active<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">pthread_mutex_lock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>linked_stream<span class="token operator">-</span><span class="token operator">&gt;</span>buf_lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
        s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>linked_stream<span class="token operator">-</span><span class="token operator">&gt;</span>linked_obj <span class="token operator">=</span> my_obj<span class="token punctuation">;</span>
        s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>linked_stream<span class="token operator">-</span><span class="token operator">&gt;</span>is_linked <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token function">pthread_mutex_unlock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>linked_stream<span class="token operator">-</span><span class="token operator">&gt;</span>buf_lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">continue</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> num_streams_to_start<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>ch_obj <span class="token operator">!=</span> my_obj<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">continue</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">/* all streams within a channel should be started at the same time */</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>state <span class="token operator">==</span> MM_STREAM_STATE_ACTIVE<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">LOGE</span><span class="token punctuation">(</span><span class="token string">"stream already started idx(%d)"</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
        rc <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
	<span class="token comment">// 创建 streams 对应的 buff</span>
    <span class="token comment">/* allocate buf */</span>
    rc <span class="token operator">=</span> <span class="token function">mm_stream_fsm_fn</span><span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> MM_STREAM_EVT_GET_BUF<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">// 注册 streams 对应的 buf</span>
    <span class="token comment">/* reg buf */</span>
    rc <span class="token operator">=</span> <span class="token function">mm_stream_fsm_fn</span><span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> MM_STREAM_EVT_REG_BUF<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">// 开始 stream</span>
    <span class="token comment">/* start stream */</span>
    rc <span class="token operator">=</span> <span class="token function">mm_stream_fsm_fn</span><span class="token punctuation">(</span>s_objs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> MM_STREAM_EVT_START<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
    	<span class="token operator">+</span>	<span class="token function">snprintf</span><span class="token punctuation">(</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>cmd_thread<span class="token punctuation">.</span>threadName<span class="token punctuation">,</span> THREAD_NAME_SIZE<span class="token punctuation">,</span> <span class="token string">"CAM_StrmAppData"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">+</span>    <span class="token function">mm_camera_cmd_thread_launch</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>cmd_thread<span class="token punctuation">,</span> mm_stream_dispatch_app_data<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">+</span>    my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>state <span class="token operator">=</span> MM_STREAM_STATE_ACTIVE<span class="token punctuation">;</span>
        <span class="token operator">+</span>	rc <span class="token operator">=</span> <span class="token function">mm_stream_streamon</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token punctuation">}</span>


my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bWaitForPrepSnapshotDone <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>my_obj<span class="token operator">-</span><span class="token operator">&gt;</span>bundle<span class="token punctuation">.</span>superbuf_queue<span class="token punctuation">.</span>attr<span class="token punctuation">.</span>enable_frame_sync<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"registering Channel obj %p"</span><span class="token punctuation">,</span> my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">mm_frame_sync_register_channel</span><span class="token punctuation">(</span>my_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
SDM660平台上同时兼容外接的AW35615CSR芯片和内置的USB Type-C controller,你需要对SDM660平台的USB Type-C controller驱动程序进行修改,以便同时支持两种控制器。具体的修改步骤如下: 1. 在SDM660平台上加载AW35615CSR芯片的驱动程序,并确保AW35615CSR芯片已经被成功识别。 2. 在SDM660平台上加载USB Type-C controller驱动程序,并确保内置的USB Type-C controller已经被成功识别。 3. 在USB Type-C controller驱动程序中添加对AW35615CSR芯片的支持。具体来说,你需要修改驱动程序中的probe函数,以便在检测到AW35615CSR芯片时将其作为备选controller,并在AW35615CSR芯片不可用时使用内置的USB Type-C controller。具体代码实现可能因驱动程序而异,以下是一个简单的示例: ```c static int usb_tc_probe(struct platform_device *pdev) { struct usb_tc *tc; struct device *dev = &pdev->dev; int ret; tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL); if (!tc) return -ENOMEM; // 检测AW35615CSR芯片是否可用 if (aw35615csr_detect()) tc->type = USB_TC_TYPE_EXTERNAL; else tc->type = USB_TC_TYPE_INTERNAL; // 初始化Type-C controller switch (tc->type) { case USB_TC_TYPE_EXTERNAL: // 初始化外部Type-C controller ret = aw35615csr_tc_init(); if (ret) { dev_err(dev, "failed to initialize external Type-C controller\n"); return ret; } break; case USB_TC_TYPE_INTERNAL: // 初始化内部Type-C controller ret = msm_usb_tc_init(); if (ret) { dev_err(dev, "failed to initialize internal Type-C controller\n"); return ret; } break; default: dev_err(dev, "unsupported Type-C controller type\n"); return -EINVAL; } // 注册Type-C controller tc_set_drvdata(tc, dev); ret = usb_add_tc_dev(dev, tc); if (ret) { dev_err(dev, "failed to register Type-C controller\n"); goto err_tc_exit; } return 0; err_tc_exit: switch (tc->type) { case USB_TC_TYPE_EXTERNAL: aw35615csr_tc_exit(); break; case USB_TC_TYPE_INTERNAL: msm_usb_tc_exit(); break; } return ret; } ``` 在这个示例代码中,我们在probe函数中使用aw35615csr_detect函数来检测AW35615CSR芯片是否可用,如果可用,就将其作为备选controller,并在初始化Type-C controller时使用aw35615csr_tc_init函数初始化AW35615CSR芯片的Type-C controller。如果AW35615CSR芯片不可用,则使用内置的USB Type-C controller,并在初始化Type-C controller时使用msm_usb_tc_init函数初始化内置的USB Type-C controller。 4. 编译和安装修改后的USB Type-C controller驱动程序,并重新启动SDM660平台。在重新启动后,SDM660平台应该可以同时支持内置的USB Type-C controller和外接的AW35615CSR芯片了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值