CameraSource.cpp revision 20111aa043c5f404472bc63b90bc5aad906b1101
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#undef NDEBUG 20#include <assert.h> 21 22#include <OMX_Component.h> 23 24#include <binder/IServiceManager.h> 25#include <media/stagefright/CameraSource.h> 26#include <media/stagefright/MediaErrors.h> 27#include <media/stagefright/MetaData.h> 28#include <ui/ICameraClient.h> 29#include <ui/ICameraService.h> 30#include <ui/Overlay.h> 31#include <utils/String16.h> 32 33namespace android { 34 35class CameraBuffer : public MediaBuffer { 36public: 37 CameraBuffer(const sp<IMemory> &frame) 38 : MediaBuffer(frame->pointer(), frame->size()), 39 mFrame(frame) { 40 } 41 42 sp<IMemory> releaseFrame() { 43 sp<IMemory> frame = mFrame; 44 mFrame.clear(); 45 return frame; 46 } 47 48private: 49 sp<IMemory> mFrame; 50}; 51 52class CameraSourceClient : public BnCameraClient { 53public: 54 CameraSourceClient() 55 : mSource(NULL) { 56 } 57 58 virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { 59 assert(mSource != NULL); 60 mSource->notifyCallback(msgType, ext1, ext2); 61 } 62 63 virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) { 64 assert(mSource != NULL); 65 mSource->dataCallback(msgType, data); 66 } 67 68 void setCameraSource(CameraSource *source) { 69 mSource = source; 70 } 71 72private: 73 CameraSource *mSource; 74}; 75 76class DummySurface : public BnSurface { 77public: 78 DummySurface() {} 79 80 virtual status_t registerBuffers(const BufferHeap &buffers) { 81 return OK; 82 } 83 84 virtual void postBuffer(ssize_t offset) { 85 } 86 87 virtual void unregisterBuffers() { 88 } 89 90 virtual sp<OverlayRef> createOverlay( 91 uint32_t w, uint32_t h, int32_t format) { 92 return NULL; 93 } 94}; 95 96// static 97CameraSource *CameraSource::Create() { 98 sp<IServiceManager> sm = defaultServiceManager(); 99 100 sp<ICameraService> service = 101 interface_cast<ICameraService>( 102 sm->getService(String16("media.camera"))); 103 104 sp<CameraSourceClient> client = new CameraSourceClient; 105 sp<ICamera> camera = service->connect(client); 106 107 CameraSource *source = new CameraSource(camera, client); 108 client->setCameraSource(source); 109 110 return source; 111} 112 113CameraSource::CameraSource( 114 const sp<ICamera> &camera, const sp<ICameraClient> &client) 115 : mCamera(camera), 116 mCameraClient(client), 117 mNumFrames(0), 118 mStarted(false) { 119 printf("params: \"%s\"\n", mCamera->getParameters().string()); 120} 121 122CameraSource::~CameraSource() { 123 if (mStarted) { 124 stop(); 125 } 126 127 mCamera->disconnect(); 128} 129 130status_t CameraSource::start(MetaData *) { 131 assert(!mStarted); 132 133 status_t err = mCamera->lock(); 134 assert(err == OK); 135 136 err = mCamera->setPreviewDisplay(new DummySurface); 137 assert(err == OK); 138 mCamera->setPreviewCallbackFlag(1); 139 mCamera->startPreview(); 140 assert(err == OK); 141 142 mStarted = true; 143 144 return OK; 145} 146 147status_t CameraSource::stop() { 148 assert(mStarted); 149 150 mCamera->stopPreview(); 151 mCamera->unlock(); 152 153 mStarted = false; 154 155 return OK; 156} 157 158sp<MetaData> CameraSource::getFormat() { 159 sp<MetaData> meta = new MetaData; 160 meta->setCString(kKeyMIMEType, "video/raw"); 161 meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar); 162 meta->setInt32(kKeyWidth, 480); 163 meta->setInt32(kKeyHeight, 320); 164 165 return meta; 166} 167 168status_t CameraSource::read( 169 MediaBuffer **buffer, const ReadOptions *options) { 170 assert(mStarted); 171 172 *buffer = NULL; 173 174 int64_t seekTimeUs; 175 if (options && options->getSeekTo(&seekTimeUs)) { 176 return ERROR_UNSUPPORTED; 177 } 178 179 sp<IMemory> frame; 180 181 { 182 Mutex::Autolock autoLock(mLock); 183 while (mFrames.empty()) { 184 mFrameAvailableCondition.wait(mLock); 185 } 186 187 frame = *mFrames.begin(); 188 mFrames.erase(mFrames.begin()); 189 } 190 191 int count = mNumFrames++; 192 193 *buffer = new CameraBuffer(frame); 194 195 (*buffer)->meta_data()->clear(); 196 (*buffer)->meta_data()->setInt32(kKeyTimeScale, 15); 197 (*buffer)->meta_data()->setInt32(kKeyTimeUnits, count); 198 199 (*buffer)->add_ref(); 200 (*buffer)->setObserver(this); 201 202 return OK; 203} 204 205void CameraSource::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { 206 printf("notifyCallback %d, %d, %d\n", msgType, ext1, ext2); 207} 208 209void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) { 210 Mutex::Autolock autoLock(mLock); 211 212 mFrames.push_back(data); 213 mFrameAvailableCondition.signal(); 214} 215 216void CameraSource::signalBufferReturned(MediaBuffer *_buffer) { 217 CameraBuffer *buffer = static_cast<CameraBuffer *>(_buffer); 218 219 mCamera->releaseRecordingFrame(buffer->releaseFrame()); 220 221 buffer->setObserver(NULL); 222 buffer->release(); 223 buffer = NULL; 224} 225 226} // namespace android 227