PDA

View Full Version : How to decompress rle-subpicturestreams? Please help!!


Chatwalker
13th November 2002, 13:43
Hi @ all

I want decompress run-lenght-encodet Subpicturestreams to BMP.
I'am able to read each subtitle PES packet from the VOB into an array (Subtitle.Packet[]) and seperate
its controlsequences with the code below. Now i have all information about the subtitle including
the Offsets to both run-lenght-encodet pictures (interlaced) in the array.

Can anyone explain how to decompress the picture to BMP? I found only 1 document on the internet and with
this i was'nt able to do.

Regards
Chatwalker




DataSize = CDbl(Subtitle.Packet(2)) * 256 + Subtitle.Packet(3)
Pointer = DataSize 'first Control-Sequence

'control sequence
cseqNext = 0
cseqNextOld = 0

Do
cseqNextOld = cseqNext
cseqDate = CDbl(Subtitle.Packet(Pointer)) * 256 + Subtitle.Packet(Pointer + 1)
cseqNext = CDbl(Subtitle.Packet(Pointer + 2)) * 256 + Subtitle.Packet(Pointer + 3)
Pointer = Pointer + 4


Do
cseqCommand = Subtitle.Packet(Pointer)

Select Case cseqCommand
'forced Start (1Byte)
Case 0:
Pointer = Pointer + 1
StartTime = Frames2Time(((Int((Subtitle.PTS - VideoStreamDetails.PTS) / 90) + (cseqDate * 10)) * VideoStreamDetails.Framerate) / 1000, VideoStreamDetails.Framerate)
Forced = "Yes"

'non-forced Start (1Byte)
Case 1:
Pointer = Pointer + 1
StartTime = Frames2Time(((Int((Subtitle.PTS - VideoStreamDetails.PTS) / 90) + (cseqDate * 10)) * VideoStreamDetails.Framerate) / 1000, VideoStreamDetails.Framerate)
Forced = "No"

'Stop (1Byte)
Case 2:
Pointer = Pointer + 1
StopTime = Frames2Time(((Int((Subtitle.PTS - VideoStreamDetails.PTS) / 90) + (cseqDate * 10)) * VideoStreamDetails.Framerate) / 1000, VideoStreamDetails.Framerate)

'Color (1Byte + 2Bytes Arg)
Case 3:
Pointer = Pointer + 3

'Transparancy (1Byte + 2Bytes Arg)
Case 4:
Pointer = Pointer + 3

'SubSize (1Byte + 6Bytes Arg)
Case 5:
Left = CLng(Subtitle.Packet(Pointer + 1) * 16) + Int(Subtitle.Packet(Pointer + 2) / 16)
Right = CLng(Subtitle.Packet(Pointer + 2) Mod 16) * 256 + Subtitle.Packet(Pointer + 3)

Top = CLng(Subtitle.Packet(Pointer + 4) * 16) + Int(Subtitle.Packet(Pointer + 5) / 16)
Bottom = CLng(Subtitle.Packet(Pointer + 5) Mod 16) * 256 + Subtitle.Packet(Pointer + 6)

SubSizeX = LastColumn - FirstColumn + 1
SubSizeY = LastLine - FirstLine + 1
Pointer = Pointer + 7

'Offset (1Byte + 4Bytes Arg)
Case 6:
FirstOffset = CDbl(Subtitle.Packet(Pointer + 1)) * 256 + Subtitle.Packet(Pointer + 2)
SecondOffset = CDbl(Subtitle.Packet(Pointer + 3)) * 256 + Subtitle.Packet(Pointer + 4)
Pointer = Pointer + 5

'End (1Byte)
Case 255:
Pointer = Pointer + 1

'Unknown Command
Case Else:
Exit Sub

End Select
Loop While cseqCommand <> 255

Loop Until (cseqNext = cseqNextOld) Or (Pointer >= Subtitle.PacketLenght - 1)

llemor
13th November 2002, 22:58
Try this site:

http://www.shrinkwrapvb.com

mpucoder
14th November 2002, 05:28
You'll need to add a case 7, the CHG_COLCON command. Try also looking at http://mpucoder.kewlhair.com/DVD/spu.html

Chatwalker
15th November 2002, 13:16
Hi

Thank you for your replies!

@Ilemor
At http://www.shrinkwrapvb.com i did'nt found any information about subtitle. I'am wrong?

@mpucoder
Is there a LFCR for each line in the encoded subpicture, or do i have to check if the end of line is reached?

Regards
Chatwalker

mpucoder
17th November 2002, 00:14
The bitmaps do not have any bit patterns to denote end of line. You have to keep track of that yourself, and account for the 4-bit fill when needed. Also remember that each block is a television field, the lines are interlaced, so that when one line is decoded, you start decoding 2 lines after, not one.

FatBastard
19th November 2002, 09:27
Hi!

All Infos i was able to find in net about SubPictures:

http://sam.zoy.org/doc/dvd/subtitles/
http://members.aol.com/mpucoder/DVD/spu.html
http://dvd.sourceforge.net/spu_notes
http://www.mpeg.org/MPEG/DVD/Book_B/Subpic.html

You should download and watch the sourcecode pack of SubRip (at Doom9īs Source Code Download page). Itīs Pascal/Delphi Code but easy to understand (unless the french comments).
In the Docs Subdir there is a document which describes the decoding procedure, too.

You can also look at the X-Mpeg Source Code (download from same position as above). Itīs C++ but it is a very nice implementation.

I think you should first watch the implementations which are done already and then try to code it in VB.

Hope this will help and that I am not too late :)

BTW: Thx to mpucoder for all the infos about dvd!

Bye FatBastard