• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 namespace android {
32 
33 class CameraBuffer : public MediaBuffer {
34 public:
CameraBuffer(const sp<IMemory> & frame)35     CameraBuffer(const sp<IMemory> &frame)
36         : MediaBuffer(frame->pointer(), frame->size()),
37           mFrame(frame) {
38     }
39 
releaseFrame()40     sp<IMemory> releaseFrame() {
41         sp<IMemory> frame = mFrame;
42         mFrame.clear();
43         return frame;
44     }
45 
46 private:
47     sp<IMemory> mFrame;
48 };
49 
50 class CameraSourceClient : public BnCameraClient {
51 public:
CameraSourceClient()52     CameraSourceClient()
53         : mSource(NULL) {
54     }
55 
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)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 
dataCallback(int32_t msgType,const sp<IMemory> & data)61     virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) {
62         CHECK(mSource != NULL);
63         mSource->dataCallback(msgType, data);
64     }
65 
setCameraSource(CameraSource * source)66     void setCameraSource(CameraSource *source) {
67         mSource = source;
68     }
69 
70 private:
71     CameraSource *mSource;
72 };
73 
74 class DummySurface : public BnSurface {
75 public:
DummySurface()76     DummySurface() {}
77 
registerBuffers(const BufferHeap & buffers)78     virtual status_t registerBuffers(const BufferHeap &buffers) {
79         return OK;
80     }
81 
postBuffer(ssize_t offset)82     virtual void postBuffer(ssize_t offset) {
83     }
84 
unregisterBuffers()85     virtual void unregisterBuffers() {
86     }
87 
createOverlay(uint32_t w,uint32_t h,int32_t format)88     virtual sp<OverlayRef> createOverlay(
89             uint32_t w, uint32_t h, int32_t format) {
90         return NULL;
91     }
92 };
93 
94 // static
Create()95 CameraSource *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 
CameraSource(const sp<ICamera> & camera,const sp<ICameraClient> & client)111 CameraSource::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 
~CameraSource()120 CameraSource::~CameraSource() {
121     if (mStarted) {
122         stop();
123     }
124 
125     mCamera->disconnect();
126 }
127 
start(MetaData *)128 status_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 
stop()145 status_t CameraSource::stop() {
146     CHECK(mStarted);
147 
148     mCamera->stopPreview();
149     mCamera->unlock();
150 
151     mStarted = false;
152 
153     return OK;
154 }
155 
getFormat()156 sp<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 
read(MediaBuffer ** buffer,const ReadOptions * options)166 status_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()->setInt32(kKeyTimeScale, 15);
195     (*buffer)->meta_data()->setInt32(kKeyTimeUnits, count);
196 
197     (*buffer)->add_ref();
198     (*buffer)->setObserver(this);
199 
200     return OK;
201 }
202 
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)203 void CameraSource::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
204     printf("notifyCallback %d, %d, %d\n", msgType, ext1, ext2);
205 }
206 
dataCallback(int32_t msgType,const sp<IMemory> & data)207 void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) {
208     Mutex::Autolock autoLock(mLock);
209 
210     mFrames.push_back(data);
211     mFrameAvailableCondition.signal();
212 }
213 
signalBufferReturned(MediaBuffer * _buffer)214 void CameraSource::signalBufferReturned(MediaBuffer *_buffer) {
215     CameraBuffer *buffer = static_cast<CameraBuffer *>(_buffer);
216 
217     mCamera->releaseRecordingFrame(buffer->releaseFrame());
218 
219     buffer->setObserver(NULL);
220     buffer->release();
221     buffer = NULL;
222 }
223 
224 }  // namespace android
225