14 Microsoft Video 1 Decoder
16 (C) 2001 Mike Melanson
18 The description of the algorithm you can read here:
19 http://www.pcisys.net/~melanson/codecs/
21 Heavily optimized by Mathias "AmiDog" Roslund
24 #define LE_16(val) ({ unsigned short x = *(unsigned short *)(val); x = (x << 8) | (x >> 8); x; })
26 #define RGB555_TO_RGB888(argb, c) \
27 argb = ((c & 0x7c00) << 9) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 3);
29 #define DECODE_RGB555_TO_RGB888(x) \
30 RGB555_TO_RGB888(x.argb[1], x.c1); \
31 RGB555_TO_RGB888(x.argb[0], x.c2);
33 #define CRAM16(x, y) \
34 *(unsigned long *)&decoded[pixel_ptr] = quad[x][y].argb[flags & 1]; \
39 decoded[pixel_ptr++] = quad[x][y].b[flags & 1]; \
43 unsigned short c1
, c2
;
44 unsigned long argb
[2];
48 void AVI_Decode_Video1_16(unsigned char *encoded
, int encoded_size
, unsigned char *decoded
, int width
, int height
)
50 int block_ptr
, pixel_ptr
;
52 int pixel_y
; // pixel height iterator
53 int block_x
, block_y
; // block width and height iterators
54 int blocks_wide
, blocks_high
; // width and height in 4x4 blocks
58 // decoding parameters
60 unsigned char byte_a
, byte_b
;
66 blocks_wide
= width
/ 4;
67 blocks_high
= height
/ 4;
68 total_blocks
= blocks_wide
* blocks_high
;
70 row_dec
= (width
+ 4) * 4;
72 for (block_y
= blocks_high
; block_y
> 0; block_y
--)
74 block_ptr
= ((block_y
* 4) - 1) * (width
* 4);
75 for (block_x
= blocks_wide
; block_x
> 0; block_x
--)
77 // check if this block should be skipped
80 block_ptr
+= block_inc
;
86 pixel_ptr
= block_ptr
;
88 // get the next two bytes in the encoded data stream
89 byte_a
= encoded
[stream_ptr
++];
90 byte_b
= encoded
[stream_ptr
++];
92 // check if the decode is finished
93 if ((byte_a
== 0) && (byte_b
== 0) && (total_blocks
== 0))
96 // check if this is a skip code
97 else if ((byte_b
& 0xFC) == 0x84)
99 // but don't count the current block
100 skip_blocks
= ((byte_b
- 0x84) << 8) + byte_a
- 1;
103 // check if this is in the 2- or 8-color classes
104 else if (byte_b
< 0x80)
106 flags
= (byte_b
<< 8) | byte_a
;
108 quad
[0][0].c1
= LE_16(&encoded
[stream_ptr
]);
110 quad
[0][0].c2
= LE_16(&encoded
[stream_ptr
]);
113 DECODE_RGB555_TO_RGB888(quad
[0][0]);
115 if (quad
[0][0].c1
& 0x8000)
118 quad
[1][0].c1
= LE_16(&encoded
[stream_ptr
]);
120 quad
[1][0].c2
= LE_16(&encoded
[stream_ptr
]);
122 quad
[0][1].c1
= LE_16(&encoded
[stream_ptr
]);
124 quad
[0][1].c2
= LE_16(&encoded
[stream_ptr
]);
126 quad
[1][1].c1
= LE_16(&encoded
[stream_ptr
]);
128 quad
[1][1].c2
= LE_16(&encoded
[stream_ptr
]);
131 DECODE_RGB555_TO_RGB888(quad
[0][1]);
132 DECODE_RGB555_TO_RGB888(quad
[1][0]);
133 DECODE_RGB555_TO_RGB888(quad
[1][1]);
135 for (pixel_y
= 0; pixel_y
< 4; pixel_y
++)
137 CRAM16(0, pixel_y
>> 1);
138 CRAM16(0, pixel_y
>> 1);
139 CRAM16(1, pixel_y
>> 1);
140 CRAM16(1, pixel_y
>> 1);
141 pixel_ptr
-= row_dec
;
147 for (pixel_y
= 0; pixel_y
< 4; pixel_y
++)
153 pixel_ptr
-= row_dec
;
158 // otherwise, it's a 1-color block
161 unsigned long argb
, c
;
163 c
= (byte_b
<< 8) | byte_a
;
164 RGB555_TO_RGB888(argb
, c
);
166 for (pixel_y
= 0; pixel_y
< 4; pixel_y
++)
168 *(unsigned long *)&decoded
[pixel_ptr
] = argb
;
170 *(unsigned long *)&decoded
[pixel_ptr
] = argb
;
172 *(unsigned long *)&decoded
[pixel_ptr
] = argb
;
174 *(unsigned long *)&decoded
[pixel_ptr
] = argb
;
176 pixel_ptr
-= row_dec
;
180 block_ptr
+= block_inc
;
186 void AVI_Decode_Video1_8(unsigned char *encoded
, int encoded_size
, unsigned char *decoded
, int width
, int height
)
188 int block_ptr
, pixel_ptr
;
190 int pixel_y
; // pixel height iterator
191 int block_x
, block_y
; // block width and height iterators
192 int blocks_wide
, blocks_high
; // width and height in 4x4 blocks
196 // decoding parameters
198 unsigned char byte_a
, byte_b
;
199 unsigned short flags
;
204 blocks_wide
= width
/ 4;
205 blocks_high
= height
/ 4;
206 total_blocks
= blocks_wide
* blocks_high
;
208 row_dec
= (width
+ 4) * 1;
210 for (block_y
= blocks_high
; block_y
> 0; block_y
--)
212 block_ptr
= ((block_y
* 4) - 1) * (width
* 1);
213 for (block_x
= blocks_wide
; block_x
> 0; block_x
--)
215 // check if this block should be skipped
218 block_ptr
+= block_inc
;
224 pixel_ptr
= block_ptr
;
226 // get the next two bytes in the encoded data stream
227 byte_a
= encoded
[stream_ptr
++];
228 byte_b
= encoded
[stream_ptr
++];
230 // check if the decode is finished
231 if ((byte_a
== 0) && (byte_b
== 0) && (total_blocks
== 0))
234 // check if this is a skip code
235 else if ((byte_b
& 0xFC) == 0x84)
237 // but don't count the current block
238 skip_blocks
= ((byte_b
- 0x84) << 8) + byte_a
- 1;
241 // check if this is a 2-color block
242 else if (byte_b
< 0x80)
244 flags
= (byte_b
<< 8) | byte_a
;
246 quad
[0][0].b
[1] = encoded
[stream_ptr
++];
247 quad
[0][0].b
[0] = encoded
[stream_ptr
++];
250 for (pixel_y
= 0; pixel_y
< 4; pixel_y
++)
256 pixel_ptr
-= row_dec
;
260 // check if it's an 8-color block
261 else if (byte_b
>= 0x90)
263 flags
= (byte_b
<< 8) | byte_a
;
265 quad
[0][0].b
[1] = encoded
[stream_ptr
++];
266 quad
[0][0].b
[0] = encoded
[stream_ptr
++];
267 quad
[1][0].b
[1] = encoded
[stream_ptr
++];
268 quad
[1][0].b
[0] = encoded
[stream_ptr
++];
270 quad
[0][1].b
[1] = encoded
[stream_ptr
++];
271 quad
[0][1].b
[0] = encoded
[stream_ptr
++];
272 quad
[1][1].b
[1] = encoded
[stream_ptr
++];
273 quad
[1][1].b
[0] = encoded
[stream_ptr
++];
275 for (pixel_y
= 0; pixel_y
< 4; pixel_y
++)
277 CRAM8(0, pixel_y
>> 1);
278 CRAM8(0, pixel_y
>> 1);
279 CRAM8(1, pixel_y
>> 1);
280 CRAM8(1, pixel_y
>> 1);
281 pixel_ptr
-= row_dec
;
285 // otherwise, it's a 1-color block
290 c
= byte_a
| (byte_a
<< 8);
293 *(unsigned long *)&decoded
[pixel_ptr
] = c
;
295 pixel_ptr
-= row_dec
;
297 *(unsigned long *)&decoded
[pixel_ptr
] = c
;
299 pixel_ptr
-= row_dec
;
301 *(unsigned long *)&decoded
[pixel_ptr
] = c
;
303 pixel_ptr
-= row_dec
;
305 *(unsigned long *)&decoded
[pixel_ptr
] = c
;
307 pixel_ptr
-= row_dec
;
310 block_ptr
+= block_inc
;
316 static unsigned char *buffer
= NULL
;
318 static int video_w
, video_h
;
319 static int msvc_error
= 0;
321 static double current_time
= 0.0;
322 static double current_frame_time
= 0.0;
323 static double current_video_time
= 0.0;
325 int decode_msvc(unsigned char *buf
, unsigned long length
, double sync_time
)
327 if (msvc_error
!= 0) {
332 if (amp
->depth
== 8) {
333 AVI_Decode_Video1_8(buf
, length
, buffer
, video_w
, video_h
);
335 AVI_Decode_Video1_16(buf
, length
, buffer
, video_w
, video_h
);
338 if (sync_time
> 0.0) {
339 current_time
= sync_time
;
342 amp
->video_refresh(&buffer
, current_time
, current_video_time
);
345 current_time
+= current_frame_time
;
346 current_video_time
+= current_frame_time
;
352 int init_msvc(unsigned long type
, unsigned long fourcc
)
357 height
= amp
->height
;
359 buffer
= malloc(width
* height
* 4);
360 memset(buffer
, 0, width
* height
* 4);
365 amp
->total_frames
= 0;
366 amp
->skiped_frames
= 0;
371 current_frame_time
= 1.0 / amp
->framerate
;
372 current_video_time
= 0.0;
374 if (amp
->depth
== 8) {
375 if (amp
->video_init(width
, height
, width
, CMODE_CHUNKY
) != PLUGIN_OK
) {
380 if (amp
->video_init(width
, height
, width
, CMODE_ARGB32
) != PLUGIN_OK
) {
391 if (buffer
!= NULL
) {
399 VERSION("MSVC v1.01 (020520)");
402 IDENT_ADD((TYPE_VIDEO
| SUBTYPE_NONE
), FOURCC_MSVC
, init_msvc
, decode_msvc
, exit_msvc
)
403 IDENT_ADD((TYPE_VIDEO
| SUBTYPE_NONE
), FOURCC_msvc
, init_msvc
, decode_msvc
, exit_msvc
)
404 IDENT_ADD((TYPE_VIDEO
| SUBTYPE_NONE
), FOURCC_CRAM
, init_msvc
, decode_msvc
, exit_msvc
)
405 IDENT_ADD((TYPE_VIDEO
| SUBTYPE_NONE
), FOURCC_cram
, init_msvc
, decode_msvc
, exit_msvc
)
406 IDENT_ADD((TYPE_VIDEO
| SUBTYPE_NONE
), FOURCC_WHAM
, init_msvc
, decode_msvc
, exit_msvc
)
407 IDENT_ADD((TYPE_VIDEO
| SUBTYPE_NONE
), FOURCC_wham
, init_msvc
, decode_msvc
, exit_msvc
)