C-ify MediaBuffer
Bug: 111407253
Test: CTS, manual
Change-Id: Id20094f23d9d0dc0ec23127bbedc62c6e29944bd
diff --git a/include/media/MediaExtractorPluginApi.h b/include/media/MediaExtractorPluginApi.h
index 38962e5..b480bbe 100644
--- a/include/media/MediaExtractorPluginApi.h
+++ b/include/media/MediaExtractorPluginApi.h
@@ -69,6 +69,40 @@
bool (*supportsNonBlockingRead)(void *data);
};
+/**
+ * only use CMediaBufferV3 allocated from the CMediaBufferGroupV3 that is
+ * provided to CMediaTrack::start()
+ */
+struct CMediaBufferV3 {
+ void *handle;
+ void (*release)(void *handle);
+ void* (*data)(void *handle);
+ size_t (*size)(void *handle);
+ size_t (*range_offset)(void *handle);
+ size_t (*range_length)(void *handle);
+ void (*set_range)(void *handle, size_t offset, size_t length);
+ AMediaFormat* (*meta_data)(void *handle);
+};
+
+struct CMediaBufferGroupV3 {
+ void *handle;
+ bool (*init)(void *handle, size_t buffers, size_t buffer_size, size_t growthLimit);
+ void (*add_buffer)(void *handle, size_t size);
+ media_status_t (*acquire_buffer)(void *handle,
+ CMediaBufferV3 **buffer, bool nonBlocking, size_t requestedSize);
+ bool (*has_buffers)(void *handle);
+};
+
+struct CMediaTrackV3 {
+ void *data;
+ void (*free)(void *data);
+
+ media_status_t (*start)(void *data, CMediaBufferGroupV3 *bufferGroup);
+ media_status_t (*stop)(void *data);
+ media_status_t (*getFormat)(void *data, AMediaFormat *format);
+ media_status_t (*read)(void *data, CMediaBufferV3 **buffer, uint32_t options, int64_t seekPosUs);
+ bool (*supportsNonBlockingRead)(void *data);
+};
struct CMediaExtractorV1 {
void *data;
@@ -104,6 +138,23 @@
const char * (*name)(void *data);
};
+struct CMediaExtractorV3 {
+ void *data;
+
+ void (*free)(void *data);
+ size_t (*countTracks)(void *data);
+ CMediaTrackV3* (*getTrack)(void *data, size_t index);
+ media_status_t (*getTrackMetaData)(
+ void *data,
+ AMediaFormat *meta,
+ size_t index, uint32_t flags);
+
+ media_status_t (*getMetaData)(void *data, AMediaFormat *meta);
+ uint32_t (*flags)(void *data);
+ media_status_t (*setMediaCas)(void *data, const uint8_t* casToken, size_t size);
+ const char * (*name)(void *data);
+};
+
typedef CMediaExtractorV1* (*CreatorFuncV1)(CDataSource *source, void *meta);
typedef void (*FreeMetaFunc)(void *meta);
@@ -121,6 +172,12 @@
CDataSource *source, float *confidence,
void **meta, FreeMetaFunc *freeMeta);
+typedef CMediaExtractorV3* (*CreatorFuncV3)(CDataSource *source, void *meta);
+
+typedef CreatorFuncV3 (*SnifferFuncV3)(
+ CDataSource *source, float *confidence,
+ void **meta, FreeMetaFunc *freeMeta);
+
typedef CMediaExtractorV1 CMediaExtractor;
typedef CreatorFuncV1 CreatorFunc;
@@ -148,6 +205,7 @@
union {
SnifferFuncV1 v1;
SnifferFuncV2 v2;
+ SnifferFuncV3 v3;
} sniff;
};
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
index 858c575..292ec93 100644
--- a/include/media/MediaExtractorPluginHelper.h
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -20,12 +20,13 @@
#include <arpa/inet.h>
#include <stdio.h>
-#include <vector>
+#include <map>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaFormat.h>
namespace android {
@@ -171,6 +172,176 @@
return wrapper;
}
+class MediaTrackHelperV3;
+
+class MediaBufferHelperV3 {
+private:
+ friend CMediaTrackV3 *wrapV3(MediaTrackHelperV3 *);
+ CMediaBufferV3 *mBuffer;
+public:
+ MediaBufferHelperV3(CMediaBufferV3 *buf) {
+ mBuffer = buf;
+ }
+
+ ~MediaBufferHelperV3() {}
+
+ void release() {
+ mBuffer->release(mBuffer->handle);
+ }
+
+ void* data() {
+ return mBuffer->data(mBuffer->handle);
+ }
+
+ size_t size() {
+ return mBuffer->size(mBuffer->handle);
+ }
+
+ size_t range_offset() {
+ return mBuffer->range_offset(mBuffer->handle);
+ }
+
+ size_t range_length() {
+ return mBuffer->range_length(mBuffer->handle);
+ }
+
+ void set_range(size_t offset, size_t length) {
+ mBuffer->set_range(mBuffer->handle, offset, length);
+ }
+ AMediaFormat *meta_data() {
+ return mBuffer->meta_data(mBuffer->handle);
+ }
+};
+
+class MediaBufferGroupHelperV3 {
+private:
+ CMediaBufferGroupV3 *mGroup;
+ std::map<CMediaBufferV3*, MediaBufferHelperV3*> mBufferHelpers;
+public:
+ MediaBufferGroupHelperV3(CMediaBufferGroupV3 *group) {
+ mGroup = group;
+ }
+ ~MediaBufferGroupHelperV3() {
+ // delete all entries in map
+ ALOGV("buffergroup %p map has %zu entries", this, mBufferHelpers.size());
+ for (auto it = mBufferHelpers.begin(); it != mBufferHelpers.end(); ++it) {
+ delete it->second;
+ }
+ }
+ bool init(size_t buffers, size_t buffer_size, size_t growthLimit = 0) {
+ return mGroup->init(mGroup->handle, buffers, buffer_size, growthLimit);
+ }
+ void add_buffer(size_t size) {
+ mGroup->add_buffer(mGroup->handle, size);
+ }
+ media_status_t acquire_buffer(
+ MediaBufferHelperV3 **buffer, bool nonBlocking = false, size_t requestedSize = 0) {
+ CMediaBufferV3 *buf = nullptr;
+ media_status_t ret =
+ mGroup->acquire_buffer(mGroup->handle, &buf, nonBlocking, requestedSize);
+ if (ret == AMEDIA_OK && buf != nullptr) {
+ auto helper = mBufferHelpers.find(buf);
+ if (helper == mBufferHelpers.end()) {
+ MediaBufferHelperV3* newHelper = new MediaBufferHelperV3(buf);
+ mBufferHelpers.insert(std::make_pair(buf, newHelper));
+ *buffer = newHelper;
+ } else {
+ *buffer = helper->second;
+ }
+ } else {
+ *buffer = nullptr;
+ }
+ return ret;
+ }
+ bool has_buffers() {
+ return mGroup->has_buffers(mGroup->handle);
+ }
+};
+
+class MediaTrackHelperV3 {
+public:
+ MediaTrackHelperV3() : mBufferGroup(nullptr) {
+ }
+ virtual ~MediaTrackHelperV3() {
+ delete mBufferGroup;
+ }
+ virtual media_status_t start() = 0;
+ virtual media_status_t stop() = 0;
+ virtual media_status_t getFormat(AMediaFormat *format) = 0;
+
+ class ReadOptions {
+ public:
+ enum SeekMode : int32_t {
+ SEEK_PREVIOUS_SYNC,
+ SEEK_NEXT_SYNC,
+ SEEK_CLOSEST_SYNC,
+ SEEK_CLOSEST,
+ SEEK_FRAME_INDEX,
+ };
+
+ ReadOptions(uint32_t options, int64_t seekPosUs) {
+ mOptions = options;
+ mSeekPosUs = seekPosUs;
+ }
+ bool getSeekTo(int64_t *time_us, SeekMode *mode) const {
+ if ((mOptions & CMediaTrackReadOptions::SEEK) == 0) {
+ return false;
+ }
+ *time_us = mSeekPosUs;
+ *mode = (SeekMode) (mOptions & 7);
+ return true;
+ }
+ bool getNonBlocking() const {
+ return mOptions & CMediaTrackReadOptions::NONBLOCKING;
+ }
+ private:
+ uint32_t mOptions;
+ int64_t mSeekPosUs;
+ };
+
+ virtual media_status_t read(
+ MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL) = 0;
+ virtual bool supportsNonBlockingRead() { return false; }
+protected:
+ friend CMediaTrackV3 *wrapV3(MediaTrackHelperV3 *track);
+ MediaBufferGroupHelperV3 *mBufferGroup;
+};
+
+inline CMediaTrackV3 *wrapV3(MediaTrackHelperV3 *track) {
+ CMediaTrackV3 *wrapper = (CMediaTrackV3*) malloc(sizeof(CMediaTrackV3));
+ wrapper->data = track;
+ wrapper->free = [](void *data) -> void {
+ delete (MediaTrackHelperV3*)(data);
+ };
+ wrapper->start = [](void *data, CMediaBufferGroupV3 *bufferGroup) -> media_status_t {
+ if (((MediaTrackHelperV3*)data)->mBufferGroup) {
+ // this shouldn't happen, but handle it anyway
+ delete ((MediaTrackHelperV3*)data)->mBufferGroup;
+ }
+ ((MediaTrackHelperV3*)data)->mBufferGroup = new MediaBufferGroupHelperV3(bufferGroup);
+ return ((MediaTrackHelperV3*)data)->start();
+ };
+ wrapper->stop = [](void *data) -> media_status_t {
+ return ((MediaTrackHelperV3*)data)->stop();
+ };
+ wrapper->getFormat = [](void *data, AMediaFormat *meta) -> media_status_t {
+ return ((MediaTrackHelperV3*)data)->getFormat(meta);
+ };
+ wrapper->read = [](void *data, CMediaBufferV3 **buffer, uint32_t options, int64_t seekPosUs)
+ -> media_status_t {
+ MediaTrackHelperV3::ReadOptions opts(options, seekPosUs);
+ MediaBufferHelperV3 *buf = NULL;
+ media_status_t ret = ((MediaTrackHelperV3*)data)->read(&buf, &opts);
+ if (ret == AMEDIA_OK && buf != nullptr) {
+ *buffer = buf->mBuffer;
+ }
+ return ret;
+ };
+ wrapper->supportsNonBlockingRead = [](void *data) -> bool {
+ return ((MediaTrackHelperV3*)data)->supportsNonBlockingRead();
+ };
+ return wrapper;
+}
// extractor plugins can derive from this class which looks remarkably
@@ -341,6 +512,89 @@
return wrapper;
}
+class MediaExtractorPluginHelperV3
+{
+public:
+ virtual ~MediaExtractorPluginHelperV3() {}
+ virtual size_t countTracks() = 0;
+ virtual MediaTrackHelperV3 *getTrack(size_t index) = 0;
+
+ enum GetTrackMetaDataFlags {
+ kIncludeExtensiveMetaData = 1
+ };
+ virtual media_status_t getTrackMetaData(
+ AMediaFormat *meta,
+ size_t index, uint32_t flags = 0) = 0;
+
+ // Return container specific meta-data. The default implementation
+ // returns an empty metadata object.
+ virtual media_status_t getMetaData(AMediaFormat *meta) = 0;
+
+ enum Flags {
+ CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
+ CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
+ CAN_PAUSE = 4,
+ CAN_SEEK = 8, // the "seek bar"
+ };
+
+ // If subclasses do _not_ override this, the default is
+ // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+ virtual uint32_t flags() const {
+ return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE;
+ };
+
+ virtual media_status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
+ return AMEDIA_ERROR_INVALID_OPERATION;
+ }
+
+ virtual const char * name() { return "<unspecified>"; }
+
+protected:
+ MediaExtractorPluginHelperV3() {}
+
+private:
+ MediaExtractorPluginHelperV3(const MediaExtractorPluginHelperV2 &);
+ MediaExtractorPluginHelperV3 &operator=(const MediaExtractorPluginHelperV2 &);
+};
+
+inline CMediaExtractorV3 *wrapV3(MediaExtractorPluginHelperV3 *extractor) {
+ CMediaExtractorV3 *wrapper = (CMediaExtractorV3*) malloc(sizeof(CMediaExtractorV3));
+ wrapper->data = extractor;
+ wrapper->free = [](void *data) -> void {
+ delete (MediaExtractorPluginHelperV3*)(data);
+ };
+ wrapper->countTracks = [](void *data) -> size_t {
+ return ((MediaExtractorPluginHelperV3*)data)->countTracks();
+ };
+ wrapper->getTrack = [](void *data, size_t index) -> CMediaTrackV3* {
+ return wrapV3(((MediaExtractorPluginHelperV3*)data)->getTrack(index));
+ };
+ wrapper->getTrackMetaData = [](
+ void *data,
+ AMediaFormat *meta,
+ size_t index, uint32_t flags) -> media_status_t {
+ return ((MediaExtractorPluginHelperV3*)data)->getTrackMetaData(meta, index, flags);
+ };
+ wrapper->getMetaData = [](
+ void *data,
+ AMediaFormat *meta) -> media_status_t {
+ return ((MediaExtractorPluginHelperV3*)data)->getMetaData(meta);
+ };
+ wrapper->flags = [](
+ void *data) -> uint32_t {
+ return ((MediaExtractorPluginHelperV3*)data)->flags();
+ };
+ wrapper->setMediaCas = [](
+ void *data, const uint8_t *casToken, size_t size) -> media_status_t {
+ return ((MediaExtractorPluginHelperV3*)data)->setMediaCas(casToken, size);
+ };
+ wrapper->name = [](
+ void *data) -> const char * {
+ return ((MediaExtractorPluginHelperV3*)data)->name();
+ };
+ return wrapper;
+}
+
/* adds some convience methods */
class DataSourceHelper {
public:
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
index ee3591e..baa3410 100644
--- a/include/media/MediaTrack.h
+++ b/include/media/MediaTrack.h
@@ -23,6 +23,7 @@
#include <binder/IMemory.h>
#include <binder/MemoryDealer.h>
#include <media/MediaExtractorPluginApi.h>
+#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/MediaExtractorPluginApi.h>
@@ -175,6 +176,25 @@
CMediaTrackV2 *wrapper;
};
+class MediaTrackCUnwrapperV3 : public MediaTrack {
+public:
+ explicit MediaTrackCUnwrapperV3(CMediaTrackV3 *wrapper);
+
+ virtual status_t start();
+ virtual status_t stop();
+ virtual status_t getFormat(MetaDataBase& format);
+ virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
+
+ virtual bool supportNonblockingRead();
+
+protected:
+ virtual ~MediaTrackCUnwrapperV3();
+
+private:
+ CMediaTrackV3 *wrapper;
+ MediaBufferGroup *bufferGroup;
+};
+
} // namespace android
#endif // MEDIA_SOURCE_BASE_H_
diff --git a/include/media/NdkMediaErrorPriv.h b/include/media/NdkMediaErrorPriv.h
index f5e2f02..3bbba79 100644
--- a/include/media/NdkMediaErrorPriv.h
+++ b/include/media/NdkMediaErrorPriv.h
@@ -20,10 +20,8 @@
#include <media/NdkMediaError.h>
#include <utils/Errors.h>
-using namespace android;
+media_status_t translate_error(android::status_t);
-media_status_t translate_error(status_t);
-
-status_t reverse_translate_error(media_status_t);
+android::status_t reverse_translate_error(media_status_t);
#endif // _NDK_MEDIA_ERROR_PRIV_H
diff --git a/include/media/NdkMediaFormatPriv.h b/include/media/NdkMediaFormatPriv.h
index 6c452c3..1fda4a8 100644
--- a/include/media/NdkMediaFormatPriv.h
+++ b/include/media/NdkMediaFormatPriv.h
@@ -27,6 +27,7 @@
#ifndef _NDK_MEDIA_FORMAT_PRIV_H
#define _NDK_MEDIA_FORMAT_PRIV_H
+#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -35,20 +36,22 @@
extern "C" {
#endif
-using namespace android;
-
struct AMediaFormat {
- sp<AMessage> mFormat;
- String8 mDebug;
- KeyedVector<String8, String8> mStringCache;
+ android::sp<android::AMessage> mFormat;
+ android::String8 mDebug;
+ android::KeyedVector<android::String8, android::String8> mStringCache;
};
-AMediaFormat* AMediaFormat_fromMsg(const void*);
-void AMediaFormat_getFormat(const AMediaFormat* mData, void* dest);
-
#ifdef __cplusplus
} // extern "C"
#endif
+namespace android {
+
+AMediaFormat* AMediaFormat_fromMsg(sp<AMessage> *);
+void AMediaFormat_getFormat(const AMediaFormat* mData, sp<AMessage> *dest);
+
+} // namespace android
+
#endif // _NDK_MEDIA_FORMAT_PRIV_H
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 185bb32..dcc73bb 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -9,7 +9,6 @@
shared_libs: [
"libbinder_ndk",
"liblog",
- "libmediaextractor",
"libmediandk",
],
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index 86500ef..17b5f81 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -22,9 +22,7 @@
#include <android/binder_ibinder.h> // for AIBinder_getCallingUid
#include <audio_utils/primitives.h>
-#include <media/DataSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
@@ -68,7 +66,7 @@
return ptr[1] << 8 | ptr[0];
}
-struct WAVSource : public MediaTrackHelperV2 {
+struct WAVSource : public MediaTrackHelperV3 {
WAVSource(
DataSourceHelper *dataSource,
AMediaFormat *meta,
@@ -81,7 +79,7 @@
virtual media_status_t getFormat(AMediaFormat *meta);
virtual media_status_t read(
- MediaBufferBase **buffer, const ReadOptions *options = NULL);
+ MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
virtual bool supportNonblockingRead() { return true; }
@@ -101,7 +99,6 @@
off64_t mOffset;
size_t mSize;
bool mStarted;
- MediaBufferGroup *mGroup;
off64_t mCurrentPos;
WAVSource(const WAVSource &);
@@ -134,7 +131,7 @@
return mInitCheck == OK ? 1 : 0;
}
-MediaTrackHelperV2 *WAVExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *WAVExtractor::getTrack(size_t index) {
if (mInitCheck != OK || index > 0) {
return NULL;
}
@@ -379,14 +376,14 @@
mOutputFloat(outputFloat),
mOffset(offset),
mSize(size),
- mStarted(false),
- mGroup(NULL) {
+ mStarted(false) {
CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &mSampleRate));
CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &mNumChannels));
CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &mBitsPerSample));
}
WAVSource::~WAVSource() {
+ ALOGI("~WAVSource");
if (mStarted) {
stop();
}
@@ -398,7 +395,9 @@
CHECK(!mStarted);
// some WAV files may have large audio buffers that use shared memory transfer.
- mGroup = new MediaBufferGroup(4 /* buffers */, kMaxFrameSize);
+ if (!mBufferGroup->init(4 /* buffers */, kMaxFrameSize)) {
+ return AMEDIA_ERROR_UNKNOWN;
+ }
mCurrentPos = mOffset;
@@ -412,9 +411,6 @@
CHECK(mStarted);
- delete mGroup;
- mGroup = NULL;
-
mStarted = false;
return AMEDIA_OK;
@@ -433,10 +429,10 @@
}
media_status_t WAVSource::read(
- MediaBufferBase **out, const ReadOptions *options) {
+ MediaBufferHelperV3 **out, const ReadOptions *options) {
*out = NULL;
- if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
+ if (options != nullptr && options->getNonBlocking() && !mBufferGroup->has_buffers()) {
return AMEDIA_ERROR_WOULD_BLOCK;
}
@@ -459,10 +455,10 @@
mCurrentPos = pos + mOffset;
}
- MediaBufferBase *buffer;
- status_t err = mGroup->acquire_buffer(&buffer);
+ MediaBufferHelperV3 *buffer;
+ media_status_t err = mBufferGroup->acquire_buffer(&buffer);
if (err != OK) {
- return AMEDIA_ERROR_UNKNOWN;
+ return err;
}
// maxBytesToRead may be reduced so that in-place data conversion will fit in buffer size.
@@ -573,9 +569,10 @@
/ (mNumChannels * bytesPerSample) / mSampleRate;
}
- buffer->meta_data().setInt64(kKeyTime, timeStampUs);
+ AMediaFormat *meta = buffer->meta_data();
+ AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
- buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
mCurrentPos += n;
*out = buffer;
@@ -585,13 +582,13 @@
////////////////////////////////////////////////////////////////////////////////
-static CMediaExtractorV2* CreateExtractor(
+static CMediaExtractorV3* CreateExtractor(
CDataSource *source,
void *) {
- return wrapV2(new WAVExtractor(new DataSourceHelper(source)));
+ return wrapV3(new WAVExtractor(new DataSourceHelper(source)));
}
-static CreatorFuncV2 Sniff(
+static CreatorFuncV3 Sniff(
CDataSource *source,
float *confidence,
void **,
@@ -625,11 +622,11 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION_CURRENT,
+ EXTRACTORDEF_VERSION_CURRENT + 1,
UUID("7d613858-5837-4a38-84c5-332d1cddee27"),
1, // version
"WAV Extractor",
- { .v2 = Sniff }
+ { .v3 = Sniff }
};
}
diff --git a/media/extractors/wav/WAVExtractor.h b/media/extractors/wav/WAVExtractor.h
index ce34881..9b7dfde 100644
--- a/media/extractors/wav/WAVExtractor.h
+++ b/media/extractors/wav/WAVExtractor.h
@@ -29,12 +29,12 @@
struct CDataSource;
class String8;
-class WAVExtractor : public MediaExtractorPluginHelperV2 {
+class WAVExtractor : public MediaExtractorPluginHelperV3 {
public:
explicit WAVExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual MediaTrackHelperV3 *getTrack(size_t index);
virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
virtual media_status_t getMetaData(AMediaFormat *meta);
diff --git a/media/libmedia/NdkMediaFormatPriv.cpp b/media/libmedia/NdkMediaFormatPriv.cpp
index 3c84d6a..3a9fb8b 100644
--- a/media/libmedia/NdkMediaFormatPriv.cpp
+++ b/media/libmedia/NdkMediaFormatPriv.cpp
@@ -19,27 +19,22 @@
#include <inttypes.h>
-//#include <ndk/include/media/NdkMediaFormat.h>
-
#include <utils/Log.h>
#include <utils/StrongPointer.h>
#include <media/NdkMediaFormatPriv.h>
-#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
-//#include <android_runtime/AndroidRuntime.h>
-//#include <android_util_Binder.h>
#include <jni.h>
using namespace android;
-extern "C" {
+namespace android {
// private functions for conversion to/from AMessage
-AMediaFormat* AMediaFormat_fromMsg(const void* data) {
+AMediaFormat* AMediaFormat_fromMsg(sp<AMessage> *data) {
ALOGV("private ctor");
AMediaFormat* mData = new AMediaFormat();
- mData->mFormat = *((sp<AMessage>*)data);
+ mData->mFormat = *data;
if (mData->mFormat == NULL) {
ALOGW("got NULL format");
mData->mFormat = new AMessage;
@@ -47,10 +42,10 @@
return mData;
}
-void AMediaFormat_getFormat(const AMediaFormat* mData, void* dest) {
- *((sp<AMessage>*)dest) = mData->mFormat;
+void AMediaFormat_getFormat(const AMediaFormat* mData, sp<AMessage> *dest) {
+ *dest = mData->mFormat;
}
-} // extern "C"
+} // namespace android
diff --git a/media/libmediaextractor/MediaBufferGroup.cpp b/media/libmediaextractor/MediaBufferGroup.cpp
index 62b83cc..4e6beca 100644
--- a/media/libmediaextractor/MediaBufferGroup.cpp
+++ b/media/libmediaextractor/MediaBufferGroup.cpp
@@ -44,12 +44,16 @@
};
MediaBufferGroup::MediaBufferGroup(size_t growthLimit)
- : mInternal(new InternalData()) {
+ : mWrapper(nullptr), mInternal(new InternalData()) {
mInternal->mGrowthLimit = growthLimit;
}
MediaBufferGroup::MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit)
- : mInternal(new InternalData()) {
+ : mWrapper(nullptr), mInternal(new InternalData()) {
+ init(buffers, buffer_size, growthLimit);
+}
+
+void MediaBufferGroup::init(size_t buffers, size_t buffer_size, size_t growthLimit) {
mInternal->mGrowthLimit = growthLimit;
if (mInternal->mGrowthLimit > 0 && buffers > mInternal->mGrowthLimit) {
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libmediaextractor/include/media/DataSource.h
index cb96ff5..1f7a473 100644
--- a/media/libmediaextractor/include/media/DataSource.h
+++ b/media/libmediaextractor/include/media/DataSource.h
@@ -22,7 +22,7 @@
#include <media/stagefright/MediaErrors.h>
#include <media/DataSourceBase.h>
#include <media/IDataSource.h>
-#include <media/MediaExtractorPluginHelper.h>
+#include <media/MediaExtractorPluginApi.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
index 6c8d94a..d67ddbd 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
@@ -18,6 +18,10 @@
#define MEDIA_BUFFER_BASE_H_
+#include <media/MediaExtractorPluginApi.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/NdkMediaFormatPriv.h>
+
namespace android {
class MediaBufferBase;
@@ -77,6 +81,48 @@
virtual int remoteRefcount() const = 0;
virtual ~MediaBufferBase() {};
+
+ CMediaBufferV3 *wrap() {
+ if (mWrapper) {
+ return mWrapper;
+ }
+ mWrapper = new CMediaBufferV3;
+ mWrapper->handle = this;
+
+ mWrapper->release = [](void *handle) -> void {
+ ((MediaBufferBase*)handle)->release();
+ };
+
+ mWrapper->data = [](void *handle) -> void * {
+ return ((MediaBufferBase*)handle)->data();
+ };
+
+ mWrapper->size = [](void *handle) -> size_t {
+ return ((MediaBufferBase*)handle)->size();
+ };
+
+ mWrapper->set_range = [](void *handle, size_t offset, size_t length) -> void {
+ return ((MediaBufferBase*)handle)->set_range(offset, length);
+ };
+
+ mWrapper->meta_data = [](void *handle) -> AMediaFormat* {
+ if (((MediaBufferBase*)handle)->mFormat == nullptr) {
+ sp<AMessage> msg = new AMessage();
+ ((MediaBufferBase*)handle)->mFormat = AMediaFormat_fromMsg(&msg);
+ }
+ return ((MediaBufferBase*)handle)->mFormat;
+ };
+
+ return mWrapper;
+ }
+protected:
+ MediaBufferBase() {
+ mWrapper = nullptr;
+ mFormat = nullptr;
+ }
+private:
+ CMediaBufferV3 *mWrapper;
+ AMediaFormat *mFormat;
};
} // namespace android
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h b/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
index 75d5df7..dc04556 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
@@ -20,6 +20,8 @@
#include <list>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaErrorPriv.h>
#include <media/stagefright/MediaBufferBase.h>
#include <utils/Errors.h>
#include <utils/threads.h>
@@ -57,12 +59,54 @@
// If buffer is nullptr, have acquire_buffer() check for remote release.
virtual void signalBufferReturned(MediaBufferBase *buffer);
+ CMediaBufferGroupV3 *wrap() {
+ if (mWrapper) {
+ return mWrapper;
+ }
+
+ mWrapper = new CMediaBufferGroupV3;
+ mWrapper->handle = this;
+
+ mWrapper->add_buffer = [](void *handle, size_t size) -> void {
+ MediaBufferBase *buf = MediaBufferBase::Create(size);
+ ((MediaBufferGroup*)handle)->add_buffer(buf);
+ };
+
+ mWrapper->init = [](void *handle,
+ size_t buffers, size_t buffer_size, size_t growthLimit) -> bool {
+ ((MediaBufferGroup*)handle)->init(buffers, buffer_size, growthLimit);
+ // ((MediaBufferGroup*)handle)->mWrapper->init = nullptr; // enforce call-once
+ return true;
+ };
+
+ mWrapper->acquire_buffer = [](void *handle,
+ CMediaBufferV3 **buf, bool nonBlocking, size_t requestedSize) -> media_status_t {
+ MediaBufferBase *acquiredBuf = nullptr;
+ status_t err = ((MediaBufferGroup*)handle)->acquire_buffer(
+ &acquiredBuf, nonBlocking, requestedSize);
+ if (err == OK && acquiredBuf != nullptr) {
+ *buf = acquiredBuf->wrap();
+ } else {
+ *buf = nullptr;
+ }
+ return translate_error(err);
+ };
+
+ mWrapper->has_buffers = [](void *handle) -> bool {
+ return ((MediaBufferGroup*)handle)->has_buffers();
+ };
+
+ return mWrapper;
+ }
+
private:
+ CMediaBufferGroupV3 *mWrapper;
struct InternalData;
InternalData *mInternal;
MediaBufferGroup(const MediaBufferGroup &);
MediaBufferGroup &operator=(const MediaBufferGroup &);
+ void init(size_t buffers, size_t buffer_size, size_t growthLimit);
};
} // namespace android
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index ac9eb0b..ea818ff 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -134,4 +134,57 @@
return plugin->setMediaCas(plugin->data, casToken, size);
}
+// --------------------------------------------------------------------------------
+MediaExtractorCUnwrapperV3::MediaExtractorCUnwrapperV3(CMediaExtractorV3 *plugin) {
+ this->plugin = plugin;
+}
+
+MediaExtractorCUnwrapperV3::~MediaExtractorCUnwrapperV3() {
+ plugin->free(plugin->data);
+ free(plugin);
+}
+
+size_t MediaExtractorCUnwrapperV3::countTracks() {
+ return plugin->countTracks(plugin->data);
+}
+
+MediaTrack *MediaExtractorCUnwrapperV3::getTrack(size_t index) {
+ return new MediaTrackCUnwrapperV3(plugin->getTrack(plugin->data, index));
+}
+
+status_t MediaExtractorCUnwrapperV3::getTrackMetaData(
+ MetaDataBase& meta, size_t index, uint32_t flags) {
+ sp<AMessage> msg = new AMessage();
+ AMediaFormat *format = AMediaFormat_fromMsg(&msg);
+ media_status_t ret = plugin->getTrackMetaData(plugin->data, format, index, flags);
+ sp<MetaData> newMeta = new MetaData();
+ convertMessageToMetaData(msg, newMeta);
+ delete format;
+ meta = *newMeta;
+ return reverse_translate_error(ret);
+}
+
+status_t MediaExtractorCUnwrapperV3::getMetaData(MetaDataBase& meta) {
+ sp<AMessage> msg = new AMessage();
+ AMediaFormat *format = AMediaFormat_fromMsg(&msg);
+ media_status_t ret = plugin->getMetaData(plugin->data, format);
+ sp<MetaData> newMeta = new MetaData();
+ convertMessageToMetaData(msg, newMeta);
+ delete format;
+ meta = *newMeta;
+ return reverse_translate_error(ret);
+}
+
+const char * MediaExtractorCUnwrapperV3::name() {
+ return plugin->name(plugin->data);
+}
+
+uint32_t MediaExtractorCUnwrapperV3::flags() const {
+ return plugin->flags(plugin->data);
+}
+
+status_t MediaExtractorCUnwrapperV3::setMediaCas(const uint8_t* casToken, size_t size) {
+ return plugin->setMediaCas(plugin->data, casToken, size);
+}
+
} // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 318c1eb..1f8ccb3 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -100,6 +100,12 @@
freeMeta(meta);
}
ex = ret != nullptr ? new MediaExtractorCUnwrapperV2(ret) : nullptr;
+ } else if (creatorVersion == 3) {
+ CMediaExtractorV3 *ret = ((CreatorFuncV3)creator)(source->wrap(), meta);
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+ ex = ret != nullptr ? new MediaExtractorCUnwrapperV3(ret) : nullptr;
}
ALOGV("Created an extractor '%s' with confidence %.2f",
@@ -170,6 +176,9 @@
} else if ((*it)->def.def_version == 2) {
curCreator = (void*) (*it)->def.sniff.v2(
source->wrap(), &newConfidence, &newMeta, &newFreeMeta);
+ } else if ((*it)->def.def_version == 3) {
+ curCreator = (void*) (*it)->def.sniff.v3(
+ source->wrap(), &newConfidence, &newMeta, &newFreeMeta);
}
if (curCreator) {
@@ -199,7 +208,7 @@
std::list<sp<ExtractorPlugin>> &pluginList) {
// sanity check check struct version, uuid, name
if (plugin->def.def_version == 0
- || plugin->def.def_version > EXTRACTORDEF_VERSION_CURRENT) {
+ || plugin->def.def_version > EXTRACTORDEF_VERSION_CURRENT + 1) {
ALOGE("don't understand extractor format %u, ignoring.", plugin->def.def_version);
return;
}
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
index 821605d..daed5a0 100644
--- a/media/libstagefright/MediaTrack.cpp
+++ b/media/libstagefright/MediaTrack.cpp
@@ -155,4 +155,76 @@
return wrapper->supportsNonBlockingRead(wrapper->data);
}
+/* -------------- unwrapper v3 --------------- */
+
+MediaTrackCUnwrapperV3::MediaTrackCUnwrapperV3(CMediaTrackV3 *cmediatrack3) {
+ wrapper = cmediatrack3;
+ bufferGroup = nullptr;
+}
+
+MediaTrackCUnwrapperV3::~MediaTrackCUnwrapperV3() {
+ wrapper->free(wrapper->data);
+ free(wrapper);
+}
+
+status_t MediaTrackCUnwrapperV3::start() {
+ if (bufferGroup == nullptr) {
+ bufferGroup = new MediaBufferGroup();
+ }
+ return reverse_translate_error(wrapper->start(wrapper->data, bufferGroup->wrap()));
+}
+
+status_t MediaTrackCUnwrapperV3::stop() {
+ return reverse_translate_error(wrapper->stop(wrapper->data));
+}
+
+status_t MediaTrackCUnwrapperV3::getFormat(MetaDataBase& format) {
+ sp<AMessage> msg = new AMessage();
+ AMediaFormat *tmpFormat = AMediaFormat_fromMsg(&msg);
+ media_status_t ret = wrapper->getFormat(wrapper->data, tmpFormat);
+ sp<MetaData> newMeta = new MetaData();
+ convertMessageToMetaData(msg, newMeta);
+ delete tmpFormat;
+ format = *newMeta;
+ return reverse_translate_error(ret);
+}
+
+status_t MediaTrackCUnwrapperV3::read(MediaBufferBase **buffer, const ReadOptions *options) {
+
+ uint32_t opts = 0;
+
+ if (options && options->getNonBlocking()) {
+ opts |= CMediaTrackReadOptions::NONBLOCKING;
+ }
+
+ int64_t seekPosition = 0;
+ MediaTrack::ReadOptions::SeekMode seekMode;
+ if (options && options->getSeekTo(&seekPosition, &seekMode)) {
+ opts |= SEEK;
+ opts |= (uint32_t) seekMode;
+ }
+ CMediaBufferV3 *buf = nullptr;
+ media_status_t ret = wrapper->read(wrapper->data, &buf, opts, seekPosition);
+ if (ret == AMEDIA_OK && buf != nullptr) {
+ *buffer = (MediaBufferBase*)buf->handle;
+ MetaDataBase &meta = (*buffer)->meta_data();
+ AMediaFormat *format = buf->meta_data(buf->handle);
+ // only convert the keys we're actually expecting, as doing
+ // the full convertMessageToMetadata() for every buffer is
+ // too expensive
+ int64_t val;
+ if (format->mFormat->findInt64("timeUs", &val)) {
+ meta.setInt64(kKeyTime, val);
+ }
+ } else {
+ *buffer = nullptr;
+ }
+
+ return reverse_translate_error(ret);
+}
+
+bool MediaTrackCUnwrapperV3::supportNonblockingRead() {
+ return wrapper->supportsNonBlockingRead(wrapper->data);
+}
+
} // namespace android
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
index 00f2dd3..71e1170 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h
@@ -17,7 +17,6 @@
#ifndef SOFT_MPEG4_ENCODER_H_
#define SOFT_MPEG4_ENCODER_H_
-#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
#include "mp4enc_api.h"
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index 71343d5..6f3e57e 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -135,6 +135,22 @@
CMediaExtractorV2 *plugin;
};
+class MediaExtractorCUnwrapperV3 : public MediaExtractorCUnwrapper {
+public:
+ explicit MediaExtractorCUnwrapperV3(CMediaExtractorV3 *plugin);
+ virtual size_t countTracks();
+ virtual MediaTrack *getTrack(size_t index);
+ virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags = 0);
+ virtual status_t getMetaData(MetaDataBase& meta);
+ virtual const char * name();
+ virtual uint32_t flags() const;
+ virtual status_t setMediaCas(const uint8_t* casToken, size_t size);
+protected:
+ virtual ~MediaExtractorCUnwrapperV3();
+private:
+ CMediaExtractorV3 *plugin;
+};
+
} // namespace android
#endif // MEDIA_EXTRACTOR_H_
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index bf9725c..bc140bf 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -327,6 +327,7 @@
EXPORT const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT = "is-autoselect";
EXPORT const char* AMEDIAFORMAT_KEY_IS_DEFAULT = "is-default";
EXPORT const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE = "is-forced-subtitle";
+EXPORT const char* AMEDIAFORMAT_KEY_IS_SYNC_FRAME = "is-sync-frame";
EXPORT const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL = "i-frame-interval";
EXPORT const char* AMEDIAFORMAT_KEY_LANGUAGE = "language";
EXPORT const char* AMEDIAFORMAT_KEY_LATENCY = "latency";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 658cbac..4be1928 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -209,6 +209,7 @@
extern const char* AMEDIAFORMAT_KEY_GENRE __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_HDR_STATIC_INFO __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_ICC_PROFILE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_IS_SYNC_FRAME __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_LOCATION __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_LOOP __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_LYRICIST __INTRODUCED_IN(29);