// Copyright (C) 2020 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 "host-common/MediaH264DecoderVideoToolBoxProxy.h"

#include <cstdint>
#include <string>
#include <vector>

#include <stdio.h>
#include <string.h>

#include <stddef.h>

#define MEDIA_H264_DEBUG 0

#if MEDIA_H264_DEBUG
#define H264_DPRINT(fmt,...) fprintf(stderr, "h264-videotoolbox-proxy-dec: %s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
#else
#define H264_DPRINT(fmt,...)
#endif


namespace android {
namespace emulation {

using InitContextParam = H264PingInfoParser::InitContextParam;
using DecodeFrameParam = H264PingInfoParser::DecodeFrameParam;
using ResetParam = H264PingInfoParser::ResetParam;
using GetImageParam = H264PingInfoParser::GetImageParam;
MediaH264DecoderVideoToolBoxProxy::MediaH264DecoderVideoToolBoxProxy(
        uint64_t id,
        H264PingInfoParser parser)
    : mId(id),
      mParser(parser),
      mFfmpegDecoder(id, parser),
      mVideoToolBoxDecoder(id, parser) {
    mCurrentDecoder = &mVideoToolBoxDecoder;
}

MediaH264DecoderPlugin* MediaH264DecoderVideoToolBoxProxy::clone() {
    return new MediaH264DecoderVideoToolBoxProxy(mId, mParser);
}

MediaH264DecoderVideoToolBoxProxy::~MediaH264DecoderVideoToolBoxProxy() {
    mCurrentDecoder->destroyH264Context();
    mCurrentDecoder = nullptr;
}

void MediaH264DecoderVideoToolBoxProxy::initH264Context(void* ptr) {
    mVideoToolBoxDecoder.initH264Context(ptr);
    mFfmpegDecoder.initH264Context(ptr);
}

void MediaH264DecoderVideoToolBoxProxy::reset(void* ptr) {
    mCurrentDecoder->reset(ptr);
}

std::vector<uint8_t> MediaH264DecoderVideoToolBoxProxy::prefixNaluHeader(std::vector<uint8_t> data) {
    std::vector<uint8_t> result {0x00, 0x00, 0x00,0x01};
    result.insert(result.end(), data.begin(), data.end());
    return result;
}

void MediaH264DecoderVideoToolBoxProxy::decodeFrame(void* ptr) {
    if (mIsVideoToolBoxDecoderInGoodState) {
        mVideoToolBoxDecoder.decodeFrame(ptr);
        if (mVideoToolBoxDecoder.getState() == DecoderState::BAD_STATE) {
            mSPS = prefixNaluHeader(mVideoToolBoxDecoder.getSPS());
            mPPS = prefixNaluHeader(mVideoToolBoxDecoder.getPPS());
            // right now, the only place that videotoolbox can fail is when it gets SPS and PPS, and
            // failed to create decoding session
            mVideoToolBoxDecoder.destroyH264Context();
            mIsVideoToolBoxDecoderInGoodState = false;
            mFfmpegDecoder.decodeFrameDirect(ptr, &(mSPS[0]), mSPS.size(), 0);
            mFfmpegDecoder.decodeFrameDirect(ptr, &(mPPS[0]), mPPS.size(), 0);
            mCurrentDecoder = &mFfmpegDecoder;
        }
    } else {
        mFfmpegDecoder.decodeFrame(ptr);
    }
}

void MediaH264DecoderVideoToolBoxProxy::flush(void* ptr) {
    mCurrentDecoder->flush(ptr);
}

void MediaH264DecoderVideoToolBoxProxy::getImage(void* ptr) {
    mCurrentDecoder->getImage(ptr);
}

void MediaH264DecoderVideoToolBoxProxy::destroyH264Context() {
    mCurrentDecoder->destroyH264Context();
}

void MediaH264DecoderVideoToolBoxProxy::save(base::Stream* stream) const {
    H264_DPRINT("saving ...");
    stream->putBe32(mParser.version());
    const int useHardwareDecoder = mIsVideoToolBoxDecoderInGoodState ? 1 : 0;
    stream->putBe32(useHardwareDecoder);
    mFfmpegDecoder.save(stream);
    mVideoToolBoxDecoder.save(stream);
}

bool MediaH264DecoderVideoToolBoxProxy::load(base::Stream* stream) {
    H264_DPRINT("loading ...");
    uint32_t version = stream->getBe32();
    mParser = H264PingInfoParser{version};
    const int useHardwareDecoder = stream->getBe32();
    mFfmpegDecoder.load(stream);
    mVideoToolBoxDecoder.load(stream);
    if (useHardwareDecoder) {
        mCurrentDecoder = &mVideoToolBoxDecoder;
    } else {
        mCurrentDecoder = &mFfmpegDecoder;
    }
    return true;
}

}  // namespace emulation
}  // namespace android
