当前位置:操作系统 > 安卓/Android >>

Android Camera OMX方式Preview完整过程分析

Android Camera OMX方式Preview完整过程分析

在之前的文章中已经说过OMXCameraAdapter的初始化了,为了更好的了解A9和Ducati的数据交互过程,这里很有必要深入研究一下Camera采用OMX方式的Preview过程

这里我们还是从CameraHal开始我们对preview过程的分析吧,因为hal层的preview方法对整个preview过程做了一些很重要的初始化,看看代码吧   @brief Start preview mode.

   @param none

   @todo Update function header with the different errors that are possible


    下面调用的这个方法是我们关注的重点,他实现了很多preview开始前的初始化

/**

   @param none

   @todo Update function header with the different errors that are possible


    这里是我添加的注释,这里这个mPreviewStartInProgress表示camera preview是否正在进行,false则表示不在进行,mDisplayPaused表示camera已经开始显示,只是暂时停止了,这两个状态的检查表明这里是第一次调用preview,初次使用要查询camera匹配的分辨率,所以这里查询获得宽和高,同时保持在外面的全局变量中,以备之后使用

    if ((mPreviewStartInProgress == false) && (mDisplayPaused == false)){

      ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW,( int ) &frame);

      if ( NO_ERROR != ret ){

        CAMHAL_LOGEB("Error: CAMERA_QUERY_RESOLUTION_PREVIEW %d", ret);

        return ret;

      }


      ///Update the current preview width and height

      mPreviewWidth = frame.mWidth;

      mPreviewHeight = frame.mHeight;

    }

    这里我们没有设置preview callback同时也没有使能display adapter,那么我们既没有使用VL4CameraAdapter方式,也没有使用overlay方式,那么OMX方式就是我们唯一的选择了,所以这里让组件进入到Excuting state

    ///If we don't have the preview callback enabled and display adapter,

    if(!mSetPreviewWindowCalled || (mDisplayAdapter.get() == NULL)){

      CAMHAL_LOGD("Preview not started. Preview in progress flag set");

      mPreviewStartInProgress = true;

      ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SWITCH_TO_EXECUTING);

      if ( NO_ERROR != ret ){

        CAMHAL_LOGEB("Error: CAMERA_SWITCH_TO_EXECUTING %d", ret);

        return ret;

      }

      return NO_ERROR;

    }

    这里判断我们使用overlay方式,但是这里其实只是暂停了preview,这里做的工作只是从新开启preview,并且开始preview callback

    if( (mDisplayAdapter.get() != NULL) && ( !mPreviewEnabled ) && ( mDisplayPaused ) )

        {

        CAMHAL_LOGDA("Preview is in paused state");


        mDisplayPaused = false;

        mPreviewEnabled = true;

        if ( NO_ERROR == ret )

            {

            ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);


            if ( NO_ERROR != ret )

                {

                CAMHAL_LOGEB("Display adapter resume failed %x", ret);

                }

            }

        //restart preview callbacks

        if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)

        {

            mAppCallbackNotifier->enableMsgType (CAMERA_MSG_PREVIEW_FRAME);

        }


        signalEndImageCapture();

        return ret;

        }

    获取到属性中的指定的buffer count

    required_buffer_count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));


    ///Allocate the preview buffers<span color:teal;"="" style="word-wrap: break-word; font-size: 10pt;">

    ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count,max_queueble_buffers);


    if ( NO_ERROR != ret )

        {

        CAMHAL_LOGEA("Couldn't allocate buffers for Preview");

        goto error;

        }

    这里其实我一直想不清楚这个MeasurementEnable到底是哪个功能的flag,暂认为是测试数据专用回调吧

    if ( mMeasurementEnabled )

        {

        这里先获取分辨率中的长度

        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA,

                                          ( int ) &frame,

                                          required_buffer_count);

        if ( NO_ERROR != ret )

            {

            return ret;

            }


         ///Allocate the preview data buffers

        ret = allocPreviewDataBufs(frame.mLength, required_buffer_count);

        if ( NO_ERROR != ret ) {

            CAMHAL_LOGEA("Couldn't allocate preview data buffers");

            goto error;

           }


        if ( NO_ERROR == ret )

            {

            desc.mBuffers = mPreviewDataBuffers;

  &

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,