/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "SFrameUtils.h"

#if ENABLE(WEB_RTC)

#include <wtf/Function.h>

namespace WebCore {

static inline bool isSliceNALU(uint8_t data)
{
    return (data & 0x1F) == 1;
}

static inline bool isSPSNALU(uint8_t data)
{
    return (data & 0x1F) == 7;
}

static inline bool isPPSNALU(uint8_t data)
{
    return (data & 0x1F) == 8;
}

static inline bool isIDRNALU(uint8_t data)
{
    return (data & 0x1F) == 5;
}

static inline void findNalus(const uint8_t* frameData, size_t frameSize, size_t offset, const Function<bool(size_t)>& callback)
{
    for (size_t i = 4 + offset; i < frameSize; ++i) {
        if (frameData[i - 4] == 0 && frameData[i - 3] == 0 && frameData[i - 2] == 0 && frameData[i - 1] == 1) {
            if (callback(i))
                return;
        }
    }
}

size_t computeH264PrefixOffset(const uint8_t* frameData, size_t frameSize)
{
    size_t offset = 0;
    findNalus(frameData, frameSize, 0, [&offset, &frameData](auto position) {
        if (isIDRNALU(frameData[position]) || isSliceNALU(frameData[position])) {
            // Skip 00 00 00 01, nalu type byte and the next byte.
            offset = position + 2;
            return true;
        }
        return false;
    });
    return offset;
}

bool needsRbspUnescaping(const uint8_t* frameData, size_t frameSize)
{
    for (size_t i = 0; i < frameSize - 3; ++i) {
        if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3)
            return true;
    }
    return false;
}

Vector<uint8_t> fromRbsp(const uint8_t* frameData, size_t frameSize)
{
    Vector<uint8_t> buffer;
    buffer.reserveInitialCapacity(frameSize);

    size_t i;
    for (i = 0; i < frameSize - 3; ++i) {
        if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) {
            buffer.uncheckedAppend(frameData[i]);
            buffer.uncheckedAppend(frameData[i + 1]);
            // Skip next byte which is delimiter.
            i += 2;
        } else
            buffer.uncheckedAppend(frameData[i]);
    }
    for (; i < frameSize; ++i)
        buffer.uncheckedAppend(frameData[i]);

    return buffer;
}

SFrameCompatibilityPrefixBuffer computeH264PrefixBuffer(const uint8_t* frameData, size_t frameSize)
{
    // Delta and key prefixes assume SPS/PPS with IDs equal to 0 have been transmitted.
    static const uint8_t prefixDeltaFrame[6] = { 0x00, 0x00, 0x00, 0x01, 0x21, 0xe0 };

    if (frameSize < 5)
        return { };

    // We assume a key frame starts with SPS, then PPS. Otherwise we wrap it as a delta frame.
    if (!isSPSNALU(frameData[4]))
        return SFrameCompatibilityPrefixBuffer { prefixDeltaFrame, sizeof(prefixDeltaFrame), { } };

    // Search for PPS
    size_t spsPpsLength = 0;
    findNalus(frameData, frameSize, 5, [frameData, &spsPpsLength](auto position) {
        if (isPPSNALU(frameData[position]))
            spsPpsLength = position;
        return true;
    });
    if (!spsPpsLength)
        return SFrameCompatibilityPrefixBuffer { prefixDeltaFrame, sizeof(prefixDeltaFrame), { } };

    // Search for next NALU to compute the real spsPpsLength, including the next 00 00 00 01.
    findNalus(frameData, frameSize, spsPpsLength + 1, [&spsPpsLength](auto position) {
        spsPpsLength = position;
        return true;
    });

    Vector<uint8_t> buffer;
    buffer.resize(spsPpsLength + 2);
    std::memcpy(buffer.data(), frameData, spsPpsLength);
    buffer[spsPpsLength] = 0x25;
    buffer[spsPpsLength + 1] = 0xb8;
    return { buffer.data(), buffer.size(), WTFMove(buffer) };
}

static inline void findEscapeRbspPatterns(const Vector<uint8_t>& frame, size_t offset, const Function<void(size_t, bool)>& callback)
{
    size_t numConsecutiveZeros = 0;
    auto* data = frame.data();
    for (size_t i = offset; i < frame.size(); ++i) {
        bool shouldEscape = data[i] <= 3 && numConsecutiveZeros >= 2;
        if (shouldEscape)
            numConsecutiveZeros = 0;

        if (data[i] == 0)
            ++numConsecutiveZeros;
        else
            numConsecutiveZeros = 0;

        callback(i, shouldEscape);
    }
}

void toRbsp(Vector<uint8_t>& frame, size_t offset)
{
    size_t count = 0;
    findEscapeRbspPatterns(frame, offset, [&count](size_t, bool shouldBeEscaped) {
        if (shouldBeEscaped)
            ++count;
    });
    if (!count)
        return;

    Vector<uint8_t> newFrame;
    newFrame.reserveInitialCapacity(frame.size() + count);
    newFrame.append(frame.data(), offset);

    findEscapeRbspPatterns(frame, offset, [data = frame.data(), &newFrame](size_t position, bool shouldBeEscaped) {
        if (shouldBeEscaped)
            newFrame.uncheckedAppend(3);
        newFrame.uncheckedAppend(data[position]);
    });

    frame = WTFMove(newFrame);
}

static inline bool isVP8KeyFrame(const uint8_t* frame, size_t size)
{
    ASSERT_UNUSED(size, size);
    return !(*frame & 0x01);
}

size_t computeVP8PrefixOffset(const uint8_t* frame, size_t size)
{
    return isVP8KeyFrame(frame, size) ? 10 : 3;
}

SFrameCompatibilityPrefixBuffer computeVP8PrefixBuffer(const uint8_t* frame, size_t size)
{
    Vector<uint8_t> prefix;
    prefix.append(frame, isVP8KeyFrame(frame, size) ? 10 : 3);
    return { prefix.data(), prefix.size(), WTFMove(prefix) };
}

} // namespace WebCore

#endif // ENABLE(WEB_RTC)
