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