changeset 3687:7fb817c9060b

This commit adds initial support for Quicktime Animation (RLE) video. It also fixes a FLI function name (FLI is not an AVI decoder).
author melanson
date Sun, 23 Dec 2001 22:20:46 +0000
parents bed6226ffb46
children b574619f912f
files Makefile codec-cfg.c codec-cfg.h dec_video.c etc/codecs.conf fli.c qtrle.c
diffstat 7 files changed, 166 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Dec 23 22:09:02 2001 +0000
+++ b/Makefile	Sun Dec 23 22:20:46 2001 +0000
@@ -22,7 +22,7 @@
 # a BSD compatible 'install' program
 INSTALL = install
 
-SRCS_COMMON = ima4.c xacodec.c cpudetect.c mp_msg.c ac3-iec958.c dec_audio.c dec_video.c msvidc.c cinepak.c fli.c codec-cfg.c cfgparser.c my_profile.c
+SRCS_COMMON = ima4.c xacodec.c cpudetect.c mp_msg.c ac3-iec958.c dec_audio.c dec_video.c msvidc.c cinepak.c fli.c qtrle.c codec-cfg.c cfgparser.c my_profile.c
 SRCS_MENCODER = mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/img_format.c
 SRCS_MPLAYER = mplayer.c $(SRCS_COMMON) find_sub.c subreader.c lirc_mp.c mixer.c spudec.c
 
--- a/codec-cfg.c	Sun Dec 23 22:09:02 2001 +0000
+++ b/codec-cfg.c	Sun Dec 23 22:20:46 2001 +0000
@@ -232,6 +232,7 @@
 		"msvidc",
 		"fli",
 		"cinepak",
+		"qtrle",
 		NULL
 	};
         char **drv=audioflag?audiodrv:videodrv;
--- a/codec-cfg.h	Sun Dec 23 22:09:02 2001 +0000
+++ b/codec-cfg.h	Sun Dec 23 22:20:46 2001 +0000
@@ -47,6 +47,7 @@
 #define VFM_MSVIDC 11
 #define VFM_FLI 12
 #define VFM_CINEPAK 13
+#define VFM_QTRLE 14
 
 #ifndef GUID_TYPE
 #define GUID_TYPE
--- a/dec_video.c	Sun Dec 23 22:09:02 2001 +0000
+++ b/dec_video.c	Sun Dec 23 22:20:46 2001 +0000
@@ -111,7 +111,7 @@
   unsigned char *palette_map,
   int bytes_per_pixel);
 
-void AVI_Decode_Fli(
+void Decode_Fli(
   unsigned char *encoded,
   int encoded_size,
   unsigned char *decoded,
@@ -119,6 +119,14 @@
   int height,
   int bytes_per_pixel);
 
+void qt_decode_rle(
+  unsigned char *encoded,
+  int encoded_size,
+  unsigned char *decoded,
+  int width,
+  int height,
+  int encoded_bpp,
+  int bytes_per_pixel);
 
 //**************************************************************************//
 //             The OpenDivX stuff:
@@ -522,16 +530,20 @@
      }
    }
    break;
- case VFM_MSVIDC: {
+ case VFM_MSVIDC:
+ case VFM_FLI:
+ case VFM_QTRLE:
+   {
    int bpp=((out_fmt&255)+7)/8; // RGB only
    sh_video->our_out_buffer = 
      (char*)memalign(64, sh_video->disp_w*sh_video->disp_h*bpp); // FIXME!!!
-   }
-   break;
- case VFM_FLI: {
-   int bpp=((out_fmt&255)+7)/8; // RGB only
-   sh_video->our_out_buffer = 
-     (char*)memalign(64, sh_video->disp_w*sh_video->disp_h*bpp); // FIXME!!!
+if ((sh_video->codec->driver == VFM_QTRLE) && (sh_video->bih->biBitCount != 24))
+  printf (
+    "    *** FYI: This Quicktime file is using %d-bit RLE Animation\n" \
+    "    encoding, which is not yet supported by MPlayer. But if you upload\n" \
+    "    this Quicktime file to the MPlayer FTP, the team could look at it.\n",
+    sh_video->bih->biBitCount);
+
    }
    break;
  }
@@ -785,12 +797,20 @@
     blit_frame = 3;
     break;
   case VFM_FLI:
-      AVI_Decode_Fli(
+    Decode_Fli(
         start, in_size, sh_video->our_out_buffer,
         sh_video->disp_w, sh_video->disp_h,
         ((out_fmt&255)+7)/8);
     blit_frame = 3;
     break;
+  case VFM_QTRLE:
+    qt_decode_rle(
+        start, in_size, sh_video->our_out_buffer,
+        sh_video->disp_w, sh_video->disp_h,
+        sh_video->bih->biBitCount,
+        ((out_fmt&255)+7)/8);
+    blit_frame = 3;
+    break;
 } // switch
 //------------------------ frame decoded. --------------------
 
--- a/etc/codecs.conf	Sun Dec 23 22:09:02 2001 +0000
+++ b/etc/codecs.conf	Sun Dec 23 22:20:46 2001 +0000
@@ -302,6 +302,14 @@
   driver msvidc
   out BGR32,BGR24
 
+videocodec qtrle
+  info "Quicktime Animation (RLE)"
+  status working
+; codec fourcc = "rle "
+  format 0x20656C72
+  driver qtrle
+  out BGR32,BGR24
+
 ; =============== WINDOWS DLL's ==============
 
 videocodec vp3
--- a/fli.c	Sun Dec 23 22:09:02 2001 +0000
+++ b/fli.c	Sun Dec 23 22:20:46 2001 +0000
@@ -25,7 +25,7 @@
 // to index 4-byte entries
 static unsigned char palette[256 * 4];
 
-void AVI_Decode_Fli(
+void Decode_Fli(
   unsigned char *encoded,
   int encoded_size,
   unsigned char *decoded,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qtrle.c	Sun Dec 23 22:20:46 2001 +0000
@@ -0,0 +1,125 @@
+/*
+    Quicktime Animation (RLE) Decoder for MPlayer
+
+    (C) 2001 Mike Melanson
+*/
+
+#include "config.h"
+#include "bswap.h"
+
+#define BE_16(x) (be2me_16(*(unsigned short *)(x)))
+#define BE_32(x) (be2me_32(*(unsigned int *)(x)))
+
+// 256 RGB entries; 25% of these bytes will be unused, but it's faster
+// to index 4-byte entries
+static unsigned char palette[256 * 4];
+
+void qt_decode_rle24(
+  unsigned char *encoded,
+  int encoded_size,
+  unsigned char *decoded,
+  int width,
+  int height,
+  int bytes_per_pixel)
+{
+  int stream_ptr;
+  int header;
+  int start_line;
+  int lines_to_change;
+  signed char rle_code;
+  int row_ptr, pixel_ptr;
+  int row_inc = bytes_per_pixel * width;
+  unsigned char r, g, b;
+
+  // check if this frame is even supposed to change
+  if (encoded_size < 8)
+    return;
+
+  // start after the chunk size
+  stream_ptr = 4;
+
+  // fetch the header
+  header = BE_16(&encoded[stream_ptr]);
+  stream_ptr += 2;
+
+  // if a header is present, fetch additional decoding parameters
+  if (header & 0x0008)
+  {
+    start_line = BE_16(&encoded[stream_ptr]);
+    stream_ptr += 4;
+    lines_to_change = BE_16(&encoded[stream_ptr]);
+    stream_ptr += 4;
+  }
+  else
+  {
+    start_line = 0;
+    lines_to_change = height;
+  }
+
+  row_ptr = row_inc * start_line;
+  while (lines_to_change--)
+  {
+    pixel_ptr = row_ptr + ((encoded[stream_ptr++] - 1) * bytes_per_pixel);
+
+    while ((rle_code = (signed char)encoded[stream_ptr++]) != -1)
+    {
+      if (rle_code == 0)
+        // there's another skip code in the stream
+        pixel_ptr += ((encoded[stream_ptr++] - 1) * bytes_per_pixel);
+      else if (rle_code < 0)
+      {
+        // decode the run length code
+        rle_code = -rle_code;
+        r = encoded[stream_ptr++];
+        g = encoded[stream_ptr++];
+        b = encoded[stream_ptr++];
+        while (rle_code--)
+        {
+          decoded[pixel_ptr++] = b;
+          decoded[pixel_ptr++] = g;
+          decoded[pixel_ptr++] = r;
+          if (bytes_per_pixel == 4)
+            pixel_ptr++;
+        }
+      }
+      else
+      {
+        // copy pixels directly to output
+        while (rle_code--)
+        {
+          decoded[pixel_ptr++] = encoded[stream_ptr + 2];
+          decoded[pixel_ptr++] = encoded[stream_ptr + 1];
+          decoded[pixel_ptr++] = encoded[stream_ptr + 0];
+          stream_ptr += 3;
+          if (bytes_per_pixel == 4)
+            pixel_ptr++;
+        }
+      }
+    }
+
+    row_ptr += row_inc;
+  }
+}
+
+void qt_decode_rle(
+  unsigned char *encoded,
+  int encoded_size,
+  unsigned char *decoded,
+  int width,
+  int height,
+  int encoded_bpp,
+  int bytes_per_pixel)
+{
+  switch (encoded_bpp)
+  {
+    case 24:
+      qt_decode_rle24(
+        encoded,
+        encoded_size,
+        decoded,
+        width,
+        height,
+        bytes_per_pixel);
+      break;
+  }
+}