bool tsPacket::getNextPES(TS_PESpacket *pes) { #if 1 #define zprintf(...) {} #else #define zprintf ADM_info #endif int nbRetries=0,counter=0; uint64_t startOffset=0; TSpacketInfo pkt; pkt.startAt=0; pes->fresh=false; nextPack3: if(pkt.startAt-startOffset>(1<<25)) // max. 32 MiB { ADM_warning("Giving up after %d retries, consumed %" PRId64" bytes\n",nbRetries,pkt.startAt-startOffset); return false; } // Sync at source if(false==getNextPacket_NoHeader(pes->pid,&pkt,false)) return false; if(!nbRetries) startOffset=pkt.startAt; nbRetries++; // If it does not contain a payload start continue bool mark=false; uint32_t code=(pkt.payload[0]<<24)+(pkt.payload[1]<<16)+(pkt.payload[2]<<8)+pkt.payload[3]; if((code&0xffffffC0)==0x1C0) mark=true; zprintf("Mark=%x\n",code); if(!pkt.payloadStart && !mark) { #if 0 printf("[Ts Demuxer] Pes for Pid = 0x%x (%d) does not contain payload start\n",pes->pid,pes->pid); #endif counter++; goto nextPack3; } if(counter>1) zprintf("Payload start for Pid = 0x%x (%d) found after %d retries\n",pes->pid,pes->pid,counter); counter=0; //____________________ //____________________ // 1- Start Headers //____________________ //____________________ zprintf("[TS Demuxer] Code=0x%x pid=0x%x\n",code,pes->pid); if((code&0xffffff00)!=0x100) { #if 0 printf("[Ts Demuxer] No PES startcode at 0x%" PRIx64"\n",pkt.startAt); printf("0x:%02x %02x %02x %02x\n",pkt.payload[4],pkt.payload[5],pkt.payload[6],pkt.payload[7]); #endif goto nextPack3; } if(nbRetries>1) ADM_info("PES startcode found at 0x%" PRIx64" after %d retries\n",pkt.startAt,nbRetries); //mixDump(pkt.payload,pkt.payloadSize); uint32_t pesPacketLen=(pkt.payload[4]<<8)+(pkt.payload[5]); zprintf("[TS Demuxer] Pes Packet Len=%d\n",pesPacketLen); pes->payloadSize=0; pes->addData(pkt.payloadSize,pkt.payload); pes->startAt=pkt.startAt; while(1) { uint64_t pos; _file->getpos(&pos); if(false==getNextPacket_NoHeader(pes->pid,&pkt,false)) return false; if(!pkt.payloadStart) { pes->addData(pkt.payloadSize,pkt.payload); }else { _file->setpos(pos); break; } if(pes->payloadLimit>TS_PES_MAX_LIMIT) { printf("[Ts Demuxer] Pes Packet too big\n"); goto nextPack3; } } //____________________ // Now decode PES header (extra memcpy) //____________________ zprintf("[Ts Demuxer] Full size :%d\n",pes->payloadSize); if(false==decodePesHeader(pes)) goto nextPack3; // zprintf("[Ts Demuxer] Found PES of len %d, offset=%d\n",pes->payloadSize, pes->offset); pes->fresh=true; return true; }
bool tsPacket::getNextPES(TS_PESpacket *pes) { #if 1 #define zprintf(...) {} #else #define zprintf printf #endif TSpacketInfo pkt; pes->fresh=false; nextPack3: // Sync at source if(false==getNextPacket_NoHeader(pes->pid,&pkt,false)) return false; // If it does not contain a payload start continue if(!pkt.payloadStart) { printf("[Ts Demuxer] Pes for Pid =0x%d does not contain payload start\n",pes->pid); goto nextPack3; } //____________________ //____________________ // 1- Start Headers //____________________ //____________________ uint32_t code=(pkt.payload[0]<<24)+(pkt.payload[1]<<16)+(pkt.payload[2]<<8)+pkt.payload[3]; zprintf("[TS Demuxer] Code=0x%x pid=0x%x\n",code,pes->pid); if((code&0xffffff00)!=0x100) { printf("[Ts Demuxer] No PES startcode at 0x%"PRIx64"\n",pkt.startAt); printf("0x:%02x %02x %02x %02x\n",pkt.payload[4],pkt.payload[5],pkt.payload[6],pkt.payload[7]); goto nextPack3; } //mixDump(pkt.payload,pkt.payloadSize); uint32_t pesPacketLen=(pkt.payload[4]<<8)+(pkt.payload[5]); zprintf("[TS Demuxer] Pes Packet Len=%d\n",pesPacketLen); pes->payloadSize=0; pes->addData(pkt.payloadSize,pkt.payload); pes->startAt=pkt.startAt; while(1) { uint64_t pos; _file->getpos(&pos); if(false==getNextPacket_NoHeader(pes->pid,&pkt,false)) return false; if(!pkt.payloadStart) { pes->addData(pkt.payloadSize,pkt.payload); }else { _file->setpos(pos); break; } if(pes->payloadLimit>TS_PES_MAX_LIMIT) { printf("[Ts Demuxer] Pes Packet too big\n"); goto nextPack3; } } //____________________ // Now decode PES header (extra memcpy) //____________________ zprintf("[Ts Demuxer] Full size :%d\n",pes->payloadSize); if(false==decodePesHeader(pes)) goto nextPack3; // zprintf("[Ts Demuxer] Found PES of len %d\n",pes->payloadSize); pes->fresh=true; return true; }
bool tsPacket::getNextPSI(uint32_t pid,TS_PSIpacketInfo *psi) { int multiPacketPsi=0; int nbRetries=0; uint64_t startOffset=0; TSpacketInfo pkt; nextPack2: if(nbRetries && pkt.startAt-startOffset>(1<<25)) // max. 32 MiB { ADM_warning("Giving up after %d retries, consumed %" PRId64" bytes\n",nbRetries,pkt.startAt-startOffset); return false; } if(false==getNextPacket_NoHeader(pid,&pkt,true)) return false; if(!nbRetries) startOffset=pkt.startAt; nbRetries++; uint32_t tableId; uint32_t sectionLength=0; uint32_t transportStreamId=0; uint32_t dummy; getBits bits(pkt.payloadSize,pkt.payload); DUMMY(tableId,8); int section_syntax_indicator=bits.get(1); #ifdef VERBOSE_PSI if(!section_syntax_indicator) ADM_warning("Syntax section indicator not set\n"); #endif if(bits.get(1)) // Private bit { ADM_warning("Section syntax is set to private\n"); goto nextPack2; } bits.get(2); // 2 Reserved bits sectionLength=bits.get(12); // Section Length #if 1 if(sectionLength+3>pkt.payloadSize) { if(!multiPacketPsi) ADM_warning("[MpegTs] Multi Packet PSI ? sectionLength=%d, len=%d\n",sectionLength,pkt.payloadSize); multiPacketPsi++; goto nextPack2; } if(multiPacketPsi>1) ADM_warning("Multi packet PSI warning repeated %d times\n",multiPacketPsi); multiPacketPsi=0; #endif transportStreamId=bits.get(16);// transportStreamId #ifdef VERBOSE_PSI printf("[MpegTs] Section length =%d\n",sectionLength); printf("[MpegTs] transportStreamId =%d\n",transportStreamId); #endif bits.skip(2); // ignored DUMMY(VersionNumber,5); // Version number DUMMY(CurrentNext,1); // Current Next indicator psi->count=bits.get(8); // Section number psi->countMax=bits.get(8); // Section last number #ifdef VERBOSE_PSI printf("[MpegTs] Count=%d CountMax=%d\n",psi->count,psi->countMax); #endif if(psi->count!=psi->countMax) return false; // we dont handle split psi at the moment uint8_t *c=pkt.payload+sectionLength-4+3; // Verify CRC uint32_t crc1=mpegTsCRC(pkt.payload,sectionLength-4+3); uint32_t crc2=(c[0]<<24)+(c[1]<<16)+(c[2]<<8)+c[3]; if(crc1!=crc2) { printf("[MpegTs] getNextPSI bad checksum :%04x vs %04x\n",crc1,crc2); goto nextPack2; } int hdr=(8+16+16+8+8+8)/8; int payloadsize=sectionLength-4-5; // Remove checksum & header if(payloadsize<4) goto nextPack2; psi->payloadSize=payloadsize; memcpy(psi->payload,pkt.payload+hdr,psi->payloadSize); return true; }
bool tsPacket::getNextPSI(uint32_t pid,TS_PSIpacketInfo *psi) { TSpacketInfo pkt; nextPack2: if(false==getNextPacket_NoHeader(pid,&pkt,true)) return false; uint32_t tableId; uint32_t sectionLength=0; uint32_t transportStreamId=0; uint32_t dummy; getBits bits(pkt.payloadSize,pkt.payload); DUMMY(tableId,8); int section_syntax_indicator=bits.get(1); if(section_syntax_indicator) ADM_warning("Section Syntax is set to private\n"); if(bits.get(1)) // Marker { printf("[MpegTs] getNextPSI Missing 0 marker\n"); goto nextPack2; } bits.get(2); sectionLength=bits.get(12); // Section Length #if 1 if(sectionLength+3>pkt.payloadSize) { ADM_warning("[MpegTs] Multi Packet PSI ? sectionLength=%d, len=%d\n",sectionLength,pkt.payloadSize); goto nextPack2; } #endif transportStreamId=bits.get(16);// transportStreamId #ifdef VERBOSE_PSI printf("[MpegTs] Section length =%d\n",sectionLength); printf("[MpegTs] transportStreamId =%d\n",transportStreamId); #endif bits.skip(2); // ignored DUMMY(VersionNumber,5); // Version number DUMMY(CurrentNext,1); // Current Next indicator psi->count=bits.get(8); // Section number psi->countMax=bits.get(8); // Section last number #ifdef VERBOSE_PSI printf("[MpegTs] Count=%d CountMax=%d\n",psi->count,psi->countMax); #endif if(psi->count!=psi->countMax) return false; // we dont handle split psi at the moment uint8_t *c=pkt.payload+sectionLength-4+3; // Verify CRC uint32_t crc1=mpegTsCRC(pkt.payload,sectionLength-4+3); uint32_t crc2=(c[0]<<24)+(c[1]<<16)+(c[2]<<8)+c[3]; if(crc1!=crc2) { printf("[MpegTs] getNextPSI bad checksum :%04x vs %04x\n",crc1,crc2); goto nextPack2; } int hdr=(8+16+16+8+8+8)/8; int payloadsize=sectionLength-4-5; // Remove checksum & header if(payloadsize<4) goto nextPack2; psi->payloadSize=payloadsize; memcpy(psi->payload,pkt.payload+hdr,psi->payloadSize); return true; }