[Matroska-devel] Re: MPEG2 in MKV!

Gabest gabest at freemail.hu
Sun Nov 2 02:03:11 CET 2003


> Yeah yeah, I was lazy (no, I was ignorant). First I didn't know that the
> SPU packets were inside a MPEG stream, and I just used the difference
> between two entries in the .idx file as the duration.
>
> How do I extract the duration from the SPU packets? I should probably
> look at mplayer's sources, but maybe you have a quick explanation ;)

Here is my stripped down function getting the properties of the subpic. The
two int args are the first two WORDs in the data. A bit redundant though,
since it could be extracted from lpData, but this function doesn't have to
know about the full subpic format :) Anyway, the "delay" variable will hold
the duration at the end.

void CVobSubImage::GetPacketInfo(BYTE* lpData, int packetsize, int datasize)
{
    int i, nextctrlblk = datasize;
    WORD pal, tr;
    do
    {
        i = nextctrlblk;
        int t = (lpData[i] << 8) | lpData[i+1]; i += 2;
        nextctrlblk = (lpData[i] << 8) | lpData[i+1]; i += 2;
        if(nextctrlblk > packetsize || nextctrlblk < datasize)
        {
            ASSERT(0);
            return;
        }
        bool fBreak = false;
        while(!fBreak)
        {
            int len = 0;
            switch(lpData[i])
            {
                case 0x00: len = 0; break;
                case 0x01: len = 0; break;
                case 0x02: len = 0; break;
                case 0x03: len = 2; break;
                case 0x04: len = 2; break;
                case 0x05: len = 6; break;
                case 0x06: len = 4; break;
                default: len = 0; break;
            }
            if(i+len >= packetsize)
            {
                TRACE(_T("Warning: Wrong subpicture parameter block
ending\n"));
                break;
            }
            switch(lpData[i++])
            {
                case 0x00: // forced start displaying
                    fForced = true;
                    break;
                case 0x01: // start displaying
                    fForced = false;
                    break;
                case 0x02: // stop displaying
                    delay = 1024 * t / 90;
                    break;
                // ...
                case 0xff: // end of ctrlblk
                    fBreak = true;
                    continue;
                default: // skip this ctrlblk
                    fBreak = true;
                    break;
                }
            }
        }
        while(i <= nextctrlblk && i < packetsize);
}

> > I think we should really put all data into one block for one subtitle...
> > Just like in the case of realmedia, when I tried to store fragments of a
> > frame into multiple blocks, but then was corrected.
>
> Ok, sounds reasonable. One entry corresponds to one line in the .idx
> file, or should we just ignore those lines and parse the MPEG stream and
> use those timestamps?

No. The additional 2k blocks will follow the entry point given in the idx,
but not right after, just in the order they were extracted from the dvd. You
can tell which by the stream id and where it ends by looking at the PES
packet length or the subpic's own packet length.

> > (3rd little problem: where do I find zlib for vc7? I know I could
probably
> > convert the sources at www.gzip.org/zlib, but I though it was easier to
ask
> > first :)
>
> I have no idea :)

Hm... anyone else?




More information about the Matroska-devel mailing list