stagefright.cpp revision 20111aa043c5f404472bc63b90bc5aad906b1101
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <sys/time.h>
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#undef NDEBUG
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <assert.h>
2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <pthread.h>
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h>
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/IServiceManager.h>
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/ProcessState.h>
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/IMediaPlayerService.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/AudioPlayer.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CachingDataSource.h>
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/ESDS.h>
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/FileSource.h>
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h>
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaPlayerImpl.h>
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaExtractor.h>
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h>
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MmapSource.h>
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXClient.h>
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXDecoder.h>
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include "WaveWriter.h"
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android;
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic bool convertToWav(
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        OMXClient *client, const sp<MetaData> &meta, MediaSource *source) {
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    printf("convertToWav\n");
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    OMXDecoder *decoder = OMXDecoder::Create(client, meta);
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t sampleRate;
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = meta->findInt32(kKeySampleRate, &sampleRate);
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    assert(success);
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t numChannels;
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = meta->findInt32(kKeyChannelCount, &numChannels);
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    assert(success);
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = meta->findCString(kKeyMIMEType, &mime);
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    assert(success);
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!strcasecmp("audio/3gpp", mime)) {
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        numChannels = 1;  // XXX
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    WaveWriter writer("/sdcard/Music/shoutcast.wav", numChannels, sampleRate);
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    decoder->setSource(source);
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (int i = 0; i < 100; ++i) {
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer *buffer;
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        ::status_t err = decoder->read(&buffer);
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != ::OK) {
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        writer.Append((const char *)buffer->data() + buffer->range_offset(),
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                      buffer->range_length());
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer->release();
8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer = NULL;
8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete decoder;
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    decoder = NULL;
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int64_t getNowUs() {
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    struct timeval tv;
9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    gettimeofday(&tv, NULL);
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) {
10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    android::ProcessState::self()->startThreadPool();
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (argc > 1 && !strcmp(argv[1], "--list")) {
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        sp<IServiceManager> sm = defaultServiceManager();
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        sp<IBinder> binder = sm->getService(String16("media.player"));
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        assert(service.get() != NULL);
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        sp<IOMX> omx = service->createOMX();
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        assert(omx.get() != NULL);
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        List<String8> list;
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        omx->list_nodes(&list);
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (List<String8>::iterator it = list.begin();
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber             it != list.end(); ++it) {
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            printf("%s\n", (*it).string());
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return 0;
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0
12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaPlayerImpl player(argv[1]);
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    player.play();
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sleep(10000);
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#else
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    DataSource::RegisterDefaultSniffers();
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    OMXClient client;
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err = client.connect();
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MmapSource *dataSource = new MmapSource(argv[1]);
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaExtractor *extractor = MediaExtractor::Create(dataSource);
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    dataSource = NULL;
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int numTracks;
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    err = extractor->countTracks(&numTracks);
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> meta;
14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int i;
14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (i = 0; i < numTracks; ++i) {
14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        meta = extractor->getTrackMetaData(i);
14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const char *mime;
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        meta->findCString(kKeyMIMEType, &mime);
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (!strncasecmp(mime, "video/", 6)) {
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    OMXDecoder *decoder = OMXDecoder::Create(&client, meta);
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (decoder != NULL) {
16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaSource *source;
16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        err = extractor->getTrack(i, &source);
16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        decoder->setSource(source);
16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        decoder->start();
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        int64_t startTime = getNowUs();
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        int n = 0;
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer *buffer;
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        while ((err = decoder->read(&buffer)) == OK) {
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if ((++n % 16) == 0) {
17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(".");
17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                fflush(stdout);
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            buffer->release();
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            buffer = NULL;
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        decoder->stop();
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("\n");
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        int64_t delay = getNowUs() - startTime;
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("avg. %.2f fps\n", n * 1E6 / delay);
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete decoder;
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        decoder = NULL;
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete source;
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        source = NULL;
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete extractor;
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    extractor = NULL;
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    client.disconnect();
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return 0;
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
201