Fix for several TS-related problems.
This commit is contained in:
parent
7b0d3a9365
commit
9536ab1414
6 changed files with 148 additions and 93 deletions
25
lib/adts.cpp
25
lib/adts.cpp
|
@ -18,6 +18,12 @@ namespace aac {
|
||||||
memcpy(data, _data, len);
|
memcpy(data, _data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool adts::sameHeader(const adts & rhs) const {
|
||||||
|
if (len < 7 || rhs.len < 7){return false;}
|
||||||
|
return (memcmp(data, rhs.data, 7) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
adts::adts(const adts & rhs){
|
adts::adts(const adts & rhs){
|
||||||
data = NULL;
|
data = NULL;
|
||||||
len = 0;
|
len = 0;
|
||||||
|
@ -56,7 +62,7 @@ namespace aac {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long adts::getFrequency(){
|
unsigned long adts::getFrequency(){
|
||||||
if (!data || !len){
|
if (!data || len < 3){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
switch(getFrequencyIndex()){
|
switch(getFrequencyIndex()){
|
||||||
|
@ -99,14 +105,25 @@ namespace aac {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long adts::getPayloadSize(){
|
unsigned long adts::getPayloadSize(){
|
||||||
if (!data || !len){
|
if (!data || len < 6){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] >> 5) & 0x07)) - getHeaderSize();
|
unsigned long ret = (((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] >> 5) & 0x07));
|
||||||
|
if (!ret){return ret;}//catch zero length
|
||||||
|
if (ret >= getHeaderSize()){
|
||||||
|
ret -= getHeaderSize();
|
||||||
|
}else{
|
||||||
|
return 0;//catch size less than header size (corrupt data)
|
||||||
|
}
|
||||||
|
if (len < ret + getHeaderSize() ){
|
||||||
|
ret = len - getHeaderSize();
|
||||||
|
//catch size less than length (corrupt data)
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long adts::getSampleCount(){
|
unsigned long adts::getSampleCount(){
|
||||||
if (!data || !len){
|
if (!data || len < 7){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ((data[6] & 0x03) + 1) * 1024;//Number of samples in this frame * 1024
|
return ((data[6] & 0x03) + 1) * 1024;//Number of samples in this frame * 1024
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace aac {
|
||||||
adts(const adts & rhs);
|
adts(const adts & rhs);
|
||||||
~adts();
|
~adts();
|
||||||
adts& operator = (const adts & rhs);
|
adts& operator = (const adts & rhs);
|
||||||
|
bool sameHeader(const adts & rhs) const;
|
||||||
unsigned long getAACProfile();
|
unsigned long getAACProfile();
|
||||||
unsigned long getFrequencyIndex();
|
unsigned long getFrequencyIndex();
|
||||||
unsigned long getFrequency();
|
unsigned long getFrequency();
|
||||||
|
|
|
@ -56,8 +56,10 @@ namespace TS {
|
||||||
}
|
}
|
||||||
|
|
||||||
int tid = newPack.getPID();
|
int tid = newPack.getPID();
|
||||||
|
if ((pidToCodec.count(tid) || tid == 0 || newPack.isPMT()) && (pesStreams[tid].size() || newPack.getUnitStart())){
|
||||||
pesStreams[tid].push_back(newPack);
|
pesStreams[tid].push_back(newPack);
|
||||||
pesPositions[tid].push_back(bytePos);
|
pesPositions[tid].push_back(bytePos);
|
||||||
|
}
|
||||||
|
|
||||||
if (threaded){
|
if (threaded){
|
||||||
globalSem.post();
|
globalSem.post();
|
||||||
|
@ -102,6 +104,7 @@ namespace TS {
|
||||||
globalSem.wait();
|
globalSem.wait();
|
||||||
}
|
}
|
||||||
associationTable = trackPackets.back();
|
associationTable = trackPackets.back();
|
||||||
|
associationTable.parsePIDs();
|
||||||
lastPAT = Util::bootSecs();
|
lastPAT = Util::bootSecs();
|
||||||
if (threaded){
|
if (threaded){
|
||||||
globalSem.post();
|
globalSem.post();
|
||||||
|
@ -124,6 +127,11 @@ namespace TS {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Ignore conditional access packets. We don't care.
|
||||||
|
if (tid == 1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Handle PMT packets
|
//Handle PMT packets
|
||||||
if (pmtTracks.count(tid)){
|
if (pmtTracks.count(tid)){
|
||||||
///\todo Keep track of updates in PMT instead of keeping only the last PMT per program as a reference
|
///\todo Keep track of updates in PMT instead of keeping only the last PMT per program as a reference
|
||||||
|
@ -142,7 +150,6 @@ namespace TS {
|
||||||
switch(sType){
|
switch(sType){
|
||||||
case H264:
|
case H264:
|
||||||
case AAC:
|
case AAC:
|
||||||
case HEVC:
|
|
||||||
case H265:
|
case H265:
|
||||||
case AC3:
|
case AC3:
|
||||||
case ID3:
|
case ID3:
|
||||||
|
@ -272,6 +279,7 @@ namespace TS {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::parsePES(unsigned long tid){
|
void Stream::parsePES(unsigned long tid){
|
||||||
|
if (!pidToCodec.count(tid)){return;}//skip unknown codecs
|
||||||
if (threaded){
|
if (threaded){
|
||||||
globalSem.wait();
|
globalSem.wait();
|
||||||
}
|
}
|
||||||
|
@ -308,11 +316,13 @@ namespace TS {
|
||||||
paySize += curPack->getPayloadLength();
|
paySize += curPack->getPayloadLength();
|
||||||
curPack++;
|
curPack++;
|
||||||
}
|
}
|
||||||
|
VERYHIGH_MSG("Parsing PES for track %lu, length %i", tid, paySize);
|
||||||
char * payload = (char*)malloc(paySize);
|
char * payload = (char*)malloc(paySize);
|
||||||
paySize = 0;
|
paySize = 0;
|
||||||
curPack = inStream.begin();
|
curPack = inStream.begin();
|
||||||
int lastCtr = curPack->getContinuityCounter() - 1;
|
int lastCtr = curPack->getContinuityCounter() - 1;
|
||||||
for (int i = 0; i < packNum; i++){
|
for (int i = 0; i < packNum; i++){
|
||||||
|
if (curPack->getContinuityCounter() == lastCtr){curPack++; continue;}
|
||||||
if (curPack->getContinuityCounter() - lastCtr != 1 && curPack->getContinuityCounter()){
|
if (curPack->getContinuityCounter() - lastCtr != 1 && curPack->getContinuityCounter()){
|
||||||
INFO_MSG("Parsing a pes on track %d, missed %d packets", tid, curPack->getContinuityCounter() - lastCtr - 1);
|
INFO_MSG("Parsing a pes on track %d, missed %d packets", tid, curPack->getContinuityCounter() - lastCtr - 1);
|
||||||
}
|
}
|
||||||
|
@ -375,6 +385,22 @@ namespace TS {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pesHeader[7] & 0x20){ //ESCR - ignored
|
||||||
|
pesOffset += 6;
|
||||||
|
}
|
||||||
|
if (pesHeader[7] & 0x10){ //ESR - ignored
|
||||||
|
pesOffset += 3;
|
||||||
|
}
|
||||||
|
if (pesHeader[7] & 0x08){ //trick mode - ignored
|
||||||
|
pesOffset += 1;
|
||||||
|
}
|
||||||
|
if (pesHeader[7] & 0x04){//additional copy - ignored
|
||||||
|
pesOffset += 1;
|
||||||
|
}
|
||||||
|
if (pesHeader[7] & 0x02){ //crc - ignored
|
||||||
|
pesOffset += 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (paySize - offset - pesOffset < realPayloadSize){
|
if (paySize - offset - pesOffset < realPayloadSize){
|
||||||
INFO_MSG("Not enough data left on track %lu.", tid);
|
INFO_MSG("Not enough data left on track %lu.", tid);
|
||||||
break;
|
break;
|
||||||
|
@ -391,12 +417,14 @@ namespace TS {
|
||||||
globalSem.wait();
|
globalSem.wait();
|
||||||
}
|
}
|
||||||
while (offsetInPes < realPayloadSize){
|
while (offsetInPes < realPayloadSize){
|
||||||
outPackets[tid].push_back(DTSC::Packet());
|
|
||||||
aac::adts adtsPack(pesPayload + offsetInPes, realPayloadSize - offsetInPes);
|
aac::adts adtsPack(pesPayload + offsetInPes, realPayloadSize - offsetInPes);
|
||||||
if (!adtsInfo.count(tid)){
|
if (adtsPack.getFrequency() && adtsPack.getPayloadSize()){
|
||||||
|
if (!adtsInfo.count(tid) || !adtsInfo[tid].sameHeader(adtsPack)){
|
||||||
adtsInfo[tid] = adtsPack;
|
adtsInfo[tid] = adtsPack;
|
||||||
}
|
}
|
||||||
|
outPackets[tid].push_back(DTSC::Packet());
|
||||||
outPackets[tid].back().genericFill(timeStamp + ((samplesRead * 1000) / adtsPack.getFrequency()), timeOffset, tid, adtsPack.getPayload(), adtsPack.getPayloadSize(), bPos, 0);
|
outPackets[tid].back().genericFill(timeStamp + ((samplesRead * 1000) / adtsPack.getFrequency()), timeOffset, tid, adtsPack.getPayload(), adtsPack.getPayloadSize(), bPos, 0);
|
||||||
|
}
|
||||||
samplesRead += adtsPack.getSampleCount();
|
samplesRead += adtsPack.getSampleCount();
|
||||||
offsetInPes += adtsPack.getHeaderSize() + adtsPack.getPayloadSize();
|
offsetInPes += adtsPack.getHeaderSize() + adtsPack.getPayloadSize();
|
||||||
}
|
}
|
||||||
|
@ -414,7 +442,7 @@ namespace TS {
|
||||||
globalSem.post();
|
globalSem.post();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pidToCodec[tid] == H264 || pidToCodec[tid] == HEVC || pidToCodec[tid] == H265){
|
if (pidToCodec[tid] == H264 || pidToCodec[tid] == H265){
|
||||||
//Convert from annex b
|
//Convert from annex b
|
||||||
char * parsedData = (char*)malloc(realPayloadSize * 2);
|
char * parsedData = (char*)malloc(realPayloadSize * 2);
|
||||||
bool isKeyFrame = false;
|
bool isKeyFrame = false;
|
||||||
|
@ -423,7 +451,7 @@ namespace TS {
|
||||||
if (pidToCodec[tid] == H264) {
|
if (pidToCodec[tid] == H264) {
|
||||||
nalInfo = h264::analysePackets(parsedData, parsedSize);
|
nalInfo = h264::analysePackets(parsedData, parsedSize);
|
||||||
}
|
}
|
||||||
if (pidToCodec[tid] == HEVC || pidToCodec[tid] == H265){
|
if (pidToCodec[tid] == H265){
|
||||||
nalInfo = h265::analysePackets(parsedData, parsedSize);
|
nalInfo = h265::analysePackets(parsedData, parsedSize);
|
||||||
}
|
}
|
||||||
int dataOffset = 0;
|
int dataOffset = 0;
|
||||||
|
@ -457,7 +485,7 @@ namespace TS {
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pidToCodec[tid] == HEVC || pidToCodec[tid] == H265){
|
if (pidToCodec[tid] == H265){
|
||||||
switch (it->nalType){
|
switch (it->nalType){
|
||||||
case 2: case 3: //TSA Picture
|
case 2: case 3: //TSA Picture
|
||||||
case 4: case 5: //STSA Picture
|
case 4: case 5: //STSA Picture
|
||||||
|
@ -590,8 +618,11 @@ namespace TS {
|
||||||
if (tid && it->first != tid){
|
if (tid && it->first != tid){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!meta.tracks.count(it->first) && it->second == H264){
|
if (meta.tracks.count(it->first) && meta.tracks[it->first].codec.size()){continue;}
|
||||||
|
switch (it->second){
|
||||||
|
case H264: {
|
||||||
if (!spsInfo.count(it->first) || !ppsInfo.count(it->first)){
|
if (!spsInfo.count(it->first) || !ppsInfo.count(it->first)){
|
||||||
|
MEDIUM_MSG("Aborted meta fill for h264 track %lu: no SPS/PPS", it->first);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
meta.tracks[it->first].type = "video";
|
meta.tracks[it->first].type = "video";
|
||||||
|
@ -614,8 +645,10 @@ namespace TS {
|
||||||
avccBox.setPPS(ppsInfo[it->first]);
|
avccBox.setPPS(ppsInfo[it->first]);
|
||||||
meta.tracks[it->first].init = std::string(avccBox.payload(), avccBox.payloadSize());
|
meta.tracks[it->first].init = std::string(avccBox.payload(), avccBox.payloadSize());
|
||||||
}
|
}
|
||||||
if (!meta.tracks.count(it->first) && (it->second == HEVC || it->second == H265)){
|
break;
|
||||||
|
case H265: {
|
||||||
if (!hevcInfo.count(it->first) || !hevcInfo[it->first].haveRequired()){
|
if (!hevcInfo.count(it->first) || !hevcInfo[it->first].haveRequired()){
|
||||||
|
MEDIUM_MSG("Aborted meta fill for hevc track %lu: no info nal unit", it->first);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
meta.tracks[it->first].type = "video";
|
meta.tracks[it->first].type = "video";
|
||||||
|
@ -623,13 +656,15 @@ namespace TS {
|
||||||
meta.tracks[it->first].trackID = it->first;
|
meta.tracks[it->first].trackID = it->first;
|
||||||
meta.tracks[it->first].init = hevcInfo[it->first].generateHVCC();
|
meta.tracks[it->first].init = hevcInfo[it->first].generateHVCC();
|
||||||
}
|
}
|
||||||
if (!meta.tracks.count(it->first) && it->second == ID3){
|
break;
|
||||||
|
case ID3: {
|
||||||
meta.tracks[it->first].type = "meta";
|
meta.tracks[it->first].type = "meta";
|
||||||
meta.tracks[it->first].codec = "ID3";
|
meta.tracks[it->first].codec = "ID3";
|
||||||
meta.tracks[it->first].trackID = it->first;
|
meta.tracks[it->first].trackID = it->first;
|
||||||
meta.tracks[it->first].init = metaInit[it->first];
|
meta.tracks[it->first].init = metaInit[it->first];
|
||||||
}
|
}
|
||||||
if (!meta.tracks.count(it->first) && it->second == AC3){
|
break;
|
||||||
|
case AC3: {
|
||||||
meta.tracks[it->first].type = "audio";
|
meta.tracks[it->first].type = "audio";
|
||||||
meta.tracks[it->first].codec = "AC3";
|
meta.tracks[it->first].codec = "AC3";
|
||||||
meta.tracks[it->first].trackID = it->first;
|
meta.tracks[it->first].trackID = it->first;
|
||||||
|
@ -638,7 +673,8 @@ namespace TS {
|
||||||
meta.tracks[it->first].rate = 0;
|
meta.tracks[it->first].rate = 0;
|
||||||
meta.tracks[it->first].channels = 0;
|
meta.tracks[it->first].channels = 0;
|
||||||
}
|
}
|
||||||
if (!meta.tracks.count(it->first) && it->second == AAC){
|
break;
|
||||||
|
case AAC: {
|
||||||
meta.tracks[it->first].type = "audio";
|
meta.tracks[it->first].type = "audio";
|
||||||
meta.tracks[it->first].codec = "AAC";
|
meta.tracks[it->first].codec = "AAC";
|
||||||
meta.tracks[it->first].trackID = it->first;
|
meta.tracks[it->first].trackID = it->first;
|
||||||
|
@ -650,6 +686,9 @@ namespace TS {
|
||||||
audioInit[1] = ((adtsInfo[it->first].getFrequencyIndex() & 0x01) << 7) | ((adtsInfo[it->first].getChannelConfig() & 0x0F) << 3);
|
audioInit[1] = ((adtsInfo[it->first].getFrequencyIndex() & 0x01) << 7) | ((adtsInfo[it->first].getChannelConfig() & 0x0F) << 3);
|
||||||
meta.tracks[it->first].init = std::string(audioInit, 2);
|
meta.tracks[it->first].init = std::string(audioInit, 2);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MEDIUM_MSG("Initialized track %lu as %s %s", it->first, meta.tracks[it->first].codec.c_str(), meta.tracks[it->first].type.c_str());
|
||||||
}
|
}
|
||||||
if (threaded){
|
if (threaded){
|
||||||
globalSem.post();
|
globalSem.post();
|
||||||
|
@ -679,7 +718,6 @@ namespace TS {
|
||||||
switch(entry.getStreamType()){
|
switch(entry.getStreamType()){
|
||||||
case H264:
|
case H264:
|
||||||
case AAC:
|
case AAC:
|
||||||
case HEVC:
|
|
||||||
case H265:
|
case H265:
|
||||||
case AC3:
|
case AC3:
|
||||||
case ID3:
|
case ID3:
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace TS {
|
||||||
AAC = 0x0F,
|
AAC = 0x0F,
|
||||||
AC3 = 0x81,
|
AC3 = 0x81,
|
||||||
MP3 = 0x03,
|
MP3 = 0x03,
|
||||||
HEVC = 0x06,
|
|
||||||
H265 = 0x24,
|
H265 = 0x24,
|
||||||
ID3 = 0x15
|
ID3 = 0x15
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <mist/ts_packet.h>
|
#include <mist/ts_packet.h>
|
||||||
|
#include <mist/bitfields.h>
|
||||||
#include <mist/config.h>
|
#include <mist/config.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,10 +30,10 @@ namespace Analysers {
|
||||||
known = true;
|
known = true;
|
||||||
}
|
}
|
||||||
if (!known){
|
if (!known){
|
||||||
res << " [Unknown stream ID]";
|
res << " [Unknown stream ID: " << (int)d[3] << "]";
|
||||||
}
|
}
|
||||||
if (d[0] != 0 || d[1] != 0 || d[2] != 1){
|
if (d[0] != 0 || d[1] != 0 || d[2] != 1){
|
||||||
res << " [!INVALID START CODE!]";
|
res << " [!!! INVALID START CODE: " << (int)d[0] << " " << (int)d[1] << " " << (int)d[2] << " ]";
|
||||||
}
|
}
|
||||||
if (known){
|
if (known){
|
||||||
if ((d[6] & 0xC0) != 0x80){
|
if ((d[6] & 0xC0) != 0x80){
|
||||||
|
@ -56,12 +57,20 @@ namespace Analysers {
|
||||||
res << " [Copy]";
|
res << " [Copy]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int timeFlags = ((d[7] & 0xC0) >> 6);
|
||||||
|
if (timeFlags == 2){
|
||||||
|
headSize += 5;
|
||||||
|
}
|
||||||
|
if (timeFlags == 3){
|
||||||
|
headSize += 10;
|
||||||
|
}
|
||||||
if (d[7] & 0x20){
|
if (d[7] & 0x20){
|
||||||
res << " [ESCR present, not decoded!]";
|
res << " [ESCR present, not decoded!]";
|
||||||
headSize += 6;
|
headSize += 6;
|
||||||
}
|
}
|
||||||
if (d[7] & 0x10){
|
if (d[7] & 0x10){
|
||||||
res << " [ESR present, not decoded!]";
|
uint32_t es_rate = (Bit::btoh24(d.data()+9+headSize) & 0x7FFFFF) >> 1;
|
||||||
|
res << " [ESR: " << (es_rate * 50) / 1024 << " KiB/s]";
|
||||||
headSize += 3;
|
headSize += 3;
|
||||||
}
|
}
|
||||||
if (d[7] & 0x08){
|
if (d[7] & 0x08){
|
||||||
|
@ -80,13 +89,6 @@ namespace Analysers {
|
||||||
res << " [Extension present, not decoded!]";
|
res << " [Extension present, not decoded!]";
|
||||||
headSize += 0; /// \todo Implement this. Complicated field, bah.
|
headSize += 0; /// \todo Implement this. Complicated field, bah.
|
||||||
}
|
}
|
||||||
int timeFlags = ((d[7] & 0xC0) >> 6);
|
|
||||||
if (timeFlags == 2){
|
|
||||||
headSize += 5;
|
|
||||||
}
|
|
||||||
if (timeFlags == 3){
|
|
||||||
headSize += 10;
|
|
||||||
}
|
|
||||||
if (d[8] != headSize){
|
if (d[8] != headSize){
|
||||||
res << " [Padding: " << ((int)d[8] - headSize) << "b]";
|
res << " [Padding: " << ((int)d[8] - headSize) << "b]";
|
||||||
}
|
}
|
||||||
|
@ -145,13 +147,13 @@ namespace Analysers {
|
||||||
std::cout << printPES(payloads[packet.getPID()], packet.getPID(), detailLevel);
|
std::cout << printPES(payloads[packet.getPID()], packet.getPID(), detailLevel);
|
||||||
payloads.erase(packet.getPID());
|
payloads.erase(packet.getPID());
|
||||||
}
|
}
|
||||||
if (detailLevel < 2){
|
if (detailLevel >= 3 || !packet.getPID() || packet.isPMT()){
|
||||||
std::stringstream nul;
|
if (packet.getPID() == 0){
|
||||||
nul << packet.toPrettyString(0, detailLevel);
|
((TS::ProgramAssociationTable*)&packet)->parsePIDs();
|
||||||
}else{
|
}
|
||||||
std::cout << packet.toPrettyString(0, detailLevel);
|
std::cout << packet.toPrettyString(0, detailLevel);
|
||||||
}
|
}
|
||||||
if (packet.getPID() && !packet.isPMT()){
|
if (packet.getPID() && !packet.isPMT() && (payloads[packet.getPID()].size() || packet.getUnitStart())){
|
||||||
payloads[packet.getPID()].append(packet.getPayload(), packet.getPayloadLength());
|
payloads[packet.getPID()].append(packet.getPayload(), packet.getPayloadLength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,18 +245,16 @@ namespace Mist {
|
||||||
TS::Packet packet;//to analyse and extract data
|
TS::Packet packet;//to analyse and extract data
|
||||||
fseek(inFile, 0, SEEK_SET);//seek to beginning
|
fseek(inFile, 0, SEEK_SET);//seek to beginning
|
||||||
|
|
||||||
bool first = true;
|
|
||||||
long long int lastBpos = 0;
|
long long int lastBpos = 0;
|
||||||
while (packet.FromFile(inFile) && !feof(inFile)) {
|
while (packet.FromFile(inFile) && !feof(inFile)) {
|
||||||
tsStream.parse(packet, lastBpos);
|
tsStream.parse(packet, lastBpos);
|
||||||
lastBpos = ftell(inFile);
|
lastBpos = ftell(inFile);
|
||||||
while (tsStream.hasPacketOnEachTrack()) {
|
while (tsStream.hasPacketOnEachTrack()) {
|
||||||
if (first) {
|
|
||||||
tsStream.initializeMetadata(myMeta);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
DTSC::Packet headerPack;
|
DTSC::Packet headerPack;
|
||||||
tsStream.getEarliestPacket(headerPack);
|
tsStream.getEarliestPacket(headerPack);
|
||||||
|
if (!myMeta.tracks.count(headerPack.getTrackId()) || !myMeta.tracks[headerPack.getTrackId()].codec.size()) {
|
||||||
|
tsStream.initializeMetadata(myMeta, headerPack.getTrackId());
|
||||||
|
}
|
||||||
myMeta.update(headerPack);
|
myMeta.update(headerPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue