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

Commit 148c1a2a authored by James Dong's avatar James Dong
Browse files

Add basic metadata retrieval support for midi, ogg, etc.

Bug 2050320
parent e07db23c
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -44,6 +44,28 @@ class MediaMetadataRetrieverInterface : public MediaMetadataRetrieverBase
{
public:
    virtual             ~MediaMetadataRetrieverInterface() {}

    // @param mode The intended mode of operations:
    // can be any of the following:
    // METADATA_MODE_NOOP: Experimental - just add and remove data source.
    // METADATA_MODE_FRAME_CAPTURE_ONLY: For capture frame/thumbnail only.
    // METADATA_MODE_METADATA_RETRIEVAL_ONLY: For meta data retrieval only.
    // METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL: For both frame
    //     capture and meta data retrieval.
    virtual status_t    setMode(int mode) {
                            if (mode < METADATA_MODE_NOOP ||
                                mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) {
                                return BAD_VALUE;
                            }
                            return NO_ERROR;
                        }

    virtual status_t    getMode(int* mode) const { *mode = mMode; return NO_ERROR; }
    virtual VideoFrame* captureFrame() { return NULL; }
    virtual MediaAlbumArt* extractAlbumArt() { return NULL; }
    virtual const char* extractMetadata(int keyCode) { return NULL; }

    uint32_t mMode;
};

}; // namespace android
+12 −0
Original line number Diff line number Diff line
@@ -56,6 +56,18 @@ enum {
    // Add more here...
};

// The intended mode of operations:$
// METADATA_MODE_NOOP: Experimental - just add and remove data source.$
// METADATA_MODE_FRAME_CAPTURE_ONLY: For capture frame/thumbnail only.$
// METADATA_MODE_METADATA_RETRIEVAL_ONLY: For meta data retrieval only.$
// METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL: For both frame capture
//   and meta data retrieval.$
enum {
    METADATA_MODE_NOOP                                 = 0x00,
    METADATA_MODE_FRAME_CAPTURE_ONLY                   = 0x01,
    METADATA_MODE_METADATA_RETRIEVAL_ONLY              = 0x02,
    METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL = 0x03
};

class MediaMetadataRetriever: public RefBase
{
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ LOCAL_SRC_FILES:= \
    StagefrightPlayer.cpp       \
    TestPlayerStub.cpp          \
    VorbisPlayer.cpp            \
    VorbisMetadataRetriever.cpp \
    MidiMetadataRetriever.cpp \
    MidiFile.cpp

ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
+2 −2
Original line number Diff line number Diff line
@@ -611,7 +611,7 @@ static player_type getDefaultPlayerType() {
    return PV_PLAYER;
}

static player_type getPlayerType(int fd, int64_t offset, int64_t length)
player_type getPlayerType(int fd, int64_t offset, int64_t length)
{
    char buf[20];
    lseek(fd, offset, SEEK_SET);
@@ -644,7 +644,7 @@ static player_type getPlayerType(int fd, int64_t offset, int64_t length)
    return getDefaultPlayerType();
}

static player_type getPlayerType(const char* url)
player_type getPlayerType(const char* url)
{
    if (TestPlayerStub::canBeUsed(url)) {
        return TEST_PLAYER;
+55 −11
Original line number Diff line number Diff line
@@ -34,12 +34,15 @@
#include <media/MediaPlayerInterface.h>
#include <media/PVMetadataRetriever.h>
#include <private/media/VideoFrame.h>

#include "VorbisMetadataRetriever.h"
#include "MidiMetadataRetriever.h"
#include "MetadataRetrieverClient.h"


namespace android {

extern player_type getPlayerType(const char* url);
extern player_type getPlayerType(int fd, int64_t offset, int64_t length);

MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid)
{
    LOGV("MetadataRetrieverClient constructor pid(%d)", pid);
@@ -90,6 +93,36 @@ void MetadataRetrieverClient::disconnect()
    IPCThreadState::self()->flushCommands();
}

static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType)
{
    sp<MediaMetadataRetrieverBase> p;
    switch (playerType) {
#ifndef NO_OPENCORE
        case PV_PLAYER:
            LOGV("create pv metadata retriever");
            p = new PVMetadataRetriever();
            break;
#endif
        case VORBIS_PLAYER:
            LOGV("create vorbis metadata retriever");
            p = new VorbisMetadataRetriever();
            break;
        case SONIVOX_PLAYER:
            LOGV("create midi metadata retriever");
            p = new MidiMetadataRetriever();
            break;
        default:
            // TODO:
            // support for STAGEFRIGHT_PLAYER and TEST_PLAYER
            LOGE("player type %d is not supported",  playerType);
            break;
    }
    if (p == NULL) {
        LOGE("failed to create a retriever object");
    }
    return p;
}

status_t MetadataRetrieverClient::setDataSource(const char *url)
{
    LOGV("setDataSource(%s)", url);
@@ -97,11 +130,13 @@ status_t MetadataRetrieverClient::setDataSource(const char *url)
    if (url == NULL) {
        return UNKNOWN_ERROR;
    }
    if (mRetriever == NULL) {
        LOGE("retriever is not initialized");
        return NO_INIT;
    }
    return mRetriever->setDataSource(url);
    player_type playerType = getPlayerType(url);
    LOGV("player type = %d", playerType);
    sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
    if (p == NULL) return NO_INIT;
    status_t ret = p->setDataSource(url);
    if (ret == NO_ERROR) mRetriever = p;
    return ret;
}

status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t length)
@@ -118,7 +153,7 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t
    int ret = fstat(fd, &sb);
    if (ret != 0) {
        LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
        return UNKNOWN_ERROR;
        return BAD_VALUE;
    }
    LOGV("st_dev  = %llu", sb.st_dev);
    LOGV("st_mode = %u", sb.st_mode);
@@ -129,13 +164,22 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t
    if (offset >= sb.st_size) {
        LOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size);
        ::close(fd);
        return UNKNOWN_ERROR;
        return BAD_VALUE;
    }
    if (offset + length > sb.st_size) {
        length = sb.st_size - offset;
        LOGE("calculated length = %lld", length);
        LOGV("calculated length = %lld", length);
    }

    player_type playerType = getPlayerType(fd, offset, length);
    LOGV("player type = %d", playerType);
    sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
    if (p == NULL) {
        ::close(fd);
        return NO_INIT;
    }
    status_t status = mRetriever->setDataSource(fd, offset, length);
    status_t status = p->setDataSource(fd, offset, length);
    if (status == NO_ERROR) mRetriever = p;
    ::close(fd);
    return status;
}
Loading