PI-Video

From MultimediaWiki
Jump to navigation Jump to search
  • FOURCC: PIVC
  • Company: Nordic Company

This is a rather simple quadtree-based paletted video codec with its name probably coming from its developer initials.

The image is split into squares of 4nx4n pixels large for the closest match with frame dimensions (e.g. 256x256 squares for 320x240 video) that get divided into 16 parts with a flag telling if the part is fill/skip or should be further subdivided (or coded as raw for 4x4 squares). Flags and pixel data are grouped into separate data chunks inside the frame.

Frame consists of the following data: 32-bit frame flags, 32-bit frame size (not counting frame flags), tile flags data (starting with 32-bit size), and pixel data. There are two known frame flags: bit 0 signals inter frame coding and bit 1 signals that pixel data is LZW-compressed.

Simplified decoding process:

 tile_size = 0x4000;
 do {
   tile_size >>= 2;
 } while (tile_size >= max(width, height))
 tile_size <<= 2;
 
 cur_tile_size = tile_size;
 for each tile in image
   decode_tile(tile_pos, cur_tile_size);
 
 decode_tile(pos, cur_tile_size) {
   flags = get_16bit_le(flags_data);
   for each one of 16 subparts in tile {
     if part is inside the image area {
       if ((flag & 1) == 0) {
          pix = get_byte(pixel_data);
          if (intra || pix != 0) {
              fill subpart with pix value
          }
       } else if (cur_tile_size > 4) {
          decode_tile(subpart, cur_tile_size >> 2);
       } else {
          fill 4x4 block with 16 values read from pixel data
       }
     }
     flags >>= 1;
   }
 }

LZW differs from the conventional algorithm used e.g. in GIF. First, there is single escape code 256 which is followed by two-bit mode (0 - end of stream, 1 - restart, 2 - increase current index bits). Second, index bits increase is manual because inter-frames keep using previous LZW dictionary to decode pixel data, so while they start decoding with 9-bit indices, they may bump it a couple of time and start reading e.g. 11-bit indices.

Additionally codec uses fixed palette stored in the middle of its extradata (first 32-bit word of it seems to be the header size before actual palette starts).