/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013 Orange
 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
 * Copyright (C) 2015, 2016 Metrological Group B.V.
 * Copyright (C) 2015, 2016 Igalia, S.L
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER 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 "SourceBufferPrivateGStreamer.h"

#if ENABLE(MEDIA_SOURCE) && USE(GSTREAMER)

#include "AppendPipeline.h"
#include "AudioTrackPrivateGStreamer.h"
#include "ContentType.h"
#include "GStreamerCommon.h"
#include "InbandTextTrackPrivate.h"
#include "InbandTextTrackPrivateGStreamer.h"
#include "MediaPlayerPrivateGStreamerMSE.h"
#include "MediaSample.h"
#include "MediaSourcePrivateGStreamer.h"
#include "MediaSourceTrackGStreamer.h"
#include "NotImplemented.h"
#include "VideoTrackPrivateGStreamer.h"
#include "WebKitMediaSourceGStreamer.h"

GST_DEBUG_CATEGORY_EXTERN(webkit_mse_debug);
#define GST_CAT_DEFAULT webkit_mse_debug

namespace WebCore {

Ref<SourceBufferPrivateGStreamer> SourceBufferPrivateGStreamer::create(MediaSourcePrivateGStreamer* mediaSource, const ContentType& contentType, MediaPlayerPrivateGStreamerMSE& playerPrivate)
{
    return adoptRef(*new SourceBufferPrivateGStreamer(mediaSource, contentType, playerPrivate));
}

SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer(MediaSourcePrivateGStreamer* mediaSource, const ContentType& contentType, MediaPlayerPrivateGStreamerMSE& playerPrivate)
    : SourceBufferPrivate()
    , m_mediaSource(mediaSource)
    , m_type(contentType)
    , m_playerPrivate(playerPrivate)
    , m_appendPipeline(makeUniqueRef<AppendPipeline>(*this, playerPrivate))
#if !RELEASE_LOG_DISABLED
    , m_logger(mediaSource->logger())
    , m_logIdentifier(mediaSource->nextSourceBufferLogIdentifier())
#endif
{
}

void SourceBufferPrivateGStreamer::append(Vector<unsigned char>&& data)
{
    ASSERT(isMainThread());
    ASSERT(m_mediaSource);
    ASSERT(m_client);

    GST_DEBUG("Appending %zu bytes", data.size());
    // Wrap the whole Vector object in case the data is stored in the inlined buffer.
    auto* bufferData = data.data();
    auto bufferLength = data.size();
    GRefPtr<GstBuffer> buffer = adoptGRef(gst_buffer_new_wrapped_full(static_cast<GstMemoryFlags>(0), bufferData, bufferLength, 0, bufferLength, new Vector<unsigned char>(WTFMove(data)),
        [](gpointer data)
        {
            delete static_cast<Vector<unsigned char>*>(data);
        }));

    m_appendPipeline->pushNewBuffer(WTFMove(buffer));
}

void SourceBufferPrivateGStreamer::abort()
{
    ASSERT(isMainThread());
    GST_DEBUG("aborting");
    m_appendPipeline->resetParserState();
}

void SourceBufferPrivateGStreamer::resetParserState()
{
    ASSERT(isMainThread());
    GST_DEBUG("resetting parser state");
    m_appendPipeline->resetParserState();
}

void SourceBufferPrivateGStreamer::removedFromMediaSource()
{
    ASSERT(isMainThread());
    clearTrackBuffers();
    m_mediaSource->removeSourceBuffer(this);

    for (auto& track : m_tracks.values())
        track->remove();
    m_hasBeenRemovedFromMediaSource = true;
}

MediaPlayer::ReadyState SourceBufferPrivateGStreamer::readyState() const
{
    return m_mediaSource->readyState();
}

void SourceBufferPrivateGStreamer::setReadyState(MediaPlayer::ReadyState state)
{
    m_mediaSource->setReadyState(state);
}

void SourceBufferPrivateGStreamer::flush(const AtomString& trackId)
{
    ASSERT(isMainThread());

    // This is only for on-the-fly reenqueues after appends. When seeking, the seek will do its own flush.

    if (!m_playerPrivate.hasAllTracks()) {
        // Source element has not emitted tracks yet, so we only need to clear the queue.
        MediaSourceTrackGStreamer* track = m_tracks.get(trackId);
        track->clearQueue();
        return;
    }

    // Source element has emitted tracks, let it handle the flush, which may cause a pipeline flush as well.
    webKitMediaSrcFlush(m_playerPrivate.webKitMediaSrc(), trackId);
}

void SourceBufferPrivateGStreamer::enqueueSample(Ref<MediaSample>&& sample, const AtomString& trackId)
{
    ASSERT(isMainThread());

    GST_TRACE("enqueing sample trackId=%s PTS=%s presentationSize=%.0fx%.0f at %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT,
        trackId.string().utf8().data(), sample->presentationTime().toString().utf8().data(),
        sample->presentationSize().width(), sample->presentationSize().height(),
        GST_TIME_ARGS(WebCore::toGstClockTime(sample->presentationTime())),
        GST_TIME_ARGS(WebCore::toGstClockTime(sample->duration())));

    GRefPtr<GstSample> gstSample = sample->platformSample().sample.gstSample;
    ASSERT(gstSample);
    ASSERT(gst_sample_get_buffer(gstSample.get()));

    MediaSourceTrackGStreamer* track = m_tracks.get(trackId);
    track->enqueueObject(adoptGRef(GST_MINI_OBJECT(gstSample.leakRef())));
}

bool SourceBufferPrivateGStreamer::isReadyForMoreSamples(const AtomString& trackId)
{
    ASSERT(isMainThread());
    MediaSourceTrackGStreamer* track = m_tracks.get(trackId);
    bool ret = track->isReadyForMoreSamples();
    GST_TRACE("SourceBufferPrivate(%p) - isReadyForMoreSamples: %s", this, boolForPrinting(ret));
    return ret;
}

void SourceBufferPrivateGStreamer::notifyClientWhenReadyForMoreSamples(const AtomString& trackId)
{
    ASSERT(isMainThread());
    MediaSourceTrackGStreamer* track = m_tracks.get(trackId);
    track->notifyWhenReadyForMoreSamples([protector = Ref { *this }, this, trackId]() mutable {
        RunLoop::main().dispatch([protector = WTFMove(protector), this, trackId]() {
            if (!m_hasBeenRemovedFromMediaSource)
                provideMediaData(trackId);
        });
    });
}

void SourceBufferPrivateGStreamer::allSamplesInTrackEnqueued(const AtomString& trackId)
{
    ASSERT(isMainThread());
    GST_DEBUG("Enqueueing EOS for track '%s'", trackId.string().utf8().data());
    MediaSourceTrackGStreamer* track = m_tracks.get(trackId);
    track->enqueueObject(adoptGRef(GST_MINI_OBJECT(gst_event_new_eos())));
}

void SourceBufferPrivateGStreamer::setActive(bool isActive)
{
    m_isActive = isActive;
    m_mediaSource->sourceBufferPrivateDidChangeActiveState(this, isActive);
}

bool SourceBufferPrivateGStreamer::isActive() const
{
    return m_isActive;
}

void SourceBufferPrivateGStreamer::didReceiveInitializationSegment(SourceBufferPrivateClient::InitializationSegment&& initializationSegment, CompletionHandler<void()>&& completionHandler)
{
    m_hasReceivedInitializationSegment = true;
    for (auto& trackInfo : initializationSegment.videoTracks) {
        GRefPtr<GstCaps> initialCaps = static_cast<VideoTrackPrivateGStreamer*>(trackInfo.track.get())->initialCaps();
        ASSERT(initialCaps);
        if (!m_tracks.contains(trackInfo.track->id()))
            m_tracks.add(trackInfo.track->id(), MediaSourceTrackGStreamer::create(TrackPrivateBaseGStreamer::TrackType::Video, trackInfo.track->id(), WTFMove(initialCaps)));
    }
    for (auto& trackInfo : initializationSegment.audioTracks) {
        GRefPtr<GstCaps> initialCaps = static_cast<AudioTrackPrivateGStreamer*>(trackInfo.track.get())->initialCaps();
        ASSERT(initialCaps);
        if (!m_tracks.contains(trackInfo.track->id()))
            m_tracks.add(trackInfo.track->id(), MediaSourceTrackGStreamer::create(TrackPrivateBaseGStreamer::TrackType::Audio, trackInfo.track->id(), WTFMove(initialCaps)));
    }
    for (auto& trackInfo : initializationSegment.textTracks) {
        GRefPtr<GstCaps> initialCaps = static_cast<InbandTextTrackPrivateGStreamer*>(trackInfo.track.get())->initialCaps();
        ASSERT(initialCaps);
        if (!m_tracks.contains(trackInfo.track->id()))
            m_tracks.add(trackInfo.track->id(), MediaSourceTrackGStreamer::create(TrackPrivateBaseGStreamer::TrackType::Text, trackInfo.track->id(), WTFMove(initialCaps)));
    }

    m_mediaSource->startPlaybackIfHasAllTracks();

    SourceBufferPrivate::didReceiveInitializationSegment(WTFMove(initializationSegment), WTFMove(completionHandler));
}

void SourceBufferPrivateGStreamer::didReceiveSample(Ref<MediaSample>&& sample)
{
    SourceBufferPrivate::didReceiveSample(WTFMove(sample));
}

void SourceBufferPrivateGStreamer::didReceiveAllPendingSamples()
{
    SourceBufferPrivate::appendCompleted(true, m_mediaSource ? m_mediaSource->isEnded() : true);
}

void SourceBufferPrivateGStreamer::appendParsingFailed()
{
    SourceBufferPrivate::appendCompleted(false, m_mediaSource ? m_mediaSource->isEnded() : true);
}

bool SourceBufferPrivateGStreamer::isSeeking() const
{
    return m_mediaSource && m_mediaSource->isSeeking();
}

MediaTime SourceBufferPrivateGStreamer::currentMediaTime() const
{
    if (!m_mediaSource)
        return { };

    return m_mediaSource->currentMediaTime();
}

MediaTime SourceBufferPrivateGStreamer::duration() const
{
    if (!m_mediaSource)
        return { };

    return m_mediaSource->duration();
}

#if !RELEASE_LOG_DISABLED
WTFLogChannel& SourceBufferPrivateGStreamer::logChannel() const
{
    return LogMediaSource;
}
#endif

}
#endif
