/*
 * Copyright (C) 2020-2021 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. AND ITS CONTRIBUTORS ``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 ITS 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.
 */

#import "config.h"
#import "VP9UtilitiesCocoa.h"

#if ENABLE(VP9) && PLATFORM(COCOA)

#import "FourCC.h"
#import "LibWebRTCProvider.h"
#import "MediaCapabilitiesInfo.h"
#import "MediaSample.h"
#import "PlatformScreen.h"
#import "ScreenProperties.h"
#import "SharedBuffer.h"
#import "SystemBattery.h"
#import "VideoConfiguration.h"
#import <JavaScriptCore/DataView.h>
#import <webm/vp9_header_parser.h>
#import <wtf/text/StringToIntegerConversion.h>

#import <pal/cocoa/AVFoundationSoftLink.h>
#import <pal/cf/CoreMediaSoftLink.h>
#import "CoreVideoSoftLink.h"
#import "VideoToolboxSoftLink.h"

namespace WebCore {

using namespace webm;

VP9TestingOverrides& VP9TestingOverrides::singleton()
{
    static NeverDestroyed<VP9TestingOverrides> instance;
    return instance;
}

void VP9TestingOverrides::setHardwareDecoderDisabled(std::optional<bool>&& disabled)
{
    m_hardwareDecoderDisabled = WTFMove(disabled);
    if (m_configurationChangedCallback)
        m_configurationChangedCallback();
}

void VP9TestingOverrides::setVP9ScreenSizeAndScale(std::optional<ScreenDataOverrides>&& overrides)
{
    m_screenSizeAndScale = WTFMove(overrides);
    if (m_configurationChangedCallback)
        m_configurationChangedCallback();
}

void VP9TestingOverrides::setConfigurationChangedCallback(std::function<void()>&& callback)
{
    m_configurationChangedCallback = WTFMove(callback);
}

enum class ResolutionCategory : uint8_t {
    R_480p,
    R_720p,
    R_1080p,
    R_2K,
    R_4K,
    R_8K,
    R_12K,
};

static ResolutionCategory resolutionCategory(const FloatSize& size)
{
    auto pixels = size.area();
    if (pixels > 7680 * 4320)
        return ResolutionCategory::R_12K;
    if (pixels > 4096 * 2160)
        return ResolutionCategory::R_8K;
    if (pixels > 2048 * 1080)
        return ResolutionCategory::R_4K;
    if (pixels > 1920 * 1080)
        return ResolutionCategory::R_2K;
    if (pixels > 1280 * 720)
        return ResolutionCategory::R_1080p;
    if (pixels > 640 * 480)
        return ResolutionCategory::R_720p;
    return ResolutionCategory::R_480p;
}

void registerWebKitVP9Decoder()
{
    LibWebRTCProvider::registerWebKitVP9Decoder();
}

void registerWebKitVP8Decoder()
{
    LibWebRTCProvider::registerWebKitVP8Decoder();
}

void registerSupplementalVP9Decoder()
{
    if (!VideoToolboxLibrary(true))
        return;

    if (canLoad_VideoToolbox_VTRegisterSupplementalVideoDecoderIfAvailable())
        softLink_VideoToolbox_VTRegisterSupplementalVideoDecoderIfAvailable(kCMVideoCodecType_VP9);
}

bool isVP9DecoderAvailable()
{
#if PLATFORM(IOS)
    return canLoad_VideoToolbox_VTIsHardwareDecodeSupported() && VTIsHardwareDecodeSupported(kCMVideoCodecType_VP9);
#else
    if (!VideoToolboxLibrary(true))
        return false;
    return noErr == VTSelectAndCreateVideoDecoderInstance(kCMVideoCodecType_VP9, kCFAllocatorDefault, nullptr, nullptr);
#endif
}

bool isVP8DecoderAvailable()
{
    if (!VideoToolboxLibrary(true))
        return false;
    return noErr == VTSelectAndCreateVideoDecoderInstance('vp08', kCFAllocatorDefault, nullptr, nullptr);
}

bool vp9HardwareDecoderAvailable()
{
    if (auto disabledForTesting = VP9TestingOverrides::singleton().hardwareDecoderDisabled())
        return !*disabledForTesting;

    return canLoad_VideoToolbox_VTIsHardwareDecodeSupported() && VTIsHardwareDecodeSupported(kCMVideoCodecType_VP9);
}

static bool isVP9CodecConfigurationRecordSupported(const VPCodecConfigurationRecord& codecConfiguration)
{
    if (!isVP9DecoderAvailable())
        return false;

    // HW & SW VP9 Decoders support Profile 0 & 2:
    if (codecConfiguration.profile && codecConfiguration.profile != 2)
        return false;

    // HW & SW VP9 Decoders support only 420 chroma subsampling:
    if (codecConfiguration.chromaSubsampling > VPConfigurationChromaSubsampling::Subsampling_420_Colocated)
        return false;

    // HW & SW VP9 Decoders support 8 or 10 bit color:
    if (codecConfiguration.bitDepth > 10)
        return false;

    // HW & SW VP9 Decoders support up to Level 6:
    if (codecConfiguration.level > VPConfigurationLevel::Level_6)
        return false;

    // Hardware decoders are always available.
    if (vp9HardwareDecoderAvailable())
        return true;

    // For wall-powered devices, always report VP9 as supported, even if not powerEfficient.
    if (!systemHasBattery())
        return true;

    // For battery-powered devices, always report VP9 as supported when running on AC power,
    // but only on battery when there is an attached screen whose resolution is large enough
    // to support 4K video.
    if (systemHasAC())
        return true;

    bool has4kScreen = false;
    if (auto overrideForTesting = VP9TestingOverrides::singleton().vp9ScreenSizeAndScale()) {
        auto screenSize = FloatSize(overrideForTesting->width, overrideForTesting->height).scaled(overrideForTesting->scale);
        has4kScreen = resolutionCategory(screenSize) >= ResolutionCategory::R_4K;
    } else {
        for (auto& screenData : getScreenProperties().screenDataMap.values()) {
            if (resolutionCategory(screenData.screenRect.size().scaled(screenData.scaleFactor)) >= ResolutionCategory::R_4K) {
                has4kScreen = true;
                break;
            }
        }
    }

    return has4kScreen;
}

static bool isVP8CodecConfigurationRecordSupported(const VPCodecConfigurationRecord& codecConfiguration)
{
    if (!isVP8DecoderAvailable())
        return false;

    // VP8 decoder only supports Profile 0;
    if (codecConfiguration.profile)
        return false;

    // VP8 decoder only supports 420 chroma subsampling.
    if (codecConfiguration.chromaSubsampling > VPConfigurationChromaSubsampling::Subsampling_420_Colocated)
        return false;

    // VP8 decoder only supports 8-bit color:
    if (codecConfiguration.bitDepth > 8)
        return false;

    return true;
}

bool isVPCodecConfigurationRecordSupported(const VPCodecConfigurationRecord& codecConfiguration)
{
    if (codecConfiguration.codecName == "vp08"_s || codecConfiguration.codecName == "vp8"_s)
        return isVP8CodecConfigurationRecordSupported(codecConfiguration);

    if (codecConfiguration.codecName == "vp09"_s || codecConfiguration.codecName == "vp9"_s)
        return isVP9CodecConfigurationRecordSupported(codecConfiguration);

    return false;
}

std::optional<MediaCapabilitiesInfo> validateVPParameters(const VPCodecConfigurationRecord& codecConfiguration, const VideoConfiguration& videoConfiguration)
{
    if (!isVPCodecConfigurationRecordSupported(codecConfiguration))
        return std::nullopt;

    // VideoConfiguration and VPCodecConfigurationRecord can have conflicting values for HDR properties. If so, reject.
    if (videoConfiguration.transferFunction) {
        // Note: Transfer Characteristics are defined by ISO/IEC 23091-2:2019.
        if (*videoConfiguration.transferFunction == TransferFunction::SRGB && codecConfiguration.transferCharacteristics > 15)
            return std::nullopt;
        if (*videoConfiguration.transferFunction == TransferFunction::PQ && codecConfiguration.transferCharacteristics != 16)
            return std::nullopt;
        if (*videoConfiguration.transferFunction == TransferFunction::HLG && codecConfiguration.transferCharacteristics != 18)
            return std::nullopt;
    }

    if (videoConfiguration.colorGamut) {
        if (*videoConfiguration.colorGamut == ColorGamut::Rec2020 && codecConfiguration.colorPrimaries != 9)
            return std::nullopt;
    }
    return computeVPParameters(videoConfiguration);
}

bool isVPSoftwareDecoderSmooth(const VideoConfiguration& videoConfiguration)
{
    if (videoConfiguration.height <= 1080 && videoConfiguration.framerate > 60)
        return false;

    if (videoConfiguration.height <= 2160 && videoConfiguration.framerate > 30)
        return false;

    return true;
}

std::optional<MediaCapabilitiesInfo> computeVPParameters(const VideoConfiguration& videoConfiguration)
{
    MediaCapabilitiesInfo info;

    if (vp9HardwareDecoderAvailable()) {
        // HW VP9 Decoder does not support alpha channel:
        if (videoConfiguration.alphaChannel && *videoConfiguration.alphaChannel)
            return std::nullopt;

        // HW VP9 Decoder can support up to 4K @ 120 or 8K @ 30
        auto resolution = resolutionCategory({ (float)videoConfiguration.width, (float)videoConfiguration.height });
        if (resolution > ResolutionCategory::R_8K)
            return std::nullopt;
        if (resolution == ResolutionCategory::R_8K && videoConfiguration.framerate > 30)
            info.smooth = false;
        else if (resolution <= ResolutionCategory::R_4K && videoConfiguration.framerate > 120)
            info.smooth = false;
        else
            info.smooth = true;

        info.powerEfficient = true;
        info.supported = true;
        return info;
    }

    info.powerEfficient = false;

    // SW VP9 Decoder has much more variable capabilities depending on CPU characteristics.
    // FIXME: Add a lookup table for device-to-capabilities. For now, assume that the SW VP9
    // decoder can support 4K @ 30.
    info.smooth = isVPSoftwareDecoderSmooth(videoConfiguration);

    // For wall-powered devices, always report VP9 as supported, even if not powerEfficient.
    if (!systemHasBattery()) {
        info.supported = true;
        return info;
    }

    // For battery-powered devices, always report VP9 as supported when running on AC power,
    // but only on battery when there is an attached screen whose resolution is large enough
    // to support 4K video.
    if (systemHasAC()) {
        info.supported = true;
        return info;
    }

    bool has4kScreen = false;

    if (auto overrideForTesting = VP9TestingOverrides::singleton().vp9ScreenSizeAndScale()) {
        auto screenSize = FloatSize(overrideForTesting->width, overrideForTesting->height).scaled(overrideForTesting->scale);
        has4kScreen = resolutionCategory(screenSize) >= ResolutionCategory::R_4K;
    } else {
        for (auto& screenData : getScreenProperties().screenDataMap.values()) {
            if (resolutionCategory(screenData.screenRect.size().scaled(screenData.scaleFactor)) >= ResolutionCategory::R_4K) {
                has4kScreen = true;
                break;
            }
        }
    }

    if (!has4kScreen)
        return std::nullopt;

    info.supported = true;
    return info;
}

static uint8_t convertToColorPrimaries(const Primaries& coefficients)
{
    switch (coefficients) {
    case Primaries::kBt709:
        return VPConfigurationColorPrimaries::BT_709_6;
    case Primaries::kUnspecified:
        return VPConfigurationColorPrimaries::Unspecified;
    case Primaries::kBt470M:
        return VPConfigurationColorPrimaries::BT_470_6_M;
    case Primaries::kBt470Bg:
        return VPConfigurationColorPrimaries::BT_470_7_BG;
    case Primaries::kSmpte170M:
        return VPConfigurationColorPrimaries::BT_601_7;
    case Primaries::kSmpte240M:
        return VPConfigurationColorPrimaries::SMPTE_ST_240;
    case Primaries::kFilm:
        return VPConfigurationColorPrimaries::Film;
    case Primaries::kBt2020:
        return VPConfigurationColorPrimaries::BT_2020_Nonconstant_Luminance;
    case Primaries::kSmpteSt4281:
        return VPConfigurationColorPrimaries::SMPTE_ST_428_1;
    case Primaries::kSmpteRp431:
        return VPConfigurationColorPrimaries::SMPTE_RP_431_2;
    case Primaries::kSmpteEg432:
        return VPConfigurationColorPrimaries::SMPTE_EG_432_1;
    case Primaries::kJedecP22Phosphors:
        return VPConfigurationColorPrimaries::EBU_Tech_3213_E;
    }
}

static PlatformVideoColorPrimaries convertToPlatformVideoColorPrimaries(uint8_t primaries)
{
    switch (primaries) {
    case VPConfigurationColorPrimaries::BT_709_6:
        return PlatformVideoColorPrimaries::Bt709;
    case VPConfigurationColorPrimaries::BT_470_6_M:
        return PlatformVideoColorPrimaries::Bt470m;
    case VPConfigurationColorPrimaries::BT_470_7_BG:
        return PlatformVideoColorPrimaries::Bt470bg;
    case VPConfigurationColorPrimaries::BT_601_7:
        return PlatformVideoColorPrimaries::Smpte170m;
    case VPConfigurationColorPrimaries::SMPTE_ST_240:
        return PlatformVideoColorPrimaries::Smpte240m;
    case VPConfigurationColorPrimaries::Film:
        return PlatformVideoColorPrimaries::Film;
    case VPConfigurationColorPrimaries::BT_2020_Nonconstant_Luminance:
        return PlatformVideoColorPrimaries::Bt2020;
    case VPConfigurationColorPrimaries::SMPTE_ST_428_1:
        return PlatformVideoColorPrimaries::SmpteSt4281;
    case VPConfigurationColorPrimaries::SMPTE_RP_431_2:
        return PlatformVideoColorPrimaries::SmpteRp431;
    case VPConfigurationColorPrimaries::SMPTE_EG_432_1:
        return PlatformVideoColorPrimaries::SmpteEg432;
    case VPConfigurationColorPrimaries::EBU_Tech_3213_E:
        return PlatformVideoColorPrimaries::JedecP22Phosphors;
    case VPConfigurationColorPrimaries::Unspecified:
    default:
        return PlatformVideoColorPrimaries::Unspecified;
    }
}

static uint8_t convertToTransferCharacteristics(const TransferCharacteristics& characteristics)
{
    switch (characteristics) {
    case TransferCharacteristics::kBt709:
        return VPConfigurationTransferCharacteristics::BT_709_6;
    case TransferCharacteristics::kUnspecified:
        return VPConfigurationTransferCharacteristics::Unspecified;
    case TransferCharacteristics::kGamma22curve:
        return VPConfigurationTransferCharacteristics::BT_470_6_M;
    case TransferCharacteristics::kGamma28curve:
        return VPConfigurationTransferCharacteristics::BT_470_7_BG;
    case TransferCharacteristics::kSmpte170M:
        return VPConfigurationTransferCharacteristics::BT_601_7;
    case TransferCharacteristics::kSmpte240M:
        return VPConfigurationTransferCharacteristics::SMPTE_ST_240;
    case TransferCharacteristics::kLinear:
        return VPConfigurationTransferCharacteristics::Linear;
    case TransferCharacteristics::kLog:
        return VPConfigurationTransferCharacteristics::Logrithmic;
    case TransferCharacteristics::kLogSqrt:
        return VPConfigurationTransferCharacteristics::Logrithmic_Sqrt;
    case TransferCharacteristics::kIec6196624:
        return VPConfigurationTransferCharacteristics::IEC_61966_2_4;
    case TransferCharacteristics::kBt1361ExtendedColourGamut:
        return VPConfigurationTransferCharacteristics::BT_1361_0;
    case TransferCharacteristics::kIec6196621:
        return VPConfigurationTransferCharacteristics::IEC_61966_2_1;
    case TransferCharacteristics::k10BitBt2020:
        return VPConfigurationTransferCharacteristics::BT_2020_10bit;
    case TransferCharacteristics::k12BitBt2020:
        return VPConfigurationTransferCharacteristics::BT_2020_12bit;
    case TransferCharacteristics::kSmpteSt2084:
        return VPConfigurationTransferCharacteristics::SMPTE_ST_2084;
    case TransferCharacteristics::kSmpteSt4281:
        return VPConfigurationTransferCharacteristics::SMPTE_ST_428_1;
    case TransferCharacteristics::kAribStdB67Hlg:
        return VPConfigurationTransferCharacteristics::BT_2100_HLG;
    }
}

static PlatformVideoTransferCharacteristics convertToPlatformVideoTransferCharacteristics(uint8_t characteristics)
{
    switch (characteristics) {
    case VPConfigurationTransferCharacteristics::BT_709_6:
        return PlatformVideoTransferCharacteristics::Bt709;
    case VPConfigurationTransferCharacteristics::BT_470_6_M:
        return PlatformVideoTransferCharacteristics::Gamma22curve;
    case VPConfigurationTransferCharacteristics::BT_470_7_BG:
        return PlatformVideoTransferCharacteristics::Gamma28curve;
    case VPConfigurationTransferCharacteristics::BT_601_7:
        return PlatformVideoTransferCharacteristics::Smpte170m;
    case VPConfigurationTransferCharacteristics::SMPTE_ST_240:
        return PlatformVideoTransferCharacteristics::Smpte240m;
    case VPConfigurationTransferCharacteristics::Linear:
        return PlatformVideoTransferCharacteristics::Linear;
    case VPConfigurationTransferCharacteristics::Logrithmic:
        return PlatformVideoTransferCharacteristics::Log;
    case VPConfigurationTransferCharacteristics::Logrithmic_Sqrt:
        return PlatformVideoTransferCharacteristics::LogSqrt;
    case VPConfigurationTransferCharacteristics::IEC_61966_2_4:
        return PlatformVideoTransferCharacteristics::Iec6196624;
    case VPConfigurationTransferCharacteristics::BT_1361_0:
        return PlatformVideoTransferCharacteristics::Bt1361ExtendedColourGamut;
    case VPConfigurationTransferCharacteristics::IEC_61966_2_1:
        return PlatformVideoTransferCharacteristics::Iec6196621;
    case VPConfigurationTransferCharacteristics::BT_2020_10bit:
        return PlatformVideoTransferCharacteristics::Bt2020_10bit;
    case VPConfigurationTransferCharacteristics::BT_2020_12bit:
        return PlatformVideoTransferCharacteristics::Bt2020_12bit;
    case VPConfigurationTransferCharacteristics::SMPTE_ST_2084:
        return PlatformVideoTransferCharacteristics::SmpteSt2084;
    case VPConfigurationTransferCharacteristics::SMPTE_ST_428_1:
        return PlatformVideoTransferCharacteristics::SmpteSt4281;
    case VPConfigurationTransferCharacteristics::BT_2100_HLG:
        return PlatformVideoTransferCharacteristics::AribStdB67Hlg;
    case VPConfigurationTransferCharacteristics::Unspecified:
    default:
        return PlatformVideoTransferCharacteristics::Unspecified;
    }
}

static uint8_t convertToMatrixCoefficients(const MatrixCoefficients& coefficients)
{
    switch (coefficients) {
    case MatrixCoefficients::kRgb:
        return VPConfigurationMatrixCoefficients::Identity;
    case MatrixCoefficients::kBt709:
        return VPConfigurationMatrixCoefficients::BT_709_6;
    case MatrixCoefficients::kUnspecified:
        return VPConfigurationMatrixCoefficients::Unspecified;
    case MatrixCoefficients::kFcc:
        return VPConfigurationMatrixCoefficients::FCC;
    case MatrixCoefficients::kBt470Bg:
        return VPConfigurationMatrixCoefficients::BT_470_7_BG;
    case MatrixCoefficients::kSmpte170M:
        return VPConfigurationMatrixCoefficients::BT_601_7;
    case MatrixCoefficients::kSmpte240M:
        return VPConfigurationMatrixCoefficients::SMPTE_ST_240;
    case MatrixCoefficients::kYCgCo:
        return VPConfigurationMatrixCoefficients::YCgCo;
    case MatrixCoefficients::kBt2020NonconstantLuminance:
        return VPConfigurationMatrixCoefficients::BT_2020_Nonconstant_Luminance;
    case MatrixCoefficients::kBt2020ConstantLuminance:
        return VPConfigurationMatrixCoefficients::BT_2020_Constant_Luminance;
    }
}

static PlatformVideoMatrixCoefficients convertToPlatformVideoMatrixCoefficients(uint8_t coefficients)
{
    switch (coefficients) {
    case VPConfigurationMatrixCoefficients::Identity:
        return PlatformVideoMatrixCoefficients::Rgb;
    case VPConfigurationMatrixCoefficients::BT_709_6:
        return PlatformVideoMatrixCoefficients::Bt709;
    case VPConfigurationMatrixCoefficients::FCC:
        return PlatformVideoMatrixCoefficients::Fcc;
    case VPConfigurationMatrixCoefficients::BT_470_7_BG:
        return PlatformVideoMatrixCoefficients::Bt470bg;
    case VPConfigurationMatrixCoefficients::BT_601_7:
        return PlatformVideoMatrixCoefficients::Smpte170m;
    case VPConfigurationMatrixCoefficients::SMPTE_ST_240:
        return PlatformVideoMatrixCoefficients::Smpte240m;
    case VPConfigurationMatrixCoefficients::YCgCo:
        return PlatformVideoMatrixCoefficients::YCgCo;
    case VPConfigurationMatrixCoefficients::BT_2020_Nonconstant_Luminance:
        return PlatformVideoMatrixCoefficients::Bt2020NonconstantLuminance;
    case VPConfigurationMatrixCoefficients::BT_2020_Constant_Luminance:
        return PlatformVideoMatrixCoefficients::Bt2020ConstantLuminance;
    case VPConfigurationMatrixCoefficients::Unspecified:
    default:
        return PlatformVideoMatrixCoefficients::Unspecified;
    }
}

static uint8_t convertSubsamplingXYToChromaSubsampling(uint64_t x, uint64_t y)
{
    if (x & y)
        return VPConfigurationChromaSubsampling::Subsampling_420_Colocated;
    if (x & !y)
        return VPConfigurationChromaSubsampling::Subsampling_422;
    if (!x & !y)
        return VPConfigurationChromaSubsampling::Subsampling_444;
    // This indicates 4:4:0 subsampling, which is not expressable in the 'vpcC' box. Default to 4:2:0.
    return VPConfigurationChromaSubsampling::Subsampling_420_Colocated;
}

static Ref<VideoInfo> createVideoInfoFromVPCodecConfigurationRecord(const VPCodecConfigurationRecord& record, int32_t width, int32_t height)
{
    // Ref: "VP Codec ISO Media File Format Binding, v1.0, 2017-03-31"
    // <https://www.webmproject.org/vp9/mp4/>
    //
    // class VPCodecConfigurationBox extends FullBox('vpcC', version = 1, 0)
    // {
    //     VPCodecConfigurationRecord() vpcConfig;
    // }
    //
    // aligned (8) class VPCodecConfigurationRecord {
    //     unsigned int (8)     profile;
    //     unsigned int (8)     level;
    //     unsigned int (4)     bitDepth;
    //     unsigned int (3)     chromaSubsampling;
    //     unsigned int (1)     videoFullRangeFlag;
    //     unsigned int (8)     colourPrimaries;
    //     unsigned int (8)     transferCharacteristics;
    //     unsigned int (8)     matrixCoefficients;
    //     unsigned int (16)    codecIntializationDataSize;
    //     unsigned int (8)[]   codecIntializationData;
    // }
    //
    // codecIntializationDataSize​For VP8 and VP9 this field must be 0.
    // codecIntializationData​binary codec initialization data. Not used for VP8 and VP9.
    //
    // FIXME: Convert existing struct to an ISOBox and replace the writing code below
    // with a subclass of ISOFullBox.

    auto videoInfo = VideoInfo::create();
    videoInfo->size = videoInfo->displaySize = { float(width), float(height) };

    constexpr size_t VPCodecConfigurationContentsSize = 12;

    uint32_t versionAndFlags = 1 << 24;
    uint8_t bitDepthChromaAndRange = (0xF & record.bitDepth) << 4 | (0x7 & record.chromaSubsampling) << 1 | (0x1 & record.videoFullRangeFlag);
    uint16_t codecIntializationDataSize = 0;
    auto view = JSC::DataView::create(ArrayBuffer::create(VPCodecConfigurationContentsSize, 1), 0, VPCodecConfigurationContentsSize);
    view->set(0, versionAndFlags, false);
    view->set(4, record.profile, false);
    view->set(5, record.level, false);
    view->set(6, bitDepthChromaAndRange, false);
    view->set(7, record.colorPrimaries, false);
    view->set(8, record.transferCharacteristics, false);
    view->set(9, record.matrixCoefficients, false);
    view->set(10, codecIntializationDataSize, false);
    videoInfo->atomData = SharedBuffer::create(static_cast<uint8_t*>(view->data()), view->byteLength());
    videoInfo->colorSpace.fullRange = record.videoFullRangeFlag == VPConfigurationRange::FullRange;
    videoInfo->colorSpace.primaries = convertToPlatformVideoColorPrimaries(record.colorPrimaries);
    videoInfo->colorSpace.transfer = convertToPlatformVideoTransferCharacteristics(record.transferCharacteristics);
    videoInfo->colorSpace.matrix = convertToPlatformVideoMatrixCoefficients(record.matrixCoefficients);
    videoInfo->codecName = record.codecName == "vp09"_s ? 'vp09' : 'vp08';
    return videoInfo;
}

Ref<VideoInfo> createVideoInfoFromVP9HeaderParser(const vp9_parser::Vp9HeaderParser& parser, const webm::Element<Colour>& color)
{
    VPCodecConfigurationRecord record;

    record.codecName = "vp09"_s;
    record.profile = parser.profile();
    // CoreMedia does nat care about the VP9 codec level; hard-code to Level 1.0 here:
    record.level = 10;
    record.bitDepth = parser.bit_depth();
    record.videoFullRangeFlag = parser.color_range() ? VPConfigurationRange::FullRange : VPConfigurationRange::VideoRange;
    record.chromaSubsampling = convertSubsamplingXYToChromaSubsampling(parser.subsampling_x(), parser.subsampling_y());
    record.colorPrimaries = VPConfigurationColorPrimaries::Unspecified;
    record.transferCharacteristics = VPConfigurationTransferCharacteristics::Unspecified;
    record.matrixCoefficients = VPConfigurationMatrixCoefficients::Unspecified;

    // Container color values can override per-sample ones:
    if (color.is_present()) {
        auto& colorValue = color.value();
        if (colorValue.chroma_subsampling_x.is_present() && colorValue.chroma_subsampling_y.is_present())
            record.chromaSubsampling = convertSubsamplingXYToChromaSubsampling(colorValue.chroma_subsampling_x.value(), colorValue.chroma_subsampling_y.value());
        if (colorValue.range.is_present() && colorValue.range.value() != Range::kUnspecified)
            record.videoFullRangeFlag = colorValue.range.value() == Range::kFull ? VPConfigurationRange::FullRange : VPConfigurationRange::VideoRange;
        if (colorValue.bits_per_channel.is_present())
            record.bitDepth = colorValue.bits_per_channel.value();
        if (colorValue.transfer_characteristics.is_present())
            record.transferCharacteristics = convertToTransferCharacteristics(colorValue.transfer_characteristics.value());
        if (colorValue.matrix_coefficients.is_present())
            record.matrixCoefficients = convertToMatrixCoefficients(colorValue.matrix_coefficients.value());
        if (colorValue.primaries.is_present())
            record.colorPrimaries = convertToColorPrimaries(colorValue.primaries.value());
    }

    return createVideoInfoFromVPCodecConfigurationRecord(record, parser.width(), parser.height());
}

std::optional<VP8FrameHeader> parseVP8FrameHeader(const uint8_t* frameData, size_t frameSize)
{
    // VP8 frame headers are defined in RFC 6386: <https://tools.ietf.org/html/rfc6386>.

    // Bail if the header is below a minimum size
    if (frameSize < 11)
        return std::nullopt;

    VP8FrameHeader header;
    size_t headerSize = 11;

    auto view = JSC::DataView::create(ArrayBuffer::create(frameData, headerSize), 0, headerSize);
    bool status = true;

    auto uncompressedChunk = view->get<uint32_t>(0, true, &status);
    if (!status)
        return std::nullopt;

    header.keyframe = uncompressedChunk & 0x80000000;
    header.version = (uncompressedChunk >> 28) & 0x7;
    header.showFrame = uncompressedChunk & 0x8000000;
    header.partitionSize = (uncompressedChunk >> 8) & 0x7FFFF;

    if (!header.keyframe)
        return header;

    auto startCode0 = view->get<uint8_t>(3, true, &status);
    if (!status || startCode0 != 0x9d)
        return std::nullopt;

    auto startCode1 = view->get<uint8_t>(4, true, &status);
    if (!status || startCode1 != 0x01)
        return std::nullopt;

    auto startCode2 = view->get<uint8_t>(5, true, &status);
    if (!status || startCode2 != 0x2a)
        return std::nullopt;

    auto horizontalAndWidthField = view->get<uint16_t>(6, true, &status);
    if (!status)
        return std::nullopt;

    header.horizontalScale = static_cast<uint8_t>(horizontalAndWidthField >> 14);
    header.width = static_cast<uint16_t>(horizontalAndWidthField & 0x3FFF);

    auto verticalAndHeightField = view->get<uint16_t>(8, true, &status);
    if (!status)
        return std::nullopt;

    header.verticalScale = static_cast<uint8_t>(verticalAndHeightField >> 14);
    header.height = static_cast<uint16_t>(verticalAndHeightField & 0x3FFF);

    auto colorSpaceAndClampingField = view->get<uint8_t>(10, true, &status);
    if (!status)
        return std::nullopt;

    header.colorSpace = colorSpaceAndClampingField & 0x80;
    header.needsClamping = colorSpaceAndClampingField & 0x40;

    return header;
}

Ref<VideoInfo> createVideoInfoFromVP8Header(const VP8FrameHeader& header, const webm::Element<Colour>& color)
{
    VPCodecConfigurationRecord record;
    record.codecName = "vp08"_s;
    record.profile = 0;
    record.level = 10;
    record.bitDepth = 8;
    record.videoFullRangeFlag = VPConfigurationRange::FullRange;
    record.chromaSubsampling = VPConfigurationChromaSubsampling::Subsampling_420_Colocated;
    record.colorPrimaries = header.colorSpace ? VPConfigurationColorPrimaries::Unspecified : VPConfigurationColorPrimaries::BT_601_7;
    record.transferCharacteristics =  header.colorSpace ? VPConfigurationTransferCharacteristics::Unspecified : VPConfigurationTransferCharacteristics::BT_601_7;
    record.matrixCoefficients = header.colorSpace ? VPConfigurationMatrixCoefficients::Unspecified : VPConfigurationMatrixCoefficients::BT_601_7;

    // Container color values can override per-sample ones:
    if (color.is_present()) {
        auto& colorValue = color.value();
        if (colorValue.chroma_subsampling_x.is_present() && colorValue.chroma_subsampling_y.is_present())
            record.chromaSubsampling = convertSubsamplingXYToChromaSubsampling(colorValue.chroma_subsampling_x.value(), colorValue.chroma_subsampling_y.value());
        if (colorValue.range.is_present() && colorValue.range.value() != Range::kUnspecified)
            record.videoFullRangeFlag = colorValue.range.value() == Range::kFull ? VPConfigurationRange::FullRange : VPConfigurationRange::VideoRange;
        if (colorValue.bits_per_channel.is_present())
            record.bitDepth = colorValue.bits_per_channel.value();
        if (colorValue.transfer_characteristics.is_present())
            record.transferCharacteristics = convertToTransferCharacteristics(colorValue.transfer_characteristics.value());
        if (colorValue.matrix_coefficients.is_present())
            record.matrixCoefficients = convertToMatrixCoefficients(colorValue.matrix_coefficients.value());
        if (colorValue.primaries.is_present())
            record.colorPrimaries = convertToColorPrimaries(colorValue.primaries.value());
    }

    return createVideoInfoFromVPCodecConfigurationRecord(record, header.width, header.height);
}

}

#endif // PLATFORM(COCOA)
