Added HLS input

This commit is contained in:
Ramoe 2017-05-12 12:21:30 +02:00 committed by Thulinma
parent 30beda61ce
commit a9c5334833
6 changed files with 2104 additions and 442 deletions

View file

@ -339,6 +339,7 @@ macro(makeInput inputName format)
)
endmacro()
makeInput(HLS hls)
makeInput(DTSC dtsc)
makeInput(DTSCCrypt dtsccrypt)
makeInput(MP3 mp3)

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,28 @@ namespace TS {
H265 = 0x24,
ID3 = 0x15
};
class ADTSRemainder{
private:
char * data;
uint32_t max;
uint32_t now;
uint32_t len;
uint32_t bpos;
public:
void setRemainder(const aac::adts & p, const void * source, const uint32_t avail, const uint32_t bPos);
ADTSRemainder();
~ADTSRemainder();
uint32_t getLength();
uint32_t getBpos();
uint32_t getTodo();
char* getData();
void append(const char *p,uint32_t pLen);
bool isComplete();
void clear();
};
class Stream{
public:
@ -26,25 +48,33 @@ namespace TS {
void parse(Packet & newPack, unsigned long long bytePos);
void parse(char * newPack, unsigned long long bytePos);
void parse(unsigned long tid);
void parseNal(uint32_t tid, const char *pesPayload, const char * packetPtr, bool &isKeyFrame);
bool hasPacketOnEachTrack() const;
bool hasPacket(unsigned long tid) const;
bool hasPacket() const;
void getPacket(unsigned long tid, DTSC::Packet & pack);
void getEarliestPacket(DTSC::Packet & pack);
void initializeMetadata(DTSC::Meta & meta, unsigned long tid = 0);
void initializeMetadata(DTSC::Meta & meta, unsigned long tid = 0, unsigned long mappingId = 0);
void partialClear();
void clear();
void finish();
void eraseTrack(unsigned long tid);
bool isDataTrack(unsigned long tid);
void parseBitstream(uint32_t tid, const char * pesPayload, uint32_t realPayloadSize,uint64_t timeStamp, int64_t timeOffset, uint64_t bPos);
std::set<unsigned long> getActiveTracks();
private:
unsigned long long lastPAT;
ProgramAssociationTable associationTable;
std::map<unsigned long, ADTSRemainder> remainders;
bool firstPacketFound;
std::map<unsigned long, unsigned long long> lastPMT;
std::map<unsigned long, ProgramMappingTable> mappingTable;
std::map<unsigned long, std::deque<Packet> > pesStreams;
std::map<unsigned long, std::deque<unsigned long long> > pesPositions;
std::map<unsigned long, std::deque<DTSC::Packet> > outPackets;
std::map<unsigned long, DTSC::Packet> buildPacket;
std::map<unsigned long, unsigned long> pidToCodec;
std::map<unsigned long, aac::adts > adtsInfo;
std::map<unsigned long, std::string > spsInfo;
@ -52,13 +82,13 @@ namespace TS {
std::map<unsigned long, h265::initData > hevcInfo;
std::map<unsigned long, std::string> metaInit;
std::map<unsigned long, std::string> descriptors;
std::map<unsigned long, std::string> partialBuffer;
mutable IPC::semaphore globalSem;
bool threaded;
std::set<unsigned long> pmtTracks;
void parsePES(unsigned long tid);
void parsePES(unsigned long tid, bool finished = false);
};
}

1216
src/input/input_hls.cpp Normal file

File diff suppressed because it is too large Load diff

148
src/input/input_hls.h Normal file
View file

@ -0,0 +1,148 @@
#pragma once
#include "input.h"
#include <mist/dtsc.h>
#include <mist/nal.h>
#include <mist/ts_packet.h>
#include <mist/ts_stream.h>
#include <fstream>
#include <string>
#include <set>
#include <vector>
//#include <stdint.h>
#define BUFFERTIME 10
namespace Mist {
enum PlaylistType { VOD, LIVE, EVENT };
struct playListEntries
{
std::string filename;
uint64_t bytePos;
float duration;
unsigned int timestamp;
unsigned int wait;
};
class Playlist {
public:
Playlist();
std::string codecs;
std::string video;
std::string audio;
std::string uri;
std::string uri_root;
std::string source;
const char *packetPtr;
int id;
bool playlistEnd;
int noChangeCount;
int version;
int targetDuration;
uint64_t media_sequence;
int lastFileIndex;
int waitTime;
bool vodLive;
PlaylistType playlistType;
std::deque<playListEntries> entries;
int entryCount;
int programId;
int bandwidth;
unsigned int lastTimestamp;
};
struct entryBuffer
{
int timestamp;
playListEntries entry;
int playlistIndex;
};
class inputHLS : public Input {
public:
inputHLS(Util::Config * cfg);
~inputHLS();
bool needsLock();
bool openStreamSource();
protected:
//Private Functions
unsigned int startTime;
PlaylistType playlistType;
int version;
int targetDuration;
int media_sequence;
bool endPlaylist;
int currentPlaylist;
bool initDone;
std::string init_source;
//std::vector<playListEntries> entries;
std::vector<Playlist> playlists;
//std::vector<int> pidMapping;
std::map<int,int> pidMapping;
std::map<int,int> pidMappingR;
std::string playlistFile;
std::string playlistRootPath;
std::vector<int> reloadNext;
bool liveStream;
int currentIndex;
std::string currentFile;
std::ifstream in;
bool isUrl;
TS::Stream tsStream;///<Used for parsing the incoming ts stream
bool pushing;
Socket::UDPConnection udpCon;
std::string udpDataBuffer;
Socket::Connection conn;
TS::Packet tsBuf;
int getFirstPlaylistToReload();
int firstSegment();
bool getNextSegment();
void readPMT();
bool setup();
bool preSetup();
bool readHeader();
void getNext(bool smart = true);
void seek(int seekTime);
void trackSelect(std::string trackSpec);
FILE * inFile;
FILE * tsFile;
bool openURL(std::string urlString, Playlist &p);
void printContent();
void printBuffer();
bool readIndex();
bool initPlaylist(std::string uri);
bool readPlaylist(std::string uri);
bool reloadPlaylist(Playlist &p);
bool readNextFile();
void parseStreamHeader();
void addEntryToPlaylist(Playlist &p, std::string filename, float duration, uint64_t &totalBytes);
int getMappedTrackId(int id);
int getMappedTrackPlaylist(int id);
int getOriginalTrackId(int playlistId, int id);
int getEntryId(int playlistId, uint64_t bytePos);
int cleanLine(std::string &s);
};
}
typedef Mist::inputHLS mistIn;

View file

@ -130,7 +130,6 @@ namespace Mist {
}
}
///Live Setup of TS Input
bool inputTS::setup() {
const std::string & inpt = config->getString("input");
@ -205,7 +204,17 @@ namespace Mist {
}
myMeta.update(headerPack);
}
}
DTSC::Packet headerPack;
tsStream.getEarliestPacket(headerPack);
while (headerPack) {
if (!myMeta.tracks.count(headerPack.getTrackId()) || !myMeta.tracks[headerPack.getTrackId()].codec.size()) {
tsStream.initializeMetadata(myMeta, headerPack.getTrackId());
}
myMeta.update(headerPack);
tsStream.getEarliestPacket(headerPack);
}
fseek(inFile, 0, SEEK_SET);
@ -230,9 +239,6 @@ namespace Mist {
hasPacket = (selectedTracks.size() == 1 ? tsStream.hasPacket(*selectedTracks.begin()) : tsStream.hasPacketOnEachTrack());
}
if (!hasPacket) {
if (!feof(inFile)) {
getNext();
}
return;
}
if (selectedTracks.size() == 1) {
@ -264,14 +270,12 @@ namespace Mist {
}
//Clear leaves the PMT in place
tsStream.clear();
tsStream.partialClear();
//Restore original file position
if (fseek(inFile, bpos, SEEK_SET)) {
return;
}
}
///Seeks to a specific time