/*
 * Copyright (C) 2011 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.
 */

// OpenMAX AL MediaPlayer command-line player

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <OMXAL/OpenMAXAL.h>
#include <OMXAL/OpenMAXAL_Android.h>
#include "nativewindow.h"

#define MPEG2TS_PACKET_SIZE 188  // MPEG-2 transport stream packet size in bytes
#define PACKETS_PER_BUFFER 20    // Number of MPEG-2 transport stream packets per buffer

#define NB_BUFFERS 2    // Number of buffers in Android buffer queue

// MPEG-2 transport stream packet
typedef struct {
    char data[MPEG2TS_PACKET_SIZE];
} MPEG2TS_Packet;

#if 0
// Each buffer in Android buffer queue
typedef struct {
    MPEG2TS_Packet packets[PACKETS_PER_BUFFER];
} Buffer;
#endif

// Globals shared between main thread and buffer queue callback
MPEG2TS_Packet *packets;
size_t numPackets;
size_t curPacket;
size_t discPacket;

// These are extensions to OpenMAX AL 1.0.1 values

#define PREFETCHSTATUS_UNKNOWN ((XAuint32) 0)
#define PREFETCHSTATUS_ERROR   ((XAuint32) (-1))

// Mutex and condition shared with main program to protect prefetch_status

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
XAuint32 prefetch_status = PREFETCHSTATUS_UNKNOWN;

/* used to detect errors likely to have occured when the OpenMAX AL framework fails to open
 * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond.
 */
#define PREFETCHEVENT_ERROR_CANDIDATE \
        (XA_PREFETCHEVENT_STATUSCHANGE | XA_PREFETCHEVENT_FILLLEVELCHANGE)

// stream event change callback
void streamEventChangeCallback(XAStreamInformationItf caller, XAuint32 eventId,
        XAuint32 streamIndex, void *pEventData, void *pContext)
{
    // context parameter is specified as NULL and is unused here
    assert(NULL == pContext);
    switch (eventId) {
    case XA_STREAMCBEVENT_PROPERTYCHANGE:
        printf("XA_STREAMCBEVENT_PROPERTYCHANGE on stream index %u, pEventData %p\n", streamIndex,
                pEventData);
        break;
    default:
        printf("Unknown stream event ID %u\n", eventId);
        break;
    }
}

// prefetch status callback
void prefetchStatusCallback(XAPrefetchStatusItf caller,  void *pContext, XAuint32 event)
{
    // pContext is unused here, so we pass NULL
    assert(pContext == NULL);
    XApermille level = 0;
    XAresult result;
    result = (*caller)->GetFillLevel(caller, &level);
    assert(XA_RESULT_SUCCESS == result);
    XAuint32 status;
    result = (*caller)->GetPrefetchStatus(caller, &status);
    assert(XA_RESULT_SUCCESS == result);
    if (event & XA_PREFETCHEVENT_FILLLEVELCHANGE) {
        printf("PrefetchEventCallback: Buffer fill level is = %d\n", level);
    }
    if (event & XA_PREFETCHEVENT_STATUSCHANGE) {
        printf("PrefetchEventCallback: Prefetch Status is = %u\n", status);
    }
    XAuint32 new_prefetch_status;
    if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE))
            && (level == 0) && (status == XA_PREFETCHSTATUS_UNDERFLOW)) {
        printf("PrefetchEventCallback: Error while prefetching data, exiting\n");
        new_prefetch_status = PREFETCHSTATUS_ERROR;
    } else if (event == XA_PREFETCHEVENT_STATUSCHANGE) {
        new_prefetch_status = status;
    } else {
        return;
    }
    int ok;
    ok = pthread_mutex_lock(&mutex);
    assert(ok == 0);
    prefetch_status = new_prefetch_status;
    ok = pthread_cond_signal(&cond);
    assert(ok == 0);
    ok = pthread_mutex_unlock(&mutex);
    assert(ok == 0);
}

// playback event callback
void playEventCallback(XAPlayItf caller, void *pContext, XAuint32 event)
{
    // pContext is unused here, so we pass NULL
    assert(NULL == pContext);

    XAmillisecond position;

    if (XA_PLAYEVENT_HEADATEND & event) {
        printf("XA_PLAYEVENT_HEADATEND reached\n");
        //SignalEos();
    }

    XAresult result;
    if (XA_PLAYEVENT_HEADATNEWPOS & event) {
        result = (*caller)->GetPosition(caller, &position);
        assert(XA_RESULT_SUCCESS == result);
        printf("XA_PLAYEVENT_HEADATNEWPOS current position=%ums\n", position);
    }

    if (XA_PLAYEVENT_HEADATMARKER & event) {
        result = (*caller)->GetPosition(caller, &position);
        assert(XA_RESULT_SUCCESS == result);
        printf("XA_PLAYEVENT_HEADATMARKER current position=%ums\n", position);
    }
}

// Android buffer queue callback
XAresult bufferQueueCallback(
        XAAndroidBufferQueueItf caller,
        void *pCallbackContext,
        void *pBufferContext,
        void *pBufferData,
        XAuint32 dataSize,
        XAuint32 dataUsed,
        const XAAndroidBufferItem *pItems,
        XAuint32 itemsLength)
{
    // enqueue the .ts data directly from mapped memory, so ignore the empty buffer pBufferData
    if (curPacket <= numPackets) {
        static const XAAndroidBufferItem discontinuity = {XA_ANDROID_ITEMKEY_DISCONTINUITY, 0};
        static const XAAndroidBufferItem eos = {XA_ANDROID_ITEMKEY_EOS, 0};
        const XAAndroidBufferItem *items;
        XAuint32 itemSize;
        // compute number of packets to be enqueued in this buffer
        XAuint32 packetsThisBuffer = numPackets - curPacket;
        if (packetsThisBuffer > PACKETS_PER_BUFFER) {
            packetsThisBuffer = PACKETS_PER_BUFFER;
        }
        // last packet? this should only happen once
        if (curPacket == numPackets) {
            (void) write(1, "e", 1);
            items = &eos;
            itemSize = sizeof(eos);
        // discontinuity requested?
        } else if (curPacket == discPacket) {
            printf("sending discontinuity, rewinding from beginning of stream\n");
            items = &discontinuity;
            itemSize = sizeof(discontinuity);
            curPacket = 0;
        // pure data with no items
        } else {
            items = NULL;
            itemSize = 0;
        }
        XAresult result;
        // enqueue the optional data and optional items; there is always at least one or the other
        assert(packetsThisBuffer > 0 || itemSize > 0);
        result = (*caller)->Enqueue(caller, NULL, &packets[curPacket],
                sizeof(MPEG2TS_Packet) * packetsThisBuffer, items, itemSize);
        assert(XA_RESULT_SUCCESS == result);
        curPacket += packetsThisBuffer;
    }
    return XA_RESULT_SUCCESS;
}

// main program
int main(int argc, char **argv)
{
    const char *prog = argv[0];
    int i;

    XAboolean abq = XA_BOOLEAN_FALSE;   // use AndroidBufferQueue, default is URI
    XAboolean looping = XA_BOOLEAN_FALSE;
#ifdef REINITIALIZE
    int reinit_counter = 0;
#endif
    for (i = 1; i < argc; ++i) {
        const char *arg = argv[i];
        if (arg[0] != '-')
            break;
        switch (arg[1]) {
        case 'a':
            abq = XA_BOOLEAN_TRUE;
            break;
        case 'd':
            discPacket = atoi(&arg[2]);
            break;
        case 'l':
            looping = XA_BOOLEAN_TRUE;
            break;
#ifdef REINITIALIZE
        case 'r':
            reinit_counter = atoi(&arg[2]);
            break;
#endif
        default:
            fprintf(stderr, "%s: unknown option %s\n", prog, arg);
            break;
        }
    }

    // check that exactly one URI was specified
    if (argc - i != 1) {
        fprintf(stderr, "usage: %s [-a] [-d#] [-l] uri\n", prog);
        return EXIT_FAILURE;
    }
    const char *uri = argv[i];

    // for AndroidBufferQueue, interpret URI as a filename and open
    int fd = -1;
    if (abq) {
        fd = open(uri, O_RDONLY);
        if (fd < 0) {
            perror(uri);
            goto close;
        }
        int ok;
        struct stat statbuf;
        ok = fstat(fd, &statbuf);
        if (ok < 0) {
            perror(uri);
            goto close;
        }
        if (!S_ISREG(statbuf.st_mode)) {
            fprintf(stderr, "%s: not an ordinary file\n", uri);
            goto close;
        }
        void *ptr;
        ptr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, (off_t) 0);
        if (ptr == MAP_FAILED) {
            perror(uri);
            goto close;
        }
        size_t filelen = statbuf.st_size;
        if ((filelen % MPEG2TS_PACKET_SIZE) != 0) {
            fprintf(stderr, "%s: warning file length %zu is not a multiple of %d\n", uri, filelen,
                    MPEG2TS_PACKET_SIZE);
        }
        packets = (MPEG2TS_Packet *) ptr;
        numPackets = filelen / MPEG2TS_PACKET_SIZE;
        printf("%s has %zu packets\n", uri, numPackets);
    }

    ANativeWindow *nativeWindow;

#ifdef REINITIALIZE
reinitialize:    ;
#endif

    XAresult result;
    XAObjectItf engineObject;

    // create engine
    result = xaCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
    assert(XA_RESULT_SUCCESS == result);
    result = (*engineObject)->Realize(engineObject, XA_BOOLEAN_FALSE);
    assert(XA_RESULT_SUCCESS == result);
    XAEngineItf engineEngine;
    result = (*engineObject)->GetInterface(engineObject, XA_IID_ENGINE, &engineEngine);
    assert(XA_RESULT_SUCCESS == result);

    // create output mix
    XAObjectItf outputMixObject;
    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
    assert(XA_RESULT_SUCCESS == result);
    result = (*outputMixObject)->Realize(outputMixObject, XA_BOOLEAN_FALSE);
    assert(XA_RESULT_SUCCESS == result);

    // configure media source
    XADataLocator_URI locUri;
    locUri.locatorType = XA_DATALOCATOR_URI;
    locUri.URI = (XAchar *) uri;
    XADataFormat_MIME fmtMime;
    fmtMime.formatType = XA_DATAFORMAT_MIME;
    if (abq) {
        fmtMime.mimeType = (XAchar *) XA_ANDROID_MIME_MP2TS;
        fmtMime.containerType = XA_CONTAINERTYPE_MPEG_TS;
    } else {
        fmtMime.mimeType = NULL;
        fmtMime.containerType = XA_CONTAINERTYPE_UNSPECIFIED;
    }
    XADataLocator_AndroidBufferQueue locABQ;
    locABQ.locatorType = XA_DATALOCATOR_ANDROIDBUFFERQUEUE;
    locABQ.numBuffers = NB_BUFFERS;
    XADataSource dataSrc;
    if (abq) {
        dataSrc.pLocator = &locABQ;
    } else {
        dataSrc.pLocator = &locUri;
    }
    dataSrc.pFormat = &fmtMime;

    // configure audio sink
    XADataLocator_OutputMix locOM;
    locOM.locatorType = XA_DATALOCATOR_OUTPUTMIX;
    locOM.outputMix = outputMixObject;
    XADataSink audioSnk;
    audioSnk.pLocator = &locOM;
    audioSnk.pFormat = NULL;

    // configure video sink
    nativeWindow = getNativeWindow();
    XADataLocator_NativeDisplay locND;
    locND.locatorType = XA_DATALOCATOR_NATIVEDISPLAY;
    locND.hWindow = nativeWindow;
    locND.hDisplay = NULL;
    XADataSink imageVideoSink;
    imageVideoSink.pLocator = &locND;
    imageVideoSink.pFormat = NULL;

    // create media player
    XAObjectItf playerObject;
    XAInterfaceID ids[4] = {XA_IID_STREAMINFORMATION, XA_IID_PREFETCHSTATUS, XA_IID_SEEK,
            XA_IID_ANDROIDBUFFERQUEUESOURCE};
    XAboolean req[4] = {XA_BOOLEAN_TRUE, XA_BOOLEAN_TRUE, XA_BOOLEAN_TRUE, XA_BOOLEAN_TRUE};
    result = (*engineEngine)->CreateMediaPlayer(engineEngine, &playerObject, &dataSrc, NULL,
            &audioSnk, nativeWindow != NULL ? &imageVideoSink : NULL, NULL, NULL, abq ? 4 : 3, ids,
            req);
    assert(XA_RESULT_SUCCESS == result);

    // realize the player
    result = (*playerObject)->Realize(playerObject, XA_BOOLEAN_FALSE);
    assert(XA_RESULT_SUCCESS == result);

    if (abq) {

        // get the Android buffer queue interface
        XAAndroidBufferQueueItf playerAndroidBufferQueue;
        result = (*playerObject)->GetInterface(playerObject, XA_IID_ANDROIDBUFFERQUEUESOURCE,
                &playerAndroidBufferQueue);
        assert(XA_RESULT_SUCCESS == result);

        // register the buffer queue callback
        result = (*playerAndroidBufferQueue)->RegisterCallback(playerAndroidBufferQueue,
                bufferQueueCallback, NULL);
        assert(XA_RESULT_SUCCESS == result);
        result = (*playerAndroidBufferQueue)->SetCallbackEventsMask(playerAndroidBufferQueue,
                XA_ANDROIDBUFFERQUEUEEVENT_PROCESSED);
        assert(XA_RESULT_SUCCESS == result);

        // enqueue the initial buffers until buffer queue is full
        XAuint32 packetsThisBuffer;
        for (curPacket = 0; curPacket < numPackets; curPacket += packetsThisBuffer) {
            // handle the unlikely case of a very short .ts
            packetsThisBuffer = numPackets - curPacket;
            if (packetsThisBuffer > PACKETS_PER_BUFFER) {
                packetsThisBuffer = PACKETS_PER_BUFFER;
            }
            result = (*playerAndroidBufferQueue)->Enqueue(playerAndroidBufferQueue, NULL,
                    &packets[curPacket], MPEG2TS_PACKET_SIZE * packetsThisBuffer, NULL, 0);
            if (XA_RESULT_BUFFER_INSUFFICIENT == result) {
                printf("Enqueued initial %u packets in %u buffers\n", curPacket, curPacket / PACKETS_PER_BUFFER);
                break;
            }
            assert(XA_RESULT_SUCCESS == result);
        }

    }

    // get the stream information interface
    XAStreamInformationItf playerStreamInformation;
    result = (*playerObject)->GetInterface(playerObject, XA_IID_STREAMINFORMATION,
            &playerStreamInformation);
    assert(XA_RESULT_SUCCESS == result);

    // register the stream event change callback
    result = (*playerStreamInformation)->RegisterStreamChangeCallback(playerStreamInformation,
            streamEventChangeCallback, NULL);
    assert(XA_RESULT_SUCCESS == result);

    // get the prefetch status interface
    XAPrefetchStatusItf playerPrefetchStatus;
    result = (*playerObject)->GetInterface(playerObject, XA_IID_PREFETCHSTATUS,
            &playerPrefetchStatus);
    assert(XA_RESULT_SUCCESS == result);

    // register prefetch status callback
    result = (*playerPrefetchStatus)->RegisterCallback(playerPrefetchStatus, prefetchStatusCallback,
            NULL);
    assert(XA_RESULT_SUCCESS == result);
    result = (*playerPrefetchStatus)->SetCallbackEventsMask(playerPrefetchStatus,
            XA_PREFETCHEVENT_FILLLEVELCHANGE | XA_PREFETCHEVENT_STATUSCHANGE);
    assert(XA_RESULT_SUCCESS == result);

    // get the seek interface
    if (looping) {
        XASeekItf playerSeek;
        result = (*playerObject)->GetInterface(playerObject, XA_IID_SEEK, &playerSeek);
        assert(XA_RESULT_SUCCESS == result);
        result = (*playerSeek)->SetLoop(playerSeek, XA_BOOLEAN_TRUE, (XAmillisecond) 0,
                XA_TIME_UNKNOWN);
        assert(XA_RESULT_SUCCESS == result);
    }

    // get the play interface
    XAPlayItf playerPlay;
    result = (*playerObject)->GetInterface(playerObject, XA_IID_PLAY, &playerPlay);
    assert(XA_RESULT_SUCCESS == result);

    // register play event callback
    result = (*playerPlay)->RegisterCallback(playerPlay, playEventCallback, NULL);
    assert(XA_RESULT_SUCCESS == result);
#if 0 // FIXME broken
    result = (*playerPlay)->SetCallbackEventsMask(playerPlay,
            XA_PLAYEVENT_HEADATEND | XA_PLAYEVENT_HEADATMARKER | XA_PLAYEVENT_HEADATNEWPOS);
    assert(XA_RESULT_SUCCESS == result);
#endif

    // set a marker
    result = (*playerPlay)->SetMarkerPosition(playerPlay, 10000);
    assert(XA_RESULT_SUCCESS == result);

    // set position update period
    result = (*playerPlay)->SetPositionUpdatePeriod(playerPlay, 1000);
    assert(XA_RESULT_SUCCESS == result);

    // get the duration
    XAmillisecond duration;
    result = (*playerPlay)->GetDuration(playerPlay, &duration);
    assert(XA_RESULT_SUCCESS == result);
    if (XA_TIME_UNKNOWN == duration)
        printf("Duration: unknown\n");
    else
        printf("Duration: %.1f\n", duration / 1000.0f);

    // set the player's state to paused, to start prefetching
    printf("start prefetch\n");
    result = (*playerPlay)->SetPlayState(playerPlay, XA_PLAYSTATE_PAUSED);
    assert(XA_RESULT_SUCCESS == result);

    // wait for prefetch status callback to indicate either sufficient data or error
    pthread_mutex_lock(&mutex);
    while (prefetch_status == PREFETCHSTATUS_UNKNOWN) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);
    if (prefetch_status == PREFETCHSTATUS_ERROR) {
        fprintf(stderr, "Error during prefetch, exiting\n");
        goto destroyRes;
    }

    // get duration again, now it should be known
    result = (*playerPlay)->GetDuration(playerPlay, &duration);
    assert(XA_RESULT_SUCCESS == result);
    if (duration == XA_TIME_UNKNOWN) {
        fprintf(stdout, "Content duration is unknown (after prefetch completed)\n");
    } else {
        fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", duration);
    }

    // start playing
    printf("starting to play\n");
    result = (*playerPlay)->SetPlayState(playerPlay, XA_PLAYSTATE_PLAYING);
    assert(XA_RESULT_SUCCESS == result);

    // continue playing until end of media
    for (;;) {
        XAuint32 status;
        result = (*playerPlay)->GetPlayState(playerPlay, &status);
        assert(XA_RESULT_SUCCESS == result);
        if (status == XA_PLAYSTATE_PAUSED)
            break;
        assert(status == XA_PLAYSTATE_PLAYING);
        sleep(1);
    }

    // wait a bit more in case of additional callbacks
    printf("end of media\n");
    sleep(3);

destroyRes:

    // destroy the player
    (*playerObject)->Destroy(playerObject);

    // destroy the output mix
    (*outputMixObject)->Destroy(outputMixObject);

    // destroy the engine
    (*engineObject)->Destroy(engineObject);

#ifdef REINITIALIZE
    if (--reinit_count > 0) {
        prefetch_status = PREFETCHSTATUS_UNKNOWN;
        goto reinitialize;
    }
#endif

#if 0
    if (nativeWindow != NULL) {
        ANativeWindow_release(nativeWindow);
    }
#endif

close:
    if (fd >= 0) {
        (void) close(fd);
    }

    return EXIT_SUCCESS;
}
