Mercurial > libavcodec.hg
comparison svq1.c @ 2017:f089d25c82f0 libavcodec
motion estimation for SVQ1
author | michael |
---|---|
date | Wed, 12 May 2004 02:03:24 +0000 |
parents | b7c82b9ef098 |
children | 552ae05eb513 |
comparison
equal
deleted
inserted
replaced
2016:f8ef6f664234 | 2017:f089d25c82f0 |
---|---|
46 #include "bswap.h" | 46 #include "bswap.h" |
47 | 47 |
48 #undef NDEBUG | 48 #undef NDEBUG |
49 #include <assert.h> | 49 #include <assert.h> |
50 | 50 |
51 extern const uint8_t mvtab[33][2]; | |
52 | |
51 static VLC svq1_block_type; | 53 static VLC svq1_block_type; |
52 static VLC svq1_motion_component; | 54 static VLC svq1_motion_component; |
53 static VLC svq1_intra_multistage[6]; | 55 static VLC svq1_intra_multistage[6]; |
54 static VLC svq1_inter_multistage[6]; | 56 static VLC svq1_inter_multistage[6]; |
55 static VLC svq1_intra_mean; | 57 static VLC svq1_intra_mean; |
56 static VLC svq1_inter_mean; | 58 static VLC svq1_inter_mean; |
57 | 59 |
58 #define MEDIAN(a,b,c) (((a < b) != (b >= c)) ? b : (((a < c) != (c > b)) ? c : a)) | |
59 | |
60 #define SVQ1_BLOCK_SKIP 0 | 60 #define SVQ1_BLOCK_SKIP 0 |
61 #define SVQ1_BLOCK_INTER 1 | 61 #define SVQ1_BLOCK_INTER 1 |
62 #define SVQ1_BLOCK_INTER_4V 2 | 62 #define SVQ1_BLOCK_INTER_4V 2 |
63 #define SVQ1_BLOCK_INTRA 3 | 63 #define SVQ1_BLOCK_INTRA 3 |
64 | 64 |
65 typedef struct SVQ1Context { | 65 typedef struct SVQ1Context { |
66 | 66 MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independant of MpegEncContext, so this will be removed then (FIXME/XXX) |
67 AVCodecContext *avctx; | 67 AVCodecContext *avctx; |
68 DSPContext dsp; | 68 DSPContext dsp; |
69 AVFrame picture; | 69 AVFrame picture; |
70 AVFrame current_picture; | 70 AVFrame current_picture; |
71 AVFrame last_picture; | 71 AVFrame last_picture; |
84 /* U & V plane (C planes) block dimensions */ | 84 /* U & V plane (C planes) block dimensions */ |
85 int c_block_width; | 85 int c_block_width; |
86 int c_block_height; | 86 int c_block_height; |
87 | 87 |
88 unsigned char *c_plane; | 88 unsigned char *c_plane; |
89 | |
90 uint16_t *mb_type; | |
91 uint32_t *dummy; | |
92 int16_t (*motion_val8[3])[2]; | |
93 int16_t (*motion_val16[3])[2]; | |
89 | 94 |
90 int64_t rd_total; | 95 int64_t rd_total; |
91 } SVQ1Context; | 96 } SVQ1Context; |
92 | 97 |
93 /* motion vector (prediction) */ | 98 /* motion vector (prediction) */ |
347 int i; | 352 int i; |
348 | 353 |
349 for (i=0; i < 2; i++) { | 354 for (i=0; i < 2; i++) { |
350 | 355 |
351 /* get motion code */ | 356 /* get motion code */ |
352 diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2) - 32; | 357 diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2); |
358 if(diff<0) | |
359 return -1; | |
360 else if(diff){ | |
361 if(get_bits1(bitbuf)) diff= -diff; | |
362 } | |
353 | 363 |
354 /* add median of motion vector predictors and clip result */ | 364 /* add median of motion vector predictors and clip result */ |
355 if (i == 1) | 365 if (i == 1) |
356 mv->y = ((diff + MEDIAN(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; | 366 mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; |
357 else | 367 else |
358 mv->x = ((diff + MEDIAN(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; | 368 mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; |
359 } | 369 } |
360 | 370 |
361 return 0; | 371 return 0; |
362 } | 372 } |
363 | 373 |
832 | 842 |
833 init_vlc(&svq1_block_type, 2, 4, | 843 init_vlc(&svq1_block_type, 2, 4, |
834 &svq1_block_type_vlc[0][1], 2, 1, | 844 &svq1_block_type_vlc[0][1], 2, 1, |
835 &svq1_block_type_vlc[0][0], 2, 1); | 845 &svq1_block_type_vlc[0][0], 2, 1); |
836 | 846 |
837 init_vlc(&svq1_motion_component, 7, 65, | 847 init_vlc(&svq1_motion_component, 7, 33, |
838 &svq1_motion_component_vlc[0][1], 2, 1, | 848 &mvtab[0][1], 2, 1, |
839 &svq1_motion_component_vlc[0][0], 2, 1); | 849 &mvtab[0][0], 2, 1); |
840 | 850 |
841 for (i = 0; i < 6; i++) { | 851 for (i = 0; i < 6; i++) { |
842 init_vlc(&svq1_intra_multistage[i], 3, 8, | 852 init_vlc(&svq1_intra_multistage[i], 3, 8, |
843 &svq1_intra_multistage_vlc[i][0][1], 2, 1, | 853 &svq1_intra_multistage_vlc[i][0][1], 2, 1, |
844 &svq1_intra_multistage_vlc[i][0][0], 2, 1); | 854 &svq1_intra_multistage_vlc[i][0][0], 2, 1); |
1459 } | 1469 } |
1460 | 1470 |
1461 return best_score; | 1471 return best_score; |
1462 } | 1472 } |
1463 | 1473 |
1464 static void svq1_encode_plane(SVQ1Context *s, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane, | 1474 static void svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane, |
1465 int width, int height, int src_stride, int stride) | 1475 int width, int height, int src_stride, int stride) |
1466 { | 1476 { |
1467 unsigned char buffer0[256]; | 1477 unsigned char buffer0[256]; |
1468 unsigned char buffer1[256]; | 1478 unsigned char buffer1[256]; |
1469 int current_buffer; | 1479 int current_buffer; |
1491 threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER; | 1501 threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER; |
1492 | 1502 |
1493 block_width = (width + 15) / 16; | 1503 block_width = (width + 15) / 16; |
1494 block_height = (height + 15) / 16; | 1504 block_height = (height + 15) / 16; |
1495 | 1505 |
1506 if(s->picture.pict_type == P_TYPE){ | |
1507 s->m.avctx= s->avctx; | |
1508 s->m.current_picture_ptr= &s->m.current_picture; | |
1509 s->m.last_picture_ptr = &s->m.last_picture; | |
1510 s->m.last_picture.data[0]= ref_plane; | |
1511 s->m.linesize= | |
1512 s->m.last_picture.linesize[0]= | |
1513 s->m.new_picture.linesize[0]= | |
1514 s->m.current_picture.linesize[0]= stride; | |
1515 s->m.width= width; | |
1516 s->m.height= height; | |
1517 s->m.mb_width= block_width; | |
1518 s->m.mb_height= block_height; | |
1519 s->m.mb_stride= s->m.mb_width+1; | |
1520 s->m.b8_stride= 2*s->m.mb_width+1; | |
1521 s->m.f_code=1; | |
1522 s->m.pict_type= s->picture.pict_type; | |
1523 s->m.qscale= s->picture.quality/FF_QP2LAMBDA; | |
1524 s->m.me_method= s->avctx->me_method; | |
1525 | |
1526 if(!s->motion_val8[plane]){ | |
1527 s->motion_val8 [plane]= av_mallocz(s->m.b8_stride*block_height*2*2*sizeof(int16_t)); | |
1528 s->motion_val16[plane]= av_mallocz(s->m.mb_stride*block_height*2*sizeof(int16_t)); | |
1529 } | |
1530 | |
1531 s->m.mb_type= s->mb_type; | |
1532 | |
1533 //dummies, to avoid segfaults | |
1534 s->m.current_picture.mb_mean= s->dummy; | |
1535 s->m.current_picture.mb_var= s->dummy; | |
1536 s->m.current_picture.mc_mb_var= s->dummy; | |
1537 s->m.current_picture.mb_type= s->dummy; | |
1538 | |
1539 s->m.current_picture.motion_val[0]= s->motion_val8[plane]; | |
1540 s->m.p_mv_table= s->motion_val16[plane]; | |
1541 s->m.dsp= s->dsp; //move | |
1542 ff_init_me(&s->m); | |
1543 | |
1544 s->m.me.dia_size= s->avctx->dia_size; | |
1545 s->m.first_slice_line=1; | |
1546 for (y = 0; y < block_height; y++) { | |
1547 uint8_t src[stride*16]; | |
1548 | |
1549 s->m.new_picture.data[0]= src - y*16*stride; //ugly | |
1550 s->m.mb_y= y; | |
1551 | |
1552 for(i=0; i<16 && i + 16*y<height; i++){ | |
1553 memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); | |
1554 for(x=width; x<16*block_width; x++) | |
1555 src[i*stride+x]= src[i*stride+x-1]; | |
1556 } | |
1557 for(; i<16 && i + 16*y<16*block_height; i++) | |
1558 memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); | |
1559 | |
1560 for (x = 0; x < block_width; x++) { | |
1561 s->m.mb_x= x; | |
1562 ff_init_block_index(&s->m); | |
1563 ff_update_block_index(&s->m); | |
1564 | |
1565 ff_estimate_p_frame_motion(&s->m, x, y); | |
1566 } | |
1567 s->m.first_slice_line=0; | |
1568 } | |
1569 | |
1570 ff_fix_long_p_mvs(&s->m); | |
1571 ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, CANDIDATE_MB_TYPE_INTER, 0); | |
1572 } | |
1573 | |
1574 s->m.first_slice_line=1; | |
1496 for (y = 0; y < block_height; y++) { | 1575 for (y = 0; y < block_height; y++) { |
1497 uint8_t src[stride*16]; | 1576 uint8_t src[stride*16]; |
1498 | 1577 |
1499 for(i=0; i<16 && i + 16*y<height; i++){ | 1578 for(i=0; i<16 && i + 16*y<height; i++){ |
1500 memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); | 1579 memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); |
1502 src[i*stride+x]= src[i*stride+x-1]; | 1581 src[i*stride+x]= src[i*stride+x-1]; |
1503 } | 1582 } |
1504 for(; i<16 && i + 16*y<16*block_height; i++) | 1583 for(; i<16 && i + 16*y<16*block_height; i++) |
1505 memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); | 1584 memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); |
1506 | 1585 |
1586 s->m.mb_y= y; | |
1507 for (x = 0; x < block_width; x++) { | 1587 for (x = 0; x < block_width; x++) { |
1508 uint8_t reorder_buffer[2][6][7*32]; | 1588 uint8_t reorder_buffer[3][6][7*32]; |
1509 int count[2][6]; | 1589 int count[3][6]; |
1510 int offset = y * 16 * stride + x * 16; | 1590 int offset = y * 16 * stride + x * 16; |
1511 uint8_t *decoded= decoded_plane + offset; | 1591 uint8_t *decoded= decoded_plane + offset; |
1512 uint8_t *ref= ref_plane + offset; | 1592 uint8_t *ref= ref_plane + offset; |
1513 int score[2]={0,0}, best; | 1593 int score[4]={0,0,0,0}, best; |
1514 uint8_t temp[16*stride]; | 1594 uint8_t temp[16*stride]; |
1515 | 1595 |
1596 s->m.mb_x= x; | |
1597 ff_init_block_index(&s->m); | |
1598 ff_update_block_index(&s->m); | |
1516 #ifdef DEBUG_SVQ1 | 1599 #ifdef DEBUG_SVQ1 |
1517 av_log(s->avctx, AV_LOG_INFO, "* level 5 vector @ %d, %d:\n", x * 16, y * 16); | 1600 av_log(s->avctx, AV_LOG_INFO, "* level 5 vector @ %d, %d:\n", x * 16, y * 16); |
1518 #endif | 1601 #endif |
1519 | 1602 |
1520 for(i=0; i<6; i++){ | 1603 if(s->picture.pict_type == I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){ |
1521 init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32); | 1604 for(i=0; i<6; i++){ |
1522 } | 1605 init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32); |
1523 if(s->picture.pict_type == P_TYPE){ | 1606 } |
1524 const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; | 1607 if(s->picture.pict_type == P_TYPE){ |
1525 put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); | 1608 const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; |
1526 score[0]= vlc[1]*lambda; | 1609 put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); |
1527 } | 1610 score[0]= vlc[1]*lambda; |
1528 score[0]+= encode_block(s, src+16*x, ref, temp, stride, 5, 64, lambda, 1); | 1611 } |
1529 for(i=0; i<6; i++){ | 1612 score[0]+= encode_block(s, src+16*x, NULL, temp, stride, 5, 64, lambda, 1); |
1530 count[0][i]= put_bits_count(&s->reorder_pb[i]); | 1613 for(i=0; i<6; i++){ |
1531 flush_put_bits(&s->reorder_pb[i]); | 1614 count[0][i]= put_bits_count(&s->reorder_pb[i]); |
1532 init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); | 1615 flush_put_bits(&s->reorder_pb[i]); |
1533 } | 1616 } |
1617 }else | |
1618 score[0]= INT_MAX; | |
1619 | |
1620 best=0; | |
1621 | |
1534 if(s->picture.pict_type == P_TYPE){ | 1622 if(s->picture.pict_type == P_TYPE){ |
1535 const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTER]; | 1623 const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTER]; |
1536 put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); | 1624 int mx, my, pred_x, pred_y, dxy; |
1537 score[1] = vlc[1]*lambda; | 1625 int16_t *motion_ptr; |
1538 for(i=0; i<2; i++){ | 1626 |
1539 vlc= svq1_motion_component_vlc[32]; | 1627 motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); |
1628 if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ | |
1629 for(i=0; i<6; i++) | |
1630 init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); | |
1631 | |
1540 put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); | 1632 put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); |
1541 score[1] += vlc[1]*lambda; | 1633 |
1634 s->m.pb= s->reorder_pb[5]; | |
1635 mx= motion_ptr[0]; | |
1636 my= motion_ptr[1]; | |
1637 assert(mx>=-32 && mx<=31); | |
1638 assert(my>=-32 && my<=31); | |
1639 assert(pred_x>=-32 && pred_x<=31); | |
1640 assert(pred_y>=-32 && pred_y<=31); | |
1641 ff_h263_encode_motion(&s->m, mx - pred_x, 1); | |
1642 ff_h263_encode_motion(&s->m, my - pred_y, 1); | |
1643 s->reorder_pb[5]= s->m.pb; | |
1644 score[1] += lambda*put_bits_count(&s->reorder_pb[5]); | |
1645 | |
1646 dxy= (mx&1) + 2*(my&1); | |
1647 | |
1648 s->dsp.put_pixels_tab[0][dxy](temp+16, ref + (mx>>1) + stride*(my>>1), stride, 16); | |
1649 | |
1650 score[1]+= encode_block(s, src+16*x, temp+16, decoded, stride, 5, 64, lambda, 0); | |
1651 best= score[1] <= score[0]; | |
1542 } | 1652 } |
1543 | 1653 #if 0 |
1544 score[1]+= encode_block(s, src+16*x, ref, decoded, stride, 5, 64, lambda, 0); | 1654 if(skiped_score <= score[best]){ |
1545 best= score[1] <= score[0]; | 1655 best=3; |
1656 ... | |
1657 } | |
1658 #endif | |
1546 if(best==1){ | 1659 if(best==1){ |
1547 for(i=0; i<6; i++){ | 1660 for(i=0; i<6; i++){ |
1548 count[1][i]= put_bits_count(&s->reorder_pb[i]); | 1661 count[1][i]= put_bits_count(&s->reorder_pb[i]); |
1549 flush_put_bits(&s->reorder_pb[i]); | 1662 flush_put_bits(&s->reorder_pb[i]); |
1550 } | 1663 } |
1664 }else{ | |
1665 motion_ptr[0 ] = motion_ptr[1 ]= | |
1666 motion_ptr[2 ] = motion_ptr[3 ]= | |
1667 motion_ptr[0+2*s->m.b8_stride] = motion_ptr[1+2*s->m.b8_stride]= | |
1668 motion_ptr[2+2*s->m.b8_stride] = motion_ptr[3+2*s->m.b8_stride]=0; | |
1551 } | 1669 } |
1552 }else | 1670 } |
1553 best= 0; | |
1554 | 1671 |
1555 s->rd_total += score[best]; | 1672 s->rd_total += score[best]; |
1556 | 1673 |
1557 for(i=5; i>=0; i--){ | 1674 for(i=5; i>=0; i--){ |
1558 ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); | 1675 ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); |
1634 if (!subvector_count) | 1751 if (!subvector_count) |
1635 break; | 1752 break; |
1636 } | 1753 } |
1637 #endif | 1754 #endif |
1638 } | 1755 } |
1756 s->m.first_slice_line=0; | |
1639 } | 1757 } |
1640 } | 1758 } |
1641 | 1759 |
1642 /* output a plane with a constant mean value; good for debugging and for | 1760 /* output a plane with a constant mean value; good for debugging and for |
1643 * greyscale encoding but only valid for intra frames */ | 1761 * greyscale encoding but only valid for intra frames */ |
1689 s->y_block_height = (s->frame_height + 15) / 16; | 1807 s->y_block_height = (s->frame_height + 15) / 16; |
1690 | 1808 |
1691 s->c_block_width = (s->frame_width / 4 + 15) / 16; | 1809 s->c_block_width = (s->frame_width / 4 + 15) / 16; |
1692 s->c_block_height = (s->frame_height / 4 + 15) / 16; | 1810 s->c_block_height = (s->frame_height / 4 + 15) / 16; |
1693 | 1811 |
1812 s->avctx= avctx; | |
1813 s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t)); | |
1814 s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); | |
1815 s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); | |
1816 s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); | |
1817 s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); | |
1818 h263_encode_init(&s->m); //mv_penalty | |
1819 | |
1694 av_log(s->avctx, AV_LOG_INFO, " Hey: %d x %d, %d x %d, %d x %d\n", | 1820 av_log(s->avctx, AV_LOG_INFO, " Hey: %d x %d, %d x %d, %d x %d\n", |
1695 s->frame_width, s->frame_height, | 1821 s->frame_width, s->frame_height, |
1696 s->y_block_width, s->y_block_height, | 1822 s->y_block_width, s->y_block_height, |
1697 s->c_block_width, s->c_block_height); | 1823 s->c_block_width, s->c_block_height); |
1698 | 1824 |
1744 p->pict_type = avctx->frame_number % avctx->gop_size ? P_TYPE : I_TYPE; | 1870 p->pict_type = avctx->frame_number % avctx->gop_size ? P_TYPE : I_TYPE; |
1745 p->key_frame = p->pict_type == I_TYPE; | 1871 p->key_frame = p->pict_type == I_TYPE; |
1746 | 1872 |
1747 svq1_write_header(s, p->pict_type); | 1873 svq1_write_header(s, p->pict_type); |
1748 for(i=0; i<3; i++){ | 1874 for(i=0; i<3; i++){ |
1749 svq1_encode_plane(s, | 1875 svq1_encode_plane(s, i, |
1750 s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i], | 1876 s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i], |
1751 s->frame_width / (i?4:1), s->frame_height / (i?4:1), | 1877 s->frame_width / (i?4:1), s->frame_height / (i?4:1), |
1752 s->picture.linesize[i], s->current_picture.linesize[i]); | 1878 s->picture.linesize[i], s->current_picture.linesize[i]); |
1753 } | 1879 } |
1754 | 1880 |
1762 } | 1888 } |
1763 | 1889 |
1764 static int svq1_encode_end(AVCodecContext *avctx) | 1890 static int svq1_encode_end(AVCodecContext *avctx) |
1765 { | 1891 { |
1766 SVQ1Context * const s = avctx->priv_data; | 1892 SVQ1Context * const s = avctx->priv_data; |
1893 int i; | |
1767 | 1894 |
1768 av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number)); | 1895 av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number)); |
1769 | 1896 |
1770 av_free(s->c_plane); | 1897 av_freep(&s->c_plane); |
1898 av_freep(&s->m.me.scratchpad); | |
1899 av_freep(&s->m.me.map); | |
1900 av_freep(&s->m.me.score_map); | |
1901 av_freep(&s->mb_type); | |
1902 av_freep(&s->dummy); | |
1903 | |
1904 for(i=0; i<3; i++){ | |
1905 av_freep(&s->motion_val8[i]); | |
1906 av_freep(&s->motion_val16[i]); | |
1907 } | |
1771 | 1908 |
1772 return 0; | 1909 return 0; |
1773 } | 1910 } |
1774 | 1911 |
1775 AVCodec svq1_decoder = { | 1912 AVCodec svq1_decoder = { |