diff options
-rw-r--r-- | include/media/stagefright/SurfaceMediaSource.h | 18 | ||||
-rw-r--r-- | media/libstagefright/SurfaceMediaSource.cpp | 100 |
2 files changed, 58 insertions, 60 deletions
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index e25d444..4a8e221 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -79,10 +79,6 @@ public: MediaBuffer **buffer, const ReadOptions *options = NULL); virtual sp<MetaData> getFormat(); - // Pass the metadata over to the buffer, call when you have the lock - void passMetadataBufferLocked(MediaBuffer **buffer); - bool checkBufferMatchesSlot(int slot, MediaBuffer *buffer); - // Get / Set the frame rate used for encoding. Default fps = 30 status_t setFrameRate(int32_t fps) ; int32_t getFrameRate( ) const; @@ -105,9 +101,6 @@ public: // when a new frame becomes available. void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); - // getCurrentBuffer returns the buffer associated with the current image. - sp<GraphicBuffer> getCurrentBuffer() const; - // dump our state in a String void dump(String8& result) const; void dump(String8& result, const char* prefix, char* buffer, @@ -165,11 +158,12 @@ private: // reset mCurrentTexture to INVALID_BUFFER_SLOT. int mCurrentSlot; - // mCurrentBuf is the graphic buffer of the current slot to be used by - // buffer consumer. It's possible that this buffer is not associated - // with any buffer slot, so we must track it separately in order to - // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept. - sp<GraphicBuffer> mCurrentBuf; + // mCurrentBuffers is a list of the graphic buffers that are being used by + // buffer consumer (i.e. the video encoder). It's possible that these + // buffers are not associated with any buffer slots, so we must track them + // separately. Buffers are added to this list in read, and removed from + // this list in signalBufferReturned + Vector<sp<GraphicBuffer> > mCurrentBuffers; // mCurrentTimestamp is the timestamp for the current texture. It // gets set to mLastQueuedTimestamp each time updateTexImage is called. diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index 5d72a05..300d2fc 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -96,11 +96,6 @@ void SurfaceMediaSource::setFrameAvailableListener( mFrameAvailableListener = listener; } -sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const { - Mutex::Autolock lock(mMutex); - return mCurrentBuf; -} - void SurfaceMediaSource::dump(String8& result) const { char buffer[1024]; @@ -185,6 +180,35 @@ sp<MetaData> SurfaceMediaSource::getFormat() return meta; } +// Pass the data to the MediaBuffer. Pass in only the metadata +// The metadata passed consists of two parts: +// 1. First, there is an integer indicating that it is a GRAlloc +// source (kMetadataBufferTypeGrallocSource) +// 2. This is followed by the buffer_handle_t that is a handle to the +// GRalloc buffer. The encoder needs to interpret this GRalloc handle +// and encode the frames. +// -------------------------------------------------------------- +// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) | +// -------------------------------------------------------------- +// Note: Call only when you have the lock +static void passMetadataBuffer(MediaBuffer **buffer, + buffer_handle_t bufferHandle) { + // MediaBuffer allocates and owns this data + MediaBuffer *tempBuffer = new MediaBuffer(4 + sizeof(buffer_handle_t)); + char *data = (char *)tempBuffer->data(); + if (data == NULL) { + ALOGE("Cannot allocate memory for metadata buffer!"); + return; + } + OMX_U32 type = kMetadataBufferTypeGrallocSource; + memcpy(data, &type, 4); + memcpy(data + 4, &bufferHandle, sizeof(buffer_handle_t)); + *buffer = tempBuffer; + + ALOGV("handle = %p, , offset = %d, length = %d", + bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset()); +} + status_t SurfaceMediaSource::read( MediaBuffer **buffer, const ReadOptions *options) { @@ -251,13 +275,14 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer, if (item.mGraphicBuffer != NULL) { mBufferSlot[mCurrentSlot] = item.mGraphicBuffer; } - mCurrentBuf = mBufferSlot[mCurrentSlot]; + + mCurrentBuffers.push_back(mBufferSlot[mCurrentSlot]); int64_t prevTimeStamp = mCurrentTimestamp; mCurrentTimestamp = item.mTimestamp; mNumFramesEncoded++; // Pass the data to the MediaBuffer. Pass in only the metadata - passMetadataBufferLocked(buffer); + passMetadataBuffer(buffer, mBufferSlot[mCurrentSlot]->handle); (*buffer)->setObserver(this); (*buffer)->add_ref(); @@ -270,34 +295,12 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer, return OK; } -// Pass the data to the MediaBuffer. Pass in only the metadata -// The metadata passed consists of two parts: -// 1. First, there is an integer indicating that it is a GRAlloc -// source (kMetadataBufferTypeGrallocSource) -// 2. This is followed by the buffer_handle_t that is a handle to the -// GRalloc buffer. The encoder needs to interpret this GRalloc handle -// and encode the frames. -// -------------------------------------------------------------- -// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) | -// -------------------------------------------------------------- -// Note: Call only when you have the lock -void SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) { - ALOGV("passMetadataBuffer"); - // MediaBuffer allocates and owns this data - MediaBuffer *tempBuffer = - new MediaBuffer(4 + sizeof(buffer_handle_t)); - char *data = (char *)tempBuffer->data(); - if (data == NULL) { - ALOGE("Cannot allocate memory for metadata buffer!"); - return; - } - OMX_U32 type = kMetadataBufferTypeGrallocSource; - memcpy(data, &type, 4); - memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t)); - *buffer = tempBuffer; - - ALOGV("handle = %p, , offset = %d, length = %d", - mCurrentBuf->handle, (*buffer)->range_length(), (*buffer)->range_offset()); +static buffer_handle_t getMediaBufferHandle(MediaBuffer *buffer) { + // need to convert to char* for pointer arithmetic and then + // copy the byte stream into our handle + buffer_handle_t bufferHandle; + memcpy(&bufferHandle, (char*)(buffer->data()) + 4, sizeof(buffer_handle_t)); + return bufferHandle; } void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { @@ -307,16 +310,26 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { Mutex::Autolock lock(mMutex); - if (mStopped) { - ALOGV("signalBufferReturned: mStopped = true! Nothing to do!"); - return; + buffer_handle_t bufferHandle = getMediaBufferHandle(buffer); + + for (size_t i = 0; i < mCurrentBuffers.size(); i++) { + if (mCurrentBuffers[i]->handle == bufferHandle) { + mCurrentBuffers.removeAt(i); + foundBuffer = true; + break; + } + } + + if (!foundBuffer) { + ALOGW("returned buffer was not found in the current buffer list"); } for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) { if (mBufferSlot[id] == NULL) { continue; } - if (checkBufferMatchesSlot(id, buffer)) { + + if (bufferHandle == mBufferSlot[id]->handle) { ALOGV("Slot %d returned, matches handle = %p", id, mBufferSlot[id]->handle); @@ -335,15 +348,6 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { } } -bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) { - ALOGV("Check if Buffer matches slot"); - // need to convert to char* for pointer arithmetic and then - // copy the byte stream into our handle - buffer_handle_t bufferHandle ; - memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t)); - return mBufferSlot[slot]->handle == bufferHandle; -} - // Part of the BufferQueue::ConsumerListener void SurfaceMediaSource::onFrameAvailable() { ALOGV("onFrameAvailable"); |