/* INTEL CONFIDENTIAL
* Copyright (c) 2009 Intel Corporation.  All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
* Corporation or its suppliers or licensors.  Title to the
* Material remains with Intel Corporation or its suppliers and
* licensors.  The Material contains trade secrets and proprietary
* and confidential information of Intel or its suppliers and
* licensors. The Material is protected by worldwide copyright and
* trade secret laws and treaty provisions.  No part of the Material
* may be used, copied, reproduced, modified, published, uploaded,
* posted, transmitted, distributed, or disclosed in any way without
* Intel's prior express written permission.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you
* by disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel or otherwise. Any license
* under such intellectual property rights must be express and
* approved by Intel in writing.
*
*/



#include "AsfHeaderParser.h"
#include "AsfDataParser.h"
#include "AsfIndexParser.h"
#include "AsfStreamParser.h"
#include <string.h>


AsfStreamParser::AsfStreamParser(void)
    : mDataPacketSize(0),
      mTimeOffsetMs(0),
      mHeaderParsed(false) {
    mHeaderParser = new AsfHeaderParser;
    mDataParser = new AsfDataParser;
    mSimpleIndexParser = new AsfSimpleIndexParser;
}

AsfStreamParser::~AsfStreamParser(void) {
    delete mHeaderParser;
    delete mDataParser;
    delete mSimpleIndexParser;
}

bool AsfStreamParser::isSimpleIndexObject(uint8_t *guid) {
    GUID *id = (GUID *)guid;
    return (*id == ASF_Simple_Index_Object);
}

bool AsfStreamParser::isHeaderObject(uint8_t *guid) {
    GUID *id = (GUID *)guid;
    return (*id == ASF_Header_Object);
}

int AsfStreamParser::parseHeaderObject(uint8_t *buffer, uint32_t size) {
    int status = mHeaderParser->parse(buffer, size);
    if (status != ASF_PARSER_SUCCESS) {
        return status;
    }

    mDataPacketSize = mHeaderParser->getDataPacketSize();
    mTimeOffsetMs = mHeaderParser->getTimeOffset() / ASF_SCALE_MS_TO_100NANOSEC;

    if (mTimeOffsetMs == 0) {
        // offset of PTS in milliseconds due to buffering
        mTimeOffsetMs = mHeaderParser->getPreroll();
    }
    mHeaderParsed = true;
    return ASF_PARSER_SUCCESS;
}

AsfAudioStreamInfo* AsfStreamParser::getAudioInfo() const {
    return mHeaderParser->getAudioInfo();
}

AsfVideoStreamInfo* AsfStreamParser::getVideoInfo() const {
    return mHeaderParser->getVideoInfo();
}

AsfFileMediaInfo* AsfStreamParser::getFileInfo() const {
    return mHeaderParser->getFileInfo();
}

uint64_t AsfStreamParser::getDuration() {
    return mHeaderParser->getDuration();
}

uint32_t AsfStreamParser::getDataPacketSize() {
    return mHeaderParser->getDataPacketSize();
}

bool AsfStreamParser::hasVideo() {
    return mHeaderParser->hasVideo();
}

bool AsfStreamParser::hasAudio() {
    return mHeaderParser->hasAudio();
}

int AsfStreamParser::parseDataObjectHeader(uint8_t *buffer, uint32_t size) {
    if (mHeaderParsed == false) {
        return ASF_PARSER_INVALID_STATE;
    }
    return mDataParser->parseHeader(buffer, size);
}

int AsfStreamParser::parseDataPacket(uint8_t *buffer, uint32_t size, AsfPayloadDataInfo **out) {
    if (mHeaderParsed == false) {
        return ASF_PARSER_INVALID_STATE;
    }

    if (size != mDataPacketSize) {
        return ASF_PARSER_BAD_DATA;
    }

    if (out == NULL) {
        return ASF_PARSER_NULL_POINTER;
    }

    int status = mDataParser->parsePacket(buffer, size, out);
    if (status != ASF_PARSER_SUCCESS) {
        return status;
    }

    if (mTimeOffsetMs == 0) {
        return ASF_PARSER_SUCCESS;
    }

    // update presentation time stamp
    AsfPayloadDataInfo *next = *out;
    while (next) {
        if (next->presentationTime >= mTimeOffsetMs) {
            next->presentationTime -= mTimeOffsetMs;
        }
        else {
            // TODO:
            next->presentationTime = 0;
            //return ASF_PARSER_BAD_VALUE;
        }
        next = next->next;
    }
    return status;
}

void AsfStreamParser::releasePayloadDataInfo(AsfPayloadDataInfo *info) {
    mDataParser->releasePayloadDataInfo(info);
}


int AsfStreamParser::parseSimpleIndexObject(uint8_t *buffer, uint32_t size) {
    if (mHeaderParsed == false) {
        return ASF_PARSER_INVALID_STATE;
    }

    if (mHeaderParser->isSeekable() == false) {
        return ASF_PARSER_FAILED;
    }

    return mSimpleIndexParser->parse(buffer, size);
}

AsfSimpleIndexInfo* AsfStreamParser::getIndexInfo() const {
    return mSimpleIndexParser->getIndexInfo();
}

int AsfStreamParser::seek(
        uint64_t seekTime,
        bool nextSync,
        uint32_t& packetNumber,
        uint64_t& targetTime) {
    if (mHeaderParsed == false) {
        return ASF_PARSER_INVALID_STATE;
    }

    if (mHeaderParser->isSeekable() == false) {
        return ASF_PARSER_FAILED;
    }

    return mSimpleIndexParser->seek(seekTime, nextSync, packetNumber, targetTime);
}

uint32_t AsfStreamParser::getMaxObjectSize() {
    return mSimpleIndexParser->getMaximumPacketCount() * mDataPacketSize;
}

