New Meta commit

This commit is contained in:
Phencys 2021-04-21 18:10:03 +02:00 committed by Thulinma
parent fccf66fba2
commit 2b99f2f5ea
183 changed files with 13333 additions and 14421 deletions

View file

@ -30,7 +30,38 @@
std::set<unsigned int> pmt_pids;
std::map<unsigned int, std::string> stream_pids;
/// A standard Program Association Table, as generated by FFMPEG.
/// Seems to be independent of the stream.
// 0x47 = sync byte
// 0x4000 = transport error(1) = 0, payload unit start(1) = 1, priority(1) = 0, PID(13) = 0
// 0x10 = transportscrambling(2) = 0, adaptation(2) = 1, continuity(4) = 0
// 0x00 = pointer = 0
// 0x00 = table ID = 0 = PAT
// 0xB00D = section syntax(1) = 1, 0(1)=0, reserved(2) = 3, section_len(12) = 13
// 0x0001 = transport stream id = 1
// 0xC1 = reserved(2) = 3, version(5)=0, curr_next_indi(1) = 1
// 0x00 = section_number = 0
// 0x00 = last_section_no = 0
// 0x0001 = ProgNo = 1
// 0xF000 = reserved(3) = 7, network pid = 4096
// 0x2AB104B2 = CRC32
namespace TS{
char PAT[188] ={
0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xB0, 0x0D, 0x00, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x01,
0xF0, 0x00, 0x2A, 0xB1, 0x04, 0xB2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
/// This constructor creates an empty Packet, ready for use for either reading or writing.
/// All this constructor does is call Packet::clear().
Packet::Packet(){
@ -524,6 +555,35 @@ namespace TS{
}
return tmpStr;
}
/// Generates a PES Lead-in for a meta frame.
/// Prepends the lead-in to variable toSend, assumes toSend's length is all other data.
/// \param len The length of this frame.
/// \param PTS The timestamp of the frame.
std::string &Packet::getPESMetaLeadIn(unsigned int len, unsigned long long PTS, uint64_t bps){
if (bps >= 50){
len += 3;
}else{
bps = 0;
}
static std::string tmpStr;
tmpStr.clear();
tmpStr.reserve(20);
len += 8;
tmpStr.append("\000\000\001\374", 4);
tmpStr += (char)((len & 0xFF00) >> 8); // PES PacketLength
tmpStr += (char)(len & 0x00FF); // PES PacketLength (Cont)
tmpStr += (char)0x84; // isAligned
tmpStr += (char)(0x80 | (bps ? 0x10 : 0)); // PTS/DTS + Flags
tmpStr += (char)(5 + (bps ? 3 : 0)); // PESHeaderDataLength
encodePESTimestamp(tmpStr, 0x20, PTS);
if (bps){
char rate_buf[3];
Bit::htob24(rate_buf, (bps / 50) | 0x800001);
tmpStr.append(rate_buf, 3);
}
return tmpStr;
}
// END PES FUNCTIONS
/// Fills the free bytes of the Packet.
@ -1108,18 +1168,20 @@ namespace TS{
///\param selectedTracks tracks to include in PMT creation
///\param myMeta
///\returns character pointer to a static 188B TS packet
const char *createPMT(std::set<unsigned long> &selectedTracks, DTSC::Meta &myMeta, int contCounter){
const char *createPMT(std::set<unsigned long> &selectedTracks, const DTSC::Meta &M, int contCounter){
static ProgramMappingTable PMT;
PMT.setPID(4096);
PMT.setTableId(2);
// section length met 2 tracks: 0xB017
int sectionLen = 0;
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
std::string codec = M.getCodec(*it);
sectionLen += 5;
if (myMeta.tracks[*it].codec == "ID3"){sectionLen += myMeta.tracks[*it].init.size();}
if (myMeta.tracks[*it].codec == "AAC"){
if (codec == "ID3" || codec == "RAW"){sectionLen += M.getInit(*it).size();}
if (codec == "AAC"){
sectionLen += 4; // aac descriptor
if (myMeta.tracks[*it].lang.size() == 3 && myMeta.tracks[*it].lang != "und"){
std::string lang = M.getLang(*it);
if (lang.size() == 3 && lang != "und"){
sectionLen += 6; // language descriptor
}
}
@ -1133,42 +1195,51 @@ namespace TS{
PMT.setContinuityCounter(contCounter);
int vidTrack = -1;
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
if (myMeta.tracks[*it].type == "video"){
if (M.getType(*it) == "video"){
vidTrack = *it;
break;
}
}
if (vidTrack == -1){vidTrack = *(selectedTracks.begin());}
PMT.setPCRPID(255 + vidTrack);
size_t pcrPid = M.getID(vidTrack);
if (pcrPid < 255){pcrPid += 255;}
PMT.setPCRPID(pcrPid);
PMT.setProgramInfoLength(0);
short id = 0;
ProgramMappingEntry entry = PMT.getEntry(0);
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
entry.setElementaryPid(255 + *it);
std::string codec = M.getCodec(*it);
size_t pkgId = M.getID(*it);
if (pkgId < 255){pkgId += 255;}
entry.setElementaryPid(pkgId);
entry.setESInfo("");
if (myMeta.tracks[*it].codec == "H264"){
if (codec == "H264"){
entry.setStreamType(0x1B);
}else if (myMeta.tracks[*it].codec == "HEVC"){
}else if (codec == "HEVC"){
entry.setStreamType(0x24);
}else if (myMeta.tracks[*it].codec == "MPEG2"){
}else if (codec == "MPEG2"){
entry.setStreamType(0x02);
}else if (myMeta.tracks[*it].codec == "AAC"){
}else if (codec == "AAC"){
entry.setStreamType(0x0F);
std::string aac_info("\174\002\121\000", 4); // AAC descriptor: AAC Level 2. Hardcoded, because... what are AAC levels, anyway?
std::string aac_info("\174\002\121\000",
4); // AAC descriptor: AAC Level 2. Hardcoded, because... what are AAC levels, anyway?
// language code ddescriptor
if (myMeta.tracks[*it].lang.size() == 3 && myMeta.tracks[*it].lang != "und"){
std::string lang = M.getLang(*it);
if (lang.size() == 3 && lang != "und"){
aac_info.append("\012\004", 2);
aac_info.append(myMeta.tracks[*it].lang);
aac_info.append(lang);
aac_info.append("\000", 1);
}
entry.setESInfo(aac_info);
}else if (myMeta.tracks[*it].codec == "MP3" || myMeta.tracks[*it].codec == "MP2"){
}else if (codec == "MP3" || codec == "MP2"){
entry.setStreamType(0x03);
}else if (myMeta.tracks[*it].codec == "AC3"){
}else if (codec == "AC3"){
entry.setStreamType(0x81);
}else if (myMeta.tracks[*it].codec == "ID3"){
}else if (codec == "ID3"){
entry.setStreamType(0x15);
entry.setESInfo(myMeta.tracks[*it].init);
entry.setESInfo(M.getInit(*it));
}else if (codec == "RAW"){
entry.setStreamType(0x06);
entry.setESInfo(M.getInit(*it));
}
entry.advance();
}
@ -1365,7 +1436,9 @@ namespace TS{
getOffset() + getSectionLength();
unsigned int newVal; // this will hold the CRC32 value;
unsigned int pidLoc = 4 + (getAdaptationField() > 1 ? getAdaptationFieldLen() + 1 : 0) + getOffset() + 1;
newVal = checksum::crc32(-1, strBuf + pidLoc, loc - pidLoc); // calculating checksum over all the fields from table ID to the last stream element
newVal = checksum::crc32(-1, strBuf + pidLoc,
loc - pidLoc); // calculating checksum over all the fields from table
// ID to the last stream element
updPos(188);
strBuf[loc + 3] = (newVal >> 24) & 0xFF;
strBuf[loc + 2] = (newVal >> 16) & 0xFF;