Merge "Revert "Move MediaBufferXXX from foundation to libmediaextractor""

gugelfrei
TreeHugger Robot 7 years ago committed by Android (Google) Code Review
commit 6e075b43b0

@ -21,13 +21,15 @@
#include <media/MediaCodecBuffer.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/MediaBufferBase.h>
namespace android {
MediaCodecBuffer::MediaCodecBuffer(const sp<AMessage> &format, const sp<ABuffer> &buffer)
: mMeta(new AMessage),
mFormat(format),
mBuffer(buffer) {
mBuffer(buffer),
mMediaBufferBase(nullptr) {
}
// ABuffer-like interface
@ -56,6 +58,20 @@ status_t MediaCodecBuffer::setRange(size_t offset, size_t size) {
return OK;
}
MediaBufferBase *MediaCodecBuffer::getMediaBufferBase() {
if (mMediaBufferBase != NULL) {
mMediaBufferBase->add_ref();
}
return mMediaBufferBase;
}
void MediaCodecBuffer::setMediaBufferBase(MediaBufferBase *mediaBuffer) {
if (mMediaBufferBase != NULL) {
mMediaBufferBase->release();
}
mMediaBufferBase = mediaBuffer;
}
sp<AMessage> MediaCodecBuffer::meta() {
return mMeta;
}

@ -1,48 +0,0 @@
/*
* Copyright 2018, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_BUFFER_HOLDER_H_
#define MEDIA_BUFFER_HOLDER_H_
#include <media/stagefright/MediaBuffer.h>
#include <utils/RefBase.h>
namespace android {
struct MediaBufferHolder : public RefBase {
MediaBufferHolder(MediaBuffer* buffer)
: mMediaBuffer(buffer) {
if (mMediaBuffer != nullptr) {
mMediaBuffer->add_ref();
}
}
virtual ~MediaBufferHolder() {
if (mMediaBuffer != nullptr) {
mMediaBuffer->release();
}
}
MediaBuffer* mediaBuffer() { return mMediaBuffer; }
private:
MediaBuffer* const mMediaBuffer;
};
} // android
#endif // MEDIA_BUFFER_HOLDER_H_

@ -50,6 +50,9 @@ public:
size_t offset() const;
// Default implementation calls ABuffer::setRange() and returns OK.
virtual status_t setRange(size_t offset, size_t size);
// TODO: These can be removed if we finish replacing all MediaBuffer's.
MediaBufferBase *getMediaBufferBase();
void setMediaBufferBase(MediaBufferBase *mediaBuffer);
// TODO: Specify each field for meta/format.
sp<AMessage> meta();
@ -63,6 +66,7 @@ private:
const sp<AMessage> mMeta;
sp<AMessage> mFormat;
const sp<ABuffer> mBuffer;
MediaBufferBase *mMediaBufferBase;
};
} // namespace android

@ -24,7 +24,6 @@
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <media/DataSource.h>
#include <media/MediaBufferHolder.h>
#include <media/IMediaExtractorService.h>
#include <media/MediaHTTPService.h>
#include <media/MediaExtractor.h>
@ -1168,7 +1167,8 @@ sp<ABuffer> NuPlayer2::GenericSource::mediaBufferToABuffer(
// data is already provided in the buffer
ab = new ABuffer(NULL, mb->range_length());
ab->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mb));
mb->add_ref();
ab->setMediaBufferBase(mb);
// Modular DRM: Required b/c of the above add_ref.
// If ref>0, there must be an observer, or it'll crash at release().

@ -28,7 +28,6 @@
#include "NuPlayer2Source.h"
#include <cutils/properties.h>
#include <media/MediaBufferHolder.h>
#include <media/MediaCodecBuffer.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkWrapper.h>
@ -1082,17 +1081,16 @@ bool NuPlayer2::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
memcpy(codecBuffer->data(), buffer->data(), buffer->size());
} else { // No buffer->data()
//Modular DRM
sp<RefBase> holder;
if (buffer->meta()->findObject("mediaBufferHolder", &holder)) {
mediaBuf = (holder != nullptr) ?
static_cast<MediaBufferHolder*>(holder.get())->mediaBuffer() : nullptr;
}
mediaBuf = (MediaBuffer*)buffer->getMediaBufferBase();
if (mediaBuf != NULL) {
codecBuffer->setRange(0, mediaBuf->size());
memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
sp<MetaData> meta_data = mediaBuf->meta_data();
cryptInfo = AMediaCodecCryptoInfoWrapper::Create(meta_data);
// since getMediaBuffer() has incremented the refCount
mediaBuf->release();
} else { // No mediaBuf
ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
buffer.get());

@ -15,7 +15,6 @@ cc_library {
],
shared_libs: [
"libbinder",
"libstagefright_foundation",
"libutils",
"libcutils",
@ -24,8 +23,6 @@ cc_library {
srcs: [
"DataSource.cpp",
"MediaBuffer.cpp",
"MediaBufferGroup.cpp",
"MediaSource.cpp",
"MediaExtractor.cpp",
],

@ -1,230 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_BUFFER_H_
#define MEDIA_BUFFER_H_
#include <atomic>
#include <list>
#include <pthread.h>
#include <binder/MemoryDealer.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
namespace android {
struct ABuffer;
class GraphicBuffer;
class MediaBuffer;
class MediaBufferObserver;
class MetaData;
class MediaBufferObserver {
public:
MediaBufferObserver() {}
virtual ~MediaBufferObserver() {}
virtual void signalBufferReturned(MediaBuffer *buffer) = 0;
private:
MediaBufferObserver(const MediaBufferObserver &);
MediaBufferObserver &operator=(const MediaBufferObserver &);
};
class MediaBuffer {
public:
// allocations larger than or equal to this will use shared memory.
static const size_t kSharedMemThreshold = 64 * 1024;
// The underlying data remains the responsibility of the caller!
MediaBuffer(void *data, size_t size);
explicit MediaBuffer(size_t size);
explicit MediaBuffer(const sp<ABuffer> &buffer);
MediaBuffer(const sp<IMemory> &mem) :
MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
// delegate and override mMemory
mMemory = mem;
}
// If MediaBufferGroup is set, decrement the local reference count;
// if the local reference count drops to 0, return the buffer to the
// associated MediaBufferGroup.
//
// If no MediaBufferGroup is set, the local reference count must be zero
// when called, whereupon the MediaBuffer is deleted.
void release();
// Increments the local reference count.
// Use only when MediaBufferGroup is set.
void add_ref();
void *data() const;
size_t size() const;
size_t range_offset() const;
size_t range_length() const;
void set_range(size_t offset, size_t length);
sp<MetaData> meta_data();
// Clears meta data and resets the range to the full extent.
void reset();
void setObserver(MediaBufferObserver *group);
// Returns a clone of this MediaBuffer increasing its reference count.
// The clone references the same data but has its own range and
// MetaData.
MediaBuffer *clone();
// sum of localRefcount() and remoteRefcount()
int refcount() const {
return localRefcount() + remoteRefcount();
}
int localRefcount() const {
return mRefCount;
}
int remoteRefcount() const {
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
int32_t remoteRefcount =
reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
// Sanity check so that remoteRefCount() is non-negative.
return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
}
// returns old value
int addRemoteRefcount(int32_t value) {
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
}
bool isDeadObject() const {
return isDeadObject(mMemory);
}
static bool isDeadObject(const sp<IMemory> &memory) {
if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
}
// Sticky on enabling of shared memory MediaBuffers. By default we don't use
// shared memory for MediaBuffers, but we enable this for those processes
// that export MediaBuffers.
static void useSharedMemory() {
std::atomic_store_explicit(
&mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
}
protected:
// true if MediaBuffer is observed (part of a MediaBufferGroup).
inline bool isObserved() const {
return mObserver != nullptr;
}
~MediaBuffer();
sp<IMemory> mMemory;
private:
friend class MediaBufferGroup;
friend class OMXDecoder;
friend class BnMediaSource;
friend class BpMediaSource;
// For use by OMXDecoder, reference count must be 1, drop reference
// count to 0 without signalling the observer.
void claim();
MediaBufferObserver *mObserver;
int mRefCount;
void *mData;
size_t mSize, mRangeOffset, mRangeLength;
sp<ABuffer> mBuffer;
bool mOwnsData;
sp<MetaData> mMetaData;
MediaBuffer *mOriginal;
static std::atomic_int_least32_t mUseSharedMemory;
MediaBuffer(const MediaBuffer &);
MediaBuffer &operator=(const MediaBuffer &);
// SharedControl block at the start of IMemory.
struct SharedControl {
enum {
FLAG_DEAD_OBJECT = (1 << 0),
};
// returns old value
inline int32_t addRemoteRefcount(int32_t value) {
return std::atomic_fetch_add_explicit(
&mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
}
inline int32_t getRemoteRefcount() const {
return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
}
inline void setRemoteRefcount(int32_t value) {
std::atomic_store_explicit(
&mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
}
inline bool isDeadObject() const {
return (std::atomic_load_explicit(
&mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
}
inline void setDeadObject() {
(void)std::atomic_fetch_or_explicit(
&mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
}
inline void clear() {
std::atomic_store_explicit(
&mFlags, (int_least32_t)0, std::memory_order_seq_cst);
std::atomic_store_explicit(
&mRemoteRefcount, (int_least32_t)0, std::memory_order_seq_cst);
}
private:
// Caution: atomic_int_fast32_t is 64 bits on LP64.
std::atomic_int_least32_t mFlags;
std::atomic_int_least32_t mRemoteRefcount;
int32_t unused[6] __attribute__((__unused__)); // additional buffer space
};
inline SharedControl *getSharedControl() const {
return reinterpret_cast<SharedControl *>(mMemory->pointer());
}
};
} // namespace android
#endif // MEDIA_BUFFER_H_

@ -1,72 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_BUFFER_GROUP_H_
#define MEDIA_BUFFER_GROUP_H_
#include <media/stagefright/MediaBuffer.h>
#include <utils/Errors.h>
#include <utils/threads.h>
namespace android {
class MediaBuffer;
class MediaBufferGroup : public MediaBufferObserver {
public:
MediaBufferGroup(size_t growthLimit = 0);
// create a media buffer group with preallocated buffers
MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit = 0);
~MediaBufferGroup();
void add_buffer(MediaBuffer *buffer);
bool has_buffers();
// If nonBlocking is false, it blocks until a buffer is available and
// passes it to the caller in *buffer, while returning OK.
// The returned buffer will have a reference count of 1.
// If nonBlocking is true and a buffer is not immediately available,
// buffer is set to NULL and it returns WOULD_BLOCK.
// If requestedSize is 0, any free MediaBuffer will be returned.
// If requestedSize is > 0, the returned MediaBuffer should have buffer
// size of at least requstedSize.
status_t acquire_buffer(
MediaBuffer **buffer, bool nonBlocking = false, size_t requestedSize = 0);
size_t buffers() const { return mBuffers.size(); }
// If buffer is nullptr, have acquire_buffer() check for remote release.
virtual void signalBufferReturned(MediaBuffer *buffer);
private:
friend class MediaBuffer;
Mutex mLock;
Condition mCondition;
size_t mGrowthLimit; // Do not automatically grow group larger than this.
std::list<MediaBuffer *> mBuffers;
MediaBufferGroup(const MediaBufferGroup &);
MediaBufferGroup &operator=(const MediaBufferGroup &);
};
} // namespace android
#endif // MEDIA_BUFFER_GROUP_H_

@ -24,7 +24,6 @@
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <media/DataSource.h>
#include <media/MediaBufferHolder.h>
#include <media/MediaExtractor.h>
#include <media/MediaSource.h>
#include <media/IMediaHTTPService.h>
@ -1161,12 +1160,14 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
// data is already provided in the buffer
ab = new ABuffer(NULL, mb->range_length());
ab->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mb));
mb->add_ref();
ab->setMediaBufferBase(mb);
// Modular DRM: Required b/c of the above add_ref.
// If ref>0, there must be an observer, or it'll crash at release().
// TODO: MediaBuffer might need to be revised to ease such need.
mb->setObserver(this);
// setMediaBufferBase() interestingly doesn't increment the ref count on its own.
// Extra increment (since we want to keep mb alive and attached to ab beyond this function
// call. This is to counter the effect of mb->release() towards the end.
mb->add_ref();

@ -29,7 +29,6 @@
#include <cutils/properties.h>
#include <media/ICrypto.h>
#include <media/MediaBufferHolder.h>
#include <media/MediaCodecBuffer.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@ -1062,17 +1061,16 @@ bool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
memcpy(codecBuffer->data(), buffer->data(), buffer->size());
} else { // No buffer->data()
//Modular DRM
sp<RefBase> holder;
if (buffer->meta()->findObject("mediaBufferHolder", &holder)) {
mediaBuf = (holder != nullptr) ?
static_cast<MediaBufferHolder*>(holder.get())->mediaBuffer() : nullptr;
}
mediaBuf = (MediaBuffer*)buffer->getMediaBufferBase();
if (mediaBuf != NULL) {
codecBuffer->setRange(0, mediaBuf->size());
memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
sp<MetaData> meta_data = mediaBuf->meta_data();
cryptInfo = NuPlayerDrm::getSampleCryptoInfo(meta_data);
// since getMediaBuffer() has incremented the refCount
mediaBuf->release();
} else { // No mediaBuf
ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
buffer.get());

@ -43,7 +43,6 @@
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/SurfaceUtils.h>
#include <media/hardware/HardwareAPI.h>
#include <media/MediaBufferHolder.h>
#include <media/OMXBuffer.h>
#include <media/omx/1.0/WOmxNode.h>
@ -5640,7 +5639,7 @@ bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fence
// by this "MediaBuffer" object. Now that the OMX component has
// told us that it's done with the input buffer, we can decrement
// the mediaBuffer's reference count.
info->mData->meta()->setObject("mediaBufferHolder", sp<MediaBufferHolder>(nullptr));
info->mData->setMediaBufferBase(NULL);
PortMode mode = getPortMode(kPortIndexInput);

@ -23,7 +23,6 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
#include <media/ICrypto.h>
#include <media/MediaBufferHolder.h>
#include <media/MediaCodecBuffer.h>
#include <media/MediaSource.h>
#include <media/stagefright/foundation/ABuffer.h>
@ -740,8 +739,7 @@ status_t MediaCodecSource::feedEncoderInputBuffers() {
if (mIsVideo) {
// video encoder will release MediaBuffer when done
// with underlying data.
inbuf->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mbuf));
mbuf->release();
inbuf->setMediaBufferBase(mbuf);
} else {
mbuf->release();
}

@ -13,7 +13,6 @@ cc_binary {
"libcutils",
"libgui",
"liblog",
"libmediaextractor",
"libstagefright",
"libstagefright_codec2",
"libstagefright_codec2_vndk",

@ -19,11 +19,13 @@
#include "ADebug.h"
#include "ALooper.h"
#include "AMessage.h"
#include "MediaBufferBase.h"
namespace android {
ABuffer::ABuffer(size_t capacity)
: mRangeOffset(0),
: mMediaBufferBase(NULL),
mRangeOffset(0),
mInt32Data(0),
mOwnsData(true) {
mData = malloc(capacity);
@ -37,7 +39,8 @@ ABuffer::ABuffer(size_t capacity)
}
ABuffer::ABuffer(void *data, size_t capacity)
: mData(data),
: mMediaBufferBase(NULL),
mData(data),
mCapacity(capacity),
mRangeOffset(0),
mRangeLength(capacity),
@ -63,6 +66,8 @@ ABuffer::~ABuffer() {
mData = NULL;
}
}
setMediaBufferBase(NULL);
}
void ABuffer::setRange(size_t offset, size_t size) {
@ -80,5 +85,19 @@ sp<AMessage> ABuffer::meta() {
return mMeta;
}
MediaBufferBase *ABuffer::getMediaBufferBase() {
if (mMediaBufferBase != NULL) {
mMediaBufferBase->add_ref();
}
return mMediaBufferBase;
}
void ABuffer::setMediaBufferBase(MediaBufferBase *mediaBuffer) {
if (mMediaBufferBase != NULL) {
mMediaBufferBase->release();
}
mMediaBufferBase = mediaBuffer;
}
} // namespace android

@ -62,6 +62,8 @@ cc_library {
"AStringUtils.cpp",
"ByteUtils.cpp",
"ColorUtils.cpp",
"MediaBuffer.cpp",
"MediaBufferGroup.cpp",
"MediaDefs.cpp",
"MediaKeys.cpp",
"MetaData.cpp",

@ -26,6 +26,8 @@
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
#include <ui/GraphicBuffer.h>
namespace android {
/* static */

@ -27,6 +27,7 @@
namespace android {
struct AMessage;
class MediaBufferBase;
struct ABuffer : public RefBase {
explicit ABuffer(size_t capacity);
@ -48,12 +49,17 @@ struct ABuffer : public RefBase {
sp<AMessage> meta();
MediaBufferBase *getMediaBufferBase();
void setMediaBufferBase(MediaBufferBase *mediaBuffer);
protected:
virtual ~ABuffer();
private:
sp<AMessage> mMeta;
MediaBufferBase *mMediaBufferBase;
void *mData;
size_t mCapacity;
size_t mRangeOffset;

@ -0,0 +1,40 @@
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_BUFFER_BASE_H_
#define MEDIA_BUFFER_BASE_H_
namespace android {
class MediaBufferBase {
public:
MediaBufferBase() {}
virtual void release() = 0;
virtual void add_ref() = 0;
protected:
virtual ~MediaBufferBase() {}
private:
MediaBufferBase(const MediaBufferBase &);
MediaBufferBase &operator=(const MediaBufferBase &);
};
} // namespace android
#endif // MEDIA_BUFFER_BASE_H_

@ -1 +0,0 @@
../../../../libmediaextractor/include/media/stagefright/MediaBuffer.h

@ -0,0 +1,231 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_BUFFER_H_
#define MEDIA_BUFFER_H_
#include <atomic>
#include <list>
#include <media/stagefright/foundation/MediaBufferBase.h>
#include <pthread.h>
#include <binder/MemoryDealer.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
namespace android {
struct ABuffer;
class GraphicBuffer;
class MediaBuffer;
class MediaBufferObserver;
class MetaData;
class MediaBufferObserver {
public:
MediaBufferObserver() {}
virtual ~MediaBufferObserver() {}
virtual void signalBufferReturned(MediaBuffer *buffer) = 0;
private:
MediaBufferObserver(const MediaBufferObserver &);
MediaBufferObserver &operator=(const MediaBufferObserver &);
};
class MediaBuffer : public MediaBufferBase {
public:
// allocations larger than or equal to this will use shared memory.
static const size_t kSharedMemThreshold = 64 * 1024;
// The underlying data remains the responsibility of the caller!
MediaBuffer(void *data, size_t size);
explicit MediaBuffer(size_t size);
explicit MediaBuffer(const sp<ABuffer> &buffer);
MediaBuffer(const sp<IMemory> &mem) :
MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
// delegate and override mMemory
mMemory = mem;
}
// If MediaBufferGroup is set, decrement the local reference count;
// if the local reference count drops to 0, return the buffer to the
// associated MediaBufferGroup.
//
// If no MediaBufferGroup is set, the local reference count must be zero
// when called, whereupon the MediaBuffer is deleted.
virtual void release();
// Increments the local reference count.
// Use only when MediaBufferGroup is set.
virtual void add_ref();
void *data() const;
size_t size() const;
size_t range_offset() const;
size_t range_length() const;
void set_range(size_t offset, size_t length);
sp<MetaData> meta_data();
// Clears meta data and resets the range to the full extent.
void reset();
void setObserver(MediaBufferObserver *group);
// Returns a clone of this MediaBuffer increasing its reference count.
// The clone references the same data but has its own range and
// MetaData.
MediaBuffer *clone();
// sum of localRefcount() and remoteRefcount()
int refcount() const {
return localRefcount() + remoteRefcount();
}
int localRefcount() const {
return mRefCount;
}
int remoteRefcount() const {
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
int32_t remoteRefcount =
reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
// Sanity check so that remoteRefCount() is non-negative.
return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
}
// returns old value
int addRemoteRefcount(int32_t value) {
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
}
bool isDeadObject() const {
return isDeadObject(mMemory);
}
static bool isDeadObject(const sp<IMemory> &memory) {
if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
}
// Sticky on enabling of shared memory MediaBuffers. By default we don't use
// shared memory for MediaBuffers, but we enable this for those processes
// that export MediaBuffers.
static void useSharedMemory() {
std::atomic_store_explicit(
&mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
}
protected:
// true if MediaBuffer is observed (part of a MediaBufferGroup).
inline bool isObserved() const {
return mObserver != nullptr;
}
virtual ~MediaBuffer();
sp<IMemory> mMemory;
private:
friend class MediaBufferGroup;
friend class OMXDecoder;
friend class BnMediaSource;
friend class BpMediaSource;
// For use by OMXDecoder, reference count must be 1, drop reference
// count to 0 without signalling the observer.
void claim();
MediaBufferObserver *mObserver;
int mRefCount;
void *mData;
size_t mSize, mRangeOffset, mRangeLength;
sp<ABuffer> mBuffer;
bool mOwnsData;
sp<MetaData> mMetaData;
MediaBuffer *mOriginal;
static std::atomic_int_least32_t mUseSharedMemory;
MediaBuffer(const MediaBuffer &);
MediaBuffer &operator=(const MediaBuffer &);
// SharedControl block at the start of IMemory.
struct SharedControl {
enum {
FLAG_DEAD_OBJECT = (1 << 0),
};
// returns old value
inline int32_t addRemoteRefcount(int32_t value) {
return std::atomic_fetch_add_explicit(
&mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
}
inline int32_t getRemoteRefcount() const {
return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
}
inline void setRemoteRefcount(int32_t value) {
std::atomic_store_explicit(
&mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
}
inline bool isDeadObject() const {
return (std::atomic_load_explicit(
&mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
}
inline void setDeadObject() {
(void)std::atomic_fetch_or_explicit(
&mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
}
inline void clear() {
std::atomic_store_explicit(
&mFlags, (int_least32_t)0, std::memory_order_seq_cst);
std::atomic_store_explicit(
&mRemoteRefcount, (int_least32_t)0, std::memory_order_seq_cst);
}
private:
// Caution: atomic_int_fast32_t is 64 bits on LP64.
std::atomic_int_least32_t mFlags;
std::atomic_int_least32_t mRemoteRefcount;
int32_t unused[6] __attribute__((__unused__)); // additional buffer space
};
inline SharedControl *getSharedControl() const {
return reinterpret_cast<SharedControl *>(mMemory->pointer());
}
};
} // namespace android
#endif // MEDIA_BUFFER_H_

@ -1 +0,0 @@
../../../../libmediaextractor/include/media/stagefright/MediaBufferGroup.h

@ -0,0 +1,72 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_BUFFER_GROUP_H_
#define MEDIA_BUFFER_GROUP_H_
#include <media/stagefright/MediaBuffer.h>
#include <utils/Errors.h>
#include <utils/threads.h>
namespace android {
class MediaBuffer;
class MediaBufferGroup : public MediaBufferObserver {
public:
MediaBufferGroup(size_t growthLimit = 0);
// create a media buffer group with preallocated buffers
MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit = 0);
~MediaBufferGroup();
void add_buffer(MediaBuffer *buffer);
bool has_buffers();
// If nonBlocking is false, it blocks until a buffer is available and
// passes it to the caller in *buffer, while returning OK.
// The returned buffer will have a reference count of 1.
// If nonBlocking is true and a buffer is not immediately available,
// buffer is set to NULL and it returns WOULD_BLOCK.
// If requestedSize is 0, any free MediaBuffer will be returned.
// If requestedSize is > 0, the returned MediaBuffer should have buffer
// size of at least requstedSize.
status_t acquire_buffer(
MediaBuffer **buffer, bool nonBlocking = false, size_t requestedSize = 0);
size_t buffers() const { return mBuffers.size(); }
// If buffer is nullptr, have acquire_buffer() check for remote release.
virtual void signalBufferReturned(MediaBuffer *buffer);
private:
friend class MediaBuffer;
Mutex mLock;
Condition mCondition;
size_t mGrowthLimit; // Do not automatically grow group larger than this.
std::list<MediaBuffer *> mBuffers;
MediaBufferGroup(const MediaBufferGroup &);
MediaBufferGroup &operator=(const MediaBufferGroup &);
};
} // namespace android
#endif // MEDIA_BUFFER_GROUP_H_
Loading…
Cancel
Save