TS MPEG2/MP2 support
This commit is contained in:
parent
9c2bd38611
commit
2a721f5e7f
7 changed files with 200 additions and 97 deletions
|
@ -527,9 +527,13 @@ namespace TS {
|
||||||
/// \param len The length of this frame.
|
/// \param len The length of this frame.
|
||||||
/// \param PTS The timestamp of the frame.
|
/// \param PTS The timestamp of the frame.
|
||||||
std::string & Packet::getPESVideoLeadIn(unsigned int len, unsigned long long PTS, unsigned long long offset, bool isAligned, uint64_t bps) {
|
std::string & Packet::getPESVideoLeadIn(unsigned int len, unsigned long long PTS, unsigned long long offset, bool isAligned, uint64_t bps) {
|
||||||
len += (offset ? 13 : 8);
|
if (len){
|
||||||
|
len += (offset ? 13 : 8);
|
||||||
|
}
|
||||||
if (bps >= 50){
|
if (bps >= 50){
|
||||||
len += 3;
|
if (len){
|
||||||
|
len += 3;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
bps = 0;
|
bps = 0;
|
||||||
}
|
}
|
||||||
|
@ -826,7 +830,7 @@ namespace TS {
|
||||||
case 0x15: return "meta PES";
|
case 0x15: return "meta PES";
|
||||||
case 0x16: return "meta section";
|
case 0x16: return "meta section";
|
||||||
case 0x1B: return "H264";
|
case 0x1B: return "H264";
|
||||||
case 0x24: return "H265";
|
case 0x24: return "HEVC";
|
||||||
case 0x81: return "AC3";
|
case 0x81: return "AC3";
|
||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -1219,6 +1223,8 @@ namespace TS {
|
||||||
entry.setStreamType(0x1B);
|
entry.setStreamType(0x1B);
|
||||||
}else if (myMeta.tracks[*it].codec == "HEVC"){
|
}else if (myMeta.tracks[*it].codec == "HEVC"){
|
||||||
entry.setStreamType(0x24);
|
entry.setStreamType(0x24);
|
||||||
|
}else if (myMeta.tracks[*it].codec == "MPEG2"){
|
||||||
|
entry.setStreamType(0x02);
|
||||||
}else if (myMeta.tracks[*it].codec == "AAC"){
|
}else if (myMeta.tracks[*it].codec == "AAC"){
|
||||||
entry.setStreamType(0x0F);
|
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?
|
||||||
|
@ -1229,7 +1235,7 @@ namespace TS {
|
||||||
aac_info.append("\000", 1);
|
aac_info.append("\000", 1);
|
||||||
}
|
}
|
||||||
entry.setESInfo(aac_info);
|
entry.setESInfo(aac_info);
|
||||||
}else if (myMeta.tracks[*it].codec == "MP3"){
|
}else if (myMeta.tracks[*it].codec == "MP3" || myMeta.tracks[*it].codec == "MP2"){
|
||||||
entry.setStreamType(0x03);
|
entry.setStreamType(0x03);
|
||||||
}else if (myMeta.tracks[*it].codec == "AC3"){
|
}else if (myMeta.tracks[*it].codec == "AC3"){
|
||||||
entry.setStreamType(0x81);
|
entry.setStreamType(0x81);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "nal.h"
|
#include "nal.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "mpeg.h"
|
||||||
|
|
||||||
|
|
||||||
namespace TS{
|
namespace TS{
|
||||||
|
|
||||||
|
@ -187,6 +189,8 @@ namespace TS{
|
||||||
case H265:
|
case H265:
|
||||||
case AC3:
|
case AC3:
|
||||||
case ID3:
|
case ID3:
|
||||||
|
case MP2:
|
||||||
|
case MPEG2:
|
||||||
pidToCodec[pid] = sType;
|
pidToCodec[pid] = sType;
|
||||||
if (sType == ID3){
|
if (sType == ID3){
|
||||||
metaInit[pid] = std::string(entry.getESInfo(), entry.getESInfoLength());
|
metaInit[pid] = std::string(entry.getESInfo(), entry.getESInfoLength());
|
||||||
|
@ -517,10 +521,13 @@ namespace TS{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (thisCodec == ID3 || thisCodec == AC3){
|
if (thisCodec == ID3 || thisCodec == AC3 || thisCodec == MP2){
|
||||||
out.push_back(DTSC::Packet());
|
out.push_back(DTSC::Packet());
|
||||||
out.back().genericFill(timeStamp, timeOffset, tid, pesPayload, realPayloadSize,
|
out.back().genericFill(timeStamp, timeOffset, tid, pesPayload, realPayloadSize,
|
||||||
bPos, 0);
|
bPos, 0);
|
||||||
|
if (thisCodec == MP2 && !mp2Hdr.count(tid)){
|
||||||
|
mp2Hdr[tid] = std::string(pesPayload, realPayloadSize);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,6 +633,37 @@ namespace TS{
|
||||||
nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
|
nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (thisCodec == MPEG2){
|
||||||
|
const char *origBegin = pesPayload;
|
||||||
|
size_t origSize = realPayloadSize;
|
||||||
|
const char *nextPtr;
|
||||||
|
const char *pesEnd = pesPayload+realPayloadSize;
|
||||||
|
uint32_t nalSize = 0;
|
||||||
|
|
||||||
|
bool isKeyFrame = false;
|
||||||
|
|
||||||
|
nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
|
||||||
|
if (!nextPtr){
|
||||||
|
WARN_MSG("No start code found in entire PES packet!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (nextPtr < pesEnd){
|
||||||
|
if (!nextPtr){nextPtr = pesEnd;}
|
||||||
|
//Calculate size of NAL unit, removing null bytes from the end
|
||||||
|
nalSize = nalu::nalEndPosition(pesPayload, nextPtr - pesPayload) - pesPayload;
|
||||||
|
|
||||||
|
// Check if this is a keyframe
|
||||||
|
parseNal(tid, pesPayload, nextPtr, isKeyFrame);
|
||||||
|
|
||||||
|
if (((nextPtr - pesPayload) + 3) >= realPayloadSize){break;}//end of the loop
|
||||||
|
realPayloadSize -= ((nextPtr - pesPayload) + 3); // decrease the total size
|
||||||
|
pesPayload = nextPtr + 3;
|
||||||
|
nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
|
||||||
|
}
|
||||||
|
out.push_back(DTSC::Packet());
|
||||||
|
out.back().genericFill(timeStamp, timeOffset, tid, origBegin, origSize, bPos, isKeyFrame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::getPacket(unsigned long tid, DTSC::Packet &pack){
|
void Stream::getPacket(unsigned long tid, DTSC::Packet &pack){
|
||||||
|
@ -660,11 +698,27 @@ namespace TS{
|
||||||
bool firstSlice = true;
|
bool firstSlice = true;
|
||||||
char typeNal;
|
char typeNal;
|
||||||
|
|
||||||
isKeyFrame = false;
|
|
||||||
if (pidToCodec[tid] == MPEG2){
|
if (pidToCodec[tid] == MPEG2){
|
||||||
|
typeNal = pesPayload[0];
|
||||||
|
switch (typeNal){
|
||||||
|
case 0xB3:
|
||||||
|
if (!mpeg2SeqHdr.count(tid)){
|
||||||
|
mpeg2SeqHdr[tid] = std::string(pesPayload, (nextPtr - pesPayload));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xB5:
|
||||||
|
if (!mpeg2SeqExt.count(tid)){
|
||||||
|
mpeg2SeqExt[tid] = std::string(pesPayload, (nextPtr - pesPayload));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xB8:
|
||||||
|
isKeyFrame = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isKeyFrame = false;
|
||||||
if (pidToCodec[tid] == H264){
|
if (pidToCodec[tid] == H264){
|
||||||
typeNal = pesPayload[0] & 0x1F;
|
typeNal = pesPayload[0] & 0x1F;
|
||||||
switch (typeNal){
|
switch (typeNal){
|
||||||
|
@ -816,6 +870,17 @@ namespace TS{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
case MPEG2:{
|
||||||
|
meta.tracks[mId].type = "video";
|
||||||
|
meta.tracks[mId].codec = "MPEG2";
|
||||||
|
meta.tracks[mId].trackID = mId;
|
||||||
|
meta.tracks[mId].init = std::string("\000\000\001", 3) + mpeg2SeqHdr[it->first] + std::string("\000\000\001", 3) + mpeg2SeqExt[it->first];
|
||||||
|
|
||||||
|
Mpeg::MPEG2Info info = Mpeg::parseMPEG2Header(meta.tracks[mId].init);
|
||||||
|
meta.tracks[mId].width = info.width;
|
||||||
|
meta.tracks[mId].height = info.height;
|
||||||
|
meta.tracks[mId].fpks = info.fps * 1000;
|
||||||
|
}break;
|
||||||
case ID3:{
|
case ID3:{
|
||||||
meta.tracks[mId].type = "meta";
|
meta.tracks[mId].type = "meta";
|
||||||
meta.tracks[mId].codec = "ID3";
|
meta.tracks[mId].codec = "ID3";
|
||||||
|
@ -831,6 +896,18 @@ namespace TS{
|
||||||
meta.tracks[mId].rate = 0;
|
meta.tracks[mId].rate = 0;
|
||||||
meta.tracks[mId].channels = 0;
|
meta.tracks[mId].channels = 0;
|
||||||
}break;
|
}break;
|
||||||
|
case MP2:{
|
||||||
|
meta.tracks[mId].type = "audio";
|
||||||
|
meta.tracks[mId].codec = "MP2";
|
||||||
|
meta.tracks[mId].trackID = mId;
|
||||||
|
|
||||||
|
Mpeg::MP2Info info = Mpeg::parseMP2Header(mp2Hdr[it->first]);
|
||||||
|
meta.tracks[mId].rate = info.sampleRate;
|
||||||
|
meta.tracks[mId].channels = info.channels;
|
||||||
|
|
||||||
|
///\todo Fix this value
|
||||||
|
meta.tracks[mId].size = 0;
|
||||||
|
}break;
|
||||||
case AAC:{
|
case AAC:{
|
||||||
meta.tracks[mId].type = "audio";
|
meta.tracks[mId].type = "audio";
|
||||||
meta.tracks[mId].codec = "AAC";
|
meta.tracks[mId].codec = "AAC";
|
||||||
|
@ -887,7 +964,10 @@ namespace TS{
|
||||||
case AAC:
|
case AAC:
|
||||||
case H265:
|
case H265:
|
||||||
case AC3:
|
case AC3:
|
||||||
case ID3: result.insert(entry.getElementaryPid()); break;
|
case ID3:
|
||||||
|
case MP2:
|
||||||
|
case MPEG2:
|
||||||
|
result.insert(entry.getElementaryPid()); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
entry.advance();
|
entry.advance();
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "shared_memory.h"
|
#include "shared_memory.h"
|
||||||
|
|
||||||
namespace TS{
|
namespace TS{
|
||||||
enum codecType{H264 = 0x1B, AAC = 0x0F, AC3 = 0x81, MP3 = 0x03, H265 = 0x24, ID3 = 0x15};
|
enum codecType{H264 = 0x1B, AAC = 0x0F, AC3 = 0x81, MP3 = 0x03, H265 = 0x24, ID3 = 0x15, MPEG2 = 0x02, MP2 = 0x03};
|
||||||
|
|
||||||
class ADTSRemainder{
|
class ADTSRemainder{
|
||||||
private:
|
private:
|
||||||
|
@ -80,6 +80,9 @@ namespace TS{
|
||||||
std::map<unsigned long, std::string> metaInit;
|
std::map<unsigned long, std::string> metaInit;
|
||||||
std::map<unsigned long, std::string> descriptors;
|
std::map<unsigned long, std::string> descriptors;
|
||||||
std::map<unsigned long, uint32_t> seenUnitStart;
|
std::map<unsigned long, uint32_t> seenUnitStart;
|
||||||
|
std::map<unsigned long, std::string> mpeg2SeqHdr;
|
||||||
|
std::map<unsigned long, std::string> mpeg2SeqExt;
|
||||||
|
std::map<unsigned long, std::string> mp2Hdr;
|
||||||
mutable tthread::recursive_mutex tMutex;
|
mutable tthread::recursive_mutex tMutex;
|
||||||
|
|
||||||
bool threaded;
|
bool threaded;
|
||||||
|
|
|
@ -123,8 +123,10 @@ namespace Mist {
|
||||||
capa["priority"] = 9ll;
|
capa["priority"] = 9ll;
|
||||||
capa["codecs"][0u][0u].append("H264");
|
capa["codecs"][0u][0u].append("H264");
|
||||||
capa["codecs"][0u][0u].append("HEVC");
|
capa["codecs"][0u][0u].append("HEVC");
|
||||||
|
capa["codecs"][0u][0u].append("MPEG2");
|
||||||
capa["codecs"][0u][1u].append("AAC");
|
capa["codecs"][0u][1u].append("AAC");
|
||||||
capa["codecs"][0u][1u].append("AC3");
|
capa["codecs"][0u][1u].append("AC3");
|
||||||
|
capa["codecs"][0u][1u].append("MP2");
|
||||||
inFile = NULL;
|
inFile = NULL;
|
||||||
inputProcess = 0;
|
inputProcess = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,11 @@ namespace Mist {
|
||||||
capa["socket"] = "http_ts";
|
capa["socket"] = "http_ts";
|
||||||
capa["codecs"][0u][0u].append("H264");
|
capa["codecs"][0u][0u].append("H264");
|
||||||
capa["codecs"][0u][0u].append("HEVC");
|
capa["codecs"][0u][0u].append("HEVC");
|
||||||
|
capa["codecs"][0u][0u].append("MPEG2");
|
||||||
capa["codecs"][0u][1u].append("AAC");
|
capa["codecs"][0u][1u].append("AAC");
|
||||||
capa["codecs"][0u][1u].append("MP3");
|
capa["codecs"][0u][1u].append("MP3");
|
||||||
capa["codecs"][0u][1u].append("AC3");
|
capa["codecs"][0u][1u].append("AC3");
|
||||||
|
capa["codecs"][0u][1u].append("MP2");
|
||||||
capa["methods"][0u]["handler"] = "http";
|
capa["methods"][0u]["handler"] = "http";
|
||||||
capa["methods"][0u]["type"] = "html5/video/mpeg";
|
capa["methods"][0u]["type"] = "html5/video/mpeg";
|
||||||
capa["methods"][0u]["priority"] = 1ll;
|
capa["methods"][0u]["priority"] = 1ll;
|
||||||
|
|
|
@ -80,9 +80,11 @@ namespace Mist {
|
||||||
capa["optional"]["tracks"]["default"] = "";
|
capa["optional"]["tracks"]["default"] = "";
|
||||||
capa["codecs"][0u][0u].append("HEVC");
|
capa["codecs"][0u][0u].append("HEVC");
|
||||||
capa["codecs"][0u][0u].append("H264");
|
capa["codecs"][0u][0u].append("H264");
|
||||||
|
capa["codecs"][0u][0u].append("MPEG2");
|
||||||
capa["codecs"][0u][1u].append("AAC");
|
capa["codecs"][0u][1u].append("AAC");
|
||||||
capa["codecs"][0u][1u].append("MP3");
|
capa["codecs"][0u][1u].append("MP3");
|
||||||
capa["codecs"][0u][1u].append("AC3");
|
capa["codecs"][0u][1u].append("AC3");
|
||||||
|
capa["codecs"][0u][1u].append("MP2");
|
||||||
cfg->addConnectorOptions(8888, capa);
|
cfg->addConnectorOptions(8888, capa);
|
||||||
config = cfg;
|
config = cfg;
|
||||||
capa["push_urls"].append("tsudp://*");
|
capa["push_urls"].append("tsudp://*");
|
||||||
|
|
|
@ -81,115 +81,123 @@ namespace Mist {
|
||||||
std::string bs;
|
std::string bs;
|
||||||
//prepare bufferstring
|
//prepare bufferstring
|
||||||
if (video){
|
if (video){
|
||||||
unsigned int extraSize = 0;
|
if (Trk.codec == "H264" || Trk.codec == "HEVC"){
|
||||||
//dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
|
unsigned int extraSize = 0;
|
||||||
if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
|
//dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
|
||||||
extraSize += 6;
|
if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
|
||||||
}
|
extraSize += 6;
|
||||||
if (keyframe){
|
|
||||||
if (Trk.codec == "H264"){
|
|
||||||
if (!haveAvcc){
|
|
||||||
avccbox.setPayload(Trk.init);
|
|
||||||
haveAvcc = true;
|
|
||||||
}
|
|
||||||
bs = avccbox.asAnnexB();
|
|
||||||
extraSize += bs.size();
|
|
||||||
}
|
}
|
||||||
/*LTS-START*/
|
if (keyframe){
|
||||||
if (Trk.codec == "HEVC"){
|
if (Trk.codec == "H264"){
|
||||||
if (!haveHvcc){
|
if (!haveAvcc){
|
||||||
hvccbox.setPayload(Trk.init);
|
avccbox.setPayload(Trk.init);
|
||||||
haveHvcc = true;
|
haveAvcc = true;
|
||||||
|
}
|
||||||
|
bs = avccbox.asAnnexB();
|
||||||
|
extraSize += bs.size();
|
||||||
}
|
}
|
||||||
bs = hvccbox.asAnnexB();
|
/*LTS-START*/
|
||||||
extraSize += bs.size();
|
if (Trk.codec == "HEVC"){
|
||||||
|
if (!haveHvcc){
|
||||||
|
hvccbox.setPayload(Trk.init);
|
||||||
|
haveHvcc = true;
|
||||||
|
}
|
||||||
|
bs = hvccbox.asAnnexB();
|
||||||
|
extraSize += bs.size();
|
||||||
|
}
|
||||||
|
/*LTS-END*/
|
||||||
}
|
}
|
||||||
/*LTS-END*/
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int watKunnenWeIn1Ding = 65490-13;
|
unsigned int watKunnenWeIn1Ding = 65490-13;
|
||||||
unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding;
|
unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding;
|
||||||
unsigned int currPack = 0;
|
unsigned int currPack = 0;
|
||||||
unsigned int ThisNaluSize = 0;
|
unsigned int ThisNaluSize = 0;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned int nalLead = 0;
|
unsigned int nalLead = 0;
|
||||||
uint64_t offset = thisPacket.getInt("offset") * 90;
|
uint64_t offset = thisPacket.getInt("offset") * 90;
|
||||||
|
|
||||||
while (currPack <= splitCount){
|
while (currPack <= splitCount){
|
||||||
unsigned int alreadySent = 0;
|
unsigned int alreadySent = 0;
|
||||||
bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), packTime, offset, !currPack, Trk.bps);
|
bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), packTime, offset, !currPack, Trk.bps);
|
||||||
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
if (!currPack){
|
if (!currPack){
|
||||||
if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
|
if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
|
||||||
//End of previous nal unit, if not already present
|
//End of previous nal unit, if not already present
|
||||||
fillPacket("\000\000\000\001\011\360", 6, firstPack, video, keyframe, pkgPid, contPkg);
|
fillPacket("\000\000\000\001\011\360", 6, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
alreadySent += 6;
|
alreadySent += 6;
|
||||||
}
|
|
||||||
if (keyframe){
|
|
||||||
if (Trk.codec == "H264"){
|
|
||||||
bs = avccbox.asAnnexB();
|
|
||||||
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
|
||||||
alreadySent += bs.size();
|
|
||||||
}
|
}
|
||||||
/*LTS-START*/
|
if (keyframe){
|
||||||
if (Trk.codec == "HEVC"){
|
if (Trk.codec == "H264"){
|
||||||
bs = hvccbox.asAnnexB();
|
bs = avccbox.asAnnexB();
|
||||||
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
alreadySent += bs.size();
|
alreadySent += bs.size();
|
||||||
|
}
|
||||||
|
/*LTS-START*/
|
||||||
|
if (Trk.codec == "HEVC"){
|
||||||
|
bs = hvccbox.asAnnexB();
|
||||||
|
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
|
alreadySent += bs.size();
|
||||||
|
}
|
||||||
|
/*LTS-END*/
|
||||||
}
|
}
|
||||||
/*LTS-END*/
|
|
||||||
}
|
}
|
||||||
}
|
while (i + 4 < (unsigned int)dataLen){
|
||||||
while (i + 4 < (unsigned int)dataLen){
|
if (nalLead){
|
||||||
if (nalLead){
|
fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg);
|
i += nalLead;
|
||||||
i += nalLead;
|
alreadySent += nalLead;
|
||||||
alreadySent += nalLead;
|
nalLead = 0;
|
||||||
nalLead = 0;
|
|
||||||
}
|
|
||||||
if (!ThisNaluSize){
|
|
||||||
ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3];
|
|
||||||
if (ThisNaluSize + i + 4 > (unsigned int)dataLen){
|
|
||||||
DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (alreadySent + 4 > watKunnenWeIn1Ding){
|
if (!ThisNaluSize){
|
||||||
nalLead = 4 - (watKunnenWeIn1Ding-alreadySent);
|
ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3];
|
||||||
fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
|
if (ThisNaluSize + i + 4 > (unsigned int)dataLen){
|
||||||
|
DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (alreadySent + 4 > watKunnenWeIn1Ding){
|
||||||
|
nalLead = 4 - (watKunnenWeIn1Ding-alreadySent);
|
||||||
|
fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
|
i += watKunnenWeIn1Ding-alreadySent;
|
||||||
|
alreadySent += watKunnenWeIn1Ding-alreadySent;
|
||||||
|
}else{
|
||||||
|
fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
|
alreadySent += 4;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){
|
||||||
|
fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
i += watKunnenWeIn1Ding-alreadySent;
|
i += watKunnenWeIn1Ding-alreadySent;
|
||||||
|
ThisNaluSize -= watKunnenWeIn1Ding-alreadySent;
|
||||||
alreadySent += watKunnenWeIn1Ding-alreadySent;
|
alreadySent += watKunnenWeIn1Ding-alreadySent;
|
||||||
}else{
|
}else{
|
||||||
fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg);
|
fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
alreadySent += 4;
|
alreadySent += ThisNaluSize;
|
||||||
i += 4;
|
i += ThisNaluSize;
|
||||||
|
ThisNaluSize = 0;
|
||||||
|
}
|
||||||
|
if (alreadySent == watKunnenWeIn1Ding){
|
||||||
|
packData.addStuffing();
|
||||||
|
fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
|
firstPack = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){
|
currPack++;
|
||||||
fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
|
|
||||||
i += watKunnenWeIn1Ding-alreadySent;
|
|
||||||
ThisNaluSize -= watKunnenWeIn1Ding-alreadySent;
|
|
||||||
alreadySent += watKunnenWeIn1Ding-alreadySent;
|
|
||||||
}else{
|
|
||||||
fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg);
|
|
||||||
alreadySent += ThisNaluSize;
|
|
||||||
i += ThisNaluSize;
|
|
||||||
ThisNaluSize = 0;
|
|
||||||
}
|
|
||||||
if (alreadySent == watKunnenWeIn1Ding){
|
|
||||||
packData.addStuffing();
|
|
||||||
fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg);
|
|
||||||
firstPack = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
currPack++;
|
}else{
|
||||||
|
uint64_t offset = thisPacket.getInt("offset") * 90;
|
||||||
|
bs = TS::Packet::getPESVideoLeadIn(0, packTime, offset, true, Trk.bps);
|
||||||
|
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
|
|
||||||
|
fillPacket(dataPointer, dataLen, firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
}
|
}
|
||||||
}else if (Trk.type == "audio"){
|
}else if (Trk.type == "audio"){
|
||||||
long unsigned int tempLen = dataLen;
|
long unsigned int tempLen = dataLen;
|
||||||
if (Trk.codec == "AAC"){
|
if (Trk.codec == "AAC"){
|
||||||
tempLen += 7;
|
tempLen += 7;
|
||||||
}
|
}
|
||||||
bs = TS::Packet::getPESAudioLeadIn(tempLen, packTime, Trk.bps);// myMeta.tracks[thisPacket.getTrackId()].rate / 1000 );
|
bs = TS::Packet::getPESAudioLeadIn(tempLen, packTime, Trk.bps);
|
||||||
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
|
||||||
if (Trk.codec == "AAC"){
|
if (Trk.codec == "AAC"){
|
||||||
bs = TS::getAudioHeader(dataLen, Trk.init);
|
bs = TS::getAudioHeader(dataLen, Trk.init);
|
||||||
|
|
Loading…
Add table
Reference in a new issue