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