#pragma once
#if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(MEDIA_SOURCE)
#include "AbortableTaskQueue.h"
#include "GStreamerCommon.h"
#include "MediaPlayerPrivateGStreamerMSE.h"
#include "SourceBufferPrivateGStreamer.h"
#include <atomic>
#include <gst/gst.h>
#include <mutex>
#include <wtf/Condition.h>
#include <wtf/Threading.h>
namespace WebCore {
#if !LOG_DISABLED || ENABLE(ENCRYPTED_MEDIA)
struct PadProbeInformation {
AppendPipeline* appendPipeline;
const char* description;
gulong probeId;
};
#endif
class AppendPipeline {
WTF_MAKE_FAST_ALLOCATED;
public:
AppendPipeline(SourceBufferPrivateGStreamer&, MediaPlayerPrivateGStreamerMSE&);
virtual ~AppendPipeline();
void pushNewBuffer(GRefPtr<GstBuffer>&&);
void resetParserState();
SourceBufferPrivateGStreamer& sourceBufferPrivate() { return m_sourceBufferPrivate; }
GstCaps* appsinkCaps() { return m_appsinkCaps.get(); }
RefPtr<WebCore::TrackPrivateBase> track() { return m_track; }
MediaPlayerPrivateGStreamerMSE* playerPrivate() { return m_playerPrivate; }
private:
void handleErrorSyncMessage(GstMessage*);
void handleNeedContextSyncMessage(GstMessage*);
void handleStateChangeMessage(GstMessage*);
gint id();
void handleAppsinkNewSampleFromStreamingThread(GstElement*);
void handleErrorConditionFromStreamingThread();
void parseDemuxerSrcPadCaps(GstCaps*);
void appsinkCapsChanged();
void appsinkNewSample(GRefPtr<GstSample>&&);
void handleEndOfAppend();
void didReceiveInitializationSegment();
AtomString trackId();
GstBus* bus() { return m_bus.get(); }
GstElement* pipeline() { return m_pipeline.get(); }
GstElement* appsrc() { return m_appsrc.get(); }
GstElement* appsink() { return m_appsink.get(); }
GstCaps* demuxerSrcPadCaps() { return m_demuxerSrcPadCaps.get(); }
WebCore::MediaSourceStreamTypeGStreamer streamType() { return m_streamType; }
void disconnectDemuxerSrcPadFromAppsinkFromAnyThread(GstPad*);
void connectDemuxerSrcPadToAppsinkFromStreamingThread(GstPad*);
void connectDemuxerSrcPadToAppsink(GstPad*);
void resetPipeline();
void consumeAppsinkAvailableSamples();
GstPadProbeReturn appsrcEndOfAppendCheckerProbe(GstPadProbeInfo*);
static void staticInitialization();
static std::once_flag s_staticInitializationFlag;
static GType s_endOfAppendMetaType;
static const GstMetaInfo* s_webKitEndOfAppendMetaInfo;
WTF::Thread* m_streamingThread;
bool m_errorReceived { false };
SourceBufferPrivateGStreamer& m_sourceBufferPrivate;
MediaPlayerPrivateGStreamerMSE* m_playerPrivate;
gint m_id;
MediaTime m_initialDuration;
GRefPtr<GstElement> m_pipeline;
GRefPtr<GstBus> m_bus;
GRefPtr<GstElement> m_appsrc;
GRefPtr<GstElement> m_demux;
GRefPtr<GstElement> m_parser; GRefPtr<GstElement> m_appsink;
std::atomic_flag m_wasBusAlreadyNotifiedOfAvailableSamples;
GRefPtr<GstCaps> m_appsinkCaps;
GRefPtr<GstCaps> m_demuxerSrcPadCaps;
FloatSize m_presentationSize;
#if !LOG_DISABLED
struct PadProbeInformation m_demuxerDataEnteringPadProbeInformation;
struct PadProbeInformation m_appsinkDataEnteringPadProbeInformation;
#endif
#if ENABLE(ENCRYPTED_MEDIA)
struct PadProbeInformation m_appsinkPadEventProbeInformation;
#endif
WebCore::MediaSourceStreamTypeGStreamer m_streamType;
RefPtr<WebCore::TrackPrivateBase> m_track;
AbortableTaskQueue m_taskQueue;
GRefPtr<GstBuffer> m_pendingBuffer;
};
}
#endif // USE(GSTREAMER)