Loading include/media/stagefright/MediaBuffer.h +6 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ namespace android { class GraphicBuffer; class MediaBuffer; class MediaBufferObserver; class MetaData; Loading @@ -48,6 +49,8 @@ public: MediaBuffer(size_t size); MediaBuffer(const sp<GraphicBuffer>& graphicBuffer); // Decrements the reference count and returns the buffer to its // associated MediaBufferGroup if the reference count drops to 0. void release(); Loading @@ -63,6 +66,8 @@ public: void set_range(size_t offset, size_t length); sp<GraphicBuffer> graphicBuffer() const; sp<MetaData> meta_data(); // Clears meta data and resets the range to the full extent. Loading Loading @@ -94,6 +99,7 @@ private: void *mData; size_t mSize, mRangeOffset, mRangeLength; sp<GraphicBuffer> mGraphicBuffer; bool mOwnsData; Loading include/media/stagefright/MetaData.h +3 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,9 @@ enum { kKeyValidSamples = 'valD', // int32_t kKeyIsUnreadable = 'unre', // bool (int32_t) // An indication that a video buffer has been rendered. kKeyRendered = 'rend', // bool (int32_t) }; enum { Loading include/media/stagefright/OMXCodec.h +19 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define OMX_CODEC_H_ #include <android/native_window.h> #include <media/IOMX.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaSource.h> Loading @@ -44,7 +45,8 @@ struct OMXCodec : public MediaSource, const sp<MetaData> &meta, bool createEncoder, const sp<MediaSource> &source, const char *matchComponentName = NULL, uint32_t flags = 0); uint32_t flags = 0, const sp<ANativeWindow> &nativeWindow = NULL); static void setComponentRole( const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, Loading Loading @@ -114,6 +116,7 @@ private: struct BufferInfo { IOMX::buffer_id mBuffer; bool mOwnedByComponent; bool mOwnedByNativeWindow; sp<IMemory> mMem; size_t mSize; void *mData; Loading Loading @@ -159,13 +162,21 @@ private: bool mPaused; sp<ANativeWindow> mNativeWindow; // The index in each of the mPortBuffers arrays of the buffer that will be // submitted to OMX next. This only applies when using buffers from a // native window. size_t mNextNativeBufferIndex[2]; // A list of indices into mPortStatus[kPortIndexOutput] filled with data. List<size_t> mFilledBuffers; Condition mBufferFilled; OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, bool isEncoder, const char *mime, const char *componentName, const sp<MediaSource> &source); const sp<MediaSource> &source, const sp<ANativeWindow> &nativeWindow); void addCodecSpecificData(const void *data, size_t size); void clearCodecSpecificData(); Loading Loading @@ -216,6 +227,11 @@ private: status_t allocateBuffers(); status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t allocateOutputBuffersFromNativeWindow(); status_t queueBufferToNativeWindow(BufferInfo *info); status_t cancelBufferToNativeWindow(BufferInfo *info); BufferInfo* dequeueBufferFromNativeWindow(); status_t freeBuffersOnPort( OMX_U32 portIndex, bool onlyThoseWeOwn = false); Loading Loading @@ -250,6 +266,7 @@ private: status_t init(); void initOutputFormat(const sp<MetaData> &inputFormat); status_t initNativeWindow(); void dumpPortStatus(OMX_U32 portIndex); Loading media/libstagefright/AwesomePlayer.cpp +49 −12 Original line number Diff line number Diff line Loading @@ -194,6 +194,35 @@ void AwesomeLocalRenderer::init( } } struct AwesomeNativeWindowRenderer : public AwesomeRenderer { AwesomeNativeWindowRenderer(const sp<ANativeWindow> &nativeWindow) : mNativeWindow(nativeWindow) { } virtual void render(MediaBuffer *buffer) { status_t err = mNativeWindow->queueBuffer( mNativeWindow.get(), buffer->graphicBuffer().get()); if (err != 0) { LOGE("queueBuffer failed with error %s (%d)", strerror(-err), -err); return; } sp<MetaData> metaData = buffer->meta_data(); metaData->setInt32(kKeyRendered, 1); } protected: virtual ~AwesomeNativeWindowRenderer() {} private: sp<ANativeWindow> mNativeWindow; AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &); AwesomeNativeWindowRenderer &operator=( const AwesomeNativeWindowRenderer &); }; AwesomePlayer::AwesomePlayer() : mQueueStarted(false), mTimeSource(NULL), Loading Loading @@ -805,8 +834,16 @@ void AwesomePlayer::initRenderer_l() { IPCThreadState::self()->flushCommands(); if (mSurface != NULL) { if (strncmp(component, "OMX.", 4) == 0) { // Hardware decoders avoid the CPU color conversion by decoding // directly to ANativeBuffers, so we must use a renderer that // just pushes those buffers to the ANativeWindow. mVideoRenderer = new AwesomeNativeWindowRenderer(mSurface); } else { // Other decoders are instantiated locally and as a consequence // allocate their buffers in local address space. // allocate their buffers in local address space. This renderer // then performs a color conversion and copy to get the data // into the ANativeBuffer. mVideoRenderer = new AwesomeLocalRenderer( false, // previewOnly component, Loading @@ -815,6 +852,7 @@ void AwesomePlayer::initRenderer_l() { mSurface, mVideoWidth, mVideoHeight, decodedWidth, decodedHeight); } } else { // Our OMX codecs allocate buffers on the media_server side // therefore they require a remote IOMXRenderer that knows how Loading Loading @@ -1054,7 +1092,7 @@ status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { mClient.interface(), mVideoTrack->getFormat(), false, // createEncoder mVideoTrack, NULL, flags); NULL, flags, mSurface); if (mVideoSource != NULL) { int64_t durationUs; Loading Loading @@ -1811,4 +1849,3 @@ void AwesomePlayer::postAudioSeekComplete() { } } // namespace android media/libstagefright/MediaBuffer.cpp +26 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <media/stagefright/MediaDebug.h> #include <media/stagefright/MetaData.h> #include <ui/GraphicBuffer.h> namespace android { // XXX make this truly atomic. Loading Loading @@ -61,6 +63,20 @@ MediaBuffer::MediaBuffer(size_t size) mOriginal(NULL) { } MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer) : mObserver(NULL), mNextBuffer(NULL), mRefCount(0), mData(NULL), mSize(1), mRangeOffset(0), mRangeLength(mSize), mGraphicBuffer(graphicBuffer), mOwnsData(false), mMetaData(new MetaData), mOriginal(NULL) { } void MediaBuffer::release() { if (mObserver == NULL) { CHECK_EQ(mRefCount, 0); Loading Loading @@ -92,10 +108,12 @@ void MediaBuffer::add_ref() { } void *MediaBuffer::data() const { CHECK(mGraphicBuffer == NULL); return mData; } size_t MediaBuffer::size() const { CHECK(mGraphicBuffer == NULL); return mSize; } Loading @@ -108,15 +126,19 @@ size_t MediaBuffer::range_length() const { } void MediaBuffer::set_range(size_t offset, size_t length) { if (offset + length > mSize) { if ((mGraphicBuffer == NULL) && (offset + length > mSize)) { LOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize); } CHECK(offset + length <= mSize); CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize)); mRangeOffset = offset; mRangeLength = length; } sp<GraphicBuffer> MediaBuffer::graphicBuffer() const { return mGraphicBuffer; } sp<MetaData> MediaBuffer::meta_data() { return mMetaData; } Loading Loading @@ -158,6 +180,8 @@ int MediaBuffer::refcount() const { } MediaBuffer *MediaBuffer::clone() { CHECK_EQ(mGraphicBuffer, NULL); MediaBuffer *buffer = new MediaBuffer(mData, mSize); buffer->set_range(mRangeOffset, mRangeLength); buffer->mMetaData = new MetaData(*mMetaData.get()); Loading @@ -169,4 +193,3 @@ MediaBuffer *MediaBuffer::clone() { } } // namespace android Loading
include/media/stagefright/MediaBuffer.h +6 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ namespace android { class GraphicBuffer; class MediaBuffer; class MediaBufferObserver; class MetaData; Loading @@ -48,6 +49,8 @@ public: MediaBuffer(size_t size); MediaBuffer(const sp<GraphicBuffer>& graphicBuffer); // Decrements the reference count and returns the buffer to its // associated MediaBufferGroup if the reference count drops to 0. void release(); Loading @@ -63,6 +66,8 @@ public: void set_range(size_t offset, size_t length); sp<GraphicBuffer> graphicBuffer() const; sp<MetaData> meta_data(); // Clears meta data and resets the range to the full extent. Loading Loading @@ -94,6 +99,7 @@ private: void *mData; size_t mSize, mRangeOffset, mRangeLength; sp<GraphicBuffer> mGraphicBuffer; bool mOwnsData; Loading
include/media/stagefright/MetaData.h +3 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,9 @@ enum { kKeyValidSamples = 'valD', // int32_t kKeyIsUnreadable = 'unre', // bool (int32_t) // An indication that a video buffer has been rendered. kKeyRendered = 'rend', // bool (int32_t) }; enum { Loading
include/media/stagefright/OMXCodec.h +19 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define OMX_CODEC_H_ #include <android/native_window.h> #include <media/IOMX.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaSource.h> Loading @@ -44,7 +45,8 @@ struct OMXCodec : public MediaSource, const sp<MetaData> &meta, bool createEncoder, const sp<MediaSource> &source, const char *matchComponentName = NULL, uint32_t flags = 0); uint32_t flags = 0, const sp<ANativeWindow> &nativeWindow = NULL); static void setComponentRole( const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, Loading Loading @@ -114,6 +116,7 @@ private: struct BufferInfo { IOMX::buffer_id mBuffer; bool mOwnedByComponent; bool mOwnedByNativeWindow; sp<IMemory> mMem; size_t mSize; void *mData; Loading Loading @@ -159,13 +162,21 @@ private: bool mPaused; sp<ANativeWindow> mNativeWindow; // The index in each of the mPortBuffers arrays of the buffer that will be // submitted to OMX next. This only applies when using buffers from a // native window. size_t mNextNativeBufferIndex[2]; // A list of indices into mPortStatus[kPortIndexOutput] filled with data. List<size_t> mFilledBuffers; Condition mBufferFilled; OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, bool isEncoder, const char *mime, const char *componentName, const sp<MediaSource> &source); const sp<MediaSource> &source, const sp<ANativeWindow> &nativeWindow); void addCodecSpecificData(const void *data, size_t size); void clearCodecSpecificData(); Loading Loading @@ -216,6 +227,11 @@ private: status_t allocateBuffers(); status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t allocateOutputBuffersFromNativeWindow(); status_t queueBufferToNativeWindow(BufferInfo *info); status_t cancelBufferToNativeWindow(BufferInfo *info); BufferInfo* dequeueBufferFromNativeWindow(); status_t freeBuffersOnPort( OMX_U32 portIndex, bool onlyThoseWeOwn = false); Loading Loading @@ -250,6 +266,7 @@ private: status_t init(); void initOutputFormat(const sp<MetaData> &inputFormat); status_t initNativeWindow(); void dumpPortStatus(OMX_U32 portIndex); Loading
media/libstagefright/AwesomePlayer.cpp +49 −12 Original line number Diff line number Diff line Loading @@ -194,6 +194,35 @@ void AwesomeLocalRenderer::init( } } struct AwesomeNativeWindowRenderer : public AwesomeRenderer { AwesomeNativeWindowRenderer(const sp<ANativeWindow> &nativeWindow) : mNativeWindow(nativeWindow) { } virtual void render(MediaBuffer *buffer) { status_t err = mNativeWindow->queueBuffer( mNativeWindow.get(), buffer->graphicBuffer().get()); if (err != 0) { LOGE("queueBuffer failed with error %s (%d)", strerror(-err), -err); return; } sp<MetaData> metaData = buffer->meta_data(); metaData->setInt32(kKeyRendered, 1); } protected: virtual ~AwesomeNativeWindowRenderer() {} private: sp<ANativeWindow> mNativeWindow; AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &); AwesomeNativeWindowRenderer &operator=( const AwesomeNativeWindowRenderer &); }; AwesomePlayer::AwesomePlayer() : mQueueStarted(false), mTimeSource(NULL), Loading Loading @@ -805,8 +834,16 @@ void AwesomePlayer::initRenderer_l() { IPCThreadState::self()->flushCommands(); if (mSurface != NULL) { if (strncmp(component, "OMX.", 4) == 0) { // Hardware decoders avoid the CPU color conversion by decoding // directly to ANativeBuffers, so we must use a renderer that // just pushes those buffers to the ANativeWindow. mVideoRenderer = new AwesomeNativeWindowRenderer(mSurface); } else { // Other decoders are instantiated locally and as a consequence // allocate their buffers in local address space. // allocate their buffers in local address space. This renderer // then performs a color conversion and copy to get the data // into the ANativeBuffer. mVideoRenderer = new AwesomeLocalRenderer( false, // previewOnly component, Loading @@ -815,6 +852,7 @@ void AwesomePlayer::initRenderer_l() { mSurface, mVideoWidth, mVideoHeight, decodedWidth, decodedHeight); } } else { // Our OMX codecs allocate buffers on the media_server side // therefore they require a remote IOMXRenderer that knows how Loading Loading @@ -1054,7 +1092,7 @@ status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { mClient.interface(), mVideoTrack->getFormat(), false, // createEncoder mVideoTrack, NULL, flags); NULL, flags, mSurface); if (mVideoSource != NULL) { int64_t durationUs; Loading Loading @@ -1811,4 +1849,3 @@ void AwesomePlayer::postAudioSeekComplete() { } } // namespace android
media/libstagefright/MediaBuffer.cpp +26 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <media/stagefright/MediaDebug.h> #include <media/stagefright/MetaData.h> #include <ui/GraphicBuffer.h> namespace android { // XXX make this truly atomic. Loading Loading @@ -61,6 +63,20 @@ MediaBuffer::MediaBuffer(size_t size) mOriginal(NULL) { } MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer) : mObserver(NULL), mNextBuffer(NULL), mRefCount(0), mData(NULL), mSize(1), mRangeOffset(0), mRangeLength(mSize), mGraphicBuffer(graphicBuffer), mOwnsData(false), mMetaData(new MetaData), mOriginal(NULL) { } void MediaBuffer::release() { if (mObserver == NULL) { CHECK_EQ(mRefCount, 0); Loading Loading @@ -92,10 +108,12 @@ void MediaBuffer::add_ref() { } void *MediaBuffer::data() const { CHECK(mGraphicBuffer == NULL); return mData; } size_t MediaBuffer::size() const { CHECK(mGraphicBuffer == NULL); return mSize; } Loading @@ -108,15 +126,19 @@ size_t MediaBuffer::range_length() const { } void MediaBuffer::set_range(size_t offset, size_t length) { if (offset + length > mSize) { if ((mGraphicBuffer == NULL) && (offset + length > mSize)) { LOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize); } CHECK(offset + length <= mSize); CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize)); mRangeOffset = offset; mRangeLength = length; } sp<GraphicBuffer> MediaBuffer::graphicBuffer() const { return mGraphicBuffer; } sp<MetaData> MediaBuffer::meta_data() { return mMetaData; } Loading Loading @@ -158,6 +180,8 @@ int MediaBuffer::refcount() const { } MediaBuffer *MediaBuffer::clone() { CHECK_EQ(mGraphicBuffer, NULL); MediaBuffer *buffer = new MediaBuffer(mData, mSize); buffer->set_range(mRangeOffset, mRangeLength); buffer->mMetaData = new MetaData(*mMetaData.get()); Loading @@ -169,4 +193,3 @@ MediaBuffer *MediaBuffer::clone() { } } // namespace android