这两天一直在调拍照,由于之前拍照照片的格式只支持VGA以下的,我拿我的pad一看,居然可以支持5M和1.3M,也就是前后摄像头的最大分辨率。这让我想到肯定是软件没做好,有待改善,然后这两天有空,就调了调。终于调出来了,一直卡在死锁状态。
由于软件功底不够,对于锁,没什么概念,还好最后还是搞出来了,过程真是痛苦啊。。
流程如下:
首先cameraservice 会调用 takepicture()。
[cpp] view plain copy print ?
- status_t CameraHardwareStub::takePicture()
- {
- disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
- if (createThread(beginPictureThread, this) == false)
- return UNKNOWN_ERROR;
- return NO_ERROR;
- }
status_t CameraHardwareStub::takePicture()
{
disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
if (createThread(beginPictureThread, this) == false)
return UNKNOWN_ERROR;
return NO_ERROR;
}
[cpp] view plain copy print ?
- int CameraHardwareStub::beginPictureThread(void *cookie)
- {
- CameraHardwareStub *c = (CameraHardwareStub *)cookie;
- return c->pictureThread();
- }
/*static*/ int CameraHardwareStub::beginPictureThread(void *cookie)
{
CameraHardwareStub *c = (CameraHardwareStub *)cookie;
return c->pictureThread();
}
[cpp] view plain copy print ?
- int CameraHardwareStub::pictureThread()
- {
- int picture_width, picture_height;
- mParameters.getPictureSize(&picture_width, &picture_height);
- LOGD("picture size=%dx%d", picture_width, picture_height);
-
- if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
- LOGE("Take Picture COMPRESSED IMAGE");
-
-
-
-
-
-
-
-
-
-
-
- sp<PreviewThread> previewThread;
-
- {
- Mutex::Autolock lock(mLock);
- previewThread = mPreviewThread;
- }
-
- if (previewThread != 0) {
- previewThread->requestExitAndWait();
- Mutex::Autolock lock(mLock);
- mPreviewThread.clear();
- }
-
- mFakeCamera->Uninit();
- mFakeCamera->StopStreaming();
-
- {
- mPictureLock.lock();
- mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mFakeCamera->GrabJpegFrame(picture_width, picture_height), mCallbackCookie);
- mPictureLock.unlock();
- }
- }
- return NO_ERROR;
- }
int CameraHardwareStub::pictureThread()
{
int picture_width, picture_height;
mParameters.getPictureSize(&picture_width, &picture_height);
LOGD("picture size=%dx%d", picture_width, picture_height);
if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
LOGE("Take Picture COMPRESSED IMAGE");
/*
* The takePicture() function called by the CameraService
* must return synchronously without attempting to wait
* for any locks, to prevent circular deadlocking in
* attempting to call CameraService callbacks to deliver
* frames. This includes waiting for the preview thread
* to finish cleanly. So stopping the preview thread
* is done in this separate pictureThread
*/
sp<PreviewThread> previewThread;
{
Mutex::Autolock lock(mLock);
previewThread = mPreviewThread;
}
if (previewThread != 0) {
previewThread->requestExitAndWait();
Mutex::Autolock lock(mLock);
mPreviewThread.clear();
}
mFakeCamera->Uninit();
mFakeCamera->StopStreaming(); //卸载掉preview 内存。
{
mPictureLock.lock();
mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mFakeCamera->GrabJpegFrame(picture_width, picture_height), mCallbackCookie);
mPictureLock.unlock();
}
}
return NO_ERROR;
}
GrabJpegFrame 会具体执行拍照功能。
[cpp] view plain copy print ?
- sp<IMemory> V4L2Camera::GrabJpegFrame (int pic_width, int pic_height)
- {
- FILE *output;
- FILE *input;
- int fileSize;
- int ret, i;
-
- int w, h;
- struct v4l2_buffer v4l2_buf_picture;
- struct v4l2_format format;
- struct v4l2_streamparm parm;
- struct v4l2_requestbuffers reqbuf;
- sp<MemoryHeapBase> rawPictureHeap;
- sp<MemoryHeapBase> mjpegPictureHeap;
- sp<MemoryBase> jpegMemBase;
-
-
- memset(&format, 0, sizeof(format));
- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- format.fmt.pix.width = pic_width;
- format.fmt.pix.height = pic_height;
- format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- if (ioctl(fd, VIDIOC_S_FMT, &format) < 0)
- {
- LOGE("Error: VIDIOC_S_FMT");
- goto done;
- }
-
-
- memset(&parm, 0, sizeof(parm));
- parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- parm.parm.capture.timeperframe.numerator = 2;
- parm.parm.capture.timeperframe.denominator = 15;
- if (ioctl(fd, VIDIOC_S_PARM, &parm) < 0)
- {
- LOGE("Error: VIDIOC_S_PARM");
- goto done;
- }
-
-
- memset(&reqbuf, 0, sizeof(reqbuf));
- reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- reqbuf.memory = V4L2_MEMORY_MMAP;
- reqbuf.count = 1;
- if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0)
- {
- LOGE ("Error: VIDIOC_REQBUFS");
- goto done;
- }
-
- memset(&v4l2_buf_picture, 0, sizeof(v4l2_buf_picture));
- v4l2_buf_picture.index = 0;
- v4l2_buf_picture.type = reqbuf.type;
- if (ioctl(fd, VIDIOC_QUERYBUF, &v4l2_buf_picture) < 0)
- {
- LOGE("Error: VIDIOC_QUERYBUF");
- goto done;
- }
-
-
- rawPictureHeap = new MemoryHeapBase(fd,
- v4l2_buf_picture.length, 0, v4l2_buf_picture.m.offset);
- if (rawPictureHeap == NULL)
- {
- LOGE("Error: Cannot create rawPictureHeap");
- goto done;
- }
-
-
- if (ioctl(fd, VIDIOC_QBUF, &v4l2_buf_picture) < 0)
- {
- LOGE("Error: VIDIOC_QBUF");
- }
- StartStreaming();
-
- for(i = 0; i < PICTURE_FRAME_GRAB_COUNT; i++){
-
- if (ioctl(fd, VIDIOC_DQBUF, &v4l2_buf_picture) < 0){
- LOGE("Error: VIDIOC_DQBUF");
- goto done;
- }
- if((ioctl(fd, VIDIOC_QBUF, &v4l2_buf_picture)) < 0){
- LOGE("Error: VIDIOC_QBUF = %d:%d", ret, errno);
- }
- usleep(50*1000);
- }
-
- output = fopen("/data/tmp.jpg", "wb");
-
- if (output == NULL) {
- LOGE("GrabJpegFrame: Ouput file == NULL");
- return NULL;
- }
-
- fileSize = saveYUYVtoJPEG((unsigned char *)rawPictureHeap->getBase(), pic_width, pic_height, output, 85);
-
- fclose(output);
-
- input = fopen("/data/tmp.jpg", "rb");
-
- if (input == NULL)
- LOGE("GrabJpegFrame: Input file == NULL");
- else {
- mjpegPictureHeap = new MemoryHeapBase(fileSize);
- jpegMemBase = new MemoryBase(mjpegPictureHeap, 0, fileSize);
-
- fread((uint8_t *)mjpegPictureHeap->base(), 1, fileSize, input);
- fclose(input);
-
- rawPictureHeap.clear();
- StopStreaming();
- return jpegMemBase;
- }
-
- done:
- rawPictureHeap.clear();
- StopStreaming();
- return NULL;
- }
-
- int V4L2Camera::saveYUYVtoJPEG (unsigned char *inputBuffer, int width, int height, FILE *file, int quality)
- {
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
- JSAMPROW row_pointer[1];
- unsigned char *line_buffer, *yuyv;
- int z;
- int fileSize;
-
- line_buffer = (unsigned char *) calloc (width * 3, 1);
- yuyv = inputBuffer;
-
- cinfo.err = jpeg_std_error (&jerr);
- jpeg_create_compress (&cinfo);
- jpeg_stdio_dest (&cinfo, file);
-
- LOGI("JPEG PICTURE WIDTH AND HEIGHT: %dx%d", width, height);
-
- cinfo.image_width = width;
- cinfo.image_height = height;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
-
- jpeg_set_defaults (&cinfo);
- jpeg_set_quality (&cinfo, quality, TRUE);
-
- jpeg_start_compress (&cinfo, TRUE);
-
- z = 0;
- while (cinfo.next_scanline < cinfo.image_height) {
- int x;
- unsigned char *ptr = line_buffer;
-
- for (x = 0; x < width; x++) {
- int r, g, b;
- int y, u, v;
-
- if (!z)
- y = yuyv[0] << 8;
- else
- y = yuyv[2] << 8;
-
- u = yuyv[1] - 128;
- v = yuyv[3] - 128;
-
- r = (y + (359 * v)) >> 8;
- g = (y - (88 * u) - (183 * v)) >> 8;
- b = (y + (454 * u)) >> 8;
-
- *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
- *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
- *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
-
- if (z++) {
- z = 0;
- yuyv += 4;
- }
- }
-
- row_pointer[0] = line_buffer;
- jpeg_write_scanlines (&cinfo, row_pointer, 1);
- }
-
- jpeg_finish_compress (&cinfo);
- fileSize = ftell(file);
- jpeg_destroy_compress (&cinfo);
-
- free (line_buffer);
-
- return fileSize;
- }
sp<IMemory> V4L2Camera::GrabJpegFrame (int pic_width, int pic_height)
{
FILE *output;
FILE *input;
int fileSize;
int ret, i;
int w, h;
struct v4l2_buffer v4l2_buf_picture;
struct v4l2_format format;
struct v4l2_streamparm parm;
struct v4l2_requestbuffers reqbuf;
sp<MemoryHeapBase> rawPictureHeap;
sp<MemoryHeapBase> mjpegPictureHeap;
sp<MemoryBase> jpegMemBase;
/* VIDIOC_S_FMT */
memset(&format, 0, sizeof(format));
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = pic_width;
format.fmt.pix.height = pic_height;
format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
if (ioctl(fd, VIDIOC_S_FMT, &format) < 0)
{
LOGE("Error: VIDIOC_S_FMT");
goto done;
}
/* VIDIOC_S_PARM */
memset(&parm, 0, sizeof(parm));
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm.parm.capture.timeperframe.numerator = 2;
parm.parm.capture.timeperframe.denominator = 15;
if (ioctl(fd, VIDIOC_S_PARM, &parm) < 0)
{
LOGE("Error: VIDIOC_S_PARM");
goto done;
}
/* VIDIOC_REQBUFS */
memset(&reqbuf, 0, sizeof(reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
reqbuf.count = 1;
if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0)
{
LOGE ("Error: VIDIOC_REQBUFS");
goto done;
}
memset(&v4l2_buf_picture, 0, sizeof(v4l2_buf_picture));
v4l2_buf_picture.index = 0;
v4l2_buf_picture.type = reqbuf.type;
if (ioctl(fd, VIDIOC_QUERYBUF, &v4l2_buf_picture) < 0)
{
LOGE("Error: VIDIOC_QUERYBUF");
goto done;
}
/* use MemoryHeapBase to do mmap */
rawPictureHeap = new MemoryHeapBase(fd,
v4l2_buf_picture.length, 0, v4l2_buf_picture.m.offset);
if (rawPictureHeap == NULL)
{
LOGE("Error: Cannot create rawPictureHeap");
goto done;
}
/* VIDIOC_QBUF */
if (ioctl(fd, VIDIOC_QBUF, &v4l2_buf_picture) < 0)
{
LOGE("Error: VIDIOC_QBUF");
}
StartStreaming();
for(i = 0; i < PICTURE_FRAME_GRAB_COUNT; i++){
/* get one frame from camera */
if (ioctl(fd, VIDIOC_DQBUF, &v4l2_buf_picture) < 0){
LOGE("Error: VIDIOC_DQBUF");
goto done;
}
if((ioctl(fd, VIDIOC_QBUF, &v4l2_buf_picture)) < 0){
LOGE("Error: VIDIOC_QBUF = %d:%d", ret, errno);
}
usleep(50*1000);
}
output = fopen("/data/tmp.jpg", "wb");
if (output == NULL) {
LOGE("GrabJpegFrame: Ouput file == NULL");
return NULL;
}
fileSize = saveYUYVtoJPEG((unsigned char *)rawPictureHeap->getBase(), pic_width, pic_height, output, 85);
fclose(output);
input = fopen("/data/tmp.jpg", "rb");
if (input == NULL)
LOGE("GrabJpegFrame: Input file == NULL");
else {
mjpegPictureHeap = new MemoryHeapBase(fileSize);
jpegMemBase = new MemoryBase(mjpegPictureHeap, 0, fileSize);
fread((uint8_t *)mjpegPictureHeap->base(), 1, fileSize, input);
fclose(input);
rawPictureHeap.clear();
StopStreaming();
return jpegMemBase;
}
done:
rawPictureHeap.clear();
StopStreaming();
return NULL;
}
int V4L2Camera::saveYUYVtoJPEG (unsigned char *inputBuffer, int width, int height, FILE *file, int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char *line_buffer, *yuyv;
int z;
int fileSize;
line_buffer = (unsigned char *) calloc (width * 3, 1);
yuyv = inputBuffer;
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_compress (&cinfo);
jpeg_stdio_dest (&cinfo, file);
LOGI("JPEG PICTURE WIDTH AND HEIGHT: %dx%d", width, height);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults (&cinfo);
jpeg_set_quality (&cinfo, quality, TRUE);
jpeg_start_compress (&cinfo, TRUE);
z = 0;
while (cinfo.next_scanline < cinfo.image_height) {
int x;
unsigned char *ptr = line_buffer;
for (x = 0; x < width; x++) {
int r, g, b;
int y, u, v;
if (!z)
y = yuyv[0] << 8;
else
y = yuyv[2] << 8;
u = yuyv[1] - 128;
v = yuyv[3] - 128;
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
*(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
*(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
*(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
if (z++) {
z = 0;
yuyv += 4;
}
}
row_pointer[0] = line_buffer;
jpeg_write_scanlines (&cinfo, row_pointer, 1);
}
jpeg_finish_compress (&cinfo);
fileSize = ftell(file);
jpeg_destroy_compress (&cinfo);
free (line_buffer);
return fileSize;
}
下面这个函数,可以查询摄像头模块支持哪些照片的尺寸:
[cpp] view plain copy print ?
- String8 V4L2Camera::GetSupportPictureSize(int fd, int pixelformat, int &w, int &h)
- {
- LOGD("%s", __func__);
- String8 size_list;
- struct v4l2_frmsizeenum framesize_enum;
- memset(&framesize_enum, 0, sizeof(framesize_enum));
- framesize_enum.index = 0;
- framesize_enum.pixel_format = pixelformat;
- int ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &framesize_enum);
- if (ret < 0) {
- LOGE("Error: VIDIOC_ENUM_FRAMESIZES - %s", strerror(errno));
- return size_list;
- }
- switch(framesize_enum.type)
- {
- case V4L2_FRMSIZE_TYPE_DISCRETE:
- do {
- if (framesize_enum.index) {
- w = framesize_enum.discrete.width;
- h = framesize_enum.discrete.height;
- }
- size_list.appendFormat(
- framesize_enum.index ? ",%dx%d" : "%dx%d",
- framesize_enum.discrete.width,
- framesize_enum.discrete.height);
- framesize_enum.index++;
- ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &framesize_enum);
- } while (ret >= 0);
- LOGD("Supported sizes string: %s", size_list.string());
- break;
- case V4L2_FRMSIZE_TYPE_STEPWISE:
- case V4L2_FRMSIZE_TYPE_CONTINUOUS:
- LOGD("STEPWISE/CONTINUOUS ignored: %dx%d-%dx%d/%dx%d",
- framesize_enum.stepwise.min_width,
- framesize_enum.stepwise.min_height,
- framesize_enum.stepwise.max_width,
- framesize_enum.stepwise.max_height,
- framesize_enum.stepwise.step_width,
- framesize_enum.stepwise.step_height);
- break;
- default:
- LOGE("Unknown format type: %d!!!", framesize_enum.type);
- }
- return size_list;
- }
camera recording流程
分类: Camera
2012-07-03 10:24
140人阅读
收藏
举报
开始app调用到cameraservices
[cpp] view plain copy print ?
-
-
- status_t CameraService::Client::startRecording() {
- LOG1("startRecording (pid %d)", getCallingPid());
- return startCameraMode(CAMERA_RECORDING_MODE);
- }
-
-
-
- status_t CameraService::Client::startCameraMode(camera_mode mode) {
- LOG1("startCameraMode(%d)", mode);
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- switch(mode) {
- case CAMERA_PREVIEW_MODE:
- if (mSurface == 0) {
- LOG1("mSurface is not set yet.");
-
-
- }
- return startPreviewMode();
- case CAMERA_RECORDING_MODE:
- if (mSurface == 0) {
- LOGE("mSurface must be set before startRecordingMode.");
- return INVALID_OPERATION;
- }
- return startRecordingMode();
- default:
- return UNKNOWN_ERROR;
- }
- }
// start recording mode
status_t CameraService::Client::startRecording() {
LOG1("startRecording (pid %d)", getCallingPid());
return startCameraMode(CAMERA_RECORDING_MODE);
}
// start preview or recording
status_t CameraService::Client::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
switch(mode) {
case CAMERA_PREVIEW_MODE:
if (mSurface == 0) {
LOG1("mSurface is not set yet.");
// still able to start preview in this case.
}
return startPreviewMode();
case CAMERA_RECORDING_MODE:
if (mSurface == 0) {
LOGE("mSurface must be set before startRecordingMode.");
return INVALID_OPERATION;
}
return startRecordingMode();
default:
return UNKNOWN_ERROR;
}
}
[cpp] view plain copy print ?
- status_t CameraService::Client::startRecordingMode() {
- LOG1("startRecordingMode");
- status_t result = NO_ERROR;
-
-
-
- if (mHardware->recordingEnabled()) {
- return NO_ERROR;
- }
-
-
-
- if (!mHardware->previewEnabled()) {
- result = startPreviewMode();
- if (result != NO_ERROR) {
- return result;
- }
- }
-
-
-
- enableMsgType(CAMERA_MSG_VIDEO_FRAME);
- mCameraService->playSound(SOUND_RECORDING);
- result = mHardware->startRecording();
- if (result != NO_ERROR) {
- LOGE("mHardware->startRecording() failed with status %d", result);
- }
- return result;
- }
status_t CameraService::Client::startRecordingMode() {
LOG1("startRecordingMode");
status_t result = NO_ERROR;
// if recording has been enabled, nothing needs to be done
if (mHardware->recordingEnabled()) {
return NO_ERROR;
}
// if preview has not been started, start preview first
if (!mHardware->previewEnabled()) {
result = startPreviewMode();
if (result != NO_ERROR) {
return result;
}
}
// start recording mode
enableMsgType(CAMERA_MSG_VIDEO_FRAME);
mCameraService->playSound(SOUND_RECORDING);
result = mHardware->startRecording(); //调用hal recording.
if (result != NO_ERROR) {
LOGE("mHardware->startRecording() failed with status %d", result);
}
return result;
}
调用HAL 层的 previewthread 线程:
[cpp] view plain copy print ?
- if (mRecordRunning == true && mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) {
- 263 yuyv422_to_yuv420sp((unsigned char *)rawFramePointer,
- 264 (unsigned char *)mRecordingHeap->getBase(),
- 265 preview_width, preview_height);
- 266 LOGE(" ------- mRecordRunning --------");
- 267 mDataCbTimestamp(systemTime(SYSTEM_TIME_MONOTONIC), CAMERA_MSG_VIDEO_FRAME, mRecordingBuffer, mCallbackCookie);
- 268 }
if (mRecordRunning == true && mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) {
263 yuyv422_to_yuv420sp((unsigned char *)rawFramePointer,
264 (unsigned char *)mRecordingHeap->getBase(),
265 preview_width, preview_height);
266 LOGE(" ------- mRecordRunning --------");
267 mDataCbTimestamp(systemTime(SYSTEM_TIME_MONOTONIC), CAMERA_MSG_VIDEO_FRAME, mRecordingBuffer, mCallbackCookie);
268 }
使用回调函数: 回调到cameraservices .
[cpp] view plain copy print ?
- void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp,
- int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
- LOG2("dataCallbackTimestamp(%d)", msgType);
-
- sp<Client> client = getClientFromCookie(user);
- if (client == 0) return;
- if (!client->lockIfMessageWanted(msgType)) return;
-
- if (dataPtr == 0) {
- LOGE("Null data returned in data with timestamp callback");
- client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
- return;
- }
-
- client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
- }
void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp,
int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
LOG2("dataCallbackTimestamp(%d)", msgType);
sp<Client> client = getClientFromCookie(user);
if (client == 0) return;
if (!client->lockIfMessageWanted(msgType)) return;
if (dataPtr == 0) {
LOGE("Null data returned in data with timestamp callback");
client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
return;
}
client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
}
数据传给
client->handleGenericDataTimestamp(timestamp, msgType, dataPtr)
[cpp] view plain copy print ?
- void CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
- int32_t msgType, const sp<IMemory>& dataPtr) {
- sp<ICameraClient> c = mCameraClient;
- mLock.unlock();
- if (c != 0) {
- c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
- }
- }
void CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
int32_t msgType, const sp<IMemory>& dataPtr) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
}
}
传给 frameworks/base/libs/camera/Camera.cpp
[cpp] view plain copy print ?
-
-
- void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
- {
- sp<CameraListener> listener;
- {
- Mutex::Autolock _l(mLock);
- listener = mListener;
- }
- if (listener != NULL) {
- listener->postDataTimestamp(timestamp, msgType, dataPtr);
- }
- }
// callback from camera service when timestamped frame is ready
void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
listener = mListener;
}
if (listener != NULL) {
listener->postDataTimestamp(timestamp, msgType, dataPtr);
}
}
调用到 frameworks/base/media/libstagefright/CameraSource.cpp
frameworks/base/libs/camera/ICameraClient.cpp