/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/time.h>

#undef NDEBUG
#include <assert.h>

#include <pthread.h>
#include <stdlib.h>

#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <media/IMediaPlayerService.h>
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/CachingDataSource.h>
#include <media/stagefright/ESDS.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaPlayerImpl.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXDecoder.h>

#include "WaveWriter.h"

using namespace android;

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

static bool convertToWav(
        OMXClient *client, const sp<MetaData> &meta, MediaSource *source) {
    printf("convertToWav\n");

    OMXDecoder *decoder = OMXDecoder::Create(client, meta);

    int32_t sampleRate;
    bool success = meta->findInt32(kKeySampleRate, &sampleRate);
    assert(success);

    int32_t numChannels;
    success = meta->findInt32(kKeyChannelCount, &numChannels);
    assert(success);

    const char *mime;
    success = meta->findCString(kKeyMIMEType, &mime);
    assert(success);

    if (!strcasecmp("audio/3gpp", mime)) {
        numChannels = 1;  // XXX
    }

    WaveWriter writer("/sdcard/Music/shoutcast.wav", numChannels, sampleRate);

    decoder->setSource(source);
    for (int i = 0; i < 100; ++i) {
        MediaBuffer *buffer;

        ::status_t err = decoder->read(&buffer);
        if (err != ::OK) {
            break;
        }

        writer.Append((const char *)buffer->data() + buffer->range_offset(),
                      buffer->range_length());

        buffer->release();
        buffer = NULL;
    }

    delete decoder;
    decoder = NULL;

    return true;
}

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

static int64_t getNowUs() {
    struct timeval tv;
    gettimeofday(&tv, NULL);

    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
}

int main(int argc, char **argv) {
    android::ProcessState::self()->startThreadPool();

    if (argc > 1 && !strcmp(argv[1], "--list")) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder = sm->getService(String16("media.player"));
        sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);

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

        sp<IOMX> omx = service->createOMX();
        assert(omx.get() != NULL);

        List<String8> list;
        omx->list_nodes(&list);

        for (List<String8>::iterator it = list.begin();
             it != list.end(); ++it) {
            printf("%s\n", (*it).string());
        }

        return 0;
    }

#if 0
    MediaPlayerImpl player(argv[1]);
    player.play();

    sleep(10000);
#else
    DataSource::RegisterDefaultSniffers();

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

    MmapSource *dataSource = new MmapSource(argv[1]);
    MediaExtractor *extractor = MediaExtractor::Create(dataSource);
    dataSource = NULL;

    int numTracks;
    err = extractor->countTracks(&numTracks);

    sp<MetaData> meta;
    int i;
    for (i = 0; i < numTracks; ++i) {
        meta = extractor->getTrackMetaData(i);

        const char *mime;
        meta->findCString(kKeyMIMEType, &mime);

        if (!strncasecmp(mime, "video/", 6)) {
            break;
        }
    }

    OMXDecoder *decoder = OMXDecoder::Create(&client, meta);

    if (decoder != NULL) {
        MediaSource *source;
        err = extractor->getTrack(i, &source);

        decoder->setSource(source);

        decoder->start();

        int64_t startTime = getNowUs();

        int n = 0;
        MediaBuffer *buffer;
        while ((err = decoder->read(&buffer)) == OK) {
            if ((++n % 16) == 0) {
                printf(".");
                fflush(stdout);
            }

            buffer->release();
            buffer = NULL;
        }
        decoder->stop();
        printf("\n");

        int64_t delay = getNowUs() - startTime;
        printf("avg. %.2f fps\n", n * 1E6 / delay);

        delete decoder;
        decoder = NULL;

        delete source;
        source = NULL;
    }

    delete extractor;
    extractor = NULL;

    client.disconnect();
#endif

    return 0;
}
