blob: f75b173c1ea99decad8571fdd05bf56d1b7a41f6 [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
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
Andreas Huber20111aa2009-07-14 16:56:47 -070019#include <OMX_Component.h>
20
21#include <binder/IServiceManager.h>
22#include <media/stagefright/CameraSource.h>
Andreas Huber0c891992009-08-26 14:48:20 -070023#include <media/stagefright/MediaDebug.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070024#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) {
Andreas Huber0c891992009-08-26 14:48:20 -070057 CHECK(mSource != NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -070058 mSource->notifyCallback(msgType, ext1, ext2);
59 }
60
61 virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) {
Andreas Huber0c891992009-08-26 14:48:20 -070062 CHECK(mSource != NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -070063 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 *) {
Andreas Huber0c891992009-08-26 14:48:20 -0700129 CHECK(!mStarted);
Andreas Huber20111aa2009-07-14 16:56:47 -0700130
131 status_t err = mCamera->lock();
Andreas Huber0c891992009-08-26 14:48:20 -0700132 CHECK_EQ(err, OK);
Andreas Huber20111aa2009-07-14 16:56:47 -0700133
134 err = mCamera->setPreviewDisplay(new DummySurface);
Andreas Huber0c891992009-08-26 14:48:20 -0700135 CHECK_EQ(err, OK);
Andreas Huber20111aa2009-07-14 16:56:47 -0700136 mCamera->setPreviewCallbackFlag(1);
137 mCamera->startPreview();
Andreas Huber0c891992009-08-26 14:48:20 -0700138 CHECK_EQ(err, OK);
Andreas Huber20111aa2009-07-14 16:56:47 -0700139
140 mStarted = true;
141
142 return OK;
143}
144
145status_t CameraSource::stop() {
Andreas Huber0c891992009-08-26 14:48:20 -0700146 CHECK(mStarted);
Andreas Huber20111aa2009-07-14 16:56:47 -0700147
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, "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) {
Andreas Huber0c891992009-08-26 14:48:20 -0700168 CHECK(mStarted);
Andreas Huber20111aa2009-07-14 16:56:47 -0700169
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
203void CameraSource::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
204 printf("notifyCallback %d, %d, %d\n", msgType, ext1, ext2);
205}
206
207void 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
214void 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