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

Commit a1c7b096 authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am 6d8fae72: Merge "Instead of just writing one track to the .mp4 file, write...

am 6d8fae72: Merge "Instead of just writing one track to the .mp4 file, write all of them (at most 1 video and 1 audio track). Also support httplive URIs in the stagefright commandline tool." into gingerbread

Merge commit '6d8fae72' into gingerbread-plus-aosp

* commit '6d8fae72':
  Instead of just writing one track to the .mp4 file, write all of them (at most 1 video and 1 audio track). Also support httplive URIs in the stagefright commandline tool.
parents 2d457a32 6d8fae72
Loading
Loading
Loading
Loading
+111 −42
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/ALooper.h>
#include "include/ARTSPController.h"
#include "include/LiveSource.h"
#include "include/NuCachedSource2.h"
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/JPEGSource.h>
@@ -285,19 +287,34 @@ struct DetectSyncSource : public MediaSource {
            MediaBuffer **buffer, const ReadOptions *options);

private:
    enum StreamType {
        AVC,
        MPEG4,
        H263,
        OTHER,
    };

    sp<MediaSource> mSource;
    bool mIsAVC;
    StreamType mStreamType;

    DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource);
};

DetectSyncSource::DetectSyncSource(const sp<MediaSource> &source)
    : mSource(source),
      mIsAVC(false) {
      mStreamType(OTHER) {
    const char *mime;
    CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));

    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
        mStreamType = AVC;
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
        mStreamType = MPEG4;
        CHECK(!"sync frame detection not implemented yet for MPEG4");
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
        mStreamType = H263;
        CHECK(!"sync frame detection not implemented yet for H.263");
    }
}

status_t DetectSyncSource::start(MetaData *params) {
@@ -336,10 +353,10 @@ status_t DetectSyncSource::read(
        return err;
    }

    if (mIsAVC && isIDRFrame(*buffer)) {
    if (mStreamType == AVC && isIDRFrame(*buffer)) {
        (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true);
    } else {
        (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, false);
        (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true);
    }

    return OK;
@@ -347,19 +364,21 @@ status_t DetectSyncSource::read(

////////////////////////////////////////////////////////////////////////////////

static void writeSourceToMP4(
        sp<MediaSource> &source, bool syncInfoPresent) {
    if (!syncInfoPresent) {
        source = new DetectSyncSource(source);
    }

static void writeSourcesToMP4(
        Vector<sp<MediaSource> > &sources, bool syncInfoPresent) {
    sp<MPEG4Writer> writer =
        new MPEG4Writer(gWriteMP4Filename.string());

    // at most one minute.
    writer->setMaxFileDuration(60000000ll);

    CHECK_EQ(writer->addSource(source), (status_t)OK);
    for (size_t i = 0; i < sources.size(); ++i) {
        sp<MediaSource> source = sources.editItemAt(i);

        CHECK_EQ(writer->addSource(
                    syncInfoPresent ? source : new DetectSyncSource(source)),
                (status_t)OK);
    }

    sp<MetaData> params = new MetaData;
    params->setInt32(kKeyNotRealTime, true);
@@ -674,8 +693,10 @@ int main(int argc, char **argv) {

        sp<DataSource> dataSource = DataSource::CreateFromURI(filename);

        if ((strncasecmp(filename, "sine:", 5)
                && strncasecmp(filename, "rtsp://", 7)) && dataSource == NULL) {
        if (strncasecmp(filename, "sine:", 5)
                && strncasecmp(filename, "rtsp://", 7)
                && strncasecmp(filename, "httplive://", 11)
                && dataSource == NULL) {
            fprintf(stderr, "Unable to create data source.\n");
            return 1;
        }
@@ -687,10 +708,14 @@ int main(int argc, char **argv) {
            isJPEG = true;
        }

        Vector<sp<MediaSource> > mediaSources;
        sp<MediaSource> mediaSource;

        if (isJPEG) {
            mediaSource = new JPEGSource(dataSource);
            if (gWriteMP4) {
                mediaSources.push(mediaSource);
            }
        } else if (!strncasecmp("sine:", filename, 5)) {
            char *end;
            long sampleRate = strtol(filename + 5, &end, 10);
@@ -699,6 +724,9 @@ int main(int argc, char **argv) {
                sampleRate = 44100;
            }
            mediaSource = new SineSource(sampleRate, 1);
            if (gWriteMP4) {
                mediaSources.push(mediaSource);
            }
        } else {
            sp<MediaExtractor> extractor;

@@ -717,6 +745,18 @@ int main(int argc, char **argv) {

                extractor = rtspController.get();

                syncInfoPresent = false;
            } else if (!strncasecmp("httplive://", filename, 11)) {
                String8 uri("http://");
                uri.append(filename + 11);

                dataSource = new LiveSource(uri.string());
                dataSource = new NuCachedSource2(dataSource);

                extractor =
                    MediaExtractor::Create(
                            dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);

                syncInfoPresent = false;
            } else {
                extractor = MediaExtractor::Create(dataSource);
@@ -728,6 +768,34 @@ int main(int argc, char **argv) {

            size_t numTracks = extractor->countTracks();

            if (gWriteMP4) {
                bool haveAudio = false;
                bool haveVideo = false;
                for (size_t i = 0; i < numTracks; ++i) {
                    sp<MediaSource> source = extractor->getTrack(i);

                    const char *mime;
                    CHECK(source->getFormat()->findCString(
                                kKeyMIMEType, &mime));

                    bool useTrack = false;
                    if (!haveAudio && !strncasecmp("audio/", mime, 6)) {
                        haveAudio = true;
                        useTrack = true;
                    } else if (!haveVideo && !strncasecmp("video/", mime, 6)) {
                        haveVideo = true;
                        useTrack = true;
                    }

                    if (useTrack) {
                        mediaSources.push(source);

                        if (haveAudio && haveVideo) {
                            break;
                        }
                    }
                }
            } else {
                sp<MetaData> meta;
                size_t i;
                for (i = 0; i < numTracks; ++i) {
@@ -765,9 +833,10 @@ int main(int argc, char **argv) {

                mediaSource = extractor->getTrack(i);
            }
        }

        if (gWriteMP4) {
            writeSourceToMP4(mediaSource, syncInfoPresent);
            writeSourcesToMP4(mediaSources, syncInfoPresent);
        } else if (seekTest) {
            performSeekTest(mediaSource);
        } else {