Hi,
software decoding/detection of old ac3 streams seems to be impossible with ffmpeg. To fix this I made a modification so that recognition works.
Can someone with more ac3 stream knowledge can have a look at this diff ? This vdr-1.3.22 apply with some offset to vdr-1.3.32 and still works.
Hi,
Stefan Lucke wrote:
software decoding/detection of old ac3 streams seems to be impossible with ffmpeg. To fix this I made a modification so that recognition works.
Can someone with more ac3 stream knowledge can have a look at this diff ? This vdr-1.3.22 apply with some offset to vdr-1.3.32 and still works.
Length += 4;
*e++ = 0x80; //substream id
*e++ = 0x00; // nr of ac3 frames (sea AppendSubStream
*e++ = 0x00;
*e++ = 0x00; //??
The first byte (byte 0) is correct: 0x80 means the first dolby track.
Then, to be precise, byte 1 specifies the number of AC3 frames starting in this packet. It must at least be 0x01, even if there is no AC3 frame starting (see below), i. e. the packet contains just continuation data of the current large AC3 frame which was started in a previous packet.
Byte 2 and 3 specifiy the offset in bytes from the last byte of the substream header to the first byte of a starting AC3 frame in this packet. I. e., 0x00 0x01 specifies, that byte 4 (the first byte following the substream header) will be 0x0b (the first byte of the syncword, which starts a new AC3 frame). A value of 0x00 0x00 means, that no AC3 frame starts in this packet (i. e., just continuation data, see above).
So, to create a proper substream header, one must "read" the stream, find sync words, use the frame size and calculate frame count and offset, which is a not a trivial task.
A further problem may arise by enlarging the packets to be able to append the substream header: VDR's packets should never be larger than IPACKS (= 2048 bytes). This means, each packet which is larger than 2044 bytes needs to be split into two packets to enforce this rule.
Maybe the code of cDolbyRepacker could be reused to transform these old streams into the new format on the fly. Just feed it's Repack() method with the original PES packets and you'll find the repacked packets in the specified result buffer. BTW: whenever a DeviceClear() happens, cDolbyRepacker should be Reset(), too.
Bye.