From a361483bb5dbd3bbf132c5b99b2df7d197c3fc50 Mon Sep 17 00:00:00 2001 From: Pannag Sanketi Date: Thu, 14 Jul 2011 14:37:47 -0700 Subject: Adding Metadata mode to SurfaceMediaSource SurfaceMediaSource operates in metadata mode only, i.e. just the metadata is stored in videobuffers. SurfaceMediaSource passes the Gralloc buffer handle along with a 4 byte 'type' (indicating that the metadata is of type GrallocSource) to the encoder as opposed to the GrallocBuffer itself. Related to bug id: 4529323 Change-Id: I83aebc0dd10f317658cdf70be5802dfc35a1e72d --- media/libstagefright/SurfaceMediaSource.cpp | 50 +++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'media/libstagefright/SurfaceMediaSource.cpp') diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index ecacf64..1e682c3 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -715,9 +716,9 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer, mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer; mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp; - // Pass the data to the MediaBuffer - // TODO: Change later to pass in only the metadata - *buffer = new MediaBuffer(mCurrentBuf); + // Pass the data to the MediaBuffer. Pass in only the metadata + passMetadataBufferLocked(buffer); + (*buffer)->setObserver(this); (*buffer)->add_ref(); (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp); @@ -725,6 +726,34 @@ 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) { + LOGV("passMetadataBuffer"); + // MediaBuffer allocates and owns this data + MediaBuffer *tempBuffer = + new MediaBuffer(4 + sizeof(buffer_handle_t)); + char *data = (char *)tempBuffer->data(); + if (data == NULL) { + LOGE("Cannot allocate memory for passing buffer metadata!"); + return; + } + OMX_U32 type = kMetadataBufferTypeGrallocSource; + memcpy(data, &type, 4); + memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t)); + *buffer = tempBuffer; +} + + void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { LOGV("signalBufferReturned"); @@ -732,14 +761,13 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { Mutex::Autolock autoLock(mMutex); if (!mStarted) { - LOGV("started = false. Nothing to do"); + LOGW("signalBufferReturned: mStarted = false! Nothing to do!"); return; } for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) { - if (mSlots[*it].mGraphicBuffer == buffer->graphicBuffer()) { - LOGV("Buffer %d returned. Setting it 'FREE'. New Queue size = %d", - *it, mQueue.size()-1); + CHECK(mSlots[*it].mGraphicBuffer != NULL); + if (checkBufferMatchesSlot(*it, buffer)) { mSlots[*it].mBufferState = BufferSlot::FREE; mQueue.erase(it); buffer->setObserver(0); @@ -756,6 +784,14 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { } } +bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) { + LOGV("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 mSlots[slot].mGraphicBuffer->handle == bufferHandle; +} } // end of namespace android -- cgit v1.1