12. 3.CamersSource start
status_t Camera::reconnect()
{
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->connect(this);
}
status_t CameraService::Client::connect(const sp<ICameraClient>& client)
{
mCameraClient = client;
}
Camera
mCamera
RecordingProxy
Camerasource
mCamera
mCamera CameraService::Client
mCameraRecordingproxy x new Camera
mCameraClient
mCamera x
12 /19
13. 3.CamersSource start
status_t Camera::startRecording()
{ void CameraService::Client::dataCallbackTimestamp(..)
sp <ICamera> c = mCamera; {
if (c == 0) return NO_INIT; client->
return c->startRecording(); handleGenericDataTimestamp
} (timestamp, msgType, dataPtr);
}
status_t CameraService::Client::startRecording()
{ void
return startCameraMode(CAMERA_RECORDING_MODE); CameraService::Client::handleGenericDataTimestamp(..)
} {
sp<ICameraClient> c = mCameraClient;
status_t CameraService::Client::startCameraMode(camera_mode mode) c->
{ dataCallbackTimestamp(timestamp, msgType, dataPtr);
case CAMERA_RECORDING_MODE: }
return startRecordingMode();
} Camera.cpp
void Camera::dataCallbackTimestamp(.. dataPtr)
status_t CameraService::Client::startRecordingMode() {
{ proxylistener->
result = mHardware->startRecording(); dataCallbackTimestamp
} (timestamp, msgType, dataPtr);
CameraHardwareinterface.h ->QualcommCamera2.cpp
->QCameraHWI.cpp 를 거쳐서 }
Proxylistener 는 camerasource.cpp 의
QCameraHWI_record.cpp
status_t QCameraStream_record::processRecordFrame(void *data) proxylistener 를 가리킴 .
{
rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
mHalCamCtrl->mRecordingMemory.camera_memory[frame->video.video.idx],
0, mHalCamCtrl->mCallbackCookie);
rcb 는 cameraservice.cpp 의 Client 생성자에서 mHardware->setCallbacks 에 의해
dataCallbackTimestamp 가 등록됨 .
}
13 /19
14. 3.CamersSource start
void CameraSource::ProxyListener::dataCallbackTimestamp( nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
mSource 는 CameraSource class 를 가리킴 .
}
void CameraSource::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, const sp<IMemory> &data)
{
mFramesReceived.push_back(data);
mFrameTimes.push_back(timeUs);
mFrameAvailableCondition.signal();
mFramesReceived vector 에 data 가 채워지면 status_t CameraSource::read 에서 기다리고 있던 mFrameAvailableCondition 에
signal 을 날려 줌 .
}
status_t CameraSource::read(..)
{
mFrameAvailableCondition.waitRelative(mLock, mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)
frame = *mFramesReceived.begin();
*buffer = new MediaBuffer(frame->pointer(), frame->size());
읽은 data 를 MediaBuffer class 로 만들어서 OMXCodec 으로 넘긴다 .
}
OMXCodec.cpp
bool OMXCodec::drainInputBuffer(BufferInfo *info)
{
err = mSource->read(&srcBuffer);
srcBuffer 로 data 를 읽어서
err = mOMX->emptyBuffer(mNode, info->mBuffer, 0, offset,flags, timestampUs);
emptybuffer 에 넣는다 .
14 /19
15. 3.CamersSource start
emptybuffer 가 다 채워지면 omx_message::EMPTY_BUFFER_DONE 가 전달된다 .
void OMXCodec::on_message(const omx_message &msg)
{
case omx_message::EMPTY_BUFFER_DONE:
drainInputBuffer(&buffers->editItemAt(i));
다시 read 를 한 후 emptybuffer 에 채워 넣는다 .
}
emptybuffer 에 채워진 data 가 encoding 이 되어 fillbuffer 에 채워지면 omx_message::FILL_BUFFER_DONE
가 전달된다 .
void OMXCodec::on_message(const omx_message &msg)
{
case omx_message::FILL_BUFFER_DONE:
mFilledBuffers.push_back(i);
mBufferFilled.signal();
OMXCodec::read 의 waitForBufferFilled_l 함수에서 기다리고 있던 mBufferFilled 를 풀어준다 .
}
status_t OMXCodec::read(MediaBuffer **buffer, const ReadOptions *options)
{
waitForBufferFilled_l();
size_t index = *mFilledBuffers.begin();
BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
*buffer = info->mMediaBuffer;
mpeg4wrtier 의 read 로 buffer 를 넘긴다 .
}
status_t MPEG4Writer::Track::threadEntry()
{
while (!mDone && (err = mSource->read(&buffer)) == OK) {
15 /19