Style enforcement
This commit is contained in:
parent
6811b54186
commit
56c21b5ba6
4 changed files with 939 additions and 1151 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,21 +1,14 @@
|
||||||
#include "ts_packet.h"
|
|
||||||
#include "adts.h"
|
#include "adts.h"
|
||||||
|
#include "h265.h"
|
||||||
|
#include "ts_packet.h"
|
||||||
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <deque>
|
|
||||||
#include "h265.h"
|
|
||||||
|
|
||||||
#include "shared_memory.h"
|
#include "shared_memory.h"
|
||||||
|
|
||||||
namespace TS{
|
namespace TS{
|
||||||
enum codecType {
|
enum codecType{H264 = 0x1B, AAC = 0x0F, AC3 = 0x81, MP3 = 0x03, H265 = 0x24, ID3 = 0x15};
|
||||||
H264 = 0x1B,
|
|
||||||
AAC = 0x0F,
|
|
||||||
AC3 = 0x81,
|
|
||||||
MP3 = 0x03,
|
|
||||||
H265 = 0x24,
|
|
||||||
ID3 = 0x15
|
|
||||||
};
|
|
||||||
|
|
||||||
class ADTSRemainder{
|
class ADTSRemainder{
|
||||||
private:
|
private:
|
||||||
|
@ -24,8 +17,10 @@ namespace TS {
|
||||||
uint32_t now;
|
uint32_t now;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t bpos;
|
uint32_t bpos;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setRemainder(const aac::adts & p, const void * source, const uint32_t avail, const uint32_t bPos);
|
void setRemainder(const aac::adts &p, const void *source, const uint32_t avail,
|
||||||
|
const uint32_t bPos);
|
||||||
|
|
||||||
ADTSRemainder();
|
ADTSRemainder();
|
||||||
~ADTSRemainder();
|
~ADTSRemainder();
|
||||||
|
@ -60,8 +55,10 @@ namespace TS {
|
||||||
void finish();
|
void finish();
|
||||||
void eraseTrack(unsigned long tid);
|
void eraseTrack(unsigned long tid);
|
||||||
bool isDataTrack(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);
|
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();
|
std::set<unsigned long> getActiveTracks();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned long long lastPAT;
|
unsigned long long lastPAT;
|
||||||
ProgramAssociationTable associationTable;
|
ProgramAssociationTable associationTable;
|
||||||
|
@ -92,3 +89,4 @@ namespace TS {
|
||||||
void parsePES(unsigned long tid, bool finished = false);
|
void parsePES(unsigned long tid, bool finished = false);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,32 @@
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <fstream>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <mist/stream.h>
|
|
||||||
#include <mist/flv_tag.h>
|
|
||||||
#include <mist/defines.h>
|
|
||||||
#include <mist/ts_packet.h>
|
|
||||||
#include <mist/timing.h>
|
|
||||||
#include <mist/mp4_generic.h>
|
|
||||||
#include "input_hls.h"
|
#include "input_hls.h"
|
||||||
#include <mist/bitfields.h>
|
|
||||||
#include <mist/tinythread.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <mist/http_parser.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mist/bitfields.h>
|
||||||
|
#include <mist/defines.h>
|
||||||
|
#include <mist/flv_tag.h>
|
||||||
|
#include <mist/http_parser.h>
|
||||||
|
#include <mist/mp4_generic.h>
|
||||||
|
#include <mist/stream.h>
|
||||||
|
#include <mist/timing.h>
|
||||||
|
#include <mist/tinythread.h>
|
||||||
|
#include <mist/ts_packet.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define SEM_TS_CLAIM "/MstTSIN%s"
|
#define SEM_TS_CLAIM "/MstTSIN%s"
|
||||||
|
|
||||||
|
|
||||||
namespace Mist{
|
namespace Mist{
|
||||||
// remove trailing \r for windows generated playlist files
|
// remove trailing \r for windows generated playlist files
|
||||||
int cleanLine(std::string &s){
|
int cleanLine(std::string &s){
|
||||||
if (s.length() > 0 && s.at(s.length() - 1) == '\r') {
|
if (s.length() > 0 && s.at(s.length() - 1) == '\r'){s.erase(s.size() - 1);}
|
||||||
s.erase(s.size() - 1);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Playlist::Playlist(const std::string &uriSrc){
|
Playlist::Playlist(const std::string &uriSrc){
|
||||||
lastFileIndex = 0;
|
lastFileIndex = 0;
|
||||||
|
@ -75,13 +71,9 @@ namespace Mist {
|
||||||
key = line.substr(7, pos - 7);
|
key = line.substr(7, pos - 7);
|
||||||
val = line.c_str() + pos + 1;
|
val = line.c_str() + pos + 1;
|
||||||
|
|
||||||
if (key == "VERSION") {
|
if (key == "VERSION"){version = atoi(val.c_str());}
|
||||||
version = atoi(val.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == "TARGETDURATION") {
|
if (key == "TARGETDURATION"){waitTime = atoi(val.c_str());}
|
||||||
waitTime = atoi(val.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == "MEDIA-SEQUENCE"){
|
if (key == "MEDIA-SEQUENCE"){
|
||||||
media_sequence = atoi(val.c_str());
|
media_sequence = atoi(val.c_str());
|
||||||
|
@ -124,9 +116,7 @@ namespace Mist {
|
||||||
initDone = true;
|
initDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Playlist::atEnd() const {
|
bool Playlist::atEnd() const{return (packetPtr - source.data() + 188) > source.size();}
|
||||||
return (packetPtr - source.data() + 188) > source.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Playlist::isUrl() const{
|
bool Playlist::isUrl() const{
|
||||||
return (uri_root.size() ? uri_root.find("http://") == 0 : uri.find("http://") == 0);
|
return (uri_root.size() ? uri_root.find("http://") == 0 : uri.find("http://") == 0);
|
||||||
|
@ -171,9 +161,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
|
|
||||||
FAIL_MSG("Failed to load %s: %s", loadUrl.c_str(), conn ? "timeout" : "connection closed");
|
FAIL_MSG("Failed to load %s: %s", loadUrl.c_str(), conn ? "timeout" : "connection closed");
|
||||||
if (conn) {
|
if (conn){conn.close();}
|
||||||
conn.close();
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,9 +196,7 @@ namespace Mist {
|
||||||
skip = (lastFileIndex - media_sequence);
|
skip = (lastFileIndex - media_sequence);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.compare(0, 7, "#EXTINF") != 0) {
|
if (line.compare(0, 7, "#EXTINF") != 0){continue;}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
float f = atof(line.c_str() + 8);
|
float f = atof(line.c_str() + 8);
|
||||||
// next line belongs to this item
|
// next line belongs to this item
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
@ -226,9 +212,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isUrl()) {
|
if (!isUrl()){fileSource.close();}
|
||||||
fileSource.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (count > 0);
|
ret = (count > 0);
|
||||||
|
|
||||||
|
@ -236,9 +220,7 @@ namespace Mist {
|
||||||
noChangeCount = 0;
|
noChangeCount = 0;
|
||||||
}else{
|
}else{
|
||||||
++noChangeCount;
|
++noChangeCount;
|
||||||
if (noChangeCount > 3) {
|
if (noChangeCount > 3){VERYHIGH_MSG("enough!");}
|
||||||
VERYHIGH_MSG("enough!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -265,9 +247,7 @@ namespace Mist {
|
||||||
|
|
||||||
entry.bytePos = totalBytes;
|
entry.bytePos = totalBytes;
|
||||||
entry.duration = duration;
|
entry.duration = duration;
|
||||||
if (!isUrl()) {
|
if (!isUrl()){totalBytes += fileSource.tellg();}
|
||||||
totalBytes += fileSource.tellg();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initDone){
|
if (initDone){
|
||||||
lastTimestamp += duration;
|
lastTimestamp += duration;
|
||||||
|
@ -279,7 +259,6 @@ namespace Mist {
|
||||||
++entryCount;
|
++entryCount;
|
||||||
entries.push_back(entry);
|
entries.push_back(entry);
|
||||||
++lastFileIndex;
|
++lastFileIndex;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructor of HLS Input
|
/// Constructor of HLS Input
|
||||||
|
@ -301,26 +280,23 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
|
|
||||||
inputHLS::~inputHLS(){
|
inputHLS::~inputHLS(){
|
||||||
if (inFile) {
|
if (inFile){fclose(inFile);}
|
||||||
fclose(inFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inputHLS::setup(){
|
bool inputHLS::setup(){
|
||||||
if (config->getString("input") == "-") {
|
if (config->getString("input") == "-"){return false;}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!initPlaylist(config->getString("input"))) {
|
if (!initPlaylist(config->getString("input"))){return false;}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Util::Config::printDebugLevel >= DLVL_HIGH){
|
if (Util::Config::printDebugLevel >= DLVL_HIGH){
|
||||||
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end(); pListIt++){
|
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end();
|
||||||
|
pListIt++){
|
||||||
std::cout << pListIt->id << ": " << pListIt->uri << std::endl;
|
std::cout << pListIt->id << ": " << pListIt->uri << std::endl;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (std::deque<playListEntries>::iterator entryIt = pListIt->entries.begin(); entryIt != pListIt->entries.end(); entryIt++){
|
for (std::deque<playListEntries>::iterator entryIt = pListIt->entries.begin();
|
||||||
std::cout << " " << j++ << ": " << entryIt->filename << " bytePos: " << entryIt->bytePos << std::endl;
|
entryIt != pListIt->entries.end(); entryIt++){
|
||||||
|
std::cout << " " << j++ << ": " << entryIt->filename
|
||||||
|
<< " bytePos: " << entryIt->bytePos << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,9 +319,7 @@ namespace Mist {
|
||||||
|
|
||||||
void inputHLS::parseStreamHeader(){
|
void inputHLS::parseStreamHeader(){
|
||||||
bool hasHeader = false;
|
bool hasHeader = false;
|
||||||
if (!hasHeader) {
|
if (!hasHeader){myMeta = DTSC::Meta();}
|
||||||
myMeta = DTSC::Meta();
|
|
||||||
}
|
|
||||||
|
|
||||||
TS::Packet packet; // to analyse and extract data
|
TS::Packet packet; // to analyse and extract data
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
|
@ -355,10 +329,9 @@ namespace Mist {
|
||||||
unsigned int dataLen;
|
unsigned int dataLen;
|
||||||
bool keepReading = false;
|
bool keepReading = false;
|
||||||
|
|
||||||
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end(); pListIt++){
|
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end();
|
||||||
if (!pListIt->entries.size()) {
|
pListIt++){
|
||||||
continue;
|
if (!pListIt->entries.size()){continue;}
|
||||||
}
|
|
||||||
std::deque<playListEntries>::iterator entryIt = pListIt->entries.begin();
|
std::deque<playListEntries>::iterator entryIt = pListIt->entries.begin();
|
||||||
|
|
||||||
tsStream.clear();
|
tsStream.clear();
|
||||||
|
@ -393,7 +366,9 @@ namespace Mist {
|
||||||
pidMapping[(pListIt->id << 16) + headerPack.getTrackId()] = counter;
|
pidMapping[(pListIt->id << 16) + headerPack.getTrackId()] = counter;
|
||||||
pidMappingR[counter] = (pListIt->id << 16) + headerPack.getTrackId();
|
pidMappingR[counter] = (pListIt->id << 16) + headerPack.getTrackId();
|
||||||
packetId = counter;
|
packetId = counter;
|
||||||
HIGH_MSG("Added file %s, trackid: %d, mapped to: %d", (pListIt->uri_root + entryIt->filename).c_str(), headerPack.getTrackId(), counter);
|
HIGH_MSG("Added file %s, trackid: %d, mapped to: %d",
|
||||||
|
(pListIt->uri_root + entryIt->filename).c_str(), headerPack.getTrackId(),
|
||||||
|
counter);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +381,8 @@ namespace Mist {
|
||||||
myMeta.live = false;
|
myMeta.live = false;
|
||||||
myMeta.vod = true;
|
myMeta.vod = true;
|
||||||
|
|
||||||
if (!hasHeader && (!myMeta.tracks.count(packetId) || !myMeta.tracks[packetId].codec.size())) {
|
if (!hasHeader &&
|
||||||
|
(!myMeta.tracks.count(packetId) || !myMeta.tracks[packetId].codec.size())){
|
||||||
tsStream.initializeMetadata(myMeta, tmpTrackId, packetId);
|
tsStream.initializeMetadata(myMeta, tmpTrackId, packetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,9 +403,7 @@ namespace Mist {
|
||||||
tsStream.clear();
|
tsStream.clear();
|
||||||
|
|
||||||
INFO_MSG("end stream header tracks: %d", myMeta.tracks.size());
|
INFO_MSG("end stream header tracks: %d", myMeta.tracks.size());
|
||||||
if (hasHeader) {
|
if (hasHeader){return;}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// myMeta.live = true;
|
// myMeta.live = true;
|
||||||
// myMeta.vod = false;
|
// myMeta.vod = false;
|
||||||
|
@ -437,9 +411,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inputHLS::readHeader(){
|
bool inputHLS::readHeader(){
|
||||||
if (playlists.size() && playlists[0].playlistType == LIVE) {
|
if (playlists.size() && playlists[0].playlistType == LIVE){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istringstream urlSource;
|
std::istringstream urlSource;
|
||||||
std::ifstream fileSource;
|
std::ifstream fileSource;
|
||||||
|
@ -451,14 +423,10 @@ namespace Mist {
|
||||||
DTSC::File tmp(config->getString("input") + ".dtsh");
|
DTSC::File tmp(config->getString("input") + ".dtsh");
|
||||||
if (tmp){
|
if (tmp){
|
||||||
myMeta = tmp.getMeta();
|
myMeta = tmp.getMeta();
|
||||||
if (myMeta) {
|
if (myMeta){hasHeader = true;}
|
||||||
hasHeader = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasHeader) {
|
if (!hasHeader){myMeta = DTSC::Meta();}
|
||||||
myMeta = DTSC::Meta();
|
|
||||||
}
|
|
||||||
|
|
||||||
TS::Packet packet; // to analyse and extract data
|
TS::Packet packet; // to analyse and extract data
|
||||||
|
|
||||||
|
@ -468,11 +436,13 @@ namespace Mist {
|
||||||
char *data;
|
char *data;
|
||||||
unsigned int dataLen;
|
unsigned int dataLen;
|
||||||
|
|
||||||
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end(); pListIt++){
|
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end();
|
||||||
|
pListIt++){
|
||||||
tsStream.clear();
|
tsStream.clear();
|
||||||
uint32_t entId = 0;
|
uint32_t entId = 0;
|
||||||
|
|
||||||
for (std::deque<playListEntries>::iterator entryIt = pListIt->entries.begin(); entryIt != pListIt->entries.end(); entryIt++) {
|
for (std::deque<playListEntries>::iterator entryIt = pListIt->entries.begin();
|
||||||
|
entryIt != pListIt->entries.end(); entryIt++){
|
||||||
// WORK
|
// WORK
|
||||||
tsStream.partialClear();
|
tsStream.partialClear();
|
||||||
endOfFile = false;
|
endOfFile = false;
|
||||||
|
@ -482,9 +452,7 @@ namespace Mist {
|
||||||
urlSource.str(pListIt->source);
|
urlSource.str(pListIt->source);
|
||||||
|
|
||||||
endOfFile = !pListIt->atEnd();
|
endOfFile = !pListIt->atEnd();
|
||||||
if (!endOfFile){
|
if (!endOfFile){packet.FromPointer(pListIt->packetPtr);}
|
||||||
packet.FromPointer(pListIt->packetPtr);
|
|
||||||
}
|
|
||||||
pListIt->packetPtr += 188;
|
pListIt->packetPtr += 188;
|
||||||
}else{
|
}else{
|
||||||
in.close();
|
in.close();
|
||||||
|
@ -515,11 +483,14 @@ namespace Mist {
|
||||||
pidMapping[(pListIt->id << 16) + headerPack.getTrackId()] = counter;
|
pidMapping[(pListIt->id << 16) + headerPack.getTrackId()] = counter;
|
||||||
pidMappingR[counter] = (pListIt->id << 16) + headerPack.getTrackId();
|
pidMappingR[counter] = (pListIt->id << 16) + headerPack.getTrackId();
|
||||||
packetId = counter;
|
packetId = counter;
|
||||||
INFO_MSG("Added file %s, trackid: %d, mapped to: %d", (pListIt->uri_root + entryIt->filename).c_str(), headerPack.getTrackId(), counter);
|
INFO_MSG("Added file %s, trackid: %d, mapped to: %d",
|
||||||
|
(pListIt->uri_root + entryIt->filename).c_str(), headerPack.getTrackId(),
|
||||||
|
counter);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasHeader && (!myMeta.tracks.count(packetId) || !myMeta.tracks[packetId].codec.size())) {
|
if (!hasHeader &&
|
||||||
|
(!myMeta.tracks.count(packetId) || !myMeta.tracks[packetId].codec.size())){
|
||||||
tsStream.initializeMetadata(myMeta, tmpTrackId, packetId);
|
tsStream.initializeMetadata(myMeta, tmpTrackId, packetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,9 +499,12 @@ namespace Mist {
|
||||||
uint64_t pBPos = headerPack.getInt("bpos");
|
uint64_t pBPos = headerPack.getInt("bpos");
|
||||||
|
|
||||||
// keyframe data exists, so always add 19 bytes keyframedata.
|
// keyframe data exists, so always add 19 bytes keyframedata.
|
||||||
long long packOffset = headerPack.hasMember("offset") ? headerPack.getInt("offset") : 0;
|
long long packOffset =
|
||||||
long long packSendSize = 24 + (packOffset ? 17 : 0) + (entId >= 0 ? 15 : 0) + 19 + dataLen + 11;
|
headerPack.hasMember("offset") ? headerPack.getInt("offset") : 0;
|
||||||
myMeta.update(headerPack.getTime(), packOffset, packetId, dataLen, entId, headerPack.hasMember("keyframe"), packSendSize);
|
long long packSendSize =
|
||||||
|
24 + (packOffset ? 17 : 0) + (entId >= 0 ? 15 : 0) + 19 + dataLen + 11;
|
||||||
|
myMeta.update(headerPack.getTime(), packOffset, packetId, dataLen, entId,
|
||||||
|
headerPack.hasMember("keyframe"), packSendSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,11 +531,14 @@ namespace Mist {
|
||||||
pidMapping[(pListIt->id << 16) + headerPack.getTrackId()] = counter;
|
pidMapping[(pListIt->id << 16) + headerPack.getTrackId()] = counter;
|
||||||
pidMappingR[counter] = (pListIt->id << 16) + headerPack.getTrackId();
|
pidMappingR[counter] = (pListIt->id << 16) + headerPack.getTrackId();
|
||||||
packetId = counter;
|
packetId = counter;
|
||||||
INFO_MSG("Added file %s, trackid: %d, mapped to: %d", (pListIt->uri_root + entryIt->filename).c_str(), headerPack.getTrackId(), counter);
|
INFO_MSG("Added file %s, trackid: %d, mapped to: %d",
|
||||||
|
(pListIt->uri_root + entryIt->filename).c_str(), headerPack.getTrackId(),
|
||||||
|
counter);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasHeader && (!myMeta.tracks.count(packetId) || !myMeta.tracks[packetId].codec.size())) {
|
if (!hasHeader &&
|
||||||
|
(!myMeta.tracks.count(packetId) || !myMeta.tracks[packetId].codec.size())){
|
||||||
tsStream.initializeMetadata(myMeta, tmpTrackId, packetId);
|
tsStream.initializeMetadata(myMeta, tmpTrackId, packetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,26 +548,21 @@ namespace Mist {
|
||||||
|
|
||||||
// keyframe data exists, so always add 19 bytes keyframedata.
|
// keyframe data exists, so always add 19 bytes keyframedata.
|
||||||
long long packOffset = headerPack.hasMember("offset") ? headerPack.getInt("offset") : 0;
|
long long packOffset = headerPack.hasMember("offset") ? headerPack.getInt("offset") : 0;
|
||||||
long long packSendSize = 24 + (packOffset ? 17 : 0) + (entId >= 0 ? 15 : 0) + 19 + dataLen + 11;
|
long long packSendSize =
|
||||||
myMeta.update(headerPack.getTime(), packOffset, packetId, dataLen, entId, headerPack.hasMember("keyframe"), packSendSize);
|
24 + (packOffset ? 17 : 0) + (entId >= 0 ? 15 : 0) + 19 + dataLen + 11;
|
||||||
|
myMeta.update(headerPack.getTime(), packOffset, packetId, dataLen, entId,
|
||||||
|
headerPack.hasMember("keyframe"), packSendSize);
|
||||||
}
|
}
|
||||||
tsStream.getEarliestPacket(headerPack);
|
tsStream.getEarliestPacket(headerPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pListIt->isUrl()) {
|
if (!pListIt->isUrl()){in.close();}
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasHeader) {
|
if (hasHeader){break;}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasHeader || (playlists.size() && playlists[0].isUrl())) {
|
if (hasHeader || (playlists.size() && playlists[0].isUrl())){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
INFO_MSG("write header file...");
|
INFO_MSG("write header file...");
|
||||||
std::ofstream oFile((config->getString("input") + ".dtsh").c_str());
|
std::ofstream oFile((config->getString("input") + ".dtsh").c_str());
|
||||||
|
@ -603,18 +575,16 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inputHLS::needsLock(){
|
bool inputHLS::needsLock(){
|
||||||
if (playlists.size() && playlists[0].isUrl()) {
|
if (playlists.size() && playlists[0].isUrl()){return false;}
|
||||||
return false;
|
return (playlists.size() <= currentPlaylist) ||
|
||||||
}
|
!(playlists[currentPlaylist].playlistType == LIVE);
|
||||||
return (playlists.size() <= currentPlaylist) || !(playlists[currentPlaylist].playlistType == LIVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inputHLS::openStreamSource() {
|
bool inputHLS::openStreamSource(){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int inputHLS::getFirstPlaylistToReload(){
|
int inputHLS::getFirstPlaylistToReload(){
|
||||||
//at this point, we need to check which playlist we need to reload, and keep reading from that playlist until EndOfPlaylist
|
// at this point, we need to check which playlist we need to reload, and keep reading from that
|
||||||
|
// playlist until EndOfPlaylist
|
||||||
std::vector<int>::iterator result = std::min_element(reloadNext.begin(), reloadNext.end());
|
std::vector<int>::iterator result = std::min_element(reloadNext.begin(), reloadNext.end());
|
||||||
return std::distance(reloadNext.begin(), result);
|
return std::distance(reloadNext.begin(), result);
|
||||||
}
|
}
|
||||||
|
@ -643,19 +613,14 @@ namespace Mist {
|
||||||
endOfFile = in.eof();
|
endOfFile = in.eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// eof flag is set after unsuccesful read, so check again
|
// eof flag is set after unsuccesful read, so check again
|
||||||
if (endOfFile) {
|
if (endOfFile){tsStream.finish();}
|
||||||
tsStream.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playlists[currentPlaylist].playlistType == LIVE){
|
if (playlists[currentPlaylist].playlistType == LIVE){
|
||||||
hasPacket = tsStream.hasPacketOnEachTrack() || (endOfFile && tsStream.hasPacket());
|
hasPacket = tsStream.hasPacketOnEachTrack() || (endOfFile && tsStream.hasPacket());
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
if (!selectedTracks.size()) {
|
if (!selectedTracks.size()){return;}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tid = *selectedTracks.begin();
|
tid = *selectedTracks.begin();
|
||||||
hasPacket = tsStream.hasPacket(getMappedTrackId(tid));
|
hasPacket = tsStream.hasPacket(getMappedTrackId(tid));
|
||||||
|
@ -669,9 +634,7 @@ namespace Mist {
|
||||||
HIGH_MSG("need to reload playlist %d, time: %d", a, reloadNext[a] - Util::bootSecs());
|
HIGH_MSG("need to reload playlist %d, time: %d", a, reloadNext[a] - Util::bootSecs());
|
||||||
|
|
||||||
int f = firstSegment();
|
int f = firstSegment();
|
||||||
if (f >= 0) {
|
if (f >= 0){segmentTime = playlists[f].entries.front().timestamp - Util::bootSecs();}
|
||||||
segmentTime = playlists[f].entries.front().timestamp - Util::bootSecs();
|
|
||||||
}
|
|
||||||
|
|
||||||
int playlistTime = reloadNext.at(currentPlaylist) - Util::bootSecs() - 1;
|
int playlistTime = reloadNext.at(currentPlaylist) - Util::bootSecs() - 1;
|
||||||
|
|
||||||
|
@ -694,23 +657,25 @@ namespace Mist {
|
||||||
|
|
||||||
if (!readNextFile()){
|
if (!readNextFile()){
|
||||||
|
|
||||||
if (playlists[currentPlaylist].playlistType != LIVE) {
|
if (playlists[currentPlaylist].playlistType != LIVE){return;}
|
||||||
return;
|
// need to reload all available playlists. update the map with the amount of ms to wait
|
||||||
}
|
// before the next check.
|
||||||
//need to reload all available playlists. update the map with the amount of ms to wait before the next check.
|
|
||||||
|
|
||||||
// set specific elements with the correct bootsecs()
|
// set specific elements with the correct bootsecs()
|
||||||
reloadNext.at(currentPlaylist) = b + playlists[currentPlaylist].waitTime;
|
reloadNext.at(currentPlaylist) = b + playlists[currentPlaylist].waitTime;
|
||||||
|
|
||||||
int timeToWait = reloadNext.at(currentPlaylist) - Util::bootSecs();
|
int timeToWait = reloadNext.at(currentPlaylist) - Util::bootSecs();
|
||||||
|
|
||||||
//at this point, we need to check which playlist we need to reload, and keep reading from that playlist until EndOfPlaylist
|
// at this point, we need to check which playlist we need to reload, and keep reading from
|
||||||
std::vector<int>::iterator result = std::min_element(reloadNext.begin(), reloadNext.end());
|
// that playlist until EndOfPlaylist
|
||||||
|
std::vector<int>::iterator result =
|
||||||
|
std::min_element(reloadNext.begin(), reloadNext.end());
|
||||||
int playlistToReload = std::distance(reloadNext.begin(), result);
|
int playlistToReload = std::distance(reloadNext.begin(), result);
|
||||||
currentPlaylist = playlistToReload;
|
currentPlaylist = playlistToReload;
|
||||||
|
|
||||||
// dont wait the first time.
|
// dont wait the first time.
|
||||||
if (timeToWait > 0 && playlists[currentPlaylist].initDone && playlists[currentPlaylist].noChangeCount > 0) {
|
if (timeToWait > 0 && playlists[currentPlaylist].initDone &&
|
||||||
|
playlists[currentPlaylist].noChangeCount > 0){
|
||||||
if (timeToWait > playlists[currentPlaylist].waitTime){
|
if (timeToWait > playlists[currentPlaylist].waitTime){
|
||||||
WARN_MSG("something is not right...");
|
WARN_MSG("something is not right...");
|
||||||
return;
|
return;
|
||||||
|
@ -726,7 +691,6 @@ namespace Mist {
|
||||||
thisPacket.null();
|
thisPacket.null();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playlists[currentPlaylist].isUrl()){
|
if (playlists[currentPlaylist].isUrl()){
|
||||||
|
@ -767,14 +731,15 @@ namespace Mist {
|
||||||
Bit::htobl(thisPacket.getData() + 8, tid);
|
Bit::htobl(thisPacket.getData() + 8, tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void inputHLS::readPMT(){
|
void inputHLS::readPMT(){
|
||||||
if (playlists[currentPlaylist].isUrl()){
|
if (playlists[currentPlaylist].isUrl()){
|
||||||
size_t bpos;
|
size_t bpos;
|
||||||
TS::Packet tsBuffer;
|
TS::Packet tsBuffer;
|
||||||
const char *tmpPtr = playlists[currentPlaylist].source.data();
|
const char *tmpPtr = playlists[currentPlaylist].source.data();
|
||||||
|
|
||||||
while (!tsStream.hasPacketOnEachTrack() && (tmpPtr - playlists[currentPlaylist].source.c_str() + 188 <= playlists[currentPlaylist].source.size())) {
|
while (!tsStream.hasPacketOnEachTrack() &&
|
||||||
|
(tmpPtr - playlists[currentPlaylist].source.c_str() + 188 <=
|
||||||
|
playlists[currentPlaylist].source.size())){
|
||||||
tsBuffer.FromPointer(tmpPtr);
|
tsBuffer.FromPointer(tmpPtr);
|
||||||
tsStream.parse(tsBuffer, 0);
|
tsStream.parse(tsBuffer, 0);
|
||||||
tmpPtr += 188;
|
tmpPtr += 188;
|
||||||
|
@ -804,12 +769,12 @@ namespace Mist {
|
||||||
int trackId = 0;
|
int trackId = 0;
|
||||||
|
|
||||||
unsigned long plistEntry = 0xFFFFFFFFull;
|
unsigned long plistEntry = 0xFFFFFFFFull;
|
||||||
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++) {
|
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end();
|
||||||
|
it++){
|
||||||
unsigned long thisBPos = 0;
|
unsigned long thisBPos = 0;
|
||||||
for (std::deque<DTSC::Key>::iterator keyIt = myMeta.tracks[*it].keys.begin(); keyIt != myMeta.tracks[*it].keys.end(); keyIt++) {
|
for (std::deque<DTSC::Key>::iterator keyIt = myMeta.tracks[*it].keys.begin();
|
||||||
if (keyIt->getTime() > seekTime) {
|
keyIt != myMeta.tracks[*it].keys.end(); keyIt++){
|
||||||
break;
|
if (keyIt->getTime() > seekTime){break;}
|
||||||
}
|
|
||||||
thisBPos = keyIt->getBpos();
|
thisBPos = keyIt->getBpos();
|
||||||
}
|
}
|
||||||
if (thisBPos < plistEntry){
|
if (thisBPos < plistEntry){
|
||||||
|
@ -818,7 +783,6 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (plistEntry < 1){
|
if (plistEntry < 1){
|
||||||
WARN_MSG("attempted to seek outside the file");
|
WARN_MSG("attempted to seek outside the file");
|
||||||
return;
|
return;
|
||||||
|
@ -838,14 +802,10 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
|
|
||||||
int inputHLS::getEntryId(int playlistId, uint64_t bytePos){
|
int inputHLS::getEntryId(int playlistId, uint64_t bytePos){
|
||||||
if (bytePos == 0) {
|
if (bytePos == 0){return 0;}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < playlists[playlistId].entries.size(); i++){
|
for (int i = 0; i < playlists[playlistId].entries.size(); i++){
|
||||||
if (playlists[playlistId].entries.at(i).bytePos > bytePos) {
|
if (playlists[playlistId].entries.at(i).bytePos > bytePos){return i - 1;}
|
||||||
return i - 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return playlists[playlistId].entries.size() - 1;
|
return playlists[playlistId].entries.size() - 1;
|
||||||
|
@ -855,13 +815,9 @@ namespace Mist {
|
||||||
return pidMapping[(playlistId << 16) + id];
|
return pidMapping[(playlistId << 16) + id];
|
||||||
}
|
}
|
||||||
|
|
||||||
int inputHLS::getMappedTrackId(int id) {
|
int inputHLS::getMappedTrackId(int id){return (pidMappingR[id] & 0xFFFF);}
|
||||||
return (pidMappingR[id] & 0xFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
int inputHLS::getMappedTrackPlaylist(int id) {
|
int inputHLS::getMappedTrackPlaylist(int id){return (pidMappingR[id] >> 16);}
|
||||||
return (pidMappingR[id] >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Very first function to be called on a regular playlist or variant playlist.
|
/// Very first function to be called on a regular playlist or variant playlist.
|
||||||
bool inputHLS::initPlaylist(const std::string &uri){
|
bool inputHLS::initPlaylist(const std::string &uri){
|
||||||
|
@ -919,9 +875,7 @@ namespace Mist {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isUrl){
|
if (!isUrl){fileSource.close();}
|
||||||
fileSource.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -933,9 +887,7 @@ namespace Mist {
|
||||||
// set size of reloadNext to playlist count with default value 0
|
// set size of reloadNext to playlist count with default value 0
|
||||||
playlists.push_back(p);
|
playlists.push_back(p);
|
||||||
|
|
||||||
if (reloadNext.size() < playlists.size()) {
|
if (reloadNext.size() < playlists.size()){reloadNext.resize(playlists.size());}
|
||||||
reloadNext.resize(playlists.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadNext.at(p.id) = Util::bootSecs() + p.waitTime;
|
reloadNext.at(p.id) = Util::bootSecs() + p.waitTime;
|
||||||
return true;
|
return true;
|
||||||
|
@ -979,12 +931,14 @@ namespace Mist {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///return the playlist id from which we need to read the first upcoming segment by timestamp. this will keep the playlists in sync while reading segments.
|
/// return the playlist id from which we need to read the first upcoming segment by timestamp.
|
||||||
|
/// this will keep the playlists in sync while reading segments.
|
||||||
int inputHLS::firstSegment(){
|
int inputHLS::firstSegment(){
|
||||||
uint64_t firstTimeStamp = 0;
|
uint64_t firstTimeStamp = 0;
|
||||||
int tmpId = -1;
|
int tmpId = -1;
|
||||||
|
|
||||||
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end(); pListIt++){
|
for (std::vector<Playlist>::iterator pListIt = playlists.begin(); pListIt != playlists.end();
|
||||||
|
pListIt++){
|
||||||
if (pListIt->entries.size()){
|
if (pListIt->entries.size()){
|
||||||
if (pListIt->entries.front().timestamp < firstTimeStamp || tmpId < 0){
|
if (pListIt->entries.front().timestamp < firstTimeStamp || tmpId < 0){
|
||||||
firstTimeStamp = pListIt->entries.front().timestamp;
|
firstTimeStamp = pListIt->entries.front().timestamp;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include <fstream>
|
||||||
#include <mist/dtsc.h>
|
#include <mist/dtsc.h>
|
||||||
#include <mist/nal.h>
|
#include <mist/nal.h>
|
||||||
#include <mist/ts_packet.h>
|
#include <mist/ts_packet.h>
|
||||||
#include <mist/ts_stream.h>
|
#include <mist/ts_stream.h>
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
//#include <stdint.h>
|
//#include <stdint.h>
|
||||||
|
|
||||||
|
@ -16,9 +16,7 @@ namespace Mist {
|
||||||
|
|
||||||
enum PlaylistType{VOD, LIVE, EVENT};
|
enum PlaylistType{VOD, LIVE, EVENT};
|
||||||
|
|
||||||
|
struct playListEntries{
|
||||||
struct playListEntries
|
|
||||||
{
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
uint64_t bytePos;
|
uint64_t bytePos;
|
||||||
float duration;
|
float duration;
|
||||||
|
@ -49,7 +47,6 @@ namespace Mist {
|
||||||
uint64_t media_sequence;
|
uint64_t media_sequence;
|
||||||
int lastFileIndex;
|
int lastFileIndex;
|
||||||
|
|
||||||
|
|
||||||
int waitTime;
|
int waitTime;
|
||||||
PlaylistType playlistType;
|
PlaylistType playlistType;
|
||||||
std::deque<playListEntries> entries;
|
std::deque<playListEntries> entries;
|
||||||
|
@ -58,9 +55,7 @@ namespace Mist {
|
||||||
unsigned int startTime;
|
unsigned int startTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct entryBuffer{
|
||||||
struct entryBuffer
|
|
||||||
{
|
|
||||||
int timestamp;
|
int timestamp;
|
||||||
playListEntries entry;
|
playListEntries entry;
|
||||||
int playlistIndex;
|
int playlistIndex;
|
||||||
|
@ -72,6 +67,7 @@ namespace Mist {
|
||||||
~inputHLS();
|
~inputHLS();
|
||||||
bool needsLock();
|
bool needsLock();
|
||||||
bool openStreamSource();
|
bool openStreamSource();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Private Functions
|
// Private Functions
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue