/*
 * Copyright (C) 2018 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.
 */

#pragma once

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

#include "IOSurface.h"
#include "MediaSample.h"
#include "RemoteVideoSample.h"
#include <wtf/MachSendRight.h>
#include <wtf/MediaTime.h>

typedef struct __CVBuffer* CVPixelBufferRef;

namespace WebCore {

class RemoteVideoSample {
public:
    RemoteVideoSample() = default;
    RemoteVideoSample(RemoteVideoSample&&) = default;
    RemoteVideoSample& operator=(RemoteVideoSample&&) = default;
    ~RemoteVideoSample() = default;

    WEBCORE_EXPORT static std::unique_ptr<RemoteVideoSample> create(MediaSample&);
    WEBCORE_EXPORT static std::unique_ptr<RemoteVideoSample> create(RetainPtr<CVPixelBufferRef>&&, MediaTime&& presentationTime, MediaSample::VideoRotation = MediaSample::VideoRotation::None);
    WEBCORE_EXPORT IOSurfaceRef surface() const;

#if HAVE(IOSURFACE_SET_OWNERSHIP_IDENTITY)
    void setOwnershipIdentity(task_id_token_t newOwner);
#endif

    const MediaTime& time() const { return m_time; }
    uint32_t videoFormat() const { return m_videoFormat; }
    IntSize size() const { return m_size; }
    MediaSample::VideoRotation rotation() const { return m_rotation; }
    bool mirrored() const { return m_mirrored; }

    template<class Encoder> void encode(Encoder& encoder) const
    {
        if (m_ioSurface)
            encoder << m_ioSurface->createSendRight();
        else
            encoder << MachSendRight();
        encoder << m_rotation;
        encoder << m_time;
        encoder << m_videoFormat;
        encoder << m_size;
        encoder << m_mirrored;
    }

    template<class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder& decoder, RemoteVideoSample& sample)
    {
        MachSendRight sendRight;
        if (!decoder.decode(sendRight))
            return false;
        sample.m_sendRight = WTFMove(sendRight);

        MediaSample::VideoRotation rotation;
        if (!decoder.decode(rotation))
            return false;
        sample.m_rotation = rotation;

        MediaTime time;
        if (!decoder.decode(time))
            return false;
        sample.m_time = WTFMove(time);

        uint32_t format;
        if (!decoder.decode(format))
            return false;
        sample.m_videoFormat = format;

        IntSize size;
        if (!decoder.decode(size))
            return false;
        sample.m_size = WTFMove(size);

        bool mirrored;
        if (!decoder.decode(mirrored))
            return false;
        sample.m_mirrored = mirrored;

        return true;
    }

private:
    RemoteVideoSample(IOSurfaceRef, RetainPtr<CVPixelBufferRef>&&, const DestinationColorSpace&, MediaTime&&, MediaSample::VideoRotation, bool);

    std::unique_ptr<WebCore::IOSurface> m_ioSurface;
    RetainPtr<CVPixelBufferRef> m_imageBuffer;
    MachSendRight m_sendRight;
    MediaSample::VideoRotation m_rotation { MediaSample::VideoRotation::None };
    MediaTime m_time;
    uint32_t m_videoFormat { 0 };
    IntSize m_size;
    bool m_mirrored { false };
};

#if HAVE(IOSURFACE_SET_OWNERSHIP_IDENTITY)
inline void RemoteVideoSample::setOwnershipIdentity(task_id_token_t newOwner)
{
    if (m_ioSurface)
        m_ioSurface->setOwnershipIdentity(newOwner);
}
#endif

}

#endif // ENABLE(MEDIA_STREAM)
