summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/stagefright/SurfaceMediaSource.h18
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp100
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");