Backout a74bd5095902, Bug 959405 - Please update the Buri Moz-central, 1.3, 1.2 with...
[gecko.git] / dom / camera / GonkCameraSource.cpp
blob778219a9731a442220a0b507a073eabc6ce9d7fc
1 /*
2 * Copyright (C) 2009 The Android Open Source Project
3 * Copyright (C) 2013 Mozilla Foundation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include <base/basictypes.h>
19 #include "nsDebug.h"
20 #define DOM_CAMERA_LOG_LEVEL 3
21 #include "CameraCommon.h"
23 #define CS_LOGD(...) DOM_CAMERA_LOGA(__VA_ARGS__)
24 #define CS_LOGV(...) DOM_CAMERA_LOGI(__VA_ARGS__)
25 #define CS_LOGI(...) DOM_CAMERA_LOGI(__VA_ARGS__)
26 #define CS_LOGW(...) DOM_CAMERA_LOGW(__VA_ARGS__)
27 #define CS_LOGE(...) DOM_CAMERA_LOGE(__VA_ARGS__)
30 #define CS_LOGD(fmt, ...) DOM_CAMERA_LOGA("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
31 #define CS_LOGV(fmt, ...) DOM_CAMERA_LOGI("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
32 #define CS_LOGI(fmt, ...) DOM_CAMERA_LOGI("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
33 #define CS_LOGW(fmt, ...) DOM_CAMERA_LOGW("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
34 #define CS_LOGE(fmt, ...) DOM_CAMERA_LOGE("[%s:%d]" fmt,__FILE__,__LINE__, ## __VA_ARGS__)
36 #include <OMX_Component.h>
37 #include <binder/IPCThreadState.h>
38 #include <media/stagefright/foundation/ADebug.h>
39 #include <media/stagefright/MediaDefs.h>
40 #include <media/stagefright/MediaErrors.h>
41 #include <media/stagefright/MetaData.h>
42 #include <camera/CameraParameters.h>
43 #include <utils/String8.h>
44 #include <cutils/properties.h>
46 #include "GonkCameraSource.h"
47 #include "GonkCameraListener.h"
48 #include "GonkCameraHwMgr.h"
50 using namespace mozilla;
52 namespace android {
54 static const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
56 struct GonkCameraSourceListener : public GonkCameraListener {
57 GonkCameraSourceListener(const sp<GonkCameraSource> &source);
59 virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
60 virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
61 camera_frame_metadata_t *metadata);
63 virtual void postDataTimestamp(
64 nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
66 protected:
67 virtual ~GonkCameraSourceListener();
69 private:
70 wp<GonkCameraSource> mSource;
72 GonkCameraSourceListener(const GonkCameraSourceListener &);
73 GonkCameraSourceListener &operator=(const GonkCameraSourceListener &);
76 GonkCameraSourceListener::GonkCameraSourceListener(const sp<GonkCameraSource> &source)
77 : mSource(source) {
80 GonkCameraSourceListener::~GonkCameraSourceListener() {
83 void GonkCameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
84 CS_LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
87 void GonkCameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
88 camera_frame_metadata_t *metadata) {
89 CS_LOGV("postData(%d, ptr:%p, size:%d)",
90 msgType, dataPtr->pointer(), dataPtr->size());
92 sp<GonkCameraSource> source = mSource.promote();
93 if (source.get() != NULL) {
94 source->dataCallback(msgType, dataPtr);
98 void GonkCameraSourceListener::postDataTimestamp(
99 nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
101 sp<GonkCameraSource> source = mSource.promote();
102 if (source.get() != NULL) {
103 source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
107 static int32_t getColorFormat(const char* colorFormat) {
108 return OMX_COLOR_FormatYUV420SemiPlanar; //XXX nsGonkCameraControl uses only YUV420SemiPlanar
110 if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) {
111 return OMX_COLOR_FormatYUV420Planar;
114 if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) {
115 return OMX_COLOR_FormatYUV422SemiPlanar;
118 if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) {
119 return OMX_COLOR_FormatYUV420SemiPlanar;
122 if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) {
123 return OMX_COLOR_FormatYCbYCr;
126 if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) {
127 return OMX_COLOR_Format16bitRGB565;
130 if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) {
131 return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
133 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
134 if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) {
135 return OMX_COLOR_FormatAndroidOpaque;
137 #endif
138 CS_LOGE("Uknown color format (%s), please add it to "
139 "GonkCameraSource::getColorFormat", colorFormat);
141 CHECK(!"Unknown color format");
144 GonkCameraSource *GonkCameraSource::Create(
145 const sp<GonkCameraHardware>& aCameraHw,
146 Size videoSize,
147 int32_t frameRate,
148 bool storeMetaDataInVideoBuffers) {
150 GonkCameraSource *source = new GonkCameraSource(aCameraHw,
151 videoSize, frameRate,
152 storeMetaDataInVideoBuffers);
153 return source;
156 GonkCameraSource::GonkCameraSource(
157 const sp<GonkCameraHardware>& aCameraHw,
158 Size videoSize,
159 int32_t frameRate,
160 bool storeMetaDataInVideoBuffers)
161 : mCameraHw(aCameraHw),
162 mCameraFlags(0),
163 mNumInputBuffers(0),
164 mVideoFrameRate(-1),
165 mNumFramesReceived(0),
166 mLastFrameTimestampUs(0),
167 mStarted(false),
168 mNumFramesEncoded(0),
169 mTimeBetweenFrameCaptureUs(0),
170 mFirstFrameTimeUs(0),
171 mNumFramesDropped(0),
172 mNumGlitches(0),
173 mGlitchDurationThresholdUs(200000),
174 mCollectStats(false) {
175 mVideoSize.width = -1;
176 mVideoSize.height = -1;
178 mInitCheck = init(
179 videoSize, frameRate,
180 storeMetaDataInVideoBuffers);
181 if (mInitCheck != OK) releaseCamera();
184 status_t GonkCameraSource::initCheck() const {
185 return mInitCheck;
188 //TODO: Do we need to reimplement isCameraAvailable?
191 * Check to see whether the requested video width and height is one
192 * of the supported sizes.
193 * @param width the video frame width in pixels
194 * @param height the video frame height in pixels
195 * @param suppportedSizes the vector of sizes that we check against
196 * @return true if the dimension (width and height) is supported.
198 static bool isVideoSizeSupported(
199 int32_t width, int32_t height,
200 const Vector<Size>& supportedSizes) {
202 CS_LOGV("isVideoSizeSupported");
203 for (size_t i = 0; i < supportedSizes.size(); ++i) {
204 if (width == supportedSizes[i].width &&
205 height == supportedSizes[i].height) {
206 return true;
209 return false;
213 * If the preview and video output is separate, we only set the
214 * the video size, and applications should set the preview size
215 * to some proper value, and the recording framework will not
216 * change the preview size; otherwise, if the video and preview
217 * output is the same, we need to set the preview to be the same
218 * as the requested video size.
222 * Query the camera to retrieve the supported video frame sizes
223 * and also to see whether CameraParameters::setVideoSize()
224 * is supported or not.
225 * @param params CameraParameters to retrieve the information
226 * @@param isSetVideoSizeSupported retunrs whether method
227 * CameraParameters::setVideoSize() is supported or not.
228 * @param sizes returns the vector of Size objects for the
229 * supported video frame sizes advertised by the camera.
231 static void getSupportedVideoSizes(
232 const CameraParameters& params,
233 bool *isSetVideoSizeSupported,
234 Vector<Size>& sizes) {
236 *isSetVideoSizeSupported = true;
237 params.getSupportedVideoSizes(sizes);
238 if (sizes.size() == 0) {
239 CS_LOGD("Camera does not support setVideoSize()");
240 params.getSupportedPreviewSizes(sizes);
241 *isSetVideoSizeSupported = false;
246 * Check whether the camera has the supported color format
247 * @param params CameraParameters to retrieve the information
248 * @return OK if no error.
250 status_t GonkCameraSource::isCameraColorFormatSupported(
251 const CameraParameters& params) {
252 mColorFormat = getColorFormat(params.get(
253 CameraParameters::KEY_VIDEO_FRAME_FORMAT));
254 if (mColorFormat == -1) {
255 return BAD_VALUE;
257 return OK;
261 * Configure the camera to use the requested video size
262 * (width and height) and/or frame rate. If both width and
263 * height are -1, configuration on the video size is skipped.
264 * if frameRate is -1, configuration on the frame rate
265 * is skipped. Skipping the configuration allows one to
266 * use the current camera setting without the need to
267 * actually know the specific values (see Create() method).
269 * @param params the CameraParameters to be configured
270 * @param width the target video frame width in pixels
271 * @param height the target video frame height in pixels
272 * @param frameRate the target frame rate in frames per second.
273 * @return OK if no error.
275 status_t GonkCameraSource::configureCamera(
276 CameraParameters* params,
277 int32_t width, int32_t height,
278 int32_t frameRate) {
279 CS_LOGV("configureCamera");
280 Vector<Size> sizes;
281 bool isSetVideoSizeSupportedByCamera = true;
282 getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes);
283 bool isCameraParamChanged = false;
284 if (width != -1 && height != -1) {
285 if (!isVideoSizeSupported(width, height, sizes)) {
286 CS_LOGE("Video dimension (%dx%d) is unsupported", width, height);
287 return BAD_VALUE;
289 if (isSetVideoSizeSupportedByCamera) {
290 params->setVideoSize(width, height);
291 } else {
292 params->setPreviewSize(width, height);
294 isCameraParamChanged = true;
295 } else if ((width == -1 && height != -1) ||
296 (width != -1 && height == -1)) {
297 // If one and only one of the width and height is -1
298 // we reject such a request.
299 CS_LOGE("Requested video size (%dx%d) is not supported", width, height);
300 return BAD_VALUE;
301 } else { // width == -1 && height == -1
302 // Do not configure the camera.
303 // Use the current width and height value setting from the camera.
306 if (frameRate != -1) {
307 CHECK(frameRate > 0 && frameRate <= 120);
308 const char* supportedFrameRates =
309 params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
310 CHECK(supportedFrameRates != NULL);
311 CS_LOGV("Supported frame rates: %s", supportedFrameRates);
312 char buf[4];
313 snprintf(buf, 4, "%d", frameRate);
314 if (strstr(supportedFrameRates, buf) == NULL) {
315 CS_LOGE("Requested frame rate (%d) is not supported: %s",
316 frameRate, supportedFrameRates);
317 return BAD_VALUE;
320 // The frame rate is supported, set the camera to the requested value.
321 params->setPreviewFrameRate(frameRate);
322 isCameraParamChanged = true;
323 } else { // frameRate == -1
324 // Do not configure the camera.
325 // Use the current frame rate value setting from the camera
328 if (isCameraParamChanged) {
329 // Either frame rate or frame size needs to be changed.
330 if (OK != mCameraHw->PushParameters(*params)) {
331 CS_LOGE("Could not change settings."
332 " Someone else is using camera?");
333 return -EBUSY;
336 return OK;
340 * Check whether the requested video frame size
341 * has been successfully configured or not. If both width and height
342 * are -1, check on the current width and height value setting
343 * is performed.
345 * @param params CameraParameters to retrieve the information
346 * @param the target video frame width in pixels to check against
347 * @param the target video frame height in pixels to check against
348 * @return OK if no error
350 status_t GonkCameraSource::checkVideoSize(
351 const CameraParameters& params,
352 int32_t width, int32_t height) {
354 CS_LOGV("checkVideoSize");
355 // The actual video size is the same as the preview size
356 // if the camera hal does not support separate video and
357 // preview output. In this case, we retrieve the video
358 // size from preview.
359 int32_t frameWidthActual = -1;
360 int32_t frameHeightActual = -1;
361 Vector<Size> sizes;
362 params.getSupportedVideoSizes(sizes);
363 if (sizes.size() == 0) {
364 // video size is the same as preview size
365 params.getPreviewSize(&frameWidthActual, &frameHeightActual);
366 } else {
367 // video size may not be the same as preview
368 params.getVideoSize(&frameWidthActual, &frameHeightActual);
370 if (frameWidthActual < 0 || frameHeightActual < 0) {
371 CS_LOGE("Failed to retrieve video frame size (%dx%d)",
372 frameWidthActual, frameHeightActual);
373 return UNKNOWN_ERROR;
376 // Check the actual video frame size against the target/requested
377 // video frame size.
378 if (width != -1 && height != -1) {
379 if (frameWidthActual != width || frameHeightActual != height) {
380 CS_LOGE("Failed to set video frame size to %dx%d. "
381 "The actual video size is %dx%d ", width, height,
382 frameWidthActual, frameHeightActual);
383 return UNKNOWN_ERROR;
387 // Good now.
388 mVideoSize.width = frameWidthActual;
389 mVideoSize.height = frameHeightActual;
390 return OK;
394 * Check the requested frame rate has been successfully configured or not.
395 * If the target frameRate is -1, check on the current frame rate value
396 * setting is performed.
398 * @param params CameraParameters to retrieve the information
399 * @param the target video frame rate to check against
400 * @return OK if no error.
402 status_t GonkCameraSource::checkFrameRate(
403 const CameraParameters& params,
404 int32_t frameRate) {
406 CS_LOGV("checkFrameRate");
407 int32_t frameRateActual = params.getPreviewFrameRate();
408 if (frameRateActual < 0) {
409 CS_LOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
410 return UNKNOWN_ERROR;
413 // Check the actual video frame rate against the target/requested
414 // video frame rate.
415 if (frameRate != -1 && (frameRateActual - frameRate) != 0) {
416 CS_LOGE("Failed to set preview frame rate to %d fps. The actual "
417 "frame rate is %d", frameRate, frameRateActual);
418 return UNKNOWN_ERROR;
421 // Good now.
422 mVideoFrameRate = frameRateActual;
423 return OK;
427 * Initialize the GonkCameraSource so that it becomes
428 * ready for providing the video input streams as requested.
429 * @param camera the camera object used for the video source
430 * @param cameraId if camera == 0, use camera with this id
431 * as the video source
432 * @param videoSize the target video frame size. If both
433 * width and height in videoSize is -1, use the current
434 * width and heigth settings by the camera
435 * @param frameRate the target frame rate in frames per second.
436 * if it is -1, use the current camera frame rate setting.
437 * @param storeMetaDataInVideoBuffers request to store meta
438 * data or real YUV data in video buffers. Request to
439 * store meta data in video buffers may not be honored
440 * if the source does not support this feature.
442 * @return OK if no error.
444 status_t GonkCameraSource::init(
445 Size videoSize,
446 int32_t frameRate,
447 bool storeMetaDataInVideoBuffers) {
449 CS_LOGV("init");
450 status_t err = OK;
451 //TODO: need to do something here to check the sanity of camera
453 CameraParameters params;
454 mCameraHw->PullParameters(params);
455 if ((err = isCameraColorFormatSupported(params)) != OK) {
456 return err;
459 // Set the camera to use the requested video frame size
460 // and/or frame rate.
461 if ((err = configureCamera(&params,
462 videoSize.width, videoSize.height,
463 frameRate))) {
464 return err;
467 // Check on video frame size and frame rate.
468 CameraParameters newCameraParams;
469 mCameraHw->PullParameters(newCameraParams);
470 if ((err = checkVideoSize(newCameraParams,
471 videoSize.width, videoSize.height)) != OK) {
472 return err;
474 if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) {
475 return err;
478 // By default, do not store metadata in video buffers
479 mIsMetaDataStoredInVideoBuffers = false;
480 mCameraHw->StoreMetaDataInBuffers(false);
481 if (storeMetaDataInVideoBuffers) {
482 if (OK == mCameraHw->StoreMetaDataInBuffers(true)) {
483 mIsMetaDataStoredInVideoBuffers = true;
487 int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
488 if (glitchDurationUs > mGlitchDurationThresholdUs) {
489 mGlitchDurationThresholdUs = glitchDurationUs;
492 // XXX: query camera for the stride and slice height
493 // when the capability becomes available.
494 mMeta = new MetaData;
495 mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
496 mMeta->setInt32(kKeyColorFormat, mColorFormat);
497 mMeta->setInt32(kKeyWidth, mVideoSize.width);
498 mMeta->setInt32(kKeyHeight, mVideoSize.height);
499 mMeta->setInt32(kKeyStride, mVideoSize.width);
500 mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
501 mMeta->setInt32(kKeyFrameRate, mVideoFrameRate);
502 return OK;
505 GonkCameraSource::~GonkCameraSource() {
506 if (mStarted) {
507 reset();
508 } else if (mInitCheck == OK) {
509 // Camera is initialized but because start() is never called,
510 // the lock on Camera is never released(). This makes sure
511 // Camera's lock is released in this case.
512 // TODO: Don't think I need to do this
513 releaseCamera();
517 int GonkCameraSource::startCameraRecording() {
518 CS_LOGV("startCameraRecording");
519 return mCameraHw->StartRecording();
522 status_t GonkCameraSource::start(MetaData *meta) {
523 int rv;
525 CS_LOGV("start");
526 CHECK(!mStarted);
527 if (mInitCheck != OK) {
528 CS_LOGE("GonkCameraSource is not initialized yet");
529 return mInitCheck;
532 char value[PROPERTY_VALUE_MAX];
533 if (property_get("media.stagefright.record-stats", value, NULL)
534 && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
535 mCollectStats = true;
538 mStartTimeUs = 0;
539 mNumInputBuffers = 0;
540 if (meta) {
541 int64_t startTimeUs;
542 if (meta->findInt64(kKeyTime, &startTimeUs)) {
543 mStartTimeUs = startTimeUs;
545 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
546 int32_t nBuffers;
547 if (meta->findInt32(kKeyNumBuffers, &nBuffers)) {
548 CHECK_GT(nBuffers, 0);
549 mNumInputBuffers = nBuffers;
551 #endif
554 // Register a listener with GonkCameraHardware so that we can get callbacks
555 mCameraHw->SetListener(new GonkCameraSourceListener(this));
557 rv = startCameraRecording();
559 mStarted = (rv == OK);
560 return rv;
563 void GonkCameraSource::stopCameraRecording() {
564 CS_LOGV("stopCameraRecording");
565 mCameraHw->StopRecording();
568 void GonkCameraSource::releaseCamera() {
569 CS_LOGV("releaseCamera");
572 status_t GonkCameraSource::reset() {
573 CS_LOGD("reset: E");
574 Mutex::Autolock autoLock(mLock);
575 mStarted = false;
576 mFrameAvailableCondition.signal();
578 releaseQueuedFrames();
579 while (!mFramesBeingEncoded.empty()) {
580 if (NO_ERROR !=
581 mFrameCompleteCondition.waitRelative(mLock,
582 mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
583 CS_LOGW("Timed out waiting for outstanding frames being encoded: %d",
584 mFramesBeingEncoded.size());
587 stopCameraRecording();
588 releaseCamera();
590 if (mCollectStats) {
591 CS_LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us",
592 mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
593 mLastFrameTimestampUs - mFirstFrameTimeUs);
596 if (mNumGlitches > 0) {
597 CS_LOGW("%d long delays between neighboring video frames", mNumGlitches);
600 CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
601 CS_LOGD("reset: X");
602 return OK;
605 void GonkCameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
606 CS_LOGV("releaseRecordingFrame");
607 mCameraHw->ReleaseRecordingFrame(frame);
610 void GonkCameraSource::releaseQueuedFrames() {
611 List<sp<IMemory> >::iterator it;
612 while (!mFramesReceived.empty()) {
613 it = mFramesReceived.begin();
614 releaseRecordingFrame(*it);
615 mFramesReceived.erase(it);
616 ++mNumFramesDropped;
620 sp<MetaData> GonkCameraSource::getFormat() {
621 return mMeta;
624 void GonkCameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) {
625 releaseRecordingFrame(frame);
628 void GonkCameraSource::signalBufferReturned(MediaBuffer *buffer) {
629 CS_LOGV("signalBufferReturned: %p", buffer->data());
630 Mutex::Autolock autoLock(mLock);
631 for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
632 it != mFramesBeingEncoded.end(); ++it) {
633 if ((*it)->pointer() == buffer->data()) {
634 releaseOneRecordingFrame((*it));
635 mFramesBeingEncoded.erase(it);
636 ++mNumFramesEncoded;
637 buffer->setObserver(0);
638 buffer->release();
639 mFrameCompleteCondition.signal();
640 return;
643 CHECK(!"signalBufferReturned: bogus buffer");
646 status_t GonkCameraSource::read(
647 MediaBuffer **buffer, const ReadOptions *options) {
648 CS_LOGV("read");
650 *buffer = NULL;
652 int64_t seekTimeUs;
653 ReadOptions::SeekMode mode;
654 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
655 return ERROR_UNSUPPORTED;
658 sp<IMemory> frame;
659 int64_t frameTime;
662 Mutex::Autolock autoLock(mLock);
663 while (mStarted && mFramesReceived.empty()) {
664 if (NO_ERROR !=
665 mFrameAvailableCondition.waitRelative(mLock,
666 mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
667 //TODO: check sanity of camera?
668 CS_LOGW("Timed out waiting for incoming camera video frames: %lld us",
669 mLastFrameTimestampUs);
672 if (!mStarted) {
673 return OK;
675 frame = *mFramesReceived.begin();
676 mFramesReceived.erase(mFramesReceived.begin());
678 frameTime = *mFrameTimes.begin();
679 mFrameTimes.erase(mFrameTimes.begin());
680 mFramesBeingEncoded.push_back(frame);
681 *buffer = new MediaBuffer(frame->pointer(), frame->size());
682 (*buffer)->setObserver(this);
683 (*buffer)->add_ref();
684 (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
686 return OK;
689 void GonkCameraSource::dataCallbackTimestamp(int64_t timestampUs,
690 int32_t msgType, const sp<IMemory> &data) {
691 CS_LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
692 Mutex::Autolock autoLock(mLock);
693 if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
694 CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
695 releaseOneRecordingFrame(data);
696 return;
699 if (mNumFramesReceived > 0) {
700 CHECK(timestampUs > mLastFrameTimestampUs);
701 if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
702 ++mNumGlitches;
706 // May need to skip frame or modify timestamp. Currently implemented
707 // by the subclass CameraSourceTimeLapse.
708 if (skipCurrentFrame(timestampUs)) {
709 releaseOneRecordingFrame(data);
710 return;
713 mLastFrameTimestampUs = timestampUs;
714 if (mNumFramesReceived == 0) {
715 mFirstFrameTimeUs = timestampUs;
716 // Initial delay
717 if (mStartTimeUs > 0) {
718 if (timestampUs < mStartTimeUs) {
719 // Frame was captured before recording was started
720 // Drop it without updating the statistical data.
721 releaseOneRecordingFrame(data);
722 return;
724 mStartTimeUs = timestampUs - mStartTimeUs;
727 ++mNumFramesReceived;
729 CHECK(data != NULL && data->size() > 0);
730 mFramesReceived.push_back(data);
731 int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
732 mFrameTimes.push_back(timeUs);
733 CS_LOGV("initial delay: %lld, current time stamp: %lld",
734 mStartTimeUs, timeUs);
735 mFrameAvailableCondition.signal();
738 bool GonkCameraSource::isMetaDataStoredInVideoBuffers() const {
739 CS_LOGV("isMetaDataStoredInVideoBuffers");
740 return mIsMetaDataStoredInVideoBuffers;
743 } // namespace android