Mercurial > libavcodec.hg
comparison xan.c @ 1459:201d4e25c207 libavcodec
xan_wc3 decoder now works correctly; added a bunch of output
colorspaces
author | tmmm |
---|---|
date | Thu, 11 Sep 2003 05:46:25 +0000 |
parents | 47f4c8a5a7fc |
children | 4d2098e8c875 |
comparison
equal
deleted
inserted
replaced
1458:40b69d238beb | 1459:201d4e25c207 |
---|---|
21 /** | 21 /** |
22 * @file xan.c | 22 * @file xan.c |
23 * Xan video decoder for Wing Commander III & IV computer games | 23 * Xan video decoder for Wing Commander III & IV computer games |
24 * by Mario Brito (mbrito@student.dei.uc.pt) | 24 * by Mario Brito (mbrito@student.dei.uc.pt) |
25 * and Mike Melanson (melanson@pcisys.net) | 25 * and Mike Melanson (melanson@pcisys.net) |
26 * For more information about the Xan format, visit: | 26 * |
27 * http://www.pcisys.net/~melanson/codecs/ | 27 * The xan_wc3 decoder outputs the following colorspaces natively: |
28 * PAL8 (default), RGB555, RGB565, RGB24, BGR24, RGBA32, YUV444P | |
28 */ | 29 */ |
29 | 30 |
30 #include <stdio.h> | 31 #include <stdio.h> |
31 #include <stdlib.h> | 32 #include <stdlib.h> |
32 #include <string.h> | 33 #include <string.h> |
118 printf (" WC3 Xan video: expected extradata_size of %d\n", | 119 printf (" WC3 Xan video: expected extradata_size of %d\n", |
119 PALETTE_CONTROL_SIZE); | 120 PALETTE_CONTROL_SIZE); |
120 return -1; | 121 return -1; |
121 } | 122 } |
122 | 123 |
123 avctx->pix_fmt = PIX_FMT_YUV444P; | 124 avctx->pix_fmt = PIX_FMT_PAL8; |
124 avctx->has_b_frames = 0; | 125 avctx->has_b_frames = 0; |
125 dsputil_init(&s->dsp, avctx); | 126 dsputil_init(&s->dsp, avctx); |
126 | 127 |
127 /* initialize the RGB -> YUV tables */ | 128 /* initialize the RGB -> YUV tables */ |
128 for (i = 0; i < 256; i++) { | 129 for (i = 0; i < 256; i++) { |
137 v_r_table[i] = V_R * i; | 138 v_r_table[i] = V_R * i; |
138 v_g_table[i] = V_G * i; | 139 v_g_table[i] = V_G * i; |
139 v_b_table[i] = V_B * i; | 140 v_b_table[i] = V_B * i; |
140 } | 141 } |
141 | 142 |
142 s->buffer1 = av_malloc(avctx->width * avctx->height * 4); | 143 s->buffer1 = av_malloc(avctx->width * avctx->height); |
143 s->buffer2 = av_malloc(avctx->width * avctx->height * 4); | 144 s->buffer2 = av_malloc(avctx->width * avctx->height); |
144 if (!s->buffer1 || !s->buffer2) | 145 if (!s->buffer1 || !s->buffer2) |
145 return -1; | 146 return -1; |
146 | 147 |
147 return 0; | 148 return 0; |
148 } | 149 } |
158 | 159 |
159 for (i = 0; i < count; i++) | 160 for (i = 0; i < count; i++) |
160 dest[i] = src[i]; | 161 dest[i] = src[i]; |
161 } | 162 } |
162 | 163 |
163 static int xan_decode_method_1(unsigned char *dest, unsigned char *src) | 164 static int xan_huffman_decode(unsigned char *dest, unsigned char *src) |
164 { | 165 { |
165 unsigned char byte = *src++; | 166 unsigned char byte = *src++; |
166 unsigned char ival = byte + 0x16; | 167 unsigned char ival = byte + 0x16; |
167 unsigned char * ptr = src + byte*2; | 168 unsigned char * ptr = src + byte*2; |
168 unsigned char val = ival; | 169 unsigned char val = ival; |
188 } | 189 } |
189 | 190 |
190 return 0; | 191 return 0; |
191 } | 192 } |
192 | 193 |
193 static int xan_decode_method_2(unsigned char *dest, unsigned char *src) | 194 static void xan_unpack(unsigned char *dest, unsigned char *src) |
194 { | 195 { |
195 unsigned char opcode; | 196 unsigned char opcode; |
196 int size; | 197 int size; |
197 int offset; | 198 int offset; |
198 int byte1, byte2, byte3; | 199 int byte1, byte2, byte3; |
247 } | 248 } |
248 } | 249 } |
249 | 250 |
250 size = opcode & 3; | 251 size = opcode & 3; |
251 bytecopy(dest, src, size); dest += size; src += size; | 252 bytecopy(dest, src, size); dest += size; src += size; |
252 | |
253 return 0; | |
254 } | 253 } |
255 | 254 |
256 static void inline xan_wc3_build_palette(XanContext *s, | 255 static void inline xan_wc3_build_palette(XanContext *s, |
257 unsigned char *palette_data) | 256 unsigned char *palette_data) |
258 { | 257 { |
259 int i; | 258 int i; |
260 unsigned char r, g, b; | 259 unsigned char r, g, b; |
260 unsigned short *palette16; | |
261 unsigned int *palette32; | |
261 | 262 |
262 /* transform the palette passed through the palette control structure | 263 /* transform the palette passed through the palette control structure |
263 * into the necessary internal format depending on colorspace */ | 264 * into the necessary internal format depending on colorspace */ |
264 | 265 |
265 switch (s->avctx->pix_fmt) { | 266 switch (s->avctx->pix_fmt) { |
267 | |
268 case PIX_FMT_PAL8: | |
269 for (i = 0; i < PALETTE_COUNT; i++) { | |
270 r = *palette_data++; | |
271 g = *palette_data++; | |
272 b = *palette_data++; | |
273 s->palette[i * 4 + 0] = b; | |
274 s->palette[i * 4 + 1] = g; | |
275 s->palette[i * 4 + 2] = r; | |
276 } | |
277 break; | |
278 | |
279 case PIX_FMT_RGB555: | |
280 palette16 = (unsigned short *)s->palette; | |
281 for (i = 0; i < PALETTE_COUNT; i++) { | |
282 r = *palette_data++; | |
283 g = *palette_data++; | |
284 b = *palette_data++; | |
285 palette16[i] = | |
286 ((r >> 3) << 10) | | |
287 ((g >> 3) << 5) | | |
288 ((g >> 3) << 0); | |
289 } | |
290 break; | |
291 | |
292 case PIX_FMT_RGB565: | |
293 palette16 = (unsigned short *)s->palette; | |
294 for (i = 0; i < PALETTE_COUNT; i++) { | |
295 r = *palette_data++; | |
296 g = *palette_data++; | |
297 b = *palette_data++; | |
298 palette16[i] = | |
299 ((r >> 3) << 11) | | |
300 ((g >> 2) << 5) | | |
301 ((g >> 3) << 0); | |
302 } | |
303 break; | |
304 | |
305 case PIX_FMT_RGB24: | |
306 for (i = 0; i < PALETTE_COUNT; i++) { | |
307 s->palette[i * 4 + 0] = *palette_data++; | |
308 s->palette[i * 4 + 1] = *palette_data++; | |
309 s->palette[i * 4 + 2] = *palette_data++; | |
310 } | |
311 break; | |
312 | |
313 case PIX_FMT_BGR24: | |
314 for (i = 0; i < PALETTE_COUNT; i++) { | |
315 r = *palette_data++; | |
316 g = *palette_data++; | |
317 b = *palette_data++; | |
318 s->palette[i * 4 + 0] = b; | |
319 s->palette[i * 4 + 1] = g; | |
320 s->palette[i * 4 + 2] = r; | |
321 } | |
322 break; | |
323 | |
324 case PIX_FMT_RGBA32: | |
325 palette32 = (unsigned int *)s->palette; | |
326 for (i = 0; i < PALETTE_COUNT; i++) { | |
327 r = *palette_data++; | |
328 g = *palette_data++; | |
329 b = *palette_data++; | |
330 palette32[i] = (r << 16) | (g << 8) | (b); | |
331 } | |
332 break; | |
266 | 333 |
267 case PIX_FMT_YUV444P: | 334 case PIX_FMT_YUV444P: |
268 for (i = 0; i < PALETTE_COUNT; i++) { | 335 for (i = 0; i < PALETTE_COUNT; i++) { |
269 r = *palette_data++; | 336 r = *palette_data++; |
270 g = *palette_data++; | 337 g = *palette_data++; |
288 int line_inc; | 355 int line_inc; |
289 int index; | 356 int index; |
290 int current_x; | 357 int current_x; |
291 int width = s->avctx->width; | 358 int width = s->avctx->width; |
292 unsigned char pixel; | 359 unsigned char pixel; |
360 unsigned char *palette_plane; | |
293 unsigned char *y_plane; | 361 unsigned char *y_plane; |
294 unsigned char *u_plane; | 362 unsigned char *u_plane; |
295 unsigned char *v_plane; | 363 unsigned char *v_plane; |
364 unsigned char *rgb_plane; | |
365 unsigned short *rgb16_plane; | |
366 unsigned short *palette16; | |
367 unsigned int *rgb32_plane; | |
368 unsigned int *palette32; | |
296 | 369 |
297 switch (s->avctx->pix_fmt) { | 370 switch (s->avctx->pix_fmt) { |
371 | |
372 case PIX_FMT_PAL8: | |
373 palette_plane = s->current_frame.data[0]; | |
374 stride = s->current_frame.linesize[0]; | |
375 line_inc = stride - width; | |
376 index = y * stride + x; | |
377 current_x = x; | |
378 while(pixel_count--) { | |
379 | |
380 /* don't do a memcpy() here; keyframes generally copy an entire | |
381 * frame of data and the stride needs to be accounted for */ | |
382 palette_plane[index++] = *pixel_buffer++; | |
383 | |
384 current_x++; | |
385 if (current_x >= width) { | |
386 /* reset accounting variables */ | |
387 index += line_inc; | |
388 current_x = 0; | |
389 } | |
390 } | |
391 break; | |
392 | |
393 case PIX_FMT_RGB555: | |
394 case PIX_FMT_RGB565: | |
395 rgb16_plane = (unsigned short *)s->current_frame.data[0]; | |
396 palette16 = (unsigned short *)s->palette; | |
397 stride = s->current_frame.linesize[0] / 2; | |
398 line_inc = stride - width; | |
399 index = y * stride + x; | |
400 current_x = x; | |
401 while(pixel_count--) { | |
402 | |
403 rgb16_plane[index++] = palette16[*pixel_buffer++]; | |
404 | |
405 current_x++; | |
406 if (current_x >= width) { | |
407 /* reset accounting variables */ | |
408 index += line_inc; | |
409 current_x = 0; | |
410 } | |
411 } | |
412 break; | |
413 | |
414 case PIX_FMT_RGB24: | |
415 case PIX_FMT_BGR24: | |
416 rgb_plane = s->current_frame.data[0]; | |
417 stride = s->current_frame.linesize[0]; | |
418 line_inc = stride - width * 3; | |
419 index = y * stride + x * 3; | |
420 current_x = x; | |
421 while(pixel_count--) { | |
422 pixel = *pixel_buffer++; | |
423 | |
424 rgb_plane[index++] = s->palette[pixel * 4 + 0]; | |
425 rgb_plane[index++] = s->palette[pixel * 4 + 1]; | |
426 rgb_plane[index++] = s->palette[pixel * 4 + 2]; | |
427 | |
428 current_x++; | |
429 if (current_x >= width) { | |
430 /* reset accounting variables */ | |
431 index += line_inc; | |
432 current_x = 0; | |
433 } | |
434 } | |
435 break; | |
436 | |
437 case PIX_FMT_RGBA32: | |
438 rgb32_plane = (unsigned int *)s->current_frame.data[0]; | |
439 palette32 = (unsigned int *)s->palette; | |
440 stride = s->current_frame.linesize[0] / 4; | |
441 line_inc = stride - width; | |
442 index = y * stride + x; | |
443 current_x = x; | |
444 while(pixel_count--) { | |
445 | |
446 rgb32_plane[index++] = palette32[*pixel_buffer++]; | |
447 | |
448 current_x++; | |
449 if (current_x >= width) { | |
450 /* reset accounting variables */ | |
451 index += line_inc; | |
452 current_x = 0; | |
453 } | |
454 } | |
455 break; | |
298 | 456 |
299 case PIX_FMT_YUV444P: | 457 case PIX_FMT_YUV444P: |
300 y_plane = s->current_frame.data[0]; | 458 y_plane = s->current_frame.data[0]; |
301 u_plane = s->current_frame.data[1]; | 459 u_plane = s->current_frame.data[1]; |
302 v_plane = s->current_frame.data[2]; | 460 v_plane = s->current_frame.data[2]; |
333 int stride; | 491 int stride; |
334 int line_inc; | 492 int line_inc; |
335 int curframe_index, prevframe_index; | 493 int curframe_index, prevframe_index; |
336 int curframe_x, prevframe_x; | 494 int curframe_x, prevframe_x; |
337 int width = s->avctx->width; | 495 int width = s->avctx->width; |
496 unsigned char *palette_plane, *prev_palette_plane; | |
338 unsigned char *y_plane, *u_plane, *v_plane; | 497 unsigned char *y_plane, *u_plane, *v_plane; |
339 unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane; | 498 unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane; |
499 unsigned char *rgb_plane, *prev_rgb_plane; | |
500 unsigned short *rgb16_plane, *prev_rgb16_plane; | |
501 unsigned int *rgb32_plane, *prev_rgb32_plane; | |
340 | 502 |
341 switch (s->avctx->pix_fmt) { | 503 switch (s->avctx->pix_fmt) { |
504 | |
505 case PIX_FMT_PAL8: | |
506 palette_plane = s->current_frame.data[0]; | |
507 prev_palette_plane = s->last_frame.data[0]; | |
508 stride = s->current_frame.linesize[0]; | |
509 line_inc = stride - width; | |
510 curframe_index = y * stride + x; | |
511 curframe_x = x; | |
512 prevframe_index = (y + motion_y) * stride + x + motion_x; | |
513 prevframe_x = x + motion_x; | |
514 while(pixel_count--) { | |
515 | |
516 palette_plane[curframe_index++] = | |
517 prev_palette_plane[prevframe_index++]; | |
518 | |
519 curframe_x++; | |
520 if (curframe_x >= width) { | |
521 /* reset accounting variables */ | |
522 curframe_index += line_inc; | |
523 curframe_x = 0; | |
524 } | |
525 | |
526 prevframe_x++; | |
527 if (prevframe_x >= width) { | |
528 /* reset accounting variables */ | |
529 prevframe_index += line_inc; | |
530 prevframe_x = 0; | |
531 } | |
532 } | |
533 break; | |
534 | |
535 case PIX_FMT_RGB555: | |
536 case PIX_FMT_RGB565: | |
537 rgb16_plane = (unsigned short *)s->current_frame.data[0]; | |
538 prev_rgb16_plane = (unsigned short *)s->last_frame.data[0]; | |
539 stride = s->current_frame.linesize[0] / 2; | |
540 line_inc = stride - width; | |
541 curframe_index = y * stride + x; | |
542 curframe_x = x; | |
543 prevframe_index = (y + motion_y) * stride + x + motion_x; | |
544 prevframe_x = x + motion_x; | |
545 while(pixel_count--) { | |
546 | |
547 rgb16_plane[curframe_index++] = | |
548 prev_rgb16_plane[prevframe_index++]; | |
549 | |
550 curframe_x++; | |
551 if (curframe_x >= width) { | |
552 /* reset accounting variables */ | |
553 curframe_index += line_inc; | |
554 curframe_x = 0; | |
555 } | |
556 | |
557 prevframe_x++; | |
558 if (prevframe_x >= width) { | |
559 /* reset accounting variables */ | |
560 prevframe_index += line_inc; | |
561 prevframe_x = 0; | |
562 } | |
563 } | |
564 break; | |
565 | |
566 case PIX_FMT_RGB24: | |
567 case PIX_FMT_BGR24: | |
568 rgb_plane = s->current_frame.data[0]; | |
569 prev_rgb_plane = s->last_frame.data[0]; | |
570 stride = s->current_frame.linesize[0]; | |
571 line_inc = stride - width * 3; | |
572 curframe_index = y * stride + x * 3; | |
573 curframe_x = x; | |
574 prevframe_index = (y + motion_y) * stride + | |
575 (3 * (x + motion_x)); | |
576 prevframe_x = x + motion_x; | |
577 while(pixel_count--) { | |
578 | |
579 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; | |
580 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; | |
581 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; | |
582 | |
583 curframe_x++; | |
584 if (curframe_x >= width) { | |
585 /* reset accounting variables */ | |
586 curframe_index += line_inc; | |
587 curframe_x = 0; | |
588 } | |
589 | |
590 prevframe_x++; | |
591 if (prevframe_x >= width) { | |
592 /* reset accounting variables */ | |
593 prevframe_index += line_inc; | |
594 prevframe_x = 0; | |
595 } | |
596 } | |
597 break; | |
598 | |
599 case PIX_FMT_RGBA32: | |
600 rgb32_plane = (unsigned int *)s->current_frame.data[0]; | |
601 prev_rgb32_plane = (unsigned int *)s->last_frame.data[0]; | |
602 stride = s->current_frame.linesize[0] / 4; | |
603 line_inc = stride - width; | |
604 curframe_index = y * stride + x; | |
605 curframe_x = x; | |
606 prevframe_index = (y + motion_y) * stride + x + motion_x; | |
607 prevframe_x = x + motion_x; | |
608 while(pixel_count--) { | |
609 | |
610 rgb32_plane[curframe_index++] = | |
611 prev_rgb32_plane[prevframe_index++]; | |
612 | |
613 curframe_x++; | |
614 if (curframe_x >= width) { | |
615 /* reset accounting variables */ | |
616 curframe_index += line_inc; | |
617 curframe_x = 0; | |
618 } | |
619 | |
620 prevframe_x++; | |
621 if (prevframe_x >= width) { | |
622 /* reset accounting variables */ | |
623 prevframe_index += line_inc; | |
624 prevframe_x = 0; | |
625 } | |
626 } | |
627 break; | |
342 | 628 |
343 case PIX_FMT_YUV444P: | 629 case PIX_FMT_YUV444P: |
344 y_plane = s->current_frame.data[0]; | 630 y_plane = s->current_frame.data[0]; |
345 u_plane = s->current_frame.data[1]; | 631 u_plane = s->current_frame.data[1]; |
346 v_plane = s->current_frame.data[2]; | 632 v_plane = s->current_frame.data[2]; |
349 prev_v_plane = s->last_frame.data[2]; | 635 prev_v_plane = s->last_frame.data[2]; |
350 stride = s->current_frame.linesize[0]; | 636 stride = s->current_frame.linesize[0]; |
351 line_inc = stride - width; | 637 line_inc = stride - width; |
352 curframe_index = y * stride + x; | 638 curframe_index = y * stride + x; |
353 curframe_x = x; | 639 curframe_x = x; |
354 prevframe_index = (y + motion_x) * stride + x + motion_x; | 640 prevframe_index = (y + motion_y) * stride + x + motion_x; |
355 prevframe_x = x + motion_x; | 641 prevframe_x = x + motion_x; |
356 while(pixel_count--) { | 642 while(pixel_count--) { |
357 | 643 |
358 y_plane[curframe_index] = prev_y_plane[prevframe_index]; | 644 y_plane[curframe_index] = prev_y_plane[prevframe_index]; |
359 u_plane[curframe_index] = prev_u_plane[prevframe_index]; | 645 u_plane[curframe_index] = prev_u_plane[prevframe_index]; |
392 unsigned char flag = 0; | 678 unsigned char flag = 0; |
393 int size = 0; | 679 int size = 0; |
394 int motion_x, motion_y; | 680 int motion_x, motion_y; |
395 int x, y; | 681 int x, y; |
396 | 682 |
397 unsigned char *method1_buffer = s->buffer1; | 683 unsigned char *opcode_buffer = s->buffer1; |
398 unsigned char *method2_buffer = s->buffer2; | 684 unsigned char *imagedata_buffer = s->buffer2; |
399 | 685 |
400 /* pointers to segments inside the compressed chunk */ | 686 /* pointers to segments inside the compressed chunk */ |
401 unsigned char *method1_segment; | 687 unsigned char *huffman_segment; |
402 unsigned char *size_segment; | 688 unsigned char *size_segment; |
403 unsigned char *vector_segment; | 689 unsigned char *vector_segment; |
404 unsigned char *method2_segment; | 690 unsigned char *imagedata_segment; |
405 | 691 |
406 method1_segment = s->buf + LE_16(&s->buf[0]); | 692 huffman_segment = s->buf + LE_16(&s->buf[0]); |
407 size_segment = s->buf + LE_16(&s->buf[2]); | 693 size_segment = s->buf + LE_16(&s->buf[2]); |
408 vector_segment = s->buf + LE_16(&s->buf[4]); | 694 vector_segment = s->buf + LE_16(&s->buf[4]); |
409 method2_segment = s->buf + LE_16(&s->buf[6]); | 695 imagedata_segment = s->buf + LE_16(&s->buf[6]); |
410 | 696 |
411 xan_decode_method_1(method1_buffer, method1_segment); | 697 xan_huffman_decode(opcode_buffer, huffman_segment); |
412 if (method2_segment[0] == 2) | 698 |
413 xan_decode_method_2(method2_buffer, method2_segment + 1); | 699 if (imagedata_segment[0] == 2) |
700 xan_unpack(imagedata_buffer, &imagedata_segment[1]); | |
414 else | 701 else |
415 method2_buffer = method2_segment + 1; | 702 imagedata_buffer = &imagedata_segment[1]; |
416 | 703 |
417 /* use the decoded data segments to build the frame */ | 704 /* use the decoded data segments to build the frame */ |
418 x = y = 0; | 705 x = y = 0; |
419 while (total_pixels) { | 706 while (total_pixels) { |
420 | 707 |
421 opcode = *method1_buffer++; | 708 opcode = *opcode_buffer++; |
422 size = 0; | 709 size = 0; |
423 | 710 |
424 switch (opcode) { | 711 switch (opcode) { |
425 | 712 |
426 case 0: | 713 case 0: |
471 flag ^= 1; | 758 flag ^= 1; |
472 if (flag) { | 759 if (flag) { |
473 /* run of (size) pixels is unchanged from last frame */ | 760 /* run of (size) pixels is unchanged from last frame */ |
474 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); | 761 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); |
475 } else { | 762 } else { |
476 /* output a run of pixels from method2_buffer */ | 763 /* output a run of pixels from imagedata_buffer */ |
477 xan_wc3_output_pixel_run(s, method2_buffer, x, y, size); | 764 xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size); |
478 method2_buffer += size; | 765 imagedata_buffer += size; |
479 } | 766 } |
480 } else { | 767 } else { |
481 /* run-based motion compensation from last frame */ | 768 /* run-based motion compensation from last frame */ |
482 motion_x = (*vector_segment >> 4) & 0xF; | 769 motion_x = (*vector_segment >> 4) & 0xF; |
483 motion_y = *vector_segment & 0xF; | 770 motion_y = *vector_segment & 0xF; |
506 x += size; | 793 x += size; |
507 size = 0; | 794 size = 0; |
508 } | 795 } |
509 } | 796 } |
510 } | 797 } |
798 | |
799 /* for PAL8, make the palette available on the way out */ | |
800 if (s->avctx->pix_fmt == PIX_FMT_PAL8) | |
801 memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); | |
511 } | 802 } |
512 | 803 |
513 static void xan_wc4_decode_frame(XanContext *s) { | 804 static void xan_wc4_decode_frame(XanContext *s) { |
514 } | 805 } |
515 | 806 |
530 | 821 |
531 if (avctx->get_buffer(avctx, &s->current_frame)) { | 822 if (avctx->get_buffer(avctx, &s->current_frame)) { |
532 printf (" Interplay Video: get_buffer() failed\n"); | 823 printf (" Interplay Video: get_buffer() failed\n"); |
533 return -1; | 824 return -1; |
534 } | 825 } |
826 s->current_frame.reference = 3; | |
535 | 827 |
536 s->buf = buf; | 828 s->buf = buf; |
537 s->size = buf_size; | 829 s->size = buf_size; |
538 | 830 |
539 if (avctx->codec->id == CODEC_ID_XAN_WC3) { | 831 if (avctx->codec->id == CODEC_ID_XAN_WC3) |
540 // if (keyframe) | 832 xan_wc3_decode_frame(s); |
541 if (1) | 833 else if (avctx->codec->id == CODEC_ID_XAN_WC4) |
542 xan_wc3_decode_frame(s); | |
543 else { | |
544 memcpy(s->current_frame.data[0], s->last_frame.data[0], | |
545 s->current_frame.linesize[0] * avctx->height); | |
546 memcpy(s->current_frame.data[1], s->last_frame.data[1], | |
547 s->current_frame.linesize[1] * avctx->height); | |
548 memcpy(s->current_frame.data[2], s->last_frame.data[2], | |
549 s->current_frame.linesize[2] * avctx->height); | |
550 } | |
551 } else if (avctx->codec->id == CODEC_ID_XAN_WC4) | |
552 xan_wc4_decode_frame(s); | 834 xan_wc4_decode_frame(s); |
553 | 835 |
554 /* release the last frame if it is allocated */ | 836 /* release the last frame if it is allocated */ |
555 if (s->last_frame.data[0]) | 837 if (s->last_frame.data[0]) |
556 avctx->release_buffer(avctx, &s->last_frame); | 838 avctx->release_buffer(avctx, &s->last_frame); |
557 | 839 |
558 /* shuffle frames */ | 840 /* shuffle frames */ |