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

Commit cec44d0c authored by Marco Nelissen's avatar Marco Nelissen
Browse files

C-ify DataSource

Add a C API for DataSource/Base, and a helper so extractors
can continue using a C++ API.

Bug: 111407253
Test: build, boot, play some files

Change-Id: I1c8b2990e17d18eee53c9abf7ebef2ced0e8b7fd
parent 0b16447f
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -23,10 +23,17 @@ namespace android {

struct MediaTrack;
class MetaDataBase;
class DataSourceBase;

extern "C" {

struct CDataSource {
    ssize_t (*readAt)(void *handle, off64_t offset, void *data, size_t size);
    status_t (*getSize)(void *handle, off64_t *size);
    uint32_t (*flags)(void *handle );
    bool (*getUri)(void *handle, char *uriString, size_t bufferSize);
    void *handle;
};

struct CMediaExtractor {
    void *data;

@@ -44,7 +51,7 @@ struct CMediaExtractor {
    const char * (*name)(void *data);
};

typedef CMediaExtractor* (*CreatorFunc)(DataSourceBase *source, void *meta);
typedef CMediaExtractor* (*CreatorFunc)(CDataSource *source, void *meta);
typedef void (*FreeMetaFunc)(void *meta);

// The sniffer can optionally fill in an opaque object, "meta", that helps
@@ -52,7 +59,7 @@ typedef void (*FreeMetaFunc)(void *meta);
// effort already exerted by the sniffer. If "freeMeta" is given, it will be
// called against the opaque object when it is no longer used.
typedef CreatorFunc (*SnifferFunc)(
        DataSourceBase *source, float *confidence,
        CDataSource *source, float *confidence,
        void **meta, FreeMetaFunc *freeMeta);

typedef struct {
+131 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#define MEDIA_EXTRACTOR_PLUGIN_HELPER_H_

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

@@ -117,6 +118,136 @@ inline CMediaExtractor *wrap(MediaExtractorPluginHelper *extractor) {
    return wrapper;
}

/* adds some convience methods */
class DataSourceHelper {
public:
    explicit DataSourceHelper(CDataSource *csource) {
        mSource = csource;
    }

    explicit DataSourceHelper(DataSourceHelper *source) {
        mSource = source->mSource;
    }

    ssize_t readAt(off64_t offset, void *data, size_t size) {
        return mSource->readAt(mSource->handle, offset, data, size);
    }

    status_t getSize(off64_t *size) {
        return mSource->getSize(mSource->handle, size);
    }

    bool getUri(char *uriString, size_t bufferSize) {
        return mSource->getUri(mSource->handle, uriString, bufferSize);
    }

    uint32_t flags() {
        return mSource->flags(mSource->handle);
    }

    // Convenience methods:
    bool getUInt16(off64_t offset, uint16_t *x) {
        *x = 0;

        uint8_t byte[2];
        if (readAt(offset, byte, 2) != 2) {
            return false;
        }

        *x = (byte[0] << 8) | byte[1];

        return true;
    }

    // 3 byte int, returned as a 32-bit int
    bool getUInt24(off64_t offset, uint32_t *x) {
        *x = 0;

        uint8_t byte[3];
        if (readAt(offset, byte, 3) != 3) {
            return false;
        }

        *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];

        return true;
    }

    bool getUInt32(off64_t offset, uint32_t *x) {
        *x = 0;

        uint32_t tmp;
        if (readAt(offset, &tmp, 4) != 4) {
            return false;
        }

        *x = ntohl(tmp);

        return true;
    }

    bool getUInt64(off64_t offset, uint64_t *x) {
        *x = 0;

        uint64_t tmp;
        if (readAt(offset, &tmp, 8) != 8) {
            return false;
        }

        *x = ((uint64_t)ntohl(tmp & 0xffffffff) << 32) | ntohl(tmp >> 32);

        return true;
    }

    // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
        if (size == 2) {
            return getUInt16(offset, x);
        }
        if (size == 1) {
            uint8_t tmp;
            if (readAt(offset, &tmp, 1) == 1) {
                *x = tmp;
                return true;
            }
        }
        return false;
    }

    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
        if (size == 4) {
            return getUInt32(offset, x);
        }
        if (size == 2) {
            uint16_t tmp;
            if (getUInt16(offset, &tmp)) {
                *x = tmp;
                return true;
            }
        }
        return false;
    }

    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
        if (size == 8) {
            return getUInt64(offset, x);
        }
        if (size == 4) {
            uint32_t tmp;
            if (getUInt32(offset, &tmp)) {
                *x = tmp;
                return true;
            }
        }
        return false;
    }

protected:
    CDataSource *mSource;
};



// helpers to create a media_uuid_t from a string literal

// purposely not defined anywhere so that this will fail to link if
+12 −11
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
#include <utils/Log.h>

#include "AACExtractor.h"
#include <media/DataSourceBase.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/MediaTrack.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -36,7 +36,7 @@ namespace android {
class AACSource : public MediaTrack {
public:
    AACSource(
            DataSourceBase *source,
            DataSourceHelper *source,
            MetaDataBase &meta,
            const Vector<uint64_t> &offset_vector,
            int64_t frame_duration_us);
@@ -54,7 +54,7 @@ protected:

private:
    static const size_t kMaxFrameSize;
    DataSourceBase *mDataSource;
    DataSourceHelper *mDataSource;
    MetaDataBase mMeta;

    off64_t mOffset;
@@ -92,7 +92,7 @@ uint32_t get_sample_rate(const uint8_t sf_index)
// The returned value is the AAC frame size with the ADTS header length (regardless of
//     the presence of the CRC).
// If headerSize is non-NULL, it will be used to return the size of the header of this ADTS frame.
static size_t getAdtsFrameLength(DataSourceBase *source, off64_t offset, size_t* headerSize) {
static size_t getAdtsFrameLength(DataSourceHelper *source, off64_t offset, size_t* headerSize) {

    const size_t kAdtsHeaderLengthNoCrc = 7;
    const size_t kAdtsHeaderLengthWithCrc = 9;
@@ -133,7 +133,7 @@ static size_t getAdtsFrameLength(DataSourceBase *source, off64_t offset, size_t*
}

AACExtractor::AACExtractor(
        DataSourceBase *source, off64_t offset)
        DataSourceHelper *source, off64_t offset)
    : mDataSource(source),
      mInitCheck(NO_INIT),
      mFrameDurationUs(0) {
@@ -219,7 +219,7 @@ status_t AACExtractor::getTrackMetaData(MetaDataBase &meta, size_t index, uint32
const size_t AACSource::kMaxFrameSize = 8192;

AACSource::AACSource(
        DataSourceBase *source,
        DataSourceHelper *source,
        MetaDataBase &meta,
        const Vector<uint64_t> &offset_vector,
        int64_t frame_duration_us)
@@ -324,20 +324,21 @@ status_t AACSource::read(
////////////////////////////////////////////////////////////////////////////////

static CMediaExtractor* CreateExtractor(
        DataSourceBase *source,
        CDataSource *source,
        void *meta) {
    off64_t offset = *static_cast<off64_t*>(meta);
    return wrap(new AACExtractor(source, offset));
    return wrap(new AACExtractor(new DataSourceHelper(source), offset));
}

static CreatorFunc Sniff(
        DataSourceBase *source, float *confidence, void **meta,
        CDataSource *source, float *confidence, void **meta,
        FreeMetaFunc *freeMeta) {
    off64_t pos = 0;

    DataSourceHelper helper(source);
    for (;;) {
        uint8_t id3header[10];
        if (source->readAt(pos, id3header, sizeof(id3header))
        if (helper.readAt(pos, id3header, sizeof(id3header))
                < (ssize_t)sizeof(id3header)) {
            return NULL;
        }
@@ -364,7 +365,7 @@ static CreatorFunc Sniff(

    uint8_t header[2];

    if (source->readAt(pos, &header, 2) != 2) {
    if (helper.readAt(pos, &header, 2) != 2) {
        return NULL;
    }

+3 −3
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ class String8;

class AACExtractor : public MediaExtractorPluginHelper {
public:
    AACExtractor(DataSourceBase *source, off64_t offset);
    AACExtractor(DataSourceHelper *source, off64_t offset);

    virtual size_t countTracks();
    virtual MediaTrack *getTrack(size_t index);
@@ -44,7 +44,7 @@ protected:
    virtual ~AACExtractor();

private:
    DataSourceBase *mDataSource;
    DataSourceHelper *mDataSource;
    MetaDataBase mMeta;
    status_t mInitCheck;

@@ -56,7 +56,7 @@ private:
};

bool SniffAAC(
        DataSourceBase *source, String8 *mimeType, float *confidence, off64_t *offset);
        DataSourceHelper *source, String8 *mimeType, float *confidence, off64_t *offset);

}  // namespace android

+12 −11
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@

#include "AMRExtractor.h"

#include <media/DataSourceBase.h>
#include <media/MediaTrack.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -34,7 +33,7 @@ namespace android {
class AMRSource : public MediaTrack {
public:
    AMRSource(
            DataSourceBase *source,
            DataSourceHelper *source,
            MetaDataBase &meta,
            bool isWide,
            const off64_t *offset_table,
@@ -52,7 +51,7 @@ protected:
    virtual ~AMRSource();

private:
    DataSourceBase *mDataSource;
    DataSourceHelper *mDataSource;
    MetaDataBase mMeta;
    bool mIsWide;

@@ -98,7 +97,7 @@ static size_t getFrameSize(bool isWide, unsigned FT) {
    return frameSize;
}

static status_t getFrameSizeByOffset(DataSourceBase *source,
static status_t getFrameSizeByOffset(DataSourceHelper *source,
        off64_t offset, bool isWide, size_t *frameSize) {
    uint8_t header;
    ssize_t count = source->readAt(offset, &header, 1);
@@ -118,7 +117,7 @@ static status_t getFrameSizeByOffset(DataSourceBase *source,
}

static bool SniffAMR(
        DataSourceBase *source, bool *isWide, float *confidence) {
        DataSourceHelper *source, bool *isWide, float *confidence) {
    char header[9];

    if (source->readAt(0, header, sizeof(header)) != sizeof(header)) {
@@ -144,7 +143,7 @@ static bool SniffAMR(
    return false;
}

AMRExtractor::AMRExtractor(DataSourceBase *source)
AMRExtractor::AMRExtractor(DataSourceHelper *source)
    : mDataSource(source),
      mInitCheck(NO_INIT),
      mOffsetTableLength(0) {
@@ -192,6 +191,7 @@ AMRExtractor::AMRExtractor(DataSourceBase *source)
}

AMRExtractor::~AMRExtractor() {
    delete mDataSource;
}

status_t AMRExtractor::getMetaData(MetaDataBase &meta) {
@@ -229,7 +229,7 @@ status_t AMRExtractor::getTrackMetaData(MetaDataBase &meta, size_t index, uint32
////////////////////////////////////////////////////////////////////////////////

AMRSource::AMRSource(
        DataSourceBase *source, MetaDataBase &meta,
        DataSourceHelper *source, MetaDataBase &meta,
        bool isWide, const off64_t *offset_table, size_t offset_table_length)
    : mDataSource(source),
      mMeta(meta),
@@ -372,15 +372,16 @@ ExtractorDef GETEXTRACTORDEF() {
        1,
        "AMR Extractor",
        [](
                DataSourceBase *source,
                CDataSource *source,
                float *confidence,
                void **,
                FreeMetaFunc *) -> CreatorFunc {
            if (SniffAMR(source, nullptr, confidence)) {
            DataSourceHelper helper(source);
            if (SniffAMR(&helper, nullptr, confidence)) {
                return [](
                        DataSourceBase *source,
                        CDataSource *source,
                        void *) -> CMediaExtractor* {
                    return wrap(new AMRExtractor(source));};
                    return wrap(new AMRExtractor(new DataSourceHelper(source)));};
            }
            return NULL;
        }
Loading