changeset 5193:abea2deab4d6

MPlayer now has a Microsoft RLE decoder to call its own...only supports 8-bit right now, but 4-bit is forthcoming
author melanson
date Tue, 19 Mar 2002 07:07:06 +0000
parents 0178b7a552d5
children c298c4a21d48
files codec-cfg.c codec-cfg.h etc/codecs.conf libmpcodecs/Makefile libmpcodecs/vd.c libmpcodecs/vd_msrle.c
diffstat 6 files changed, 197 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/codec-cfg.c	Tue Mar 19 00:11:44 2002 +0000
+++ b/codec-cfg.c	Tue Mar 19 07:07:06 2002 +0000
@@ -240,7 +240,7 @@
 		"vfwex",
 		"divx4",
 		"raw",
-		"rle",
+		"msrle",
 		"xanim",
 		"msvidc",
 		"fli",
--- a/codec-cfg.h	Tue Mar 19 00:11:44 2002 +0000
+++ b/codec-cfg.h	Tue Mar 19 07:07:06 2002 +0000
@@ -50,7 +50,7 @@
 #define VFM_VFWEX 6
 #define VFM_DIVX4 7
 #define VFM_RAW 8
-#define VFM_RLE 9
+#define VFM_MSRLE 9
 #define VFM_XANIM 10
 #define VFM_MSVIDC 11
 #define VFM_FLI 12
--- a/etc/codecs.conf	Tue Mar 19 00:11:44 2002 +0000
+++ b/etc/codecs.conf	Tue Mar 19 07:07:06 2002 +0000
@@ -299,12 +299,12 @@
   out BGR32,BGR24
 
 videocodec msrle
-  info "M$ RLE8"
+  info "Microsoft RLE"
   status working
   format 0x1
-  driver rle
-  dll "xa_rle8"
-  out BGR32,BGR24,BGR16,BGR15
+  format 0x2
+  driver msrle
+  out BGR32,BGR24
 
 videocodec fli
   info "Autodesk FLI/FLC Animation"
--- a/libmpcodecs/Makefile	Tue Mar 19 00:11:44 2002 +0000
+++ b/libmpcodecs/Makefile	Tue Mar 19 07:07:06 2002 +0000
@@ -3,7 +3,7 @@
 
 LIBNAME = libmpcodecs.a
 
-SRCS=dec_video.c vd.c vd_null.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_rle.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c
+SRCS=dec_video.c vd.c vd_null.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c
 
 ifeq ($(PNG),yes)
 SRCS += vd_mpng.c
--- a/libmpcodecs/vd.c	Tue Mar 19 00:11:44 2002 +0000
+++ b/libmpcodecs/vd.c	Tue Mar 19 07:07:06 2002 +0000
@@ -33,7 +33,7 @@
 extern vd_functions_t mpcodecs_vd_divx4;
 extern vd_functions_t mpcodecs_vd_raw;
 extern vd_functions_t mpcodecs_vd_xanim;
-extern vd_functions_t mpcodecs_vd_rle;
+extern vd_functions_t mpcodecs_vd_msrle;
 extern vd_functions_t mpcodecs_vd_msvidc;
 extern vd_functions_t mpcodecs_vd_fli;
 extern vd_functions_t mpcodecs_vd_qtrle;
@@ -66,7 +66,7 @@
 #endif
 #endif
         &mpcodecs_vd_raw,
-        &mpcodecs_vd_rle,
+        &mpcodecs_vd_msrle,
         &mpcodecs_vd_msvidc,
         &mpcodecs_vd_fli,
         &mpcodecs_vd_qtrle,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/vd_msrle.c	Tue Mar 19 07:07:06 2002 +0000
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "vd_internal.h"
+
+static vd_info_t info = {
+	"Microsoft RLE decoder",
+	"msrle",
+	VFM_MSRLE,
+	"A'rpi",
+	"Mike Melanson",
+	"native codec"
+};
+
+LIBVD_EXTERN(msrle)
+
+// to set/get/query special features/parameters
+static int control(sh_video_t *sh,int cmd,void* arg,...){
+    return CONTROL_UNKNOWN;
+}
+
+// init driver
+static int init(sh_video_t *sh){
+    return mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_BGR24);
+}
+
+// uninit driver
+static void uninit(sh_video_t *sh){
+}
+
+//mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
+
+#define FETCH_NEXT_STREAM_BYTE() \
+    if (stream_ptr >= encoded_size) \
+    { \
+      mp_msg(MSGT_DECVIDEO, MSGL_WARN, \
+        "MS RLE: stream ptr just went out of bounds (1)\n"); \
+      return; \
+    } \
+    stream_byte = encoded[stream_ptr++];
+
+
+void decode_msrle8(
+  unsigned char *encoded,
+  int encoded_size,
+  unsigned char *decoded,
+  int width,
+  int height,
+  unsigned char *palette_map,
+  int bytes_per_pixel)
+{
+  unsigned char r, g, b;
+  int stream_ptr = 0;
+  unsigned char rle_code;
+  unsigned char extra_byte;
+  unsigned char stream_byte;
+  int frame_size = width * height * bytes_per_pixel;
+  int pixel_ptr = 0;
+  int row_dec = width * bytes_per_pixel;
+  int row_ptr = (height - 1) * row_dec;
+
+/*
+static int counter = 0;
+int i;
+printf ("run %d: ", counter++);
+for (i = 0; i < 16; i++)
+  printf (" %02X", encoded[i]);
+printf ("\n");
+for (i = encoded_size - 16; i < encoded_size; i++)
+  printf (" (%d)%02X", i, encoded[i]);
+printf ("\n");
+*/
+
+  while (row_ptr >= 0)
+  {
+    FETCH_NEXT_STREAM_BYTE();
+    rle_code = stream_byte;
+    if (rle_code == 0)
+    {
+      // fetch the next byte to see how to handle escape code
+      FETCH_NEXT_STREAM_BYTE();
+      if (stream_byte == 0)
+      {
+        // line is done, goto the next one
+        row_ptr -= row_dec;
+        pixel_ptr = 0;
+      }
+      else if (stream_byte == 1)
+        // decode is done
+        return;
+      else if (stream_byte == 2)
+      {
+        // reposition frame decode coordinates
+        FETCH_NEXT_STREAM_BYTE();
+        pixel_ptr += stream_byte * bytes_per_pixel;
+        FETCH_NEXT_STREAM_BYTE();
+        row_ptr -= stream_byte * row_dec;
+      }
+      else
+      {
+        // copy pixels from encoded stream
+        if ((row_ptr + pixel_ptr + stream_byte * bytes_per_pixel > frame_size) ||
+            (row_ptr < 0))
+        {
+          mp_msg(MSGT_DECVIDEO, MSGL_WARN,
+            "MS RLE: frame ptr just went out of bounds (1)\n");
+          return;
+        }
+
+        rle_code = stream_byte;
+        extra_byte = stream_byte & 0x01;
+        if (stream_ptr + rle_code + extra_byte > encoded_size)
+        {
+          mp_msg(MSGT_DECVIDEO, MSGL_WARN,
+            "MS RLE: stream ptr just went out of bounds (2)\n");
+          return;
+        }
+
+        while (rle_code--)
+        {
+          r = palette_map[encoded[stream_ptr] * 4 + 2];
+          g = palette_map[encoded[stream_ptr] * 4 + 1];
+          b = palette_map[encoded[stream_ptr] * 4 + 0];
+          stream_ptr++;
+          decoded[row_ptr + pixel_ptr + 0] = b;
+          decoded[row_ptr + pixel_ptr + 1] = g;
+          decoded[row_ptr + pixel_ptr + 2] = r;
+          pixel_ptr += bytes_per_pixel;
+        }
+
+        // if the RLE code is odd, skip a byte in the stream
+        if (extra_byte)
+          stream_ptr++;
+      }
+    }
+    else
+    {
+      // decode a run of data
+      if ((row_ptr + pixel_ptr + stream_byte * bytes_per_pixel > frame_size) ||
+          (row_ptr < 0))
+      {
+        mp_msg(MSGT_DECVIDEO, MSGL_WARN,
+          "MS RLE: frame ptr just went out of bounds (2)\n");
+        return;
+      }
+
+      FETCH_NEXT_STREAM_BYTE();
+
+      r = palette_map[stream_byte * 4 + 2];
+      g = palette_map[stream_byte * 4 + 1];
+      b = palette_map[stream_byte * 4 + 0];
+      while(rle_code--)
+      {
+        decoded[row_ptr + pixel_ptr + 0] = b;
+        decoded[row_ptr + pixel_ptr + 1] = g;
+        decoded[row_ptr + pixel_ptr + 2] = r;
+        pixel_ptr += bytes_per_pixel;
+      }
+    }
+  }
+
+  // one last sanity check on the way out
+  if (stream_ptr < encoded_size)
+    mp_msg(MSGT_DECVIDEO, MSGL_WARN,
+      "MS RLE: ended frame decode with bytes left over (%d < %d)\n",
+      stream_ptr, encoded_size);
+}
+
+// decode a frame
+static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
+    mp_image_t* mpi;
+    if(len<=0) return NULL; // skipped frame
+    
+    mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_PRESERVE, 
+	sh->disp_w, sh->disp_h);
+    if(!mpi) return NULL;
+
+    decode_msrle8(
+        data,len, mpi->planes[0],
+        sh->disp_w, sh->disp_h,
+        (unsigned char *)sh->bih+40,
+        mpi->bpp/8);
+    
+    return mpi;
+}