#pragma once
#if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(MEDIA_SOURCE)
#include "GRefPtrGStreamer.h"
#include "MediaPlayerPrivateGStreamerMSE.h"
#include "MediaSourceClientGStreamerMSE.h"
#include "SourceBufferPrivateGStreamer.h"
#include <gst/gst.h>
#include <wtf/Condition.h>
namespace WebCore {
#if !LOG_DISABLED
struct PadProbeInformation {
AppendPipeline* appendPipeline;
const char* description;
gulong probeId;
};
#endif
class AppendPipeline : public ThreadSafeRefCounted<AppendPipeline> {
public:
enum class AppendState { Invalid, NotStarted, Ongoing, KeyNegotiation, DataStarve, Sampling, LastSample, Aborting };
AppendPipeline(Ref<MediaSourceClientGStreamerMSE>, Ref<SourceBufferPrivateGStreamer>, MediaPlayerPrivateGStreamerMSE&);
virtual ~AppendPipeline();
void handleElementMessage(GstMessage*);
void handleApplicationMessage(GstMessage*);
gint id();
AppendState appendState() { return m_appendState; }
void setAppendState(AppendState);
GstFlowReturn handleNewAppsinkSample(GstElement*);
GstFlowReturn pushNewBuffer(GstBuffer*);
void parseDemuxerSrcPadCaps(GstCaps*);
void appsinkCapsChanged();
void appsinkNewSample(GstSample*);
void appsinkEOS();
void didReceiveInitializationSegment();
AtomicString trackId();
void abort();
void clearPlayerPrivate();
Ref<SourceBufferPrivateGStreamer> sourceBufferPrivate() { return m_sourceBufferPrivate.get(); }
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(); }
GstCaps* appsinkCaps() { return m_appsinkCaps.get(); }
RefPtr<WebCore::TrackPrivateBase> track() { return m_track; }
WebCore::MediaSourceStreamTypeGStreamer streamType() { return m_streamType; }
void disconnectDemuxerSrcPadFromAppsinkFromAnyThread(GstPad*);
void connectDemuxerSrcPadToAppsinkFromAnyThread(GstPad*);
void connectDemuxerSrcPadToAppsink(GstPad*);
void reportAppsrcAtLeastABufferLeft();
void reportAppsrcNeedDataReceived();
private:
void resetPipeline();
void checkEndOfAppend();
void handleAppsrcAtLeastABufferLeft();
void handleAppsrcNeedDataReceived();
void removeAppsrcDataLeavingProbe();
void setAppsrcDataLeavingProbe();
private:
Ref<MediaSourceClientGStreamerMSE> m_mediaSourceClient;
Ref<SourceBufferPrivateGStreamer> m_sourceBufferPrivate;
MediaPlayerPrivateGStreamerMSE* m_playerPrivate;
gint m_id;
MediaTime m_initialDuration;
GstFlowReturn m_flowReturn;
GRefPtr<GstElement> m_pipeline;
GRefPtr<GstBus> m_bus;
GRefPtr<GstElement> m_appsrc;
GRefPtr<GstElement> m_demux;
#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
GRefPtr<GstElement> m_decryptor;
#endif
GRefPtr<GstElement> m_appsink;
Lock m_newSampleLock;
Condition m_newSampleCondition;
Lock m_padAddRemoveLock;
Condition m_padAddRemoveCondition;
GRefPtr<GstCaps> m_appsinkCaps;
GRefPtr<GstCaps> m_demuxerSrcPadCaps;
FloatSize m_presentationSize;
bool m_appsrcAtLeastABufferLeft;
bool m_appsrcNeedDataReceived;
gulong m_appsrcDataLeavingProbeId;
#if !LOG_DISABLED
struct PadProbeInformation m_demuxerDataEnteringPadProbeInformation;
struct PadProbeInformation m_appsinkDataEnteringPadProbeInformation;
#endif
AppendState m_appendState;
bool m_abortPending;
WebCore::MediaSourceStreamTypeGStreamer m_streamType;
RefPtr<WebCore::TrackPrivateBase> m_oldTrack;
RefPtr<WebCore::TrackPrivateBase> m_track;
GRefPtr<GstBuffer> m_pendingBuffer;
};
}
#endif // USE(GSTREAMER)