CameraSource.cpp revision 03b268eac37ca2589bfff0bf58daf79d29cc14f4
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <sys/time.h> 18 19#include <OMX_Component.h> 20 21#include <binder/IServiceManager.h> 22#include <cutils/properties.h> // for property_get 23#include <media/stagefright/CameraSource.h> 24#include <media/stagefright/MediaDebug.h> 25#include <media/stagefright/MediaDefs.h> 26#include <media/stagefright/MediaErrors.h> 27#include <media/stagefright/MetaData.h> 28#include <camera/Camera.h> 29#include <camera/CameraParameters.h> 30#include <ui/GraphicBuffer.h> 31#include <ui/Overlay.h> 32#include <surfaceflinger/ISurface.h> 33#include <utils/String8.h> 34 35namespace android { 36 37static int64_t getNowUs() { 38 struct timeval tv; 39 gettimeofday(&tv, NULL); 40 41 return (int64_t)tv.tv_usec + tv.tv_sec * 1000000; 42} 43 44struct DummySurface : public BnSurface { 45 DummySurface() {} 46 47 virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) { 48 return NULL; 49 } 50 51 virtual status_t registerBuffers(const BufferHeap &buffers) { 52 return OK; 53 } 54 55 virtual void postBuffer(ssize_t offset) {} 56 virtual void unregisterBuffers() {} 57 58 virtual sp<OverlayRef> createOverlay( 59 uint32_t w, uint32_t h, int32_t format, int32_t orientation) { 60 return NULL; 61 } 62 63protected: 64 virtual ~DummySurface() {} 65 66 DummySurface(const DummySurface &); 67 DummySurface &operator=(const DummySurface &); 68}; 69 70struct CameraSourceListener : public CameraListener { 71 CameraSourceListener(const sp<CameraSource> &source); 72 73 virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); 74 virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr); 75 76 virtual void postDataTimestamp( 77 nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); 78 79protected: 80 virtual ~CameraSourceListener(); 81 82private: 83 wp<CameraSource> mSource; 84 85 CameraSourceListener(const CameraSourceListener &); 86 CameraSourceListener &operator=(const CameraSourceListener &); 87}; 88 89CameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 90 : mSource(source) { 91} 92 93CameraSourceListener::~CameraSourceListener() { 94} 95 96void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 97 LOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 98} 99 100void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) { 101 LOGV("postData(%d, ptr:%p, size:%d)", 102 msgType, dataPtr->pointer(), dataPtr->size()); 103 104 sp<CameraSource> source = mSource.promote(); 105 if (source.get() != NULL) { 106 source->dataCallback(msgType, dataPtr); 107 } 108} 109 110void CameraSourceListener::postDataTimestamp( 111 nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 112 LOGV("postDataTimestamp(%lld, %d, ptr:%p, size:%d)", 113 timestamp, msgType, dataPtr->pointer(), dataPtr->size()); 114} 115 116// static 117CameraSource *CameraSource::Create() { 118 sp<Camera> camera = Camera::connect(); 119 120 if (camera.get() == NULL) { 121 return NULL; 122 } 123 124 return new CameraSource(camera); 125} 126 127// static 128CameraSource *CameraSource::CreateFromICamera(const sp<ICamera> &icamera) { 129 sp<Camera> camera = Camera::create(icamera); 130 131 if (camera.get() == NULL) { 132 return NULL; 133 } 134 135 return new CameraSource(camera); 136} 137 138CameraSource::CameraSource(const sp<Camera> &camera) 139 : mCamera(camera), 140 mWidth(0), 141 mHeight(0), 142 mFirstFrameTimeUs(0), 143 mNumFrames(0), 144 mStarted(false) { 145 String8 s = mCamera->getParameters(); 146 printf("params: \"%s\"\n", s.string()); 147 148 CameraParameters params(s); 149 params.getPreviewSize(&mWidth, &mHeight); 150} 151 152CameraSource::~CameraSource() { 153 if (mStarted) { 154 stop(); 155 } 156} 157 158void CameraSource::setPreviewSurface(const sp<ISurface> &surface) { 159 mPreviewSurface = surface; 160} 161 162status_t CameraSource::start(MetaData *) { 163 CHECK(!mStarted); 164 165 mCamera->setListener(new CameraSourceListener(this)); 166 167 status_t err = 168 mCamera->setPreviewDisplay( 169 mPreviewSurface != NULL ? mPreviewSurface : new DummySurface); 170 CHECK_EQ(err, OK); 171 172 mCamera->setPreviewCallbackFlags( 173 FRAME_CALLBACK_FLAG_ENABLE_MASK 174 | FRAME_CALLBACK_FLAG_COPY_OUT_MASK); 175 176 err = mCamera->startPreview(); 177 CHECK_EQ(err, OK); 178 179 mStarted = true; 180 181 return OK; 182} 183 184status_t CameraSource::stop() { 185 CHECK(mStarted); 186 187 mCamera->stopPreview(); 188 189 mStarted = false; 190 191 return OK; 192} 193 194sp<MetaData> CameraSource::getFormat() { 195 sp<MetaData> meta = new MetaData; 196 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 197 meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar); 198 meta->setInt32(kKeyWidth, mWidth); 199 meta->setInt32(kKeyHeight, mHeight); 200 201 return meta; 202} 203 204status_t CameraSource::read( 205 MediaBuffer **buffer, const ReadOptions *options) { 206 CHECK(mStarted); 207 208 *buffer = NULL; 209 210 int64_t seekTimeUs; 211 if (options && options->getSeekTo(&seekTimeUs)) { 212 return ERROR_UNSUPPORTED; 213 } 214 215 sp<IMemory> frame; 216 int64_t frameTime; 217 218 { 219 Mutex::Autolock autoLock(mLock); 220 while (mFrames.empty()) { 221 mFrameAvailableCondition.wait(mLock); 222 } 223 224 frame = *mFrames.begin(); 225 mFrames.erase(mFrames.begin()); 226 227 frameTime = *mFrameTimes.begin(); 228 mFrameTimes.erase(mFrameTimes.begin()); 229 } 230 231 *buffer = new MediaBuffer(frame->size()); 232 memcpy((*buffer)->data(), frame->pointer(), frame->size()); 233 (*buffer)->set_range(0, frame->size()); 234 235 (*buffer)->meta_data()->clear(); 236 (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 237 238 return OK; 239} 240 241void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) { 242 Mutex::Autolock autoLock(mLock); 243 244 int64_t nowUs = getNowUs(); 245 if (mNumFrames == 0) { 246 mFirstFrameTimeUs = nowUs; 247 } 248 ++mNumFrames; 249 250 mFrames.push_back(data); 251 mFrameTimes.push_back(nowUs - mFirstFrameTimeUs); 252 mFrameAvailableCondition.signal(); 253} 254 255} // namespace android 256