This is the README FILE of DIMP version 0.9: a multithreaded MPEG player for 
OS/2 Warp 3.0 using DIVE (Direct Interface to Video Extensions) written by:

  Peter Van Geit
  Student at the University of Ghent, Belgium (the small country between France & 
                                                  Germany)
  vg@iris.elis.rug.ac.be

Please send your comments/suggestions/questions to the above adress.

0] CONTENTS

  1] Product description
  2] Copyright notice
  3] Contents
    3.1] Executables
    3.2] Source code
  4] Writing your own MPEG player
  5] How the player works
  6] VIDEO.DLL description
  7] DITHER.DLL description
  8] DIVE.DLL description
  9] Player performance

1] PRODUCT DESCRIPTION
  
  This player is a port of the Berkeley Plateau Research Group MPEG-1
  player version 2.0. It implements the standard described in the
  Committee Draft ISO/IEC CD 11172. This UNIX-player uses X-Windows to 
  display the video sequence. The player doesn't implement real-time 
  synchronisation nor does it supports audio streams. It is shipped with 
  various dithering algorythms. Until now the player has been ported to
  several platforms including DOS and Windows. The source can be freely
  obtained via anonymous ftp from "toe.cs.berkeley.edu" in 
  "/pub/multimedia/mpeg/mpeg-2.0.tar.Z"

  Below I include the copyright notice of the original player:

/*
 * Copyright (c) 1992 The Regents of the University of California.
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice and the following
 * two paragraphs appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

  I ported the player to IBM OS/2 Warp 3.0 and named it DIVE (DIve MPeg). It
  consists of three parts:

    video.dll : a dynamic link library which contains the MPEG decoding routines
    dither.dll: a dynamic link library which includes many dithering algorythms
    dimp.exe  : the player. It implements the interface and manages the above dll's

  The two above dll's are completely independent and REUSABLE (definition files &
  headers needed to use them are included) in other applications, the player 
  dimp.exe is nothing more than a demonstration of how to use these libraries. 
  Furthermore I think this player is a very good example showing you how to use 
  DIVE. The player runs under Presentation Manager and has a very functional 
  interface. It uses two threads: one to respond to user actions and one thread that 
  handles the decoding. The player uses the dive.dll dynamic link library for fast 
  screen access. DIVE functionality includes:  

    Direct video frame buffer access
    Video hardware interrogation
    Color space conversion (=dithering)
    Palette conversion
    Auto-resizing

  The player comes in two versions:

    dimp.exe  : optimize for speed
    dimp2.exe : generates extensive statistical information

  You can start the players at the command line or use drape-and-drop

2] COPYRIGHT NOTICE

  The changes I made to the original source (which is freely distributable) as 
  well as the new source files I wrote are FREELY distributable/modifiable/
  usable, EXCEPT for commercial goals. Also the dynamic link libraries 
  "video.dll","video2.dll" and "dither.dll" may be used FREELY, EXCEPT for 
  commercial goals. The author of this player shall not be held responsible in 
  any way for any damage caused by this player.

3] CONTENTS

  3.1] PLAYER EXECUTABLES: (dimpexe.zip)

    dimp.exe  : needs dither.dll and video.dll
                (This one is optimized for speed)

    dimp2.exe : needs dither.dll and video2.dll 
                (This one generates extensive statistical output)

  3.1] PLAYER SOURCE FILES: (dimpsrc.zip)
    
    dimp.h    : player header
    dimp.c    : player main file
    dimp.def  : player definition file
    dimp.rc   : player resource file
    
    *.ico     : various icons used by the player
    *.dlg     : various dialogs used by the player

    dither.dll: dynamic link library containing dithering routines
                (included in dimpexe.zip)
    dither.def: corresponding definition file (used to produce the import
                library which is linked with the player)
    pvgdith.h : corresponding header file containing the declarations of the
                functions implemented in dither.dll used by the player
                (this file must be #included by the player)

    video.dll : dynamic link library containg MPEG decoding routines
                (included in dimpexe.zip)
    video2.dll: idem but this one generates statistical info
                (included in dimpexe.zip)
    video.def : corresponding definition file (used to produce the import
                library which is linked with the player)
    video2.def: idem but for video2.dll
    pvgvideo.h: corresponding header file containing the declarations of the
                functions implemented in video(2).dll used by the player
                (this file must be #included by the player)

    dimp.mak  : player make file 

  3.3] Tools used

  I wrote this player under IBM OS/2 Warp 3.0 with the IBM C/Set++ 2.1 compiler
  (latest CSD's) and the IBM Warp 3.0 Toolkit. Therefore if you use the same
  configuration everything should compile without problems.

  You can generate an executable running "makeall.cmd" after customizing the
  makefile "dimp.mak"
                                                          
4] WRITING YOUR OWN MPEG PLAYER

  You can write your own MPEG player in just a few hours by using the 
  routines provided in the dither.dll and video(2).dll dynamic link 
  libraries (see below for a description of the routines). All you need 
  to do is to:
  
    1) include "pvgdith.h" and "pvgvideo.h" in your player source file
    
    2) generate the import libraries "dither.lib" and "video.lib" via:
      
      implib dither.lib dither.def
      implib video.lib video.def (use video2.def to generate stat. info)

    3) link the import libraries with the object code of your own player

  See "dimp.c" and "dimp.mak" for more information on the usage

  You don't need it for the usage of the libraries but if you would be 
  interested in the source code of the video(2) and dither dynamic link 
  libraries, send me a mail at my adress mentionned above.

5] HOW THE PLAYER WORKS
  
   EXECUTABLE          ACTIONS       DYN. LNK. LIBRARIES

  +----------+        initialize        +------------+
  | DIMP.EXE |      ---------------->   | VIDEO.DLL  |
  | ( MPEG   |      decode next frame   | ( MPEG     |
  | player)  |      ---------------->   |  decoding) |
  |          |    24-bit decoded frame  |            |
  |          |      <----------------   +------------+
  |          |
  |          |         initialize       +------------+
  |          |      ---------------->   | DITHER.DLL |
  |          |    24-bit decoded frame  | ( 8-bit    |
  |          |      ---------------->   | dithering) |
  |          |    8-bit dithered frame  |            |
  |          |      <----------------   +------------+
  |          |
  |          |         initialize       +------------+
  |          |      ---------------->   |  DIVE.DLL  |           DISPLAY
  |          |    8-bit dithered frame  |            |  -------> HARDWARE
  +----------+      ---------------->   +------------+
  
6] VIDEO.DLL DESCRIPTION

  The video.dll (video2.dll for the statistical version) dynamic link library
  implements the folowing datatypes and functions which are declared in 
  "pvgvideo.h". See "dimp.c" to know in which order the routines functions
  should be called.

  void init_tables();

    Function called first to initialize the Huffman tables used for decoding
  
  VidStream 
    
    Datatype that represents a MPEG-video sequence
  
  VidStream * NewVidStream (char * fname, int bufLength, int loop, int quiet,
                            
                            int noDisplay, int ditherType);

    Function called at the beginning to create a new video sequence structure
    which contains info/datastructures needed during decoding:

    fname       : the filename of the MPG-file
    bufLength   : 80000 should do fine
    loop        : 0 : stop at the end of the video sequence
                  1 : restart from the beginning at the end of the sequence
    noDisplay   : ignore this parameter
    ditherType  : the dithering method used (MPEG-decoding needs to know this)
                  see 7] for a description of possible values for this parameter
    return value: pointer to the video sequence structure. This pointer should
                  be passed to the function below after decoding is done:

  void DestroyVidStream (VidStream *astream );   

    Destroys the allocated datastructures needed during decoding

  typedef int TimeStamp;

    Datatype used for generating timing info
  
  int mpegVidRsrc (TimeStamp time_stamp , VidStream *vid_stream, char **
                  pditherFlags);

    Decodes the next (whichever comes first):
      
      MPEG slice 
      MPEG frame
      MB_QUANTUM macro-blocks (declared in pvgvideo.h)
  
    time_stamp  : always 0 should do fine
    vid_stream  : the pointer returned by NewVidStream
    pditherFlags: will be initialized with the correct values. This parameter
                  should afterwards be passed through DoDitherImage (see below)
                  You only need to declare it.
    return value:

    (1) When mpegVidRsrc is called the FIRST time:

    MPEG_INFO 
      mpeg stream was valid + info about mpeg-video is available 
      (cfr. dimp.c where you can find the info)
    MPEG_INVALID 
      mpeg stream was not valid
    MPEG_NULL 2
      NewVidStream was NOT called first
 
    (2) When mpegVidRsrc is called after the first time: 

    MPEG_MB_QUANTUM
      MB_QUANTUM of macroblocks decoded 
    MPEG_SLICE
      a slice was decoded 
    MPEG_FRAME_SKIP
      a frame encountered that was labeled as to be skipped 
    MPEG_FRAME_NODISP 
      a frame decoded that must not be displayed yet 
    MPEG_FRAME_DISP 
      a frame decoded that must be displayed 
    MPEG_ERROR 
      an error was encountered, but processing can continue 
    MPEG_DONE_DISP
      end of mpeg-video encountered, display last frame
    MPEG_DONE_NODISP 
      end of mpeg-video encountered, no frame left to display 

  void ResetVidStream(void);
    
    Called after decoding the last frame when looping

  void VidStreamFlags(int type, int loop, int noDisplay);

    Called whenever the method of dithering is changed
    type      : the new dithering method to be used (see below for possible 
                values)
    loop      : ignore this one
    noDisplay : ignore this one

  void TogglePFlag(void);

    Toggles decoding of P-frames on/off. Initially it will be on.
  
  void ToggleBFlag(void);

    Toggles decoding of B-frames on/off. Initially it will be on.
    With these two functions you can accelerate the video sequence by decoding:
    
      I/P/B frames (all frames)                            -> normal decoding
      I/P frames only (call ToggleBFlag())                 -> faster decoding
      I frames only (call TogglePFlag() and ToggleBFlag()) -> fastest decoding
  
    PS: P-frames are needed to decode B-frames correctly 

  typedef void FNSTAT();

    Used in the statistical version of the player (which generates extensive
    stat. info about the MPEG video stream currently being decoded)

  typedef FNSTAT * PFNSTAT;

    Pointer to the previous function type

  void PassStats(int showEachFlg, PFNSTAT ShowOneStat, PFNSTAT ShowAllStats);

    Used to pass the functions:
      
      *ShowOneStat  : will be called by decode2.dll when stat. information is
                     available about the current frame
      *ShowAllStats : will be called by decode2.dll when stat. information is
                     available about the current video sequence
      showEachFlag : 1 : *ShowOneStat is called after decoding each frame
                     0 : ShowOneStat is never called
  Statval;

    Structure used to pass statistical info (see pvgvideo.h for details)

  void GetStats(Statval ** stat);

    Call this function to get statistical info about the current frame/whole
    sequence after it is ready (when ShoneOne(All)Stat(s) is called)

7] DITHER.DLL DESCRIPTION

  The dither.dll dynamic link library implements functions/data types 
  declared in "pvgdith.h". Look at "dimp.c" to know in which order you should
  call these functions:

  void InitDither(int type, int lum_range, int cr_range, int cb_range, PBYTE
                  * pPalette, PBYTE *pPal2);

    Initializes the necessary data structures needed during dithering
    type   : the used dither method. Here follows a list of possible dither types:
      
      (1)  8-bit color dithering methods
      HYBRID_DITHER 
      HYBRID2_DITHER
      FS4_DITHER
      FS2_DITHER
      FS2FAST_DITHER 
      ORDERED_DITHER 
      ORDERED2_DITHER 
      MBORDERED_DITHER 
      Twox2_DITHER
      
      (2) 7-bit gray dithering 
      GRAY_DITHER 

      (3) Full color dithering
      FULL_COLOR_DITHER 

      (4) No dithering is performed
      NO_DITHER 
      
      (5) Black/White dithering
      MONO_DITHER 
      MONO_THRESHOLD 

    lum_range : 8 will do fine
    cr_range  : 4 will do fine
    cb_range  : 4 will do fine
    pPalette  : OS/2 256 color palette (256 4-byte entries, first three bytes
                correspond with the R,G and B values.
    pPal2     : exact copy of the previous parameter

    void TerminateDither (PBYTE pPalette, PBYTE pPal2);

      Must be called at the end to free all allocated resources used during
      dithering

    void DoDitherImage(unsigned char *l, unsigned char *Cr, unsigned char *Cb,
    unsigned char *disp, int w, int h, char * f);

      Dithers a 24-bit image (2x2 color subsampled) using the current dithering
      method

      l     : pointer to the luminance pane (use "current->luminance" field
              of your VidStream structure)
      Cr    : pointer to the Cr color pane (use "current->Cr" field of your 
              VidStream structure)
      Cb    : pointer to the Cb color pane (use "current->Cb" field of your 
              VidStream structure)
      disp  : pointer to the buffer where the image should be dithered to
      w     : width of the image in pixels (use "mb_width" field of your
              VidStream structure multiplied by 16)
      h     : height of the image in pixels (use "mb_height" field of your
              VidStream structure multiplied by 16)
      f     : dither-flags returned by mpegVidRsrc (use the ditherFlag parameter
              returned by mpegVidRsrc)

8] DIVE.DLL DESCRIPTION                                

  Information about the routines of this dynamic link library can be found
  in the documentation provided with the IBM Warp 3.0 Toolkit. For info
  on using the routines cfr. "dimp.c".

9] PLAYER PERFORMANCE

  I tested the player with many MPEG sequences. Most of them, except for a few,
  seemed to work well. Via EXTRA (Execution Trace Analyzer, included in the
  Warp Toolkit) I was able to determine the percentage processor usage (PPU) of 
  the three components of the player: (25sec video, dither method = 
  ORDERED_DITHER)

  mpg-file ->  bobo    mjackson whacking iicm     waterski son

  dimp.exe     11      13       12       10       13       12
  video.dll    68      64       66       68       64       62
  dither.dll   20      23       22       22       23       25

  It seams that the PPU is relatively constant for different MPEG sequences.
  The decoding (video.dll) takes the biggest part, but also the dithering
  ocupies the CPU 20 to 25% of the time. The overhead of the player dimp.exe
  which includes DIVE (palette conversion + resizing + blitting) is minimal.

  Secondly I analyzed the PPU when using different dithering techniques:

  dither method -> ordered ordered2 gray fs2 fs4 fs2fast hybrid hybrid2 mbordered
  
  dimp.exe         11      13       15   7   6   9       12     10      10
  video.dll        70      64       83   40  33  50      74     60      65
  dither.dll       19      23       2    52  61  41      14     30      24

  Here we see big variations in the PPU of the dither.dll module. Fastest is gray-
  dithering which translates luminance values directly to gray shades. fs4-
  dithering delivers good quality but is the slowest. Fastest 8-bit color dithering
  is hybrid while maintaining reasonable quality.

Any comments/bug reports/suggestions are appreciated. Please send them to the 
mail-adress mentionned before.

Peter Van Geit
11 juli 1995