Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07567d63 authored by Marco Nelissen's avatar Marco Nelissen Committed by Android (Google) Code Review
Browse files

Merge "C-ify MediaBuffer"

parents fb88fcd6 0e043b67
Loading
Loading
Loading
Loading
+58 −0
Original line number Original line Diff line number Diff line
@@ -69,6 +69,40 @@ struct CMediaTrackV2 {
    bool     (*supportsNonBlockingRead)(void *data);
    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 {
struct CMediaExtractorV1 {
    void *data;
    void *data;
@@ -104,6 +138,23 @@ struct CMediaExtractorV2 {
    const char * (*name)(void *data);
    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 CMediaExtractorV1* (*CreatorFuncV1)(CDataSource *source, void *meta);
typedef void (*FreeMetaFunc)(void *meta);
typedef void (*FreeMetaFunc)(void *meta);


@@ -121,6 +172,12 @@ typedef CreatorFuncV2 (*SnifferFuncV2)(
        CDataSource *source, float *confidence,
        CDataSource *source, float *confidence,
        void **meta, FreeMetaFunc *freeMeta);
        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 CMediaExtractorV1 CMediaExtractor;
typedef CreatorFuncV1 CreatorFunc;
typedef CreatorFuncV1 CreatorFunc;


@@ -148,6 +205,7 @@ struct ExtractorDef {
    union {
    union {
        SnifferFuncV1 v1;
        SnifferFuncV1 v1;
        SnifferFuncV2 v2;
        SnifferFuncV2 v2;
        SnifferFuncV3 v3;
    } sniff;
    } sniff;
};
};


+255 −1
Original line number Original line Diff line number Diff line
@@ -20,12 +20,13 @@


#include <arpa/inet.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdio.h>
#include <vector>
#include <map>


#include <utils/Errors.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <utils/RefBase.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/NdkMediaFormat.h>


namespace android {
namespace android {


@@ -171,6 +172,176 @@ inline CMediaTrackV2 *wrapV2(MediaTrackHelperV2 *track) {
    return wrapper;
    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
// extractor plugins can derive from this class which looks remarkably
@@ -341,6 +512,89 @@ inline CMediaExtractorV2 *wrapV2(MediaExtractorPluginHelperV2 *extractor) {
    return wrapper;
    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 */
/* adds some convience methods */
class DataSourceHelper {
class DataSourceHelper {
public:
public:
+20 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@
#include <binder/IMemory.h>
#include <binder/IMemory.h>
#include <binder/MemoryDealer.h>
#include <binder/MemoryDealer.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MetaData.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/MediaExtractorPluginApi.h>
@@ -175,6 +176,25 @@ private:
    CMediaTrackV2 *wrapper;
    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
}  // namespace android


#endif  // MEDIA_SOURCE_BASE_H_
#endif  // MEDIA_SOURCE_BASE_H_
+2 −4
Original line number Original line Diff line number Diff line
@@ -20,10 +20,8 @@
#include <media/NdkMediaError.h>
#include <media/NdkMediaError.h>
#include <utils/Errors.h>
#include <utils/Errors.h>


using namespace android;
media_status_t translate_error(android::status_t);


media_status_t translate_error(status_t);
android::status_t reverse_translate_error(media_status_t);

status_t reverse_translate_error(media_status_t);


#endif // _NDK_MEDIA_ERROR_PRIV_H
#endif // _NDK_MEDIA_ERROR_PRIV_H
+11 −8
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#ifndef _NDK_MEDIA_FORMAT_PRIV_H
#ifndef _NDK_MEDIA_FORMAT_PRIV_H
#define _NDK_MEDIA_FORMAT_PRIV_H
#define _NDK_MEDIA_FORMAT_PRIV_H


#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include <utils/StrongPointer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -35,20 +36,22 @@
extern "C" {
extern "C" {
#endif
#endif


using namespace android;

struct AMediaFormat {
struct AMediaFormat {
    sp<AMessage> mFormat;
    android::sp<android::AMessage> mFormat;
    String8 mDebug;
    android::String8 mDebug;
    KeyedVector<String8, String8> mStringCache;
    android::KeyedVector<android::String8, android::String8> mStringCache;
};
};


AMediaFormat* AMediaFormat_fromMsg(const void*);
void AMediaFormat_getFormat(const AMediaFormat* mData, void* dest);

#ifdef __cplusplus
#ifdef __cplusplus
} // extern "C"
} // extern "C"
#endif
#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
#endif // _NDK_MEDIA_FORMAT_PRIV_H
Loading