0

I have a basic RIFF AVI made in the early 1990's and I'm tyring to make a basic video player in native VB/C# code. According to the header, it uses the old MS RLE codec. The bitmap header in the AVI indicates it is RLE8 compressed.

bitmap rle

  1. the is the result of the raw 'xxdc' compressed data written to a bitmap pragmatically created from scratch and opened in Windows Photo Viewer
  2. the same frame extracted using VirtualDub
  3. the code below decompressing the RLE8 bitmap

The problem is both the code below AND Windows does the same thing, portions are missing which leads me to the following from an old VirtualDub blog post;

(GDI's RLE isn't the same as AVI's RLE)".

The problem is I cannot find the difference :(. I cannot find any sources on the internet or any material on MSDN.

I ported an RLE8 decompression sample from htttp://dirkbertels.net/computing/bitmap_decompression.php to VB (bitmap structures omitted for brevity). It works a treat. Problem is it doesn't work correctly for AVI frames that use RLE8.

        Dim firstByte As Byte
        Dim secondByte As Byte
        Dim currX As UInteger = 0
        Dim currY As UInteger = 0
        Dim i As UInteger

        Do
            firstByte = br.ReadByte
            If 0 <> firstByte Then
                ' Encoded Mode
                secondByte = br.ReadByte
                For i = 0 To firstByte - 1
                    frame.SetPixel(currX, currY, _bitmap.biClut(secondByte))
                    currX += 1
                Next i
            Else
                ' Absolute Mode
                firstByte = br.ReadByte ' store next byte
                Select Case firstByte
                    Case 0 ' new line
                        currX = 0
                        currY += 1 ' move cursor to beginning of next line
                    Case 1 ' end of bitmap
                        Exit Do
                    Case 2 ' delta = goto X and Y
                        currX += CInt(br.ReadByte) ' read byte and add value to x value
                        currY += CInt(br.ReadByte) ' read byte and add value to y value
                    Case Else
                        For i = 0 To firstByte - 1
                            secondByte = br.ReadByte
                            frame.SetPixel(currX, currY, _bitmap.biClut(secondByte))
                            currX += 1
                        Next i
                        'If 0 <> (firstByte And &H1) Then
                        '    br.ReadByte()
                        'End If
                        If firstByte And &H1 Then ' if the run doesn't end on a word boundary,
                            br.ReadByte()
                        End If
                End Select
            End If
        Loop

I'm at a loss now as to how VirtualDub, FFMPEG and others do it without using the old MSRLE.DLL codec... Does anybody have any ideas?

Alex Guerin
  • 2,336
  • 10
  • 36
  • 53

1 Answers1

0

I found the solution so I'll answer it here so others like me have a starting point.

The frame data WAS decompressing correctly. The issue was me not following the RIFF AVI specs correctly. For my video, each frame is decompressed over the previous.

Alex Guerin
  • 2,336
  • 10
  • 36
  • 53