Android P 相机拍照音程序流程 二

10 篇文章 2 订阅

Android P 相机拍照音程序流程 一

Android P 相机拍照音程序流程 二

上一章节中静态分析了相机拍照音流程,本章节中在 CameraService 中添加堆栈信息,动态分析拍照音的流程。

堆栈信息参考: Android 使用 addr2line 查看堆栈信息

文件列表:

  • frameworks\av\services\camera\libcameraservice\api1\client2\CaptureSequencer.cpp
  • frameworks\av\services\camera\libcameraservice\CameraService.cpp

堆栈信息如下图所示:

 

拍照音堆栈定位源码:

Camera  Capturesequencer 的线程调用流程:

// 拍照音程序动态流程
bool CaptureSequencer::threadLoop() 
    currentState = (this->*kStateManagers[currentState])(client);
    CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(sp<Camera2Client> &client) // 函数原型
        shutterNotifyLocked(l.mParameters, client, mMsgType);
        void CaptureSequencer::shutterNotifyLocked(const Parameters &params, const sp<Camera2Client>& client, int msgType) // 函数原型
            client->getCameraService()->playSound(CameraService::SOUND_SHUTTER)
            void CameraService::playSound(sound_kind kind) // 函数原型

源码如下所示

threadLoop

// frameworks\av\services\camera\libcameraservice\api1\client2\CaptureSequencer.cpp
bool CaptureSequencer::threadLoop() {

    sp<Camera2Client> client = mClient.promote();
    if (client == 0) return false;

    CaptureState currentState;
    {
        Mutex::Autolock l(mStateMutex);
        currentState = mCaptureState;
    }

    currentState = (this->*kStateManagers[currentState])(client);

    Mutex::Autolock l(mStateMutex);
    if (currentState != mCaptureState) {
        if (mCaptureState != IDLE) {
            ATRACE_ASYNC_END(kStateNames[mCaptureState], mStateTransitionCount);
        }
        mCaptureState = currentState;
        mStateTransitionCount++;
        if (mCaptureState != IDLE) {
            ATRACE_ASYNC_BEGIN(kStateNames[mCaptureState], mStateTransitionCount);
        }
        ALOGV("Camera %d: New capture state %s",
                client->getCameraId(), kStateNames[mCaptureState]);
        mStateChanged.signal();
    }

    if (mCaptureState == ERROR) {
        ALOGE("Camera %d: Stopping capture sequencer due to error",
                client->getCameraId());
        return false;
    }

    return true;
}

 manageStandardCaptureWait

// frameworks\av\services\camera\libcameraservice\api1\client2\CaptureSequencer.cpp
CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
        sp<Camera2Client> &client) {
    status_t res;
    ATRACE_CALL();
    Mutex::Autolock l(mInputMutex);


    // Wait for shutter callback
    while (!mHalNotifiedShutter) {
        if (mTimeoutCount <= 0) {
            break;
        }
        res = mShutterNotifySignal.waitRelative(mInputMutex, kWaitDuration);
        if (res == TIMED_OUT) {
            mTimeoutCount--;
            return STANDARD_CAPTURE_WAIT;
        }
    }

    if (mHalNotifiedShutter) {
        if (!mShutterNotified) {
            SharedParameters::Lock l(client->getParameters());
            /* warning: this also locks a SharedCameraCallbacks */
            shutterNotifyLocked(l.mParameters, client, mMsgType);
            mShutterNotified = true;
        }
    } else if (mTimeoutCount <= 0) {
        ALOGW("Timed out waiting for shutter notification");
        return DONE;
    }

    // Wait for new metadata result (mNewFrame)
    while (!mNewFrameReceived) {
        res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
        if (res == TIMED_OUT) {
            mTimeoutCount--;
            break;
        }
    }

    // Wait until jpeg was captured by JpegProcessor
    while (mNewFrameReceived && !mNewCaptureReceived) {
        res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
        if (res == TIMED_OUT) {
            mTimeoutCount--;
            break;
        }
    }
    if (mNewCaptureReceived) {
        if (mNewCaptureErrorCnt > kMaxRetryCount) {
            ALOGW("Exceeding multiple retry limit of %d due to buffer drop", kMaxRetryCount);
            return DONE;
        } else if (mNewCaptureErrorCnt > 0) {
            ALOGW("Capture error happened, retry %d...", mNewCaptureErrorCnt);
            mNewCaptureReceived = false;
            return STANDARD_CAPTURE;
        }
    }

    if (mTimeoutCount <= 0) {
        ALOGW("Timed out waiting for capture to complete");
        return DONE;
    }
    if (mNewFrameReceived && mNewCaptureReceived) {

        if (mNewFrameId != mCaptureId) {
            ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
                    mCaptureId, mNewFrameId);
        }
        camera_metadata_entry_t entry;
        entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
        if (entry.count == 0) {
            ALOGE("No timestamp field in capture frame!");
        } else if (entry.count == 1) {
            if (entry.data.i64[0] != mCaptureTimestamp) {
                ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 ","
                        " captured buffer %" PRId64,
                        entry.data.i64[0],
                        mCaptureTimestamp);
            }
        } else {
            ALOGE("Timestamp metadata is malformed!");
        }
        client->removeFrameListener(mCaptureId, mCaptureId + 1, this);

        mNewFrameReceived = false;
        mNewCaptureReceived = false;
        return DONE;
    }
    return STANDARD_CAPTURE_WAIT;
}


shutterNotifyLocked

// frameworks\av\services\camera\libcameraservice\api1\client2\CaptureSequencer.cpp
/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
            const sp<Camera2Client>& client, int msgType) {
    ATRACE_CALL();

    if (params.state == Parameters::STILL_CAPTURE
        && params.playShutterSound
        && (msgType & CAMERA_MSG_SHUTTER)) {
        // 通过 CameraClient 获取 CameraService 的方法 playSound 播放拍照音
        client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 
    }

    {
        Camera2Client::SharedCameraCallbacks::Lock
            l(client->mSharedCameraCallbacks);

        ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
        if (l.mRemoteCallback != 0) {
            // ShutterCallback
            l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
                                            /*ext1*/0, /*ext2*/0);

            // RawCallback with null buffer
            l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
                                            /*ext1*/0, /*ext2*/0);
        } else {
            ALOGV("%s: No client!", __FUNCTION__);
        }
    }
}

playSound

// frameworks\av\services\camera\libcameraservice\CameraService.cpp
void CameraService::playSound(sound_kind kind) {
    ATRACE_CALL();
	ALOGD("AAAAA bbbplaySound");
	android::CallStack Stack("fengchya");
//	return;
    LOG1("playSound(%d)", kind);
    Mutex::Autolock lock(mSoundLock);
    //!++
    waitloadSoundDone();
    //!--
    sp<MediaPlayer> player = mSoundPlayer[kind];
    if (player != 0) {
        player->seekTo(0);
        player->start();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值