Mercurial > libavcodec.hg
comparison vp56.c @ 5714:314be1cfdcb0 libavcodec
add a new vp6a codec (add alpha plan support to vp6)
author | aurel |
---|---|
date | Tue, 25 Sep 2007 19:12:46 +0000 |
parents | dae0f80edbb3 |
children | fbd55dbbf809 |
comparison
equal
deleted
inserted
replaced
5713:f45228f65e06 | 5714:314be1cfdcb0 |
---|---|
20 * License along with FFmpeg; if not, write to the Free Software | 20 * License along with FFmpeg; if not, write to the Free Software |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 */ | 22 */ |
23 | 23 |
24 #include "avcodec.h" | 24 #include "avcodec.h" |
25 #include "bytestream.h" | |
25 | 26 |
26 #include "vp56.h" | 27 #include "vp56.h" |
27 #include "vp56data.h" | 28 #include "vp56data.h" |
28 | 29 |
29 | 30 |
392 } else { | 393 } else { |
393 s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8); | 394 s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8); |
394 } | 395 } |
395 } | 396 } |
396 | 397 |
397 static void vp56_decode_mb(vp56_context_t *s, int row, int col) | 398 static void vp56_decode_mb(vp56_context_t *s, int row, int col, int is_alpha) |
398 { | 399 { |
399 AVFrame *frame_current, *frame_ref; | 400 AVFrame *frame_current, *frame_ref; |
400 vp56_mb_t mb_type; | 401 vp56_mb_t mb_type; |
401 vp56_frame_t ref_frame; | 402 vp56_frame_t ref_frame; |
402 int b, plan, off; | 403 int b, ab, b_max, plan, off; |
403 | 404 |
404 if (s->framep[VP56_FRAME_CURRENT]->key_frame) | 405 if (s->framep[VP56_FRAME_CURRENT]->key_frame) |
405 mb_type = VP56_MB_INTRA; | 406 mb_type = VP56_MB_INTRA; |
406 else | 407 else |
407 mb_type = vp56_decode_mv(s, row, col); | 408 mb_type = vp56_decode_mv(s, row, col); |
414 vp56_add_predictors_dc(s, ref_frame); | 415 vp56_add_predictors_dc(s, ref_frame); |
415 | 416 |
416 frame_current = s->framep[VP56_FRAME_CURRENT]; | 417 frame_current = s->framep[VP56_FRAME_CURRENT]; |
417 frame_ref = s->framep[ref_frame]; | 418 frame_ref = s->framep[ref_frame]; |
418 | 419 |
420 ab = 6*is_alpha; | |
421 b_max = 6 - 2*is_alpha; | |
422 | |
419 switch (mb_type) { | 423 switch (mb_type) { |
420 case VP56_MB_INTRA: | 424 case VP56_MB_INTRA: |
421 for (b=0; b<6; b++) { | 425 for (b=0; b<b_max; b++) { |
422 plan = vp56_b2p[b]; | 426 plan = vp56_b2p[b+ab]; |
423 s->dsp.idct_put(frame_current->data[plan] + s->block_offset[b], | 427 s->dsp.idct_put(frame_current->data[plan] + s->block_offset[b], |
424 s->stride[plan], s->block_coeff[b]); | 428 s->stride[plan], s->block_coeff[b]); |
425 } | 429 } |
426 break; | 430 break; |
427 | 431 |
428 case VP56_MB_INTER_NOVEC_PF: | 432 case VP56_MB_INTER_NOVEC_PF: |
429 case VP56_MB_INTER_NOVEC_GF: | 433 case VP56_MB_INTER_NOVEC_GF: |
430 for (b=0; b<6; b++) { | 434 for (b=0; b<b_max; b++) { |
431 plan = vp56_b2p[b]; | 435 plan = vp56_b2p[b+ab]; |
432 off = s->block_offset[b]; | 436 off = s->block_offset[b]; |
433 s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off, | 437 s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off, |
434 frame_ref->data[plan] + off, | 438 frame_ref->data[plan] + off, |
435 s->stride[plan], 8); | 439 s->stride[plan], 8); |
436 s->dsp.idct_add(frame_current->data[plan] + off, | 440 s->dsp.idct_add(frame_current->data[plan] + off, |
443 case VP56_MB_INTER_V2_PF: | 447 case VP56_MB_INTER_V2_PF: |
444 case VP56_MB_INTER_DELTA_GF: | 448 case VP56_MB_INTER_DELTA_GF: |
445 case VP56_MB_INTER_4V: | 449 case VP56_MB_INTER_4V: |
446 case VP56_MB_INTER_V1_GF: | 450 case VP56_MB_INTER_V1_GF: |
447 case VP56_MB_INTER_V2_GF: | 451 case VP56_MB_INTER_V2_GF: |
448 for (b=0; b<6; b++) { | 452 for (b=0; b<b_max; b++) { |
449 int x_off = b==1 || b==3 ? 8 : 0; | 453 int x_off = b==1 || b==3 ? 8 : 0; |
450 int y_off = b==2 || b==3 ? 8 : 0; | 454 int y_off = b==2 || b==3 ? 8 : 0; |
451 plan = vp56_b2p[b]; | 455 plan = vp56_b2p[b+ab]; |
452 vp56_mc(s, b, plan, frame_ref->data[plan], s->stride[plan], | 456 vp56_mc(s, b, plan, frame_ref->data[plan], s->stride[plan], |
453 16*col+x_off, 16*row+y_off); | 457 16*col+x_off, 16*row+y_off); |
454 s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b], | 458 s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b], |
455 s->stride[plan], s->block_coeff[b]); | 459 s->stride[plan], s->block_coeff[b]); |
456 } | 460 } |
462 { | 466 { |
463 vp56_context_t *s = avctx->priv_data; | 467 vp56_context_t *s = avctx->priv_data; |
464 int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; | 468 int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; |
465 int i; | 469 int i; |
466 | 470 |
467 s->plane_width[0] = avctx->coded_width; | 471 s->plane_width[0] = s->plane_width[3] = avctx->coded_width; |
468 s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; | 472 s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; |
469 s->plane_height[0] = avctx->coded_height; | 473 s->plane_height[0] = s->plane_height[3] = avctx->coded_height; |
470 s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; | 474 s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; |
471 | 475 |
472 for (i=0; i<3; i++) | 476 for (i=0; i<4; i++) |
473 s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; | 477 s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; |
474 | 478 |
475 s->mb_width = (avctx->coded_width +15) / 16; | 479 s->mb_width = (avctx->coded_width +15) / 16; |
476 s->mb_height = (avctx->coded_height+15) / 16; | 480 s->mb_height = (avctx->coded_height+15) / 16; |
477 | 481 |
496 int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 500 int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
497 uint8_t *buf, int buf_size) | 501 uint8_t *buf, int buf_size) |
498 { | 502 { |
499 vp56_context_t *s = avctx->priv_data; | 503 vp56_context_t *s = avctx->priv_data; |
500 AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; | 504 AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; |
505 int is_alpha, alpha_offset; | |
506 | |
507 if (s->has_alpha) { | |
508 alpha_offset = bytestream_get_be24(&buf); | |
509 buf_size -= 3; | |
510 } | |
511 | |
512 for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) { | |
501 int mb_row, mb_col, mb_row_flip, mb_offset = 0; | 513 int mb_row, mb_col, mb_row_flip, mb_offset = 0; |
502 int block, y, uv, stride_y, stride_uv; | 514 int block, y, uv, stride_y, stride_uv; |
503 int golden_frame = 0; | 515 int golden_frame = 0; |
504 int res; | 516 int res; |
505 | 517 |
506 s->modelp = &s->models; | 518 s->modelp = &s->models[is_alpha]; |
507 | 519 |
508 res = s->parse_header(s, buf, buf_size, &golden_frame); | 520 res = s->parse_header(s, buf, buf_size, &golden_frame); |
509 if (!res) | 521 if (!res) |
510 return -1; | 522 return -1; |
511 | 523 |
524 if (!is_alpha) { | |
512 p->reference = 1; | 525 p->reference = 1; |
513 if (avctx->get_buffer(avctx, p) < 0) { | 526 if (avctx->get_buffer(avctx, p) < 0) { |
514 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 527 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
515 return -1; | 528 return -1; |
516 } | 529 } |
518 if (res == 2) | 531 if (res == 2) |
519 if (vp56_size_changed(avctx)) { | 532 if (vp56_size_changed(avctx)) { |
520 avctx->release_buffer(avctx, p); | 533 avctx->release_buffer(avctx, p); |
521 return -1; | 534 return -1; |
522 } | 535 } |
536 } | |
523 | 537 |
524 if (p->key_frame) { | 538 if (p->key_frame) { |
525 p->pict_type = FF_I_TYPE; | 539 p->pict_type = FF_I_TYPE; |
526 s->default_models_init(s); | 540 s->default_models_init(s); |
527 for (block=0; block<s->mb_height*s->mb_width; block++) | 541 for (block=0; block<s->mb_height*s->mb_width; block++) |
581 s->block_offset[3] = s->block_offset[2] + 8; | 595 s->block_offset[3] = s->block_offset[2] + 8; |
582 s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; | 596 s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; |
583 s->block_offset[5] = s->block_offset[4]; | 597 s->block_offset[5] = s->block_offset[4]; |
584 | 598 |
585 for (mb_col=0; mb_col<s->mb_width; mb_col++) { | 599 for (mb_col=0; mb_col<s->mb_width; mb_col++) { |
586 vp56_decode_mb(s, mb_row, mb_col); | 600 vp56_decode_mb(s, mb_row, mb_col, is_alpha); |
587 | 601 |
588 for (y=0; y<4; y++) { | 602 for (y=0; y<4; y++) { |
589 s->above_block_idx[y] += 2; | 603 s->above_block_idx[y] += 2; |
590 s->block_offset[y] += 16; | 604 s->block_offset[y] += 16; |
591 } | 605 } |
595 s->block_offset[uv] += 8; | 609 s->block_offset[uv] += 8; |
596 } | 610 } |
597 } | 611 } |
598 } | 612 } |
599 | 613 |
600 if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN]) | |
601 FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], | |
602 s->framep[VP56_FRAME_UNUSED]); | |
603 else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) | |
604 avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); | |
605 if (p->key_frame || golden_frame) { | 614 if (p->key_frame || golden_frame) { |
606 if (s->framep[VP56_FRAME_GOLDEN]->data[0]) | 615 if (s->framep[VP56_FRAME_GOLDEN]->data[0] && |
616 s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) | |
607 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); | 617 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); |
608 s->framep[VP56_FRAME_GOLDEN] = p; | 618 s->framep[VP56_FRAME_GOLDEN] = p; |
609 } | 619 } |
620 | |
621 if (s->has_alpha) { | |
622 FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], | |
623 s->framep[VP56_FRAME_GOLDEN2]); | |
624 buf += alpha_offset; | |
625 buf_size -= alpha_offset; | |
626 } | |
627 } | |
628 | |
629 if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] || | |
630 s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) { | |
631 if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] && | |
632 s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2]) | |
633 FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], | |
634 s->framep[VP56_FRAME_UNUSED]); | |
635 else | |
636 FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], | |
637 s->framep[VP56_FRAME_UNUSED2]); | |
638 } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) | |
639 avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); | |
610 FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], | 640 FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], |
611 s->framep[VP56_FRAME_PREVIOUS]); | 641 s->framep[VP56_FRAME_PREVIOUS]); |
612 | 642 |
613 *(AVFrame*)data = *p; | 643 *(AVFrame*)data = *p; |
614 *data_size = sizeof(AVFrame); | 644 *data_size = sizeof(AVFrame); |
615 | 645 |
616 return buf_size; | 646 return buf_size; |
617 } | 647 } |
618 | 648 |
619 void vp56_init(AVCodecContext *avctx, int flip) | 649 void vp56_init(AVCodecContext *avctx, int flip, int has_alpha) |
620 { | 650 { |
621 vp56_context_t *s = avctx->priv_data; | 651 vp56_context_t *s = avctx->priv_data; |
622 int i; | 652 int i; |
623 | 653 |
624 s->avctx = avctx; | 654 s->avctx = avctx; |
625 avctx->pix_fmt = PIX_FMT_YUV420P; | 655 avctx->pix_fmt = has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; |
626 | 656 |
627 if (avctx->idct_algo == FF_IDCT_AUTO) | 657 if (avctx->idct_algo == FF_IDCT_AUTO) |
628 avctx->idct_algo = FF_IDCT_VP3; | 658 avctx->idct_algo = FF_IDCT_VP3; |
629 dsputil_init(&s->dsp, avctx); | 659 dsputil_init(&s->dsp, avctx); |
630 ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); | 660 ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); |
631 | 661 |
632 avcodec_set_dimensions(avctx, 0, 0); | 662 avcodec_set_dimensions(avctx, 0, 0); |
633 | 663 |
634 for (i=0; i<3; i++) | 664 for (i=0; i<4; i++) |
635 s->framep[i] = &s->frames[i]; | 665 s->framep[i] = &s->frames[i]; |
636 s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; | 666 s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; |
667 s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2]; | |
637 s->edge_emu_buffer_alloc = NULL; | 668 s->edge_emu_buffer_alloc = NULL; |
638 | 669 |
639 s->above_blocks = NULL; | 670 s->above_blocks = NULL; |
640 s->macroblocks = NULL; | 671 s->macroblocks = NULL; |
641 s->quantizer = -1; | 672 s->quantizer = -1; |
642 s->deblock_filtering = 1; | 673 s->deblock_filtering = 1; |
643 | 674 |
644 s->filter = NULL; | 675 s->filter = NULL; |
645 | 676 |
677 s->has_alpha = has_alpha; | |
646 if (flip) { | 678 if (flip) { |
647 s->flip = -1; | 679 s->flip = -1; |
648 s->frbi = 2; | 680 s->frbi = 2; |
649 s->srbi = 0; | 681 s->srbi = 0; |
650 } else { | 682 } else { |
661 av_free(s->above_blocks); | 693 av_free(s->above_blocks); |
662 av_free(s->macroblocks); | 694 av_free(s->macroblocks); |
663 av_free(s->edge_emu_buffer_alloc); | 695 av_free(s->edge_emu_buffer_alloc); |
664 if (s->framep[VP56_FRAME_GOLDEN]->data[0]) | 696 if (s->framep[VP56_FRAME_GOLDEN]->data[0]) |
665 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); | 697 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); |
698 if (s->framep[VP56_FRAME_GOLDEN2]->data[0]) | |
699 avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]); | |
666 if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) | 700 if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) |
667 avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); | 701 avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); |
668 return 0; | 702 return 0; |
669 } | 703 } |