Loading include/media/stagefright/MetadataBufferType.h +10 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,16 @@ typedef enum { * kMetadataBufferTypeGrallocSource is used to indicate that * the payload of the metadata buffers can be interpreted as * a buffer_handle_t. * So in this case,the metadata that the encoder receives * will have a byte stream that 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) | * -------------------------------------------------------------- */ kMetadataBufferTypeGrallocSource = 1, Loading include/media/stagefright/SurfaceMediaSource.h +5 −1 Original line number Diff line number Diff line Loading @@ -63,6 +63,10 @@ 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; Loading Loading @@ -152,7 +156,7 @@ public: status_t setBufferCountServer(int bufferCount); // getTimestamp retrieves the timestamp associated with the image // set by the most recent call to updateFrameInfoLocked(). // set by the most recent call to read() // // The timestamp is in nanoseconds, and is monotonically increasing. Its // other semantics (zero point, etc) are source-dependent and should be Loading media/libstagefright/SurfaceMediaSource.cpp +43 −7 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaDebug.h> #include <media/stagefright/openmax/OMX_IVCommon.h> #include <media/stagefright/MetadataBufferType.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/SurfaceComposerClient.h> Loading Loading @@ -710,9 +711,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); Loading @@ -720,6 +721,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"); Loading @@ -727,14 +756,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); Loading @@ -751,6 +779,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 media/libstagefright/tests/SurfaceMediaSource_test.cpp +6 −7 Original line number Diff line number Diff line Loading @@ -71,8 +71,8 @@ protected: mANW.clear(); } const int mYuvTexWidth;// = 64; const int mYuvTexHeight;// = 66; const int mYuvTexWidth; const int mYuvTexHeight; sp<SurfaceMediaSource> mSMS; sp<SurfaceTextureClient> mSTC; Loading Loading @@ -124,7 +124,6 @@ sp<MPEG4Writer> SurfaceMediaSourceTest::setUpWriter(OMXClient &client ) { // TODO: overwriting the colorformat since the format set by GRAlloc // could be wrong or not be read by OMX enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar); // colorFormat); sp<MediaSource> encoder = Loading Loading @@ -225,7 +224,6 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // )); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); Loading @@ -239,7 +237,6 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBuffe // setting the client side buffer size different than the server size ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 10, 10, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // )); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); Loading @@ -258,6 +255,7 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPa 0, 0, HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); SimpleDummyRecorder writer(mSMS); writer.start(); Loading @@ -276,10 +274,12 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPa // A dummy writer is used to simulate actual MPEG4Writer TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) { LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************"); ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 0, 0, HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); SimpleDummyRecorder writer(mSMS); writer.start(); Loading Loading @@ -322,10 +322,9 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPas TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) { LOGV("Testing the whole pipeline with actual Recorder"); ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // )); 0, 0, HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); OMXClient client; CHECK_EQ(OK, client.connect()); Loading Loading
include/media/stagefright/MetadataBufferType.h +10 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,16 @@ typedef enum { * kMetadataBufferTypeGrallocSource is used to indicate that * the payload of the metadata buffers can be interpreted as * a buffer_handle_t. * So in this case,the metadata that the encoder receives * will have a byte stream that 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) | * -------------------------------------------------------------- */ kMetadataBufferTypeGrallocSource = 1, Loading
include/media/stagefright/SurfaceMediaSource.h +5 −1 Original line number Diff line number Diff line Loading @@ -63,6 +63,10 @@ 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; Loading Loading @@ -152,7 +156,7 @@ public: status_t setBufferCountServer(int bufferCount); // getTimestamp retrieves the timestamp associated with the image // set by the most recent call to updateFrameInfoLocked(). // set by the most recent call to read() // // The timestamp is in nanoseconds, and is monotonically increasing. Its // other semantics (zero point, etc) are source-dependent and should be Loading
media/libstagefright/SurfaceMediaSource.cpp +43 −7 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaDebug.h> #include <media/stagefright/openmax/OMX_IVCommon.h> #include <media/stagefright/MetadataBufferType.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/SurfaceComposerClient.h> Loading Loading @@ -710,9 +711,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); Loading @@ -720,6 +721,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"); Loading @@ -727,14 +756,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); Loading @@ -751,6 +779,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
media/libstagefright/tests/SurfaceMediaSource_test.cpp +6 −7 Original line number Diff line number Diff line Loading @@ -71,8 +71,8 @@ protected: mANW.clear(); } const int mYuvTexWidth;// = 64; const int mYuvTexHeight;// = 66; const int mYuvTexWidth; const int mYuvTexHeight; sp<SurfaceMediaSource> mSMS; sp<SurfaceTextureClient> mSTC; Loading Loading @@ -124,7 +124,6 @@ sp<MPEG4Writer> SurfaceMediaSourceTest::setUpWriter(OMXClient &client ) { // TODO: overwriting the colorformat since the format set by GRAlloc // could be wrong or not be read by OMX enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar); // colorFormat); sp<MediaSource> encoder = Loading Loading @@ -225,7 +224,6 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // )); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); Loading @@ -239,7 +237,6 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBuffe // setting the client side buffer size different than the server size ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 10, 10, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // )); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); Loading @@ -258,6 +255,7 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPa 0, 0, HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); SimpleDummyRecorder writer(mSMS); writer.start(); Loading @@ -276,10 +274,12 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPa // A dummy writer is used to simulate actual MPEG4Writer TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) { LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************"); ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 0, 0, HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); SimpleDummyRecorder writer(mSMS); writer.start(); Loading Loading @@ -322,10 +322,9 @@ TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPas TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) { LOGV("Testing the whole pipeline with actual Recorder"); ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // )); 0, 0, HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); OMXClient client; CHECK_EQ(OK, client.connect()); Loading