1 /*
2  * Copyright (C) 2011 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 //#define LOG_NDEBUG 0
17 #define LOG_TAG "SurfaceMediaSource"
18 
19 #include <inttypes.h>
20 
21 #include <media/stagefright/foundation/ADebug.h>
22 #include <media/stagefright/SurfaceMediaSource.h>
23 #include <media/stagefright/MediaDefs.h>
24 #include <media/stagefright/MetaData.h>
25 #include <OMX_IVCommon.h>
26 #include <media/hardware/HardwareAPI.h>
27 #include <media/hardware/MetadataBufferType.h>
28 
29 #include <ui/GraphicBuffer.h>
30 #include <gui/BufferItem.h>
31 #include <gui/ISurfaceComposer.h>
32 #include <gui/IGraphicBufferAlloc.h>
33 #include <OMX_Component.h>
34 
35 #include <utils/Log.h>
36 #include <utils/String8.h>
37 
38 #include <private/gui/ComposerService.h>
39 
40 namespace android {
41 
SurfaceMediaSource(uint32_t bufferWidth,uint32_t bufferHeight)42 SurfaceMediaSource::SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight) :
43     mWidth(bufferWidth),
44     mHeight(bufferHeight),
45     mCurrentSlot(BufferQueue::INVALID_BUFFER_SLOT),
46     mNumPendingBuffers(0),
47     mCurrentTimestamp(0),
48     mFrameRate(30),
49     mStarted(false),
50     mNumFramesReceived(0),
51     mNumFramesEncoded(0),
52     mFirstFrameTimestamp(0),
53     mMaxAcquiredBufferCount(4),  // XXX double-check the default
54     mUseAbsoluteTimestamps(false) {
55     ALOGV("SurfaceMediaSource");
56 
57     if (bufferWidth == 0 || bufferHeight == 0) {
58         ALOGE("Invalid dimensions %dx%d", bufferWidth, bufferHeight);
59     }
60 
61     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
62     mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
63     mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
64             GRALLOC_USAGE_HW_TEXTURE);
65 
66     sp<ISurfaceComposer> composer(ComposerService::getComposerService());
67 
68     // Note that we can't create an sp<...>(this) in a ctor that will not keep a
69     // reference once the ctor ends, as that would cause the refcount of 'this'
70     // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
71     // that's what we create.
72     wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
73     sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
74 
75     status_t err = mConsumer->consumerConnect(proxy, false);
76     if (err != NO_ERROR) {
77         ALOGE("SurfaceMediaSource: error connecting to BufferQueue: %s (%d)",
78                 strerror(-err), err);
79     }
80 }
81 
~SurfaceMediaSource()82 SurfaceMediaSource::~SurfaceMediaSource() {
83     ALOGV("~SurfaceMediaSource");
84     CHECK(!mStarted);
85 }
86 
getTimestamp()87 nsecs_t SurfaceMediaSource::getTimestamp() {
88     ALOGV("getTimestamp");
89     Mutex::Autolock lock(mMutex);
90     return mCurrentTimestamp;
91 }
92 
setFrameAvailableListener(const sp<FrameAvailableListener> & listener)93 void SurfaceMediaSource::setFrameAvailableListener(
94         const sp<FrameAvailableListener>& listener) {
95     ALOGV("setFrameAvailableListener");
96     Mutex::Autolock lock(mMutex);
97     mFrameAvailableListener = listener;
98 }
99 
dump(String8 & result) const100 void SurfaceMediaSource::dump(String8& result) const
101 {
102     char buffer[1024];
103     dump(result, "", buffer, 1024);
104 }
105 
dump(String8 & result,const char *,char * buffer,size_t) const106 void SurfaceMediaSource::dump(
107         String8& result,
108         const char* /* prefix */,
109         char* buffer,
110         size_t /* SIZE */) const
111 {
112     Mutex::Autolock lock(mMutex);
113 
114     result.append(buffer);
115     mConsumer->dump(result, "");
116 }
117 
setFrameRate(int32_t fps)118 status_t SurfaceMediaSource::setFrameRate(int32_t fps)
119 {
120     ALOGV("setFrameRate");
121     Mutex::Autolock lock(mMutex);
122     const int MAX_FRAME_RATE = 60;
123     if (fps < 0 || fps > MAX_FRAME_RATE) {
124         return BAD_VALUE;
125     }
126     mFrameRate = fps;
127     return OK;
128 }
129 
metaDataStoredInVideoBuffers() const130 MetadataBufferType SurfaceMediaSource::metaDataStoredInVideoBuffers() const {
131     ALOGV("isMetaDataStoredInVideoBuffers");
132     return kMetadataBufferTypeANWBuffer;
133 }
134 
getFrameRate() const135 int32_t SurfaceMediaSource::getFrameRate( ) const {
136     ALOGV("getFrameRate");
137     Mutex::Autolock lock(mMutex);
138     return mFrameRate;
139 }
140 
start(MetaData * params)141 status_t SurfaceMediaSource::start(MetaData *params)
142 {
143     ALOGV("start");
144 
145     Mutex::Autolock lock(mMutex);
146 
147     CHECK(!mStarted);
148 
149     mStartTimeNs = 0;
150     int64_t startTimeUs;
151     int32_t bufferCount = 0;
152     if (params) {
153         if (params->findInt64(kKeyTime, &startTimeUs)) {
154             mStartTimeNs = startTimeUs * 1000;
155         }
156 
157         if (!params->findInt32(kKeyNumBuffers, &bufferCount)) {
158             ALOGE("Failed to find the advertised buffer count");
159             return UNKNOWN_ERROR;
160         }
161 
162         if (bufferCount <= 1) {
163             ALOGE("bufferCount %d is too small", bufferCount);
164             return BAD_VALUE;
165         }
166 
167         mMaxAcquiredBufferCount = bufferCount;
168     }
169 
170     CHECK_GT(mMaxAcquiredBufferCount, 1);
171 
172     status_t err =
173         mConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBufferCount);
174 
175     if (err != OK) {
176         return err;
177     }
178 
179     mNumPendingBuffers = 0;
180     mStarted = true;
181 
182     return OK;
183 }
184 
setMaxAcquiredBufferCount(size_t count)185 status_t SurfaceMediaSource::setMaxAcquiredBufferCount(size_t count) {
186     ALOGV("setMaxAcquiredBufferCount(%zu)", count);
187     Mutex::Autolock lock(mMutex);
188 
189     CHECK_GT(count, 1);
190     mMaxAcquiredBufferCount = count;
191 
192     return OK;
193 }
194 
setUseAbsoluteTimestamps()195 status_t SurfaceMediaSource::setUseAbsoluteTimestamps() {
196     ALOGV("setUseAbsoluteTimestamps");
197     Mutex::Autolock lock(mMutex);
198     mUseAbsoluteTimestamps = true;
199 
200     return OK;
201 }
202 
stop()203 status_t SurfaceMediaSource::stop()
204 {
205     ALOGV("stop");
206     Mutex::Autolock lock(mMutex);
207 
208     if (!mStarted) {
209         return OK;
210     }
211 
212     mStarted = false;
213     mFrameAvailableCondition.signal();
214 
215     while (mNumPendingBuffers > 0) {
216         ALOGI("Still waiting for %zu buffers to be returned.",
217                 mNumPendingBuffers);
218 
219 #if DEBUG_PENDING_BUFFERS
220         for (size_t i = 0; i < mPendingBuffers.size(); ++i) {
221             ALOGI("%d: %p", i, mPendingBuffers.itemAt(i));
222         }
223 #endif
224 
225         mMediaBuffersAvailableCondition.wait(mMutex);
226     }
227 
228     mMediaBuffersAvailableCondition.signal();
229 
230     return mConsumer->consumerDisconnect();
231 }
232 
getFormat()233 sp<MetaData> SurfaceMediaSource::getFormat()
234 {
235     ALOGV("getFormat");
236 
237     Mutex::Autolock lock(mMutex);
238     sp<MetaData> meta = new MetaData;
239 
240     meta->setInt32(kKeyWidth, mWidth);
241     meta->setInt32(kKeyHeight, mHeight);
242     // The encoder format is set as an opaque colorformat
243     // The encoder will later find out the actual colorformat
244     // from the GL Frames itself.
245     meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
246     meta->setInt32(kKeyStride, mWidth);
247     meta->setInt32(kKeySliceHeight, mHeight);
248     meta->setInt32(kKeyFrameRate, mFrameRate);
249     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
250     return meta;
251 }
252 
253 // Pass the data to the MediaBuffer. Pass in only the metadata
254 // Note: Call only when you have the lock
passMetadataBuffer_l(MediaBuffer ** buffer,ANativeWindowBuffer * bufferHandle) const255 void SurfaceMediaSource::passMetadataBuffer_l(MediaBuffer **buffer,
256         ANativeWindowBuffer *bufferHandle) const {
257     *buffer = new MediaBuffer(sizeof(VideoNativeMetadata));
258     VideoNativeMetadata *data = (VideoNativeMetadata *)(*buffer)->data();
259     if (data == NULL) {
260         ALOGE("Cannot allocate memory for metadata buffer!");
261         return;
262     }
263     data->eType = metaDataStoredInVideoBuffers();
264     data->pBuffer = bufferHandle;
265     data->nFenceFd = -1;
266     ALOGV("handle = %p, offset = %zu, length = %zu",
267             bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
268 }
269 
read(MediaBuffer ** buffer,const ReadOptions *)270 status_t SurfaceMediaSource::read(
271         MediaBuffer **buffer, const ReadOptions * /* options */) {
272     ALOGV("read");
273     Mutex::Autolock lock(mMutex);
274 
275     *buffer = NULL;
276 
277     while (mStarted && mNumPendingBuffers == mMaxAcquiredBufferCount) {
278         mMediaBuffersAvailableCondition.wait(mMutex);
279     }
280 
281     // Update the current buffer info
282     // TODO: mCurrentSlot can be made a bufferstate since there
283     // can be more than one "current" slots.
284 
285     BufferItem item;
286     // If the recording has started and the queue is empty, then just
287     // wait here till the frames come in from the client side
288     while (mStarted) {
289 
290         status_t err = mConsumer->acquireBuffer(&item, 0);
291         if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
292             // wait for a buffer to be queued
293             mFrameAvailableCondition.wait(mMutex);
294         } else if (err == OK) {
295             err = item.mFence->waitForever("SurfaceMediaSource::read");
296             if (err) {
297                 ALOGW("read: failed to wait for buffer fence: %d", err);
298             }
299 
300             // First time seeing the buffer?  Added it to the SMS slot
301             if (item.mGraphicBuffer != NULL) {
302                 mSlots[item.mSlot].mGraphicBuffer = item.mGraphicBuffer;
303             }
304             mSlots[item.mSlot].mFrameNumber = item.mFrameNumber;
305 
306             // check for the timing of this buffer
307             if (mNumFramesReceived == 0 && !mUseAbsoluteTimestamps) {
308                 mFirstFrameTimestamp = item.mTimestamp;
309                 // Initial delay
310                 if (mStartTimeNs > 0) {
311                     if (item.mTimestamp < mStartTimeNs) {
312                         // This frame predates start of record, discard
313                         mConsumer->releaseBuffer(
314                                 item.mSlot, item.mFrameNumber, EGL_NO_DISPLAY,
315                                 EGL_NO_SYNC_KHR, Fence::NO_FENCE);
316                         continue;
317                     }
318                     mStartTimeNs = item.mTimestamp - mStartTimeNs;
319                 }
320             }
321             item.mTimestamp = mStartTimeNs + (item.mTimestamp - mFirstFrameTimestamp);
322 
323             mNumFramesReceived++;
324 
325             break;
326         } else {
327             ALOGE("read: acquire failed with error code %d", err);
328             return ERROR_END_OF_STREAM;
329         }
330 
331     }
332 
333     // If the loop was exited as a result of stopping the recording,
334     // it is OK
335     if (!mStarted) {
336         ALOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
337         return ERROR_END_OF_STREAM;
338     }
339 
340     mCurrentSlot = item.mSlot;
341 
342     // First time seeing the buffer?  Added it to the SMS slot
343     if (item.mGraphicBuffer != NULL) {
344         mSlots[item.mSlot].mGraphicBuffer = item.mGraphicBuffer;
345     }
346     mSlots[item.mSlot].mFrameNumber = item.mFrameNumber;
347 
348     mCurrentBuffers.push_back(mSlots[mCurrentSlot].mGraphicBuffer);
349     int64_t prevTimeStamp = mCurrentTimestamp;
350     mCurrentTimestamp = item.mTimestamp;
351 
352     mNumFramesEncoded++;
353     // Pass the data to the MediaBuffer. Pass in only the metadata
354 
355     passMetadataBuffer_l(buffer, mSlots[mCurrentSlot].mGraphicBuffer->getNativeBuffer());
356 
357     (*buffer)->setObserver(this);
358     (*buffer)->add_ref();
359     (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp / 1000);
360     ALOGV("Frames encoded = %d, timestamp = %" PRId64 ", time diff = %" PRId64,
361             mNumFramesEncoded, mCurrentTimestamp / 1000,
362             mCurrentTimestamp / 1000 - prevTimeStamp / 1000);
363 
364     ++mNumPendingBuffers;
365 
366 #if DEBUG_PENDING_BUFFERS
367     mPendingBuffers.push_back(*buffer);
368 #endif
369 
370     ALOGV("returning mbuf %p", *buffer);
371 
372     return OK;
373 }
374 
getMediaBufferHandle(MediaBuffer * buffer)375 static buffer_handle_t getMediaBufferHandle(MediaBuffer *buffer) {
376     // need to convert to char* for pointer arithmetic and then
377     // copy the byte stream into our handle
378     buffer_handle_t bufferHandle;
379     memcpy(&bufferHandle, (char*)(buffer->data()) + 4, sizeof(buffer_handle_t));
380     return bufferHandle;
381 }
382 
signalBufferReturned(MediaBuffer * buffer)383 void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
384     ALOGV("signalBufferReturned");
385 
386     bool foundBuffer = false;
387 
388     Mutex::Autolock lock(mMutex);
389 
390     buffer_handle_t bufferHandle = getMediaBufferHandle(buffer);
391 
392     for (size_t i = 0; i < mCurrentBuffers.size(); i++) {
393         if (mCurrentBuffers[i]->handle == bufferHandle) {
394             mCurrentBuffers.removeAt(i);
395             foundBuffer = true;
396             break;
397         }
398     }
399 
400     if (!foundBuffer) {
401         ALOGW("returned buffer was not found in the current buffer list");
402     }
403 
404     for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) {
405         if (mSlots[id].mGraphicBuffer == NULL) {
406             continue;
407         }
408 
409         if (bufferHandle == mSlots[id].mGraphicBuffer->handle) {
410             ALOGV("Slot %d returned, matches handle = %p", id,
411                     mSlots[id].mGraphicBuffer->handle);
412 
413             mConsumer->releaseBuffer(id, mSlots[id].mFrameNumber,
414                                         EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
415                     Fence::NO_FENCE);
416 
417             buffer->setObserver(0);
418             buffer->release();
419 
420             foundBuffer = true;
421             break;
422         }
423     }
424 
425     if (!foundBuffer) {
426         CHECK(!"signalBufferReturned: bogus buffer");
427     }
428 
429 #if DEBUG_PENDING_BUFFERS
430     for (size_t i = 0; i < mPendingBuffers.size(); ++i) {
431         if (mPendingBuffers.itemAt(i) == buffer) {
432             mPendingBuffers.removeAt(i);
433             break;
434         }
435     }
436 #endif
437 
438     --mNumPendingBuffers;
439     mMediaBuffersAvailableCondition.broadcast();
440 }
441 
442 // Part of the BufferQueue::ConsumerListener
onFrameAvailable(const BufferItem &)443 void SurfaceMediaSource::onFrameAvailable(const BufferItem& /* item */) {
444     ALOGV("onFrameAvailable");
445 
446     sp<FrameAvailableListener> listener;
447     { // scope for the lock
448         Mutex::Autolock lock(mMutex);
449         mFrameAvailableCondition.broadcast();
450         listener = mFrameAvailableListener;
451     }
452 
453     if (listener != NULL) {
454         ALOGV("actually calling onFrameAvailable");
455         listener->onFrameAvailable();
456     }
457 }
458 
459 // SurfaceMediaSource hijacks this event to assume
460 // the prodcuer is disconnecting from the BufferQueue
461 // and that it should stop the recording
onBuffersReleased()462 void SurfaceMediaSource::onBuffersReleased() {
463     ALOGV("onBuffersReleased");
464 
465     Mutex::Autolock lock(mMutex);
466 
467     mFrameAvailableCondition.signal();
468 
469     for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
470        mSlots[i].mGraphicBuffer = 0;
471     }
472 }
473 
onSidebandStreamChanged()474 void SurfaceMediaSource::onSidebandStreamChanged() {
475     ALOG_ASSERT(false, "SurfaceMediaSource can't consume sideband streams");
476 }
477 
478 } // end of namespace android
479