John,
Sorry for the long delay in replying. The reason I'm uncomfortable with the scope of this change has to do with a future direction possibility that you couldn't know about (because it's not done & I haven't talked about it). Let me give that background:
When awk wrote the original stream code, HB only supported the DVD subset of mpeg video - program streams with fixed length, 2048 byte frames using a strictly defined subset of the ISO-13818-1 2000 spec with DVD-specific extensions such as the encapsulation headers for AC-3, DTS, LPCM & subtitles in a private-stream-1 PES. He wrote the TS code to make the right things happen given this infrastructure. Since that time the 2048 byte limit got removed to support Tivo files then the reader was generalized to handle multiple container formats and multiple demuxers for ffmpeg inputs.
The reader front end is now general enough that Transport Streams can be handled directly rather than going through the translation step. This is a big performance win since right now our the highest volume (HD) content has to go through *four* memory-to-memory copies before it ever gets to the decoder: i/o buf -> TS buf -> stream's PES buf -> reader's PS buf -> reader's PES buf. I've been working on a rewrite of the transport stream code that should get this down to one copy. It demuxes on PID, as per the spec, and decapsulates the PES header on the fly to end up with just the payload in a buf, all set to be sent downstream to the decoder. This is currently limping (I shelved it to smash 0.9.3 bugs). I don't want to make big changes to the architecture of the current TS-to-PS code because I hope it's about to go away. I really don't want to make any changes to the PS demuxer to support ISO-13818-1 2007 TS features because the TS's are going to take a completely different path.
As regards scanning all the 'unknown' PIDs, there are two reasons why we don't currently look at the descriptors in the PMT and scan all the Elementary Streams to see what they contain:
- The descriptors were frequently not there: when ATSC first rolled out the same companies made both the head-end encoder boxes and customer decoder boxes. Like Microsoft, these companies viewed standard conformance as a bug not a feature since interoperability destroys your lock-in. So, for example, jbrjake's cableco was (is?) sending AC-3 audio on a PID marked as type 6 with no descriptors at all.
- The descriptors were frequently misleading or wrong: Until the 2007 rev of the mpeg2 standard there were no standard descriptors for things like AC-3, DTS or PCM. Since the cableco's wanted to broadcast surround sound, both ATSC & DVB came up with their own descriptors to describe these formats but, since they did their work on different sides of an ocean, in a few important cases the same code points got used to mean completely different things. It would have been possible to resolve this by first deciding if we had DVB or ATSC then decode the descriptors using system-specific parsing routines but, given the previous problem, it seemed easier to kill two birds with one stone & just look at each PES to figure out what was in it (since the PES formats were governed by a single, uniform standard until bluray decided to really muck things up).
In the new code I'm trying to change this. The descriptors are used to type PIDs and we only look into the PES if we don't have an audio and/or video stream.
As far as mis-typing audio, both the AC-3 & DTS standards talk at length about alias issues with their sync pattern. Both standards have a CRC for the entire frame (AC-3 has two CRCs - one for 5/8th of the frame & one for the entire thing). Their suggested resync algorithm is: If you've lost or never had sync find a sync pattern then, if and only if the frame CRC verifies, declare sync. If you have sync, you can just check that the next frame starts with a sync pattern (but it really doesn't cost anything to check CRC since you have to haul the bytes into your cache to decode them). When I saw eddy's 'check sync twice' addition to scan, I added a 'check audio frame crc' item to my todo list in the hope that we can eventually validate sync the way the standard suggests.
As far as the PCR increment, the PCR is only used to detect clock discontinuities. As long as it increments at a rate that doesn't cause it to pass the real PCR (time going backward is always regarded as a discontinuity but it has to jump forward by more than 500ms to be considered a discontinuity & PCR's have to show up at least every 100ms) no jitter is introduced because the old-to-new timing offset is derived from some media stream's PTS differences. The increment wasn't arbitrary - in the STD the PCR is incremented by the arriving bits of the data stream. Since the transmitter is fixed rate and that rate is announced in the adaptation header that contains the PCR, the receiver puts that rate into its VCO then feeds its PLL with the leading edge of the arriving bits. Since the PCR advances by a fixed amount for a fixed number of bits & we're generating (roughly) fixed length 2048 byte PS packets, you end up with a fixed increment to the PCR for each PS packet generated. But, all that being said, your way of handling the PCR is much simpler & cleaner - it never occurred to me that the PACK header could simply be left off when we didn't have a PCR - very nice!
Anyway, my preference for the upcoming release would be to be to put in your PAT, PMT & PCR fixes but do a simpler version of the type 0x83 interleaved stream handling that leaves the ps muxer as it is. To just extract the AC-3, I think most of the runtime work could be done with a small addition to hb_ts_stream_decode to not accumulate PES data for this type until it got 'start' with an 0x76 in the stream ID extension. (I'll try to code this up to make it clearer.)