From d6fb4baff49d5b3685ee92d0fa8c45aa3b01e529 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 12 Feb 2015 14:17:33 +0100 Subject: [PATCH] Generalized TS PMT generation, fixed various minor problems with MP4 and HTTP. --- lib/http_parser.cpp | 2 +- lib/http_parser.h | 2 +- lib/mp4_generic.cpp | 7 ++++++- lib/ts_packet.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++-- lib/ts_packet.h | 4 +++- 5 files changed, 55 insertions(+), 6 deletions(-) diff --git a/lib/http_parser.cpp b/lib/http_parser.cpp index c47da332..c1261650 100644 --- a/lib/http_parser.cpp +++ b/lib/http_parser.cpp @@ -540,7 +540,7 @@ void HTTP::Parser::parseVars(std::string data) { /// Sends a string in chunked format if protocol is HTTP/1.1, sends as-is otherwise. /// \param bodypart The data to send. /// \param conn The connection to use for sending. -void HTTP::Parser::Chunkify(std::string & bodypart, Socket::Connection & conn) { +void HTTP::Parser::Chunkify(const std::string & bodypart, Socket::Connection & conn) { Chunkify(bodypart.c_str(), bodypart.size(), conn); } diff --git a/lib/http_parser.h b/lib/http_parser.h index 228baba6..b6a75daa 100644 --- a/lib/http_parser.h +++ b/lib/http_parser.h @@ -31,7 +31,7 @@ namespace HTTP { void SendResponse(std::string code, std::string message, Socket::Connection & conn); void StartResponse(std::string code, std::string message, Parser & request, Socket::Connection & conn); void StartResponse(Parser & request, Socket::Connection & conn); - void Chunkify(std::string & bodypart, Socket::Connection & conn); + void Chunkify(const std::string & bodypart, Socket::Connection & conn); void Chunkify(const char * data, unsigned int size, Socket::Connection & conn); void Proxy(Socket::Connection & from, Socket::Connection & to); void Clean(); diff --git a/lib/mp4_generic.cpp b/lib/mp4_generic.cpp index 12f4af35..cc79951d 100644 --- a/lib/mp4_generic.cpp +++ b/lib/mp4_generic.cpp @@ -2318,7 +2318,12 @@ namespace MP4 { if (no >= getSampleCount()) { return 0; } - return getInt32(12 + no * 4); + long unsigned int retVal = getInt32(12 + no * 4); + if (retVal == 0){ + return getSampleSize(); + }else{ + return retVal; + } } std::string STSZ::toPrettyString(uint32_t indent) { diff --git a/lib/ts_packet.cpp b/lib/ts_packet.cpp index a7c072ed..c5a86777 100644 --- a/lib/ts_packet.cpp +++ b/lib/ts_packet.cpp @@ -51,7 +51,7 @@ namespace TS { ///\param Data The char array that contains the data to be read into the packet ///\return true if successful (which always happens, or else a segmentation fault should occur) bool Packet::FromPointer(const char * Data) { - strBuf = std::string(Data, 188); + strBuf.assign(Data, 188); return true; } @@ -577,7 +577,7 @@ namespace TS { ///Gets the string buffer, containing the raw packet data as a string ///\return The raw TS data as a string - std::string Packet::getStrBuf() { + const std::string& Packet::getStrBuf() { return strBuf; } @@ -961,6 +961,48 @@ namespace TS { output << std::string(indent + 2, ' ') << "CRC32: " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << getCRC() << std::dec << std::endl; return output.str(); } + + const std::string& createPMT(std::set& selectedTracks, DTSC::Meta& myMeta){ + static ProgramMappingTable PMT; + PMT.PID(4096); + PMT.setTableId(2); + //section length met 2 tracks: 0xB017 + PMT.setSectionLength(0xB00D + (selectedTracks.size() * 5)); + PMT.setProgramNumber(1); + PMT.setVersionNumber(0); + PMT.setCurrentNextIndicator(0); + PMT.setSectionNumber(0); + PMT.setLastSectionNumber(0); + int vidTrack = -1; + for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ + if (myMeta.tracks[*it].type == "video"){ + vidTrack = *it; + break; + } + } + if (vidTrack == -1){ + vidTrack = *(selectedTracks.begin()); + } + PMT.setPCRPID(0x100 + vidTrack - 1); + PMT.setProgramInfoLength(0); + short id = 0; + //for all selected tracks + for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ + if (myMeta.tracks[*it].codec == "H264"){ + PMT.setStreamType(0x1B,id); + }else if (myMeta.tracks[*it].codec == "AAC"){ + PMT.setStreamType(0x0F,id); + }else if (myMeta.tracks[*it].codec == "MP3"){ + PMT.setStreamType(0x03,id); + } + PMT.setElementaryPID(0x100 + (*it) - 1, id); + PMT.setESInfoLength(0,id); + id++; + } + PMT.calcCRC(); + return PMT.getStrBuf(); + } + } diff --git a/lib/ts_packet.h b/lib/ts_packet.h index cbdccc2c..2c9e6356 100644 --- a/lib/ts_packet.h +++ b/lib/ts_packet.h @@ -70,7 +70,7 @@ namespace TS { unsigned int getTransportScramblingControl(); std::string toPrettyString(size_t indent = 0); - std::string getStrBuf(); + const std::string& getStrBuf(); const char * getBuffer(); const char * getPayload(); int getPayloadLength(); @@ -236,5 +236,7 @@ namespace TS { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + const std::string& createPMT(std::set& selectedTracks, DTSC::Meta& myMeta); + } //TS namespace