mistserver/src/output/output.h

163 lines
6.9 KiB
C++

#pragma once
#include "../io.h"
#include <cstdlib>
#include <map>
#include <mist/comms.h>
#include <mist/config.h>
#include <mist/dtsc.h>
#include <mist/flv_tag.h>
#include <mist/json.h>
#include <mist/shared_memory.h>
#include <mist/socket.h>
#include <mist/timing.h>
#include <mist/stream.h>
#include <mist/url.h>
#include <set>
namespace Mist{
/// The output class is intended to be inherited by MistOut process classes.
/// It contains all generic code and logic, while the child classes implement
/// anything specific to particular protocols or containers.
/// It contains several virtual functions, that may be overridden to "hook" into
/// the streaming process at those particular points, simplifying child class
/// logic and implementation details.
class Output : public InOutBase{
public:
// constructor and destructor
Output(Socket::Connection &conn);
// static members for initialization and capabilities
static void init(Util::Config *cfg);
static JSON::Value capa;
/*LTS-START*/
std::string reqUrl;
/*LTS-END*/
// non-virtual generic functions
virtual int run();
virtual void stats(bool force = false);
bool seek(uint64_t pos, bool toKey = false);
bool seek(size_t tid, uint64_t pos, bool getNextKey);
void seekKeyframesIn(unsigned long long pos, unsigned long long maxDelta);
void stop();
uint64_t currentTime();
uint64_t startTime();
uint64_t endTime();
void setBlocking(bool blocking);
bool selectDefaultTracks();
bool connectToFile(std::string file, bool append = false, Socket::Connection *conn = 0);
static bool listenMode(){return true;}
uint32_t currTrackCount() const;
virtual bool isReadyForPlay();
virtual bool reachedPlannedStop();
// virtuals. The optional virtuals have default implementations that do as little as possible.
/// This function is called whenever a packet is ready for sending.
/// Inside it, thisPacket is guaranteed to contain a valid packet.
virtual void sendNext(){}// REQUIRED! Others are optional.
virtual bool dropPushTrack(uint32_t trackId, const std::string &dropReason);
bool getKeyFrame();
bool prepareNext();
virtual void dropTrack(size_t trackId, const std::string &reason, bool probablyBad = true);
virtual void onRequest();
static void listener(Util::Config &conf, int (*callback)(Socket::Connection &S));
virtual void initialSeek();
uint64_t getMinKeepAway();
virtual bool liveSeek(bool rateOnly = false);
virtual bool onFinish(){return false;}
void reconnect();
void disconnect();
virtual void initialize();
virtual void sendHeader();
virtual void onFail(const std::string &msg, bool critical = false);
virtual void requestHandler();
static Util::Config *config;
void playbackSleep(uint64_t millis);
void selectAllTracks();
/// Accessor for buffer.setSyncMode.
void setSyncMode(bool synced){buffer.setSyncMode(synced);}
private: // these *should* not be messed with in child classes.
/*LTS-START*/
void Log(std::string type, std::string message);
bool checkLimits();
bool isBlacklisted(std::string host, std::string streamName, int timeConnected);
std::string hostLookup(std::string ip);
bool onList(std::string ip, std::string list);
std::string getCountry(std::string ip);
/*LTS-END*/
std::map<size_t, uint32_t> currentPage;
void loadPageForKey(size_t trackId, size_t keyNum);
uint64_t pageNumForKey(size_t trackId, size_t keyNum);
uint64_t pageNumMax(size_t trackId);
bool isRecordingToFile;
uint64_t lastStats; ///< Time of last sending of stats.
void reinitPlaylist(std::string &playlistBuffer, uint64_t &maxAge, uint64_t &maxEntries,
uint64_t &segmentCount, uint64_t &segmentsRemoved, uint64_t &curTime,
std::string targetDuration, HTTP::URL &playlistLocation);
Util::packetSorter buffer; ///< A sorted list of next-to-be-loaded packets.
bool sought; ///< If a seek has been done, this is set to true. Used for seeking on
///< prepareNext().
std::string prevHost; ///< Old value for getConnectedBinHost, for caching
size_t emptyCount;
bool recursingSync;
uint32_t seekCount;
bool firstData;
uint64_t lastPushUpdate;
bool newUA;
protected: // these are to be messed with by child classes
virtual bool inlineRestartCapable() const{
return false;
}///< True if the output is capable of restarting mid-stream. This is used for swapping recording files
bool pushing;
std::map<std::string, std::string> targetParams; /*LTS*/
std::string UA; ///< User Agent string, if known.
uint64_t uaDelay; ///< Seconds to wait before setting the UA.
uint64_t lastRecv;
uint64_t dataWaitTimeout; ///< How long to wait for new packets before dropping a track, in tens of milliseconds.
uint64_t firstTime; ///< Time of first packet after last seek. Used for real-time sending.
virtual std::string getConnectedHost();
virtual std::string getConnectedBinHost();
virtual std::string getStatsName();
virtual void connStats(uint64_t now, Comms::Connections &statComm);
std::set<size_t> getSupportedTracks(const std::string &type = "") const;
inline virtual bool keepGoing(){return config->is_active && myConn;}
virtual void idleTime(uint64_t ms){Util::sleep(ms);}
Comms::Connections statComm;
bool isBlocking; ///< If true, indicates that myConn is blocking.
std::string tkn; ///< Random identifier used to split connections into sessions
uint64_t nextKeyTime();
// stream delaying variables
uint64_t maxSkipAhead; ///< Maximum ms that we will go ahead of the intended timestamps.
uint64_t realTime; ///< Playback speed in ms of wallclock time per data-second. eg: 0 is
///< infinite, 1000 real-time, 5000 is 0.2X speed, 500 = 2X speed.
uint64_t needsLookAhead; ///< Amount of millis we need to be able to look ahead in the metadata
// Read/write status variables
Socket::Connection &myConn; ///< Connection to the client.
bool wantRequest; ///< If true, waits for a request.
bool parseData; ///< If true, triggers initalization if not already done, sending of header, sending of packets.
bool isInitialized; ///< If false, triggers initialization if parseData is true.
bool sentHeader; ///< If false, triggers sendHeader if parseData is true.
virtual bool isRecording();
virtual bool isFileTarget();
virtual bool isPushing(){return pushing;};
bool allowPush(const std::string &passwd);
void waitForStreamPushReady();
uint64_t firstPacketTime;
uint64_t lastPacketTime;
std::map<size_t, IPC::sharedPage> curPage; ///< For each track, holds the page that is currently being written.
};
}// namespace Mist