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

Commit fac3e82e authored by Lajos Molnar's avatar Lajos Molnar Committed by Android (Google) Code Review
Browse files

Merge "cmds/stagefright: use MediaCodec* instead of OMXCodec" into nyc-dev

parents 00eb2fdb 5fb00a6d
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ LOCAL_SRC_FILES:= \

LOCAL_SHARED_LIBRARIES := \
	libstagefright libmedia libutils libbinder libstagefright_foundation \
        libjpeg libgui libcutils liblog libui
	libjpeg libgui libcutils liblog

LOCAL_C_INCLUDES:= \
	frameworks/av/media/libstagefright \
+18 −20
Original line number Diff line number Diff line
@@ -23,13 +23,14 @@
#include <binder/ProcessState.h>
#include <media/mediarecorder.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/AMRWriter.h>
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/MediaCodecSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/SimpleDecodingSource.h>
#include "SineSource.h"

using namespace android;
@@ -79,8 +80,6 @@ int main(int argc, char* argv[])
    const int32_t kBitRate = outputWBAMR ? 16000 : 8000;

    android::ProcessState::self()->startThreadPool();
    OMXClient client;
    CHECK_EQ(client.connect(), (status_t)OK);
    sp<MediaSource> source;

    if (useMic) {
@@ -95,24 +94,25 @@ int main(int argc, char* argv[])
        source = new SineSource(kSampleRate, channels);
    }

    sp<MetaData> meta = new MetaData;
    meta->setCString(
            kKeyMIMEType,
    sp<AMessage> meta = new AMessage;
    meta->setString(
            "mime",
            outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
                    : MEDIA_MIMETYPE_AUDIO_AMR_NB);

    meta->setInt32(kKeyChannelCount, channels);
    meta->setInt32(kKeySampleRate, kSampleRate);
    meta->setInt32(kKeyBitRate, kBitRate);
    meta->setInt32("channel-count", channels);
    meta->setInt32("sample-rate", kSampleRate);
    meta->setInt32("bitrate", kBitRate);
    int32_t maxInputSize;
    if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
        meta->setInt32(kKeyMaxInputSize, maxInputSize);
        meta->setInt32("max-input-size", maxInputSize);
    }

    sp<IMediaSource> encoder = OMXCodec::Create(
            client.interface(),
            meta, true /* createEncoder */,
            source);
    sp<ALooper> looper = new ALooper;
    looper->setName("audioloop");
    looper->start();

    sp<IMediaSource> encoder = MediaCodecSource::Create(looper, meta, source);

    if (fileOut != NULL) {
        // target file specified, write encoded AMR output
@@ -128,17 +128,15 @@ int main(int argc, char* argv[])
        writer->stop();
    } else {
        // otherwise decode to speaker
        sp<IMediaSource> decoder = OMXCodec::Create(
                client.interface(),
                meta, false /* createEncoder */,
                encoder);
        sp<IMediaSource> decoder = SimpleDecodingSource::Create(encoder);

        if (playToSpeaker) {
            AudioPlayer *player = new AudioPlayer(NULL);
            player->setSource(decoder);
            player->start();
            sleep(duration);
            source->stop(); // must stop source otherwise delete player will hang

            decoder.clear(); // must clear |decoder| otherwise delete player will hang.
            delete player; // there is no player->stop()...
        } else {
            CHECK_EQ(decoder->start(), (status_t)OK);
+29 −34
Original line number Diff line number Diff line
@@ -18,16 +18,18 @@

#include <binder/ProcessState.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/CameraSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaCodecSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/SimpleDecodingSource.h>
#include <media/MediaPlayerInterface.h>

using namespace android;
@@ -182,9 +184,6 @@ int main(int argc, char **argv) {
        fprintf(stderr, "input color format must be 0 (YUV420SP) or 1 (YUV420P)\n");
        return 1;
    }
    OMXClient client;
    CHECK_EQ(client.connect(), (status_t)OK);

    status_t err = OK;

#if 0
@@ -197,8 +196,7 @@ int main(int argc, char **argv) {

    sp<MetaData> meta = source->getFormat();

    sp<MediaSource> decoder = OMXCodec::Create(
            client.interface(), meta, false /* createEncoder */, source);
    sp<MediaSource> decoder = SimpleDecodingSource::Create(source);

    int width, height;
    bool success = meta->findInt32(kKeyWidth, &width);
@@ -210,22 +208,21 @@ int main(int argc, char **argv) {
    sp<MediaSource> decoder = new DummySource(width, height, colorFormat);
#endif

    sp<MetaData> enc_meta = new MetaData;
    // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
    // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
    enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
    enc_meta->setInt32(kKeyWidth, width);
    enc_meta->setInt32(kKeyHeight, height);
    enc_meta->setInt32(kKeySampleRate, kFramerate);
    enc_meta->setInt32(kKeyBitRate, kVideoBitRate);
    enc_meta->setInt32(kKeyStride, width);
    enc_meta->setInt32(kKeySliceHeight, height);
    enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
    enc_meta->setInt32(kKeyColorFormat, colorFormat);
    sp<AMessage> enc_meta = new AMessage;
    // enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_H263);
    // enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
    enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
    enc_meta->setInt32("width", width);
    enc_meta->setInt32("height", height);
    enc_meta->setInt32("sample-rate", kFramerate);
    enc_meta->setInt32("bit-rate", kVideoBitRate);
    // enc_meta->setInt32("stride", width);
    // enc_meta->setInt32("slice-height", height);
    enc_meta->setInt32("i-frame-interval", kIFramesIntervalSec);
    enc_meta->setInt32("color-format", colorFormat);

    sp<MediaSource> encoder =
        OMXCodec::Create(
                client.interface(), enc_meta, true /* createEncoder */, decoder);
        MediaCodecSource::Create(looper, format, decoder);

#if 1
    sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
@@ -260,7 +257,6 @@ int main(int argc, char **argv) {
#endif

    printf("$\n");
    client.disconnect();
#endif

#if 0
@@ -299,9 +295,6 @@ int main(int argc, char **argv) {
int main(int /* argc */, char ** /* argv */) {
    android::ProcessState::self()->startThreadPool();

    OMXClient client;
    CHECK_EQ(client.connect(), (status_t)OK);

    const int32_t kSampleRate = 22050;
    const int32_t kNumChannels = 2;
    sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels);
@@ -317,16 +310,20 @@ int main(int /* argc */, char ** /* argv */) {
    player->stop();
#endif

    sp<MetaData> encMeta = new MetaData;
    encMeta->setCString(kKeyMIMEType,
    sp<AMessage> encMeta = new AMessage;
    encMeta->setString("mime",
            0 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
    encMeta->setInt32(kKeySampleRate, kSampleRate);
    encMeta->setInt32(kKeyChannelCount, kNumChannels);
    encMeta->setInt32(kKeyMaxInputSize, 8192);
    encMeta->setInt32(kKeyBitRate, kAudioBitRate);
    encMeta->setInt32("sample-rate", kSampleRate);
    encMeta->setInt32("channel-count", kNumChannels);
    encMeta->setInt32("max-input-size", 8192);
    encMeta->setInt32("bitrate", kAudioBitRate);

    sp<ALooper> looper = new ALooper;
    looper->setName("record");
    looper->start();

    sp<IMediaSource> encoder =
        OMXCodec::Create(client.interface(), encMeta, true, audioSource);
        MediaCodecSource::Create(looper, encMeta, audioSource);

    encoder->start();

@@ -348,8 +345,6 @@ int main(int /* argc */, char ** /* argv */) {

    encoder->stop();

    client.disconnect();

    return 0;
}
#endif
+26 −23
Original line number Diff line number Diff line
@@ -23,15 +23,18 @@

#include <binder/ProcessState.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaCodecSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/MediaPlayerInterface.h>

#include <OMX_Video.h>

using namespace android;

// Print usage showing how to use this utility to record videos
@@ -265,44 +268,45 @@ int main(int argc, char **argv) {
        }
    }

    OMXClient client;
    CHECK_EQ(client.connect(), (status_t)OK);

    status_t err = OK;
    sp<MediaSource> source =
        new DummySource(width, height, nFrames, frameRateFps, colorFormat);

    sp<MetaData> enc_meta = new MetaData;
    sp<AMessage> enc_meta = new AMessage;
    switch (codec) {
        case 1:
            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
            enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
            break;
        case 2:
            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
            enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_H263);
            break;
        default:
            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
            enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
            break;
    }
    enc_meta->setInt32(kKeyWidth, width);
    enc_meta->setInt32(kKeyHeight, height);
    enc_meta->setInt32(kKeyFrameRate, frameRateFps);
    enc_meta->setInt32(kKeyBitRate, bitRateBps);
    enc_meta->setInt32(kKeyStride, width);
    enc_meta->setInt32(kKeySliceHeight, height);
    enc_meta->setInt32(kKeyIFramesInterval, iFramesIntervalSeconds);
    enc_meta->setInt32(kKeyColorFormat, colorFormat);
    enc_meta->setInt32("width", width);
    enc_meta->setInt32("height", height);
    enc_meta->setInt32("frame-rate", frameRateFps);
    enc_meta->setInt32("bitrate", bitRateBps);
    enc_meta->setInt32("stride", width);
    enc_meta->setInt32("slice-height", height);
    enc_meta->setInt32("i-frame-interval", iFramesIntervalSeconds);
    enc_meta->setInt32("color-format", colorFormat);
    if (level != -1) {
        enc_meta->setInt32(kKeyVideoLevel, level);
        enc_meta->setInt32("level", level);
    }
    if (profile != -1) {
        enc_meta->setInt32(kKeyVideoProfile, profile);
        enc_meta->setInt32("profile", profile);
    }

    sp<ALooper> looper = new ALooper;
    looper->setName("recordvideo");
    looper->start();

    sp<IMediaSource> encoder =
        OMXCodec::Create(
                client.interface(), enc_meta, true /* createEncoder */, source,
                0, preferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0);
        MediaCodecSource::Create(
                looper, enc_meta, source, NULL /* consumer */,
                preferSoftwareCodec ? MediaCodecSource::FLAG_PREFER_SOFTWARE_CODEC : 0);

    int fd = open(fileName, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd < 0) {
@@ -321,7 +325,6 @@ int main(int argc, char **argv) {
    int64_t end = systemTime();

    fprintf(stderr, "$\n");
    client.disconnect();

    if (err != OK && err != ERROR_END_OF_STREAM) {
        fprintf(stderr, "record failed: %d\n", err);
+40 −71
Original line number Diff line number Diff line
@@ -31,20 +31,26 @@

#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <media/ICrypto.h>
#include <media/IMediaHTTPService.h>
#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>
#include "include/NuCachedSource2.h"
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/JPEGSource.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/SimpleDecodingSource.h>
#include <media/stagefright/Utils.h>
#include <media/mediametadataretriever.h>

#include <media/stagefright/foundation/hexdump.h>
@@ -164,7 +170,7 @@ static void dumpSource(const sp<IMediaSource> &source, const String8 &filename)
    out = NULL;
}

static void playSource(OMXClient *client, sp<IMediaSource> &source) {
static void playSource(sp<IMediaSource> &source) {
    sp<MetaData> meta = source->getFormat();

    const char *mime;
@@ -176,20 +182,14 @@ static void playSource(OMXClient *client, sp<IMediaSource> &source) {
    } else {
        int flags = 0;
        if (gPreferSoftwareCodec) {
            flags |= OMXCodec::kPreferSoftwareCodecs;
            flags |= MediaCodecList::kPreferSoftwareCodecs;
        }
        if (gForceToUseHardwareCodec) {
            CHECK(!gPreferSoftwareCodec);
            flags |= OMXCodec::kHardwareCodecsOnly;
            flags |= MediaCodecList::kHardwareCodecsOnly;
        }
        rawSource = OMXCodec::Create(
            client->interface(), meta, false /* createEncoder */, source,
            NULL /* matchComponentName */,
            flags,
            gSurface);

        rawSource = SimpleDecodingSource::Create(source, flags, gSurface);
        if (rawSource == NULL) {
            fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime);
            return;
        }
        displayAVCProfileLevelIfPossible(meta);
@@ -343,12 +343,6 @@ static void playSource(OMXClient *client, sp<IMediaSource> &source) {
                    printf(".");
                    fflush(stdout);
                }

                // render buffers from OMXCodec
                if (buffer->graphicBuffer() != NULL && gSurface != NULL) {
                    gSurface->queueBuffer(gSurface.get(), buffer->graphicBuffer()->getNativeBuffer(), -1);
                    buffer->meta_data()->setInt32(kKeyRendered, 1);
                }
            }

            sumDecodeUs += delayDecodeUs;
@@ -628,7 +622,7 @@ static void usage(const char *me) {
    fprintf(stderr, "       -D(ump) output_filename (decoded PCM data to a file)\n");
}

static void dumpCodecProfiles(const sp<IOMX>& omx, bool queryDecoders) {
static void dumpCodecProfiles(bool queryDecoders) {
    const char *kMimeTypes[] = {
        MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
        MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC,
@@ -642,29 +636,35 @@ static void dumpCodecProfiles(const sp<IOMX>& omx, bool queryDecoders) {
    const char *codecType = queryDecoders? "decoder" : "encoder";
    printf("%s profiles:\n", codecType);

    sp<IMediaCodecList> list = MediaCodecList::getInstance();
    size_t numCodecs = list->countCodecs();

    for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); ++k) {
        printf("type '%s':\n", kMimeTypes[k]);

        Vector<CodecCapabilities> results;
        // will retrieve hardware and software codecs
        CHECK_EQ(QueryCodecs(omx, kMimeTypes[k],
                             queryDecoders,
                             &results), (status_t)OK);

        for (size_t i = 0; i < results.size(); ++i) {
        for (size_t index = 0; index < numCodecs; ++index) {
            sp<MediaCodecInfo> info = list->getCodecInfo(index);
            if (info == NULL || info->isEncoder() != !queryDecoders) {
                continue;
            }
            sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(kMimeTypes[k]);
            if (caps == NULL) {
                continue;
            }
            printf("  %s '%s' supports ",
                       codecType, results[i].mComponentName.string());
                       codecType, info->getCodecName());

            if (results[i].mProfileLevels.size() == 0) {
            Vector<MediaCodecInfo::ProfileLevel> profileLevels;
            caps->getSupportedProfileLevels(&profileLevels);
            if (profileLevels.size() == 0) {
                printf("NOTHING.\n");
                continue;
            }

            for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) {
                const CodecProfileLevel &profileLevel =
                     results[i].mProfileLevels[j];
            for (size_t j = 0; j < profileLevels.size(); ++j) {
                const MediaCodecInfo::ProfileLevel &profileLevel = profileLevels[j];

                printf("%s%" PRIu32 "/%" PRIu32, j > 0 ? ", " : "",
                printf("%s%u/%u", j > 0 ? ", " : "",
                        profileLevel.mProfile, profileLevel.mLevel);
            }

@@ -898,17 +898,8 @@ int main(int argc, char **argv) {
    }

    if (dumpProfiles) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder = sm->getService(String16("media.player"));
        sp<IMediaPlayerService> service =
            interface_cast<IMediaPlayerService>(binder);

        CHECK(service.get() != NULL);

        sp<IOMX> omx = service->getOMX();
        CHECK(omx.get() != NULL);
        dumpCodecProfiles(omx, true /* queryDecoders */);
        dumpCodecProfiles(omx, false /* queryDecoders */);
        dumpCodecProfiles(true /* queryDecoders */);
        dumpCodecProfiles(false /* queryDecoders */);
    }

    if (listComponents) {
@@ -971,16 +962,11 @@ int main(int argc, char **argv) {
                    false /* isControlledByApp */);
            gSurface = new Surface(producer);
        }

        CHECK_EQ((status_t)OK,
                 native_window_api_connect(
                     gSurface.get(), NATIVE_WINDOW_API_MEDIA));
    }

    DataSource::RegisterDefaultSniffers();

    OMXClient client;
    status_t err = client.connect();
    status_t err = OK;

    for (int k = 0; k < argc && err == OK; ++k) {
        bool syncInfoPresent = true;
@@ -1120,31 +1106,16 @@ int main(int argc, char **argv) {
        } else if (dumpStream) {
            dumpSource(mediaSource, dumpStreamFilename);
        } else if (dumpPCMStream) {
            OMXClient client;
            CHECK_EQ(client.connect(), (status_t)OK);

            sp<IMediaSource> decSource =
                OMXCodec::Create(
                        client.interface(),
                        mediaSource->getFormat(),
                        false,
                        mediaSource,
                        0,
                        0);

            sp<IMediaSource> decSource = SimpleDecodingSource::Create(mediaSource);
            dumpSource(decSource, dumpStreamFilename);
        } else if (seekTest) {
            performSeekTest(mediaSource);
        } else {
            playSource(&client, mediaSource);
            playSource(mediaSource);
        }
    }

    if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
        CHECK_EQ((status_t)OK,
                 native_window_api_disconnect(
                     gSurface.get(), NATIVE_WINDOW_API_MEDIA));

        gSurface.clear();

        if (useSurfaceAlloc) {
@@ -1152,7 +1123,5 @@ int main(int argc, char **argv) {
        }
    }

    client.disconnect();

    return 0;
}