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

Commit 45bac57a authored by Andreas Huber's avatar Andreas Huber
Browse files

Support for writing the extracted data to an .mp4 file in the stagefright commandline tool.

Change-Id: I972324a8fc9757e6e8116b0270ec0882106f8733
parent a2dd4c17
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ LOCAL_SRC_FILES:= \
	SineSource.cpp

LOCAL_SHARED_LIBRARIES := \
	libstagefright libmedia libutils libbinder
	libstagefright libmedia libutils libbinder libstagefright_foundation

LOCAL_C_INCLUDES:= \
	$(JNI_H_INCLUDE) \
+35 −2
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@
#include <media/stagefright/OMXCodec.h>
#include <media/mediametadataretriever.h>

#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MPEG4Writer.h>

using namespace android;

static long gNumRepetitions;
@@ -45,6 +48,8 @@ static long gMaxNumFrames; // 0 means decode all available.
static long gReproduceBug;  // if not -1.
static bool gPreferSoftwareCodec;
static bool gPlaybackAudio;
static bool gWriteMP4;
static String8 gWriteMP4Filename;

static int64_t getNowUs() {
    struct timeval tv;
@@ -258,6 +263,21 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
    }
}

static void writeSourceToMP4(const sp<MediaSource> &source) {
    sp<MPEG4Writer> writer =
        new MPEG4Writer(gWriteMP4Filename.string());

    CHECK_EQ(writer->addSource(source), OK);

    sp<MetaData> params = new MetaData;
    CHECK_EQ(writer->start(), OK);

    while (!writer->reachedEOS()) {
        usleep(100000);
    }
    writer->stop();
}

static void usage(const char *me) {
    fprintf(stderr, "usage: %s\n", me);
    fprintf(stderr, "       -h(elp)\n");
@@ -270,6 +290,7 @@ static void usage(const char *me) {
    fprintf(stderr, "       -t(humbnail) extract video thumbnail or album art\n");
    fprintf(stderr, "       -s(oftware) prefer software codec\n");
    fprintf(stderr, "       -o playback audio\n");
    fprintf(stderr, "       -w(rite) filename (write to .mp4 file)\n");
}

int main(int argc, char **argv) {
@@ -284,9 +305,10 @@ int main(int argc, char **argv) {
    gReproduceBug = -1;
    gPreferSoftwareCodec = false;
    gPlaybackAudio = false;
    gWriteMP4 = false;

    int res;
    while ((res = getopt(argc, argv, "han:lm:b:ptso")) >= 0) {
    while ((res = getopt(argc, argv, "han:lm:b:ptsow:")) >= 0) {
        switch (res) {
            case 'a':
            {
@@ -322,6 +344,13 @@ int main(int argc, char **argv) {
                break;
            }

            case 'w':
            {
                gWriteMP4 = true;
                gWriteMP4Filename.setTo(optarg);
                break;
            }

            case 'p':
            {
                dumpProfiles = true;
@@ -554,8 +583,12 @@ int main(int argc, char **argv) {
            mediaSource = extractor->getTrack(i);
        }

        if (gWriteMP4) {
            writeSourceToMP4(mediaSource);
        } else {
            playSource(&client, mediaSource);
        }
    }

    client.disconnect();

+4 −1
Original line number Diff line number Diff line
@@ -27,7 +27,10 @@ struct MediaSource;
struct MetaData;

struct MediaWriter : public RefBase {
    MediaWriter() {}
    MediaWriter()
        : mMaxFileSizeLimitBytes(0),
          mMaxFileDurationLimitUs(0) {
    }

    virtual status_t addSource(const sp<MediaSource> &source) = 0;
    virtual bool reachedEOS() = 0;
+40 −1
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include <media/mediarecorder.h>
#include <cutils/properties.h>

#include "include/ESDS.h"

namespace android {

class MPEG4Writer::Track {
@@ -126,6 +128,8 @@ private:
            int32_t *min, int32_t *avg, int32_t *max);
    void findMinMaxChunkDurations(int64_t *min, int64_t *max);

    void getCodecSpecificDataFromInputFormatIfPossible();

    Track(const Track &);
    Track &operator=(const Track &);
};
@@ -678,6 +682,38 @@ MPEG4Writer::Track::Track(
      mCodecSpecificDataSize(0),
      mGotAllCodecSpecificData(false),
      mReachedEOS(false) {
    getCodecSpecificDataFromInputFormatIfPossible();
}

void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
    const char *mime;
    CHECK(mMeta->findCString(kKeyMIMEType, &mime));

    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
        uint32_t type;
        const void *data;
        size_t size;
        if (mMeta->findData(kKeyAVCC, &type, &data, &size)) {
            mCodecSpecificData = malloc(size);
            mCodecSpecificDataSize = size;
            memcpy(mCodecSpecificData, data, size);
            mGotAllCodecSpecificData = true;
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
        uint32_t type;
        const void *data;
        size_t size;
        if (mMeta->findData(kKeyESDS, &type, &data, &size)) {
            ESDS esds(data, size);
            if (esds.getCodecSpecificInfo(&data, &size) == OK) {
                mCodecSpecificData = malloc(size);
                mCodecSpecificDataSize = size;
                memcpy(mCodecSpecificData, data, size);
                mGotAllCodecSpecificData = true;
            }
        }
    }
}

MPEG4Writer::Track::~Track() {
@@ -721,7 +757,10 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
    }

    int64_t startTimeUs;
    CHECK(params && params->findInt64(kKeyTime, &startTimeUs));
    if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
        startTimeUs = 0;
    }

    initTrackingProgressStatus(params);

    sp<MetaData> meta = new MetaData;