/*
 * Copyright 2013, 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.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaSender"
#include <utils/Log.h>

#include "MediaSender.h"

#include "ANetworkSession.h"
#include "rtp/RTPSender.h"
#include "source/TSPacketizer.h"

#include "include/avc_utils.h"

#include <media/IHDCP.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>

namespace android {

MediaSender::MediaSender(
        const sp<ANetworkSession> &netSession,
        const sp<AMessage> &notify)
    : mNetSession(netSession),
      mNotify(notify),
      mMode(MODE_UNDEFINED),
      mGeneration(0),
      mPrevTimeUs(-1ll),
      mInitDoneCount(0),
      mLogFile(NULL) {
    // mLogFile = fopen("/data/misc/log.ts", "wb");
}

MediaSender::~MediaSender() {
    if (mLogFile != NULL) {
        fclose(mLogFile);
        mLogFile = NULL;
    }
}

status_t MediaSender::setHDCP(const sp<IHDCP> &hdcp) {
    if (mMode != MODE_UNDEFINED) {
        return INVALID_OPERATION;
    }

    mHDCP = hdcp;

    return OK;
}

ssize_t MediaSender::addTrack(const sp<AMessage> &format, uint32_t flags) {
    if (mMode != MODE_UNDEFINED) {
        return INVALID_OPERATION;
    }

    TrackInfo info;
    info.mFormat = format;
    info.mFlags = flags;
    info.mPacketizerTrackIndex = -1;

    AString mime;
    CHECK(format->findString("mime", &mime));
    info.mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);

    size_t index = mTrackInfos.size();
    mTrackInfos.push_back(info);

    return index;
}

status_t MediaSender::initAsync(
        ssize_t trackIndex,
        RTPSender::TransportMode transportMode,
        const char *remoteHost,
        int32_t remoteRTPPort,
        int32_t remoteRTCPPort,
        int32_t *localRTPPort) {
    if (trackIndex < 0) {
        if (mMode != MODE_UNDEFINED) {
            return INVALID_OPERATION;
        }

        uint32_t flags = 0;
        if (mHDCP != NULL) {
            // XXX Determine proper HDCP version.
            flags |= TSPacketizer::EMIT_HDCP20_DESCRIPTOR;
        }
        mTSPacketizer = new TSPacketizer(flags);

        status_t err = OK;
        for (size_t i = 0; i < mTrackInfos.size(); ++i) {
            TrackInfo *info = &mTrackInfos.editItemAt(i);

            ssize_t packetizerTrackIndex =
                mTSPacketizer->addTrack(info->mFormat);

            if (packetizerTrackIndex < 0) {
                err = packetizerTrackIndex;
                break;
            }

            info->mPacketizerTrackIndex = packetizerTrackIndex;
        }

        if (err == OK) {
            sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
            notify->setInt32("generation", mGeneration);
            mTSSender = new RTPSender(mNetSession, notify);
            looper()->registerHandler(mTSSender);

            err = mTSSender->initAsync(
                    transportMode,
                    remoteHost,
                    remoteRTPPort,
                    remoteRTCPPort,
                    localRTPPort);

            if (err != OK) {
                looper()->unregisterHandler(mTSSender->id());
                mTSSender.clear();
            }
        }

        if (err != OK) {
            for (size_t i = 0; i < mTrackInfos.size(); ++i) {
                TrackInfo *info = &mTrackInfos.editItemAt(i);
                info->mPacketizerTrackIndex = -1;
            }

            mTSPacketizer.clear();
            return err;
        }

        mMode = MODE_TRANSPORT_STREAM;
        mInitDoneCount = 1;

        return OK;
    }

    if (mMode == MODE_TRANSPORT_STREAM) {
        return INVALID_OPERATION;
    }

    if ((size_t)trackIndex >= mTrackInfos.size()) {
        return -ERANGE;
    }

    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);

    if (info->mSender != NULL) {
        return INVALID_OPERATION;
    }

    sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
    notify->setInt32("generation", mGeneration);
    notify->setSize("trackIndex", trackIndex);

    info->mSender = new RTPSender(mNetSession, notify);
    looper()->registerHandler(info->mSender);

    status_t err = info->mSender->initAsync(
            transportMode,
            remoteHost,
            remoteRTPPort,
            remoteRTCPPort,
            localRTPPort);

    if (err != OK) {
        looper()->unregisterHandler(info->mSender->id());
        info->mSender.clear();

        return err;
    }

    if (mMode == MODE_UNDEFINED) {
        mInitDoneCount = mTrackInfos.size();
    }

    mMode = MODE_ELEMENTARY_STREAMS;

    return OK;
}

status_t MediaSender::queueAccessUnit(
        size_t trackIndex, const sp<ABuffer> &accessUnit) {
    if (mMode == MODE_UNDEFINED) {
        return INVALID_OPERATION;
    }

    if (trackIndex >= mTrackInfos.size()) {
        return -ERANGE;
    }

    if (mMode == MODE_TRANSPORT_STREAM) {
        TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
        info->mAccessUnits.push_back(accessUnit);

        mTSPacketizer->extractCSDIfNecessary(info->mPacketizerTrackIndex);

        for (;;) {
            ssize_t minTrackIndex = -1;
            int64_t minTimeUs = -1ll;

            for (size_t i = 0; i < mTrackInfos.size(); ++i) {
                const TrackInfo &info = mTrackInfos.itemAt(i);

                if (info.mAccessUnits.empty()) {
                    minTrackIndex = -1;
                    minTimeUs = -1ll;
                    break;
                }

                int64_t timeUs;
                const sp<ABuffer> &accessUnit = *info.mAccessUnits.begin();
                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));

                if (minTrackIndex < 0 || timeUs < minTimeUs) {
                    minTrackIndex = i;
                    minTimeUs = timeUs;
                }
            }

            if (minTrackIndex < 0) {
                return OK;
            }

            TrackInfo *info = &mTrackInfos.editItemAt(minTrackIndex);
            sp<ABuffer> accessUnit = *info->mAccessUnits.begin();
            info->mAccessUnits.erase(info->mAccessUnits.begin());

            sp<ABuffer> tsPackets;
            status_t err = packetizeAccessUnit(
                    minTrackIndex, accessUnit, &tsPackets);

            if (err == OK) {
                if (mLogFile != NULL) {
                    fwrite(tsPackets->data(), 1, tsPackets->size(), mLogFile);
                }

                err = mTSSender->queueBuffer(
                        tsPackets,
                        33 /* packetType */,
                        RTPSender::PACKETIZATION_TRANSPORT_STREAM);
            }

            if (err != OK) {
                return err;
            }
        }
    }

    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);

    return info->mSender->queueBuffer(
            accessUnit,
            info->mIsAudio ? 96 : 97 /* packetType */,
            info->mIsAudio
                ? RTPSender::PACKETIZATION_AAC : RTPSender::PACKETIZATION_H264);
}

void MediaSender::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatSenderNotify:
        {
            int32_t generation;
            CHECK(msg->findInt32("generation", &generation));
            if (generation != mGeneration) {
                break;
            }

            onSenderNotify(msg);
            break;
        }

        default:
            TRESPASS();
    }
}

void MediaSender::onSenderNotify(const sp<AMessage> &msg) {
    int32_t what;
    CHECK(msg->findInt32("what", &what));

    switch (what) {
        case RTPSender::kWhatInitDone:
        {
            --mInitDoneCount;

            int32_t err;
            CHECK(msg->findInt32("err", &err));

            if (err != OK) {
                notifyInitDone(err);
                ++mGeneration;
                break;
            }

            if (mInitDoneCount == 0) {
                notifyInitDone(OK);
            }
            break;
        }

        case RTPSender::kWhatError:
        {
            int32_t err;
            CHECK(msg->findInt32("err", &err));

            notifyError(err);
            break;
        }

        default:
            TRESPASS();
    }
}

void MediaSender::notifyInitDone(status_t err) {
    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("what", kWhatInitDone);
    notify->setInt32("err", err);
    notify->post();
}

void MediaSender::notifyError(status_t err) {
    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("what", kWhatError);
    notify->setInt32("err", err);
    notify->post();
}

status_t MediaSender::packetizeAccessUnit(
        size_t trackIndex,
        sp<ABuffer> accessUnit,
        sp<ABuffer> *tsPackets) {
    const TrackInfo &info = mTrackInfos.itemAt(trackIndex);

    uint32_t flags = 0;

    bool isHDCPEncrypted = false;
    uint64_t inputCTR;
    uint8_t HDCP_private_data[16];

    bool manuallyPrependSPSPPS =
        !info.mIsAudio
        && (info.mFlags & FLAG_MANUALLY_PREPEND_SPS_PPS)
        && IsIDR(accessUnit);

    if (mHDCP != NULL && !info.mIsAudio) {
        isHDCPEncrypted = true;

        if (manuallyPrependSPSPPS) {
            accessUnit = mTSPacketizer->prependCSD(
                    info.mPacketizerTrackIndex, accessUnit);
        }

        status_t err = mHDCP->encrypt(
                accessUnit->data(), accessUnit->size(),
                trackIndex  /* streamCTR */,
                &inputCTR,
                accessUnit->data());

        if (err != OK) {
            ALOGE("Failed to HDCP-encrypt media data (err %d)",
                  err);

            return err;
        }

        HDCP_private_data[0] = 0x00;

        HDCP_private_data[1] =
            (((trackIndex >> 30) & 3) << 1) | 1;

        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;

        HDCP_private_data[3] =
            (((trackIndex >> 15) & 0x7f) << 1) | 1;

        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;

        HDCP_private_data[5] =
            ((trackIndex & 0x7f) << 1) | 1;

        HDCP_private_data[6] = 0x00;

        HDCP_private_data[7] =
            (((inputCTR >> 60) & 0x0f) << 1) | 1;

        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;

        HDCP_private_data[9] =
            (((inputCTR >> 45) & 0x7f) << 1) | 1;

        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;

        HDCP_private_data[11] =
            (((inputCTR >> 30) & 0x7f) << 1) | 1;

        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;

        HDCP_private_data[13] =
            (((inputCTR >> 15) & 0x7f) << 1) | 1;

        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;

        HDCP_private_data[15] =
            ((inputCTR & 0x7f) << 1) | 1;

        flags |= TSPacketizer::IS_ENCRYPTED;
    } else if (manuallyPrependSPSPPS) {
        flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES;
    }

    int64_t timeUs = ALooper::GetNowUs();
    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
        flags |= TSPacketizer::EMIT_PCR;
        flags |= TSPacketizer::EMIT_PAT_AND_PMT;

        mPrevTimeUs = timeUs;
    }

    mTSPacketizer->packetize(
            info.mPacketizerTrackIndex,
            accessUnit,
            tsPackets,
            flags,
            !isHDCPEncrypted ? NULL : HDCP_private_data,
            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
            info.mIsAudio ? 2 : 0 /* numStuffingBytes */);

    return OK;
}

}  // namespace android

