RIFF AVI RLE与GDI RLE不同

时间:2015-03-10 05:27:44

标签: c# vb.net bitmap avi riff

我有一个基本的RIFF AVI在1990年代早期制作,我正在使用本机VB / C#代码制作一个基本的视频播放器。根据标题,它使用旧的MS RLE编解码器。 AVI中的位图标题表示它是RLE8压缩的。

bitmap rle

  1. 是原始'xxdc'压缩数据写入从头开始实际创建并在Windows Photo Viewer中打开的位图的结果
  2. 使用VirtualDub提取的相同帧
  3. 下面的代码解压缩RLE8位图
  4. 问题是下面的代码和Windows做同样的事情,缺少部分导致我从旧的VirtualDub blog post得到以下内容;

      

    (GDI的RLE与AVI的RLE不同)“。

    问题是我找不到区别:(。我在互联网上找不到任何来源或MSDN上的任何资料。

    我将一个RLE8解压缩样本从httdp://dirkbertels.net/computing/bitmap_decompression.php移植到VB(为简洁起见省略了位图结构)。它是一种享受。问题是它对使用RLE8的AVI帧无法正常工作。

            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
    

    我现在不知道VirtualDub,FFMPEG和其他人如何在不使用旧的MSRLE.DLL编解码器的情况下这样做...有没有人有任何想法?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,所以我会在这里回答,所以像我这样的人有一个起点。

帧数据WAS正确解压缩。问题是我没有正确遵循RIFF AVI规范。对于我的视频,每个帧都会在前一个帧中解压缩。