00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035
00036 #include "common.h"
00037 #include "avcodec.h"
00038 #include "dsputil.h"
00039
00040 #define PALETTE_COUNT 256
00041 #define PALETTE_CONTROL_SIZE ((256 * 3) + 1)
00042
00043 typedef struct XanContext {
00044
00045 AVCodecContext *avctx;
00046 DSPContext dsp;
00047 AVFrame last_frame;
00048 AVFrame current_frame;
00049
00050 unsigned char *buf;
00051 int size;
00052
00053 unsigned char palette[PALETTE_COUNT * 4];
00054
00055
00056 unsigned char *buffer1;
00057 unsigned char *buffer2;
00058
00059 } XanContext;
00060
00061
00062 #define SCALEFACTOR 65536
00063 #define CENTERSAMPLE 128
00064
00065 #define COMPUTE_Y(r, g, b) \
00066 (unsigned char) \
00067 ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR)
00068 #define COMPUTE_U(r, g, b) \
00069 (unsigned char) \
00070 ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
00071 #define COMPUTE_V(r, g, b) \
00072 (unsigned char) \
00073 ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
00074
00075 #define Y_R (SCALEFACTOR * 0.29900)
00076 #define Y_G (SCALEFACTOR * 0.58700)
00077 #define Y_B (SCALEFACTOR * 0.11400)
00078
00079 #define U_R (SCALEFACTOR * -0.16874)
00080 #define U_G (SCALEFACTOR * -0.33126)
00081 #define U_B (SCALEFACTOR * 0.50000)
00082
00083 #define V_R (SCALEFACTOR * 0.50000)
00084 #define V_G (SCALEFACTOR * -0.41869)
00085 #define V_B (SCALEFACTOR * -0.08131)
00086
00087
00088
00089
00090
00091 static int y_r_table[256];
00092 static int y_g_table[256];
00093 static int y_b_table[256];
00094
00095 static int u_r_table[256];
00096 static int u_g_table[256];
00097 static int u_b_table[256];
00098
00099 static int v_r_table[256];
00100 static int v_g_table[256];
00101 static int v_b_table[256];
00102
00103 static int xan_decode_init(AVCodecContext *avctx)
00104 {
00105 XanContext *s = avctx->priv_data;
00106 int i;
00107
00108 s->avctx = avctx;
00109
00110 if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
00111 (s->avctx->palctrl == NULL)) {
00112 av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n");
00113 return -1;
00114 }
00115
00116 avctx->pix_fmt = PIX_FMT_PAL8;
00117 avctx->has_b_frames = 0;
00118 dsputil_init(&s->dsp, avctx);
00119
00120
00121 for (i = 0; i < 256; i++) {
00122 y_r_table[i] = Y_R * i;
00123 y_g_table[i] = Y_G * i;
00124 y_b_table[i] = Y_B * i;
00125
00126 u_r_table[i] = U_R * i;
00127 u_g_table[i] = U_G * i;
00128 u_b_table[i] = U_B * i;
00129
00130 v_r_table[i] = V_R * i;
00131 v_g_table[i] = V_G * i;
00132 v_b_table[i] = V_B * i;
00133 }
00134
00135 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
00136 return -1;
00137
00138 s->buffer1 = av_malloc(avctx->width * avctx->height);
00139 s->buffer2 = av_malloc(avctx->width * avctx->height);
00140 if (!s->buffer1 || !s->buffer2)
00141 return -1;
00142
00143 return 0;
00144 }
00145
00146
00147
00148
00149
00150
00151 static inline void bytecopy(unsigned char *dest, unsigned char *src, int count)
00152 {
00153 int i;
00154
00155 for (i = 0; i < count; i++)
00156 dest[i] = src[i];
00157 }
00158
00159 static int xan_huffman_decode(unsigned char *dest, unsigned char *src)
00160 {
00161 unsigned char byte = *src++;
00162 unsigned char ival = byte + 0x16;
00163 unsigned char * ptr = src + byte*2;
00164 unsigned char val = ival;
00165 int counter = 0;
00166
00167 unsigned char bits = *ptr++;
00168
00169 while ( val != 0x16 ) {
00170 if ( (1 << counter) & bits )
00171 val = src[byte + val - 0x17];
00172 else
00173 val = src[val - 0x17];
00174
00175 if ( val < 0x16 ) {
00176 *dest++ = val;
00177 val = ival;
00178 }
00179
00180 if (counter++ == 7) {
00181 counter = 0;
00182 bits = *ptr++;
00183 }
00184 }
00185
00186 return 0;
00187 }
00188
00189 static void xan_unpack(unsigned char *dest, unsigned char *src)
00190 {
00191 unsigned char opcode;
00192 int size;
00193 int offset;
00194 int byte1, byte2, byte3;
00195
00196 for (;;) {
00197 opcode = *src++;
00198
00199 if ( (opcode & 0x80) == 0 ) {
00200
00201 offset = *src++;
00202
00203 size = opcode & 3;
00204 bytecopy(dest, src, size); dest += size; src += size;
00205
00206 size = ((opcode & 0x1c) >> 2) + 3;
00207 bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size);
00208 dest += size;
00209
00210 } else if ( (opcode & 0x40) == 0 ) {
00211
00212 byte1 = *src++;
00213 byte2 = *src++;
00214
00215 size = byte1 >> 6;
00216 bytecopy (dest, src, size); dest += size; src += size;
00217
00218 size = (opcode & 0x3f) + 4;
00219 bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size);
00220 dest += size;
00221
00222 } else if ( (opcode & 0x20) == 0 ) {
00223
00224 byte1 = *src++;
00225 byte2 = *src++;
00226 byte3 = *src++;
00227
00228 size = opcode & 3;
00229 bytecopy (dest, src, size); dest += size; src += size;
00230
00231 size = byte3 + 5 + ((opcode & 0xc) << 6);
00232 bytecopy (dest,
00233 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2),
00234 size);
00235 dest += size;
00236 } else {
00237 size = ((opcode & 0x1f) << 2) + 4;
00238
00239 if (size > 0x70)
00240 break;
00241
00242 bytecopy (dest, src, size); dest += size; src += size;
00243 }
00244 }
00245
00246 size = opcode & 3;
00247 bytecopy(dest, src, size); dest += size; src += size;
00248 }
00249
00250 static void inline xan_wc3_build_palette(XanContext *s,
00251 unsigned int *palette_data)
00252 {
00253 int i;
00254 unsigned char r, g, b;
00255 unsigned short *palette16;
00256 unsigned int *palette32;
00257 unsigned int pal_elem;
00258
00259
00260
00261
00262 switch (s->avctx->pix_fmt) {
00263
00264 case PIX_FMT_RGB555:
00265 palette16 = (unsigned short *)s->palette;
00266 for (i = 0; i < PALETTE_COUNT; i++) {
00267 pal_elem = palette_data[i];
00268 r = (pal_elem >> 16) & 0xff;
00269 g = (pal_elem >> 8) & 0xff;
00270 b = pal_elem & 0xff;
00271 palette16[i] =
00272 ((r >> 3) << 10) |
00273 ((g >> 3) << 5) |
00274 ((b >> 3) << 0);
00275 }
00276 break;
00277
00278 case PIX_FMT_RGB565:
00279 palette16 = (unsigned short *)s->palette;
00280 for (i = 0; i < PALETTE_COUNT; i++) {
00281 pal_elem = palette_data[i];
00282 r = (pal_elem >> 16) & 0xff;
00283 g = (pal_elem >> 8) & 0xff;
00284 b = pal_elem & 0xff;
00285 palette16[i] =
00286 ((r >> 3) << 11) |
00287 ((g >> 2) << 5) |
00288 ((b >> 3) << 0);
00289 }
00290 break;
00291
00292 case PIX_FMT_RGB24:
00293 for (i = 0; i < PALETTE_COUNT; i++) {
00294 pal_elem = palette_data[i];
00295 r = (pal_elem >> 16) & 0xff;
00296 g = (pal_elem >> 8) & 0xff;
00297 b = pal_elem & 0xff;
00298 s->palette[i * 4 + 0] = r;
00299 s->palette[i * 4 + 1] = g;
00300 s->palette[i * 4 + 2] = b;
00301 }
00302 break;
00303
00304 case PIX_FMT_BGR24:
00305 for (i = 0; i < PALETTE_COUNT; i++) {
00306 pal_elem = palette_data[i];
00307 r = (pal_elem >> 16) & 0xff;
00308 g = (pal_elem >> 8) & 0xff;
00309 b = pal_elem & 0xff;
00310 s->palette[i * 4 + 0] = b;
00311 s->palette[i * 4 + 1] = g;
00312 s->palette[i * 4 + 2] = r;
00313 }
00314 break;
00315
00316 case PIX_FMT_PAL8:
00317 case PIX_FMT_RGBA32:
00318 palette32 = (unsigned int *)s->palette;
00319 memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int));
00320 break;
00321
00322 case PIX_FMT_YUV444P:
00323 for (i = 0; i < PALETTE_COUNT; i++) {
00324 pal_elem = palette_data[i];
00325 r = (pal_elem >> 16) & 0xff;
00326 g = (pal_elem >> 8) & 0xff;
00327 b = pal_elem & 0xff;
00328 s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b);
00329 s->palette[i * 4 + 1] = COMPUTE_U(r, g, b);
00330 s->palette[i * 4 + 2] = COMPUTE_V(r, g, b);
00331 }
00332 break;
00333
00334 default:
00335 av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");
00336 break;
00337 }
00338 }
00339
00340
00341
00342 #define ADVANCE_CURRENT_X() \
00343 current_x++; \
00344 if (current_x >= width) { \
00345 index += line_inc; \
00346 current_x = 0; \
00347 }
00348
00349 static void inline xan_wc3_output_pixel_run(XanContext *s,
00350 unsigned char *pixel_buffer, int x, int y, int pixel_count)
00351 {
00352 int stride;
00353 int line_inc;
00354 int index;
00355 int current_x;
00356 int width = s->avctx->width;
00357 unsigned char pix;
00358 unsigned char *palette_plane;
00359 unsigned char *y_plane;
00360 unsigned char *u_plane;
00361 unsigned char *v_plane;
00362 unsigned char *rgb_plane;
00363 unsigned short *rgb16_plane;
00364 unsigned short *palette16;
00365 unsigned int *rgb32_plane;
00366 unsigned int *palette32;
00367
00368 switch (s->avctx->pix_fmt) {
00369
00370 case PIX_FMT_PAL8:
00371 palette_plane = s->current_frame.data[0];
00372 stride = s->current_frame.linesize[0];
00373 line_inc = stride - width;
00374 index = y * stride + x;
00375 current_x = x;
00376 while(pixel_count--) {
00377
00378
00379
00380 palette_plane[index++] = *pixel_buffer++;
00381
00382 ADVANCE_CURRENT_X();
00383 }
00384 break;
00385
00386 case PIX_FMT_RGB555:
00387 case PIX_FMT_RGB565:
00388 rgb16_plane = (unsigned short *)s->current_frame.data[0];
00389 palette16 = (unsigned short *)s->palette;
00390 stride = s->current_frame.linesize[0] / 2;
00391 line_inc = stride - width;
00392 index = y * stride + x;
00393 current_x = x;
00394 while(pixel_count--) {
00395
00396 rgb16_plane[index++] = palette16[*pixel_buffer++];
00397
00398 ADVANCE_CURRENT_X();
00399 }
00400 break;
00401
00402 case PIX_FMT_RGB24:
00403 case PIX_FMT_BGR24:
00404 rgb_plane = s->current_frame.data[0];
00405 stride = s->current_frame.linesize[0];
00406 line_inc = stride - width * 3;
00407 index = y * stride + x * 3;
00408 current_x = x;
00409 while(pixel_count--) {
00410 pix = *pixel_buffer++;
00411
00412 rgb_plane[index++] = s->palette[pix * 4 + 0];
00413 rgb_plane[index++] = s->palette[pix * 4 + 1];
00414 rgb_plane[index++] = s->palette[pix * 4 + 2];
00415
00416 ADVANCE_CURRENT_X();
00417 }
00418 break;
00419
00420 case PIX_FMT_RGBA32:
00421 rgb32_plane = (unsigned int *)s->current_frame.data[0];
00422 palette32 = (unsigned int *)s->palette;
00423 stride = s->current_frame.linesize[0] / 4;
00424 line_inc = stride - width;
00425 index = y * stride + x;
00426 current_x = x;
00427 while(pixel_count--) {
00428
00429 rgb32_plane[index++] = palette32[*pixel_buffer++];
00430
00431 ADVANCE_CURRENT_X();
00432 }
00433 break;
00434
00435 case PIX_FMT_YUV444P:
00436 y_plane = s->current_frame.data[0];
00437 u_plane = s->current_frame.data[1];
00438 v_plane = s->current_frame.data[2];
00439 stride = s->current_frame.linesize[0];
00440 line_inc = stride - width;
00441 index = y * stride + x;
00442 current_x = x;
00443 while(pixel_count--) {
00444 pix = *pixel_buffer++;
00445
00446 y_plane[index] = s->palette[pix * 4 + 0];
00447 u_plane[index] = s->palette[pix * 4 + 1];
00448 v_plane[index] = s->palette[pix * 4 + 2];
00449
00450 index++;
00451 ADVANCE_CURRENT_X();
00452 }
00453 break;
00454
00455 default:
00456 av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");
00457 break;
00458 }
00459 }
00460
00461 #define ADVANCE_CURFRAME_X() \
00462 curframe_x++; \
00463 if (curframe_x >= width) { \
00464 curframe_index += line_inc; \
00465 curframe_x = 0; \
00466 }
00467
00468 #define ADVANCE_PREVFRAME_X() \
00469 prevframe_x++; \
00470 if (prevframe_x >= width) { \
00471 prevframe_index += line_inc; \
00472 prevframe_x = 0; \
00473 }
00474
00475 static void inline xan_wc3_copy_pixel_run(XanContext *s,
00476 int x, int y, int pixel_count, int motion_x, int motion_y)
00477 {
00478 int stride;
00479 int line_inc;
00480 int curframe_index, prevframe_index;
00481 int curframe_x, prevframe_x;
00482 int width = s->avctx->width;
00483 unsigned char *palette_plane, *prev_palette_plane;
00484 unsigned char *y_plane, *u_plane, *v_plane;
00485 unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane;
00486 unsigned char *rgb_plane, *prev_rgb_plane;
00487 unsigned short *rgb16_plane, *prev_rgb16_plane;
00488 unsigned int *rgb32_plane, *prev_rgb32_plane;
00489
00490 switch (s->avctx->pix_fmt) {
00491
00492 case PIX_FMT_PAL8:
00493 palette_plane = s->current_frame.data[0];
00494 prev_palette_plane = s->last_frame.data[0];
00495 stride = s->current_frame.linesize[0];
00496 line_inc = stride - width;
00497 curframe_index = y * stride + x;
00498 curframe_x = x;
00499 prevframe_index = (y + motion_y) * stride + x + motion_x;
00500 prevframe_x = x + motion_x;
00501 while(pixel_count--) {
00502
00503 palette_plane[curframe_index++] =
00504 prev_palette_plane[prevframe_index++];
00505
00506 ADVANCE_CURFRAME_X();
00507 ADVANCE_PREVFRAME_X();
00508 }
00509 break;
00510
00511 case PIX_FMT_RGB555:
00512 case PIX_FMT_RGB565:
00513 rgb16_plane = (unsigned short *)s->current_frame.data[0];
00514 prev_rgb16_plane = (unsigned short *)s->last_frame.data[0];
00515 stride = s->current_frame.linesize[0] / 2;
00516 line_inc = stride - width;
00517 curframe_index = y * stride + x;
00518 curframe_x = x;
00519 prevframe_index = (y + motion_y) * stride + x + motion_x;
00520 prevframe_x = x + motion_x;
00521 while(pixel_count--) {
00522
00523 rgb16_plane[curframe_index++] =
00524 prev_rgb16_plane[prevframe_index++];
00525
00526 ADVANCE_CURFRAME_X();
00527 ADVANCE_PREVFRAME_X();
00528 }
00529 break;
00530
00531 case PIX_FMT_RGB24:
00532 case PIX_FMT_BGR24:
00533 rgb_plane = s->current_frame.data[0];
00534 prev_rgb_plane = s->last_frame.data[0];
00535 stride = s->current_frame.linesize[0];
00536 line_inc = stride - width * 3;
00537 curframe_index = y * stride + x * 3;
00538 curframe_x = x;
00539 prevframe_index = (y + motion_y) * stride +
00540 (3 * (x + motion_x));
00541 prevframe_x = x + motion_x;
00542 while(pixel_count--) {
00543
00544 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
00545 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
00546 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
00547
00548 ADVANCE_CURFRAME_X();
00549 ADVANCE_PREVFRAME_X();
00550 }
00551 break;
00552
00553 case PIX_FMT_RGBA32:
00554 rgb32_plane = (unsigned int *)s->current_frame.data[0];
00555 prev_rgb32_plane = (unsigned int *)s->last_frame.data[0];
00556 stride = s->current_frame.linesize[0] / 4;
00557 line_inc = stride - width;
00558 curframe_index = y * stride + x;
00559 curframe_x = x;
00560 prevframe_index = (y + motion_y) * stride + x + motion_x;
00561 prevframe_x = x + motion_x;
00562 while(pixel_count--) {
00563
00564 rgb32_plane[curframe_index++] =
00565 prev_rgb32_plane[prevframe_index++];
00566
00567 ADVANCE_CURFRAME_X();
00568 ADVANCE_PREVFRAME_X();
00569 }
00570 break;
00571
00572 case PIX_FMT_YUV444P:
00573 y_plane = s->current_frame.data[0];
00574 u_plane = s->current_frame.data[1];
00575 v_plane = s->current_frame.data[2];
00576 prev_y_plane = s->last_frame.data[0];
00577 prev_u_plane = s->last_frame.data[1];
00578 prev_v_plane = s->last_frame.data[2];
00579 stride = s->current_frame.linesize[0];
00580 line_inc = stride - width;
00581 curframe_index = y * stride + x;
00582 curframe_x = x;
00583 prevframe_index = (y + motion_y) * stride + x + motion_x;
00584 prevframe_x = x + motion_x;
00585 while(pixel_count--) {
00586
00587 y_plane[curframe_index] = prev_y_plane[prevframe_index];
00588 u_plane[curframe_index] = prev_u_plane[prevframe_index];
00589 v_plane[curframe_index] = prev_v_plane[prevframe_index];
00590
00591 curframe_index++;
00592 ADVANCE_CURFRAME_X();
00593 prevframe_index++;
00594 ADVANCE_PREVFRAME_X();
00595 }
00596 break;
00597
00598 default:
00599 av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");
00600 break;
00601 }
00602 }
00603
00604 static void xan_wc3_decode_frame(XanContext *s) {
00605
00606 int width = s->avctx->width;
00607 int height = s->avctx->height;
00608 int total_pixels = width * height;
00609 unsigned char opcode;
00610 unsigned char flag = 0;
00611 int size = 0;
00612 int motion_x, motion_y;
00613 int x, y;
00614
00615 unsigned char *opcode_buffer = s->buffer1;
00616 unsigned char *imagedata_buffer = s->buffer2;
00617
00618
00619 unsigned char *huffman_segment;
00620 unsigned char *size_segment;
00621 unsigned char *vector_segment;
00622 unsigned char *imagedata_segment;
00623
00624 huffman_segment = s->buf + LE_16(&s->buf[0]);
00625 size_segment = s->buf + LE_16(&s->buf[2]);
00626 vector_segment = s->buf + LE_16(&s->buf[4]);
00627 imagedata_segment = s->buf + LE_16(&s->buf[6]);
00628
00629 xan_huffman_decode(opcode_buffer, huffman_segment);
00630
00631 if (imagedata_segment[0] == 2)
00632 xan_unpack(imagedata_buffer, &imagedata_segment[1]);
00633 else
00634 imagedata_buffer = &imagedata_segment[1];
00635
00636
00637 x = y = 0;
00638 while (total_pixels) {
00639
00640 opcode = *opcode_buffer++;
00641 size = 0;
00642
00643 switch (opcode) {
00644
00645 case 0:
00646 flag ^= 1;
00647 continue;
00648
00649 case 1:
00650 case 2:
00651 case 3:
00652 case 4:
00653 case 5:
00654 case 6:
00655 case 7:
00656 case 8:
00657 size = opcode;
00658 break;
00659
00660 case 12:
00661 case 13:
00662 case 14:
00663 case 15:
00664 case 16:
00665 case 17:
00666 case 18:
00667 size += (opcode - 10);
00668 break;
00669
00670 case 9:
00671 case 19:
00672 size = *size_segment++;
00673 break;
00674
00675 case 10:
00676 case 20:
00677 size = BE_16(&size_segment[0]);
00678 size_segment += 2;
00679 break;
00680
00681 case 11:
00682 case 21:
00683 size = (size_segment[0] << 16) | (size_segment[1] << 8) |
00684 size_segment[2];
00685 size_segment += 3;
00686 break;
00687 }
00688
00689 if (opcode < 12) {
00690 flag ^= 1;
00691 if (flag) {
00692
00693 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
00694 } else {
00695
00696 xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
00697 imagedata_buffer += size;
00698 }
00699 } else {
00700
00701 motion_x = (*vector_segment >> 4) & 0xF;
00702 motion_y = *vector_segment & 0xF;
00703 vector_segment++;
00704
00705
00706 if (motion_x & 0x8)
00707 motion_x |= 0xFFFFFFF0;
00708 if (motion_y & 0x8)
00709 motion_y |= 0xFFFFFFF0;
00710
00711
00712 xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
00713
00714 flag = 0;
00715 }
00716
00717
00718 total_pixels -= size;
00719 while (size) {
00720 if (x + size >= width) {
00721 y++;
00722 size -= (width - x);
00723 x = 0;
00724 } else {
00725 x += size;
00726 size = 0;
00727 }
00728 }
00729 }
00730
00731
00732 if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
00733 memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
00734 s->current_frame.palette_has_changed = 1;
00735 s->avctx->palctrl->palette_changed = 0;
00736 }
00737 }
00738
00739 static void xan_wc4_decode_frame(XanContext *s) {
00740 }
00741
00742 static int xan_decode_frame(AVCodecContext *avctx,
00743 void *data, int *data_size,
00744 uint8_t *buf, int buf_size)
00745 {
00746 XanContext *s = avctx->priv_data;
00747 AVPaletteControl *palette_control = avctx->palctrl;
00748 int keyframe = 0;
00749
00750 if (palette_control->palette_changed) {
00751
00752 xan_wc3_build_palette(s, palette_control->palette);
00753
00754 if (s->avctx->pix_fmt != PIX_FMT_PAL8)
00755 palette_control->palette_changed = 0;
00756 keyframe = 1;
00757 }
00758
00759 if (avctx->get_buffer(avctx, &s->current_frame)) {
00760 av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n");
00761 return -1;
00762 }
00763 s->current_frame.reference = 3;
00764
00765 s->buf = buf;
00766 s->size = buf_size;
00767
00768 if (avctx->codec->id == CODEC_ID_XAN_WC3)
00769 xan_wc3_decode_frame(s);
00770 else if (avctx->codec->id == CODEC_ID_XAN_WC4)
00771 xan_wc4_decode_frame(s);
00772
00773
00774 if (s->last_frame.data[0])
00775 avctx->release_buffer(avctx, &s->last_frame);
00776
00777
00778 s->last_frame = s->current_frame;
00779
00780 *data_size = sizeof(AVFrame);
00781 *(AVFrame*)data = s->current_frame;
00782
00783
00784 return buf_size;
00785 }
00786
00787 static int xan_decode_end(AVCodecContext *avctx)
00788 {
00789 XanContext *s = avctx->priv_data;
00790
00791
00792 avctx->release_buffer(avctx, &s->last_frame);
00793
00794 av_free(s->buffer1);
00795 av_free(s->buffer2);
00796
00797 return 0;
00798 }
00799
00800 AVCodec xan_wc3_decoder = {
00801 "xan_wc3",
00802 CODEC_TYPE_VIDEO,
00803 CODEC_ID_XAN_WC3,
00804 sizeof(XanContext),
00805 xan_decode_init,
00806 NULL,
00807 xan_decode_end,
00808 xan_decode_frame,
00809 CODEC_CAP_DR1,
00810 };
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824