Escape 124: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
(fill in)
 
m (changed the sample location)
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
The ESCAPE 124 codec is a slightly enhanced version of Eidos' previous [Escape 122] codec. Most important difference is the native 16-bits (15-bits, actually) color support. While general codec principle remains the same, few new techniques has been added. For example, instead of coding of each color triplet, they all are stored in several lookup tables (think about VQ or huge palette).
* Company: [[Eidos Technologies]]
* Samples: http://samples.mplayerhq.hu/game-formats/rpl/escape124/
 
ESCAPE 124 is a slightly enhanced version of Eidos Technologies' previous [[Escape 122]] codec. It is usually found encapsulated in [[ARMovie]] files bearing the extension RPL. The most important difference is native 16-bits (15-bits, actually) color support. While general principles remain the same, a few new techniques have been added. For example, instead of coding each color triplet, they all are stored in several lookup tables (think about VQ or huge palette).


Each frame chunks begins with a new 8-bytes header:
Each frame chunks begins with a new 8-bytes header:
Line 5: Line 8:
   dword frame_size  - size of the frame chunk, including this header
   dword frame_size  - size of the frame chunk, including this header


In the available sample files, frames usually grouped together in to one-second bundles, followed by sound stream (i.e., 15 fps movie will have 15 frames in a row, then 1 sec of sound data.)
In the available sample files, frames are usually grouped together in one-second bundles followed by sound stream (i.e., 15 fps movie will have 15 frames in a row, then 1 sec of sound data.)
Original decoder throws away any frames whose frame_flags has no bits 2, 4 or 8 set ( & 0x114 ).


== Video portion ==
== Video portion ==


At first, you need to check if any of bits 23..26 of frame_flags is set. If none of
At first, you need to check if any of the bits 23..26 of frame_flags is set. If none of
them is set, just leave last decoded frame unchanged. (These bits are specific to 124 decoder, unlike bits 2, 4, 8, described above).
them is set, just leave the last decoded frame unchanged. (These bits are specific to 124 decoder, unlike bits 2, 4, 8, described above).


Next, unpack 3 codebooks. Each codebook contains variable number of 2x2 macroblocks. You should maintain all three codebooks between frames.
Next, unpack 3 codebooks. Each codebook contains a variable number of 2x2 macroblocks. You should maintain all three codebooks between frames.
   if bit 17 of frame_flags is set
   if bit 17 of frame_flags is set
     read 4 bits of codebook 1 indice depth from the stream
     read 4 bits of codebook 1 index depth from the stream
     codebook 1 size is the 2^depth (power of)
     codebook 1 size is 2^depth (power of)
     codebook1 = Unpack_Codebook()
     codebook1 = Unpack_Codebook()
   
   
   if bit 18 of frame_flags is set
   if bit 18 of frame_flags is set
     read 4 bits of codebook 2 indice depth from the stream
     read 4 bits of codebook 2 index depth from the stream
     codebook 2 size is the 2^depth (power of) * total number of superblocks in the frame
     codebook 2 size is 2^depth (power of) * total number of superblocks in the frame
     codebook2 = Unpack_Codebook()
     codebook2 = Unpack_Codebook()
   
   
   if bit 19 of frame_flags is set
   if bit 19 of frame_flags is set
     read 20 bits of codebook 3 size from the stream
     read 20 bits of codebook 3 size from the stream
     evaluate codebook 3 indice depth as the index of most significant bit of size
     evaluate codebook 3 index depth as the 1-based index of most significant bit of (size - 1)
     codebook3 = Unpack_Codebook()
     codebook3 = Unpack_Codebook()
   
   
Proceed the frame decoding:
   initialize codebook_index to zero
   initialize codebook_index to zero
 
 
Proceed the frame decoding:
   repeat
   repeat
     skip_value = RICE_Decode()
     skip_value = RICE_Decode()
Line 54: Line 58:
           invert next 4 bits of multi_mask
           invert next 4 bits of multi_mask
         else
         else
           read next 4 bits of multi_mask from the stream
           XOR next 4 bits of multi_mask by next 4 bits of the stream
   
   
       for each macroblock of superblock (left to right, top to bottom)
       for each macroblock of superblock (left to right, top to bottom)
Line 86: Line 90:
       decrement codebook_index
       decrement codebook_index
     else
     else
       increment codebook_index
       increment codebook_index  
   
   
   clamp codebook_index within 0..3 range
   wrap codebook_index within 0..2 range
   
   
   if codebook_index is 0
   if codebook_index is 0
Line 111: Line 115:
       else
       else
         pixel = color0
         pixel = color0
[[Category:Video Codecs]]
[[Category:Game Formats]]

Latest revision as of 18:26, 31 March 2008

ESCAPE 124 is a slightly enhanced version of Eidos Technologies' previous Escape 122 codec. It is usually found encapsulated in ARMovie files bearing the extension RPL. The most important difference is native 16-bits (15-bits, actually) color support. While general principles remain the same, a few new techniques have been added. For example, instead of coding each color triplet, they all are stored in several lookup tables (think about VQ or huge palette).

Each frame chunks begins with a new 8-bytes header:

 dword frame_flags - frame flags, must be passed to the decoder
 dword frame_size  - size of the frame chunk, including this header

In the available sample files, frames are usually grouped together in one-second bundles followed by sound stream (i.e., 15 fps movie will have 15 frames in a row, then 1 sec of sound data.) Original decoder throws away any frames whose frame_flags has no bits 2, 4 or 8 set ( & 0x114 ).

Video portion

At first, you need to check if any of the bits 23..26 of frame_flags is set. If none of them is set, just leave the last decoded frame unchanged. (These bits are specific to 124 decoder, unlike bits 2, 4, 8, described above).

Next, unpack 3 codebooks. Each codebook contains a variable number of 2x2 macroblocks. You should maintain all three codebooks between frames.

 if bit 17 of frame_flags is set
   read 4 bits of codebook 1 index depth from the stream
   codebook 1 size is 2^depth (power of)
   codebook1 = Unpack_Codebook()

 if bit 18 of frame_flags is set
   read 4 bits of codebook 2 index depth from the stream
   codebook 2 size is 2^depth (power of) * total number of superblocks in the frame
   codebook2 = Unpack_Codebook()

 if bit 19 of frame_flags is set
   read 20 bits of codebook 3 size from the stream
   evaluate codebook 3 index depth as the 1-based index of most significant bit of (size - 1)
   codebook3 = Unpack_Codebook()

Proceed the frame decoding:

 initialize codebook_index to zero

 repeat
   skip_value = RICE_Decode()
   skip skip_value number of 8x8 superblocks (keep them unchanged from the last frame)

   if all blocks drawn/skipped
     finish

   multi_mask = 0
   while next bit of the stream is zero
     new_block = Decode_MacroBlock()
     mask = read 4*4 (number of macroblocks in superblock) bits
     multi_mask = multi_mask or'ed with mask
     for each macroblock of superblock (left to right, top to bottom)
       if corresponding bit of mask (see below) is set
         macroblock = new_block

   if next bit of the stream is zero
     inv_mask = read 4 bits from the stream
     for each bit of inv_mask (from low to high)
       if bit is set
         invert next 4 bits of multi_mask
       else
         XOR next 4 bits of multi_mask by next 4 bits of the stream

     for each macroblock of superblock (left to right, top to bottom)
       if corresponding bit of multi_mask (see below) is set
         macroblock = Decode_MacroBlock()

   else if bit 16 of frame_flags is set
     while next bit of the stream is zero
       new_block = Decode_MacroBlock()
       block_index = read next 4 bits from the stream
       set macroblock block_index of superblock to new_block

   advance to the next superblock


Superblock's macroblock bit mask matrix (in hex):

  ---- ---- ---- ---- 
 |   1|   2|  10|  20|
  ---- ---- ---- ---- 
 |   4|   8|  40|  80|
  ---- ---- ---- ---- 
 | 100| 200|1000|2000|
  ---- ---- ---- ---- 
 | 400| 800|4000|8000|
  ---- ---- ---- ---- 


Decode_Macroblock selects 2x2 macroblock from one of codebooks:

 if next bit of stream is set
   if next bit of stream is set
     decrement codebook_index
   else
     increment codebook_index 

 wrap codebook_index within 0..2 range

 if codebook_index is 0
   macroblock = codebook2[superblock_index * 2^depth + next codebook 2 depth bits of the stream]
 else if codebook_index is 1
   macroblock = codebook1[next codebook 1 depth bits of the stream]
 else
   macroblock = codebook3[next codebook 3 depth bits of the stream]


Unpack_Codebook loads macroblocks codebook:

 for each macroblock of codebook

   read 2*2 (number of pixels in macroblock) mask bits from the stream

   read 5+5+5 bits of color0 RGB triplet
   read 5+5+5 bits of color1 RGB triplet

   for each pixel of macroblock (left to right, top to bottom)
     if next bit of mask (from low to high) is set 
       pixel = color1
     else
       pixel = color0