comparison mpegvideo.c @ 697:c622224012f0 libavcodec

mpeg4 interlaced dct encoding
author michaelni
date Thu, 26 Sep 2002 00:22:25 +0000
parents 3525da287ee2
children 85b071dfc7e3
comparison
equal deleted inserted replaced
696:477bcb3b2f0a 697:c622224012f0
448 || s->avctx->dark_masking 448 || s->avctx->dark_masking
449 || s->avctx->temporal_cplx_masking 449 || s->avctx->temporal_cplx_masking
450 || s->avctx->spatial_cplx_masking 450 || s->avctx->spatial_cplx_masking
451 || s->avctx->p_masking) 451 || s->avctx->p_masking)
452 && !s->fixed_qscale; 452 && !s->fixed_qscale;
453
454 s->progressive_sequence= !(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
453 455
454 switch(avctx->codec->id) { 456 switch(avctx->codec->id) {
455 case CODEC_ID_MPEG1VIDEO: 457 case CODEC_ID_MPEG1VIDEO:
456 s->out_format = FMT_MPEG1; 458 s->out_format = FMT_MPEG1;
457 avctx->delay=0; //FIXME not sure, should check the spec 459 avctx->delay=0; //FIXME not sure, should check the spec
1745 else if(level<minlevel) level=minlevel; 1747 else if(level<minlevel) level=minlevel;
1746 block[j]= level; 1748 block[j]= level;
1747 } 1749 }
1748 } 1750 }
1749 1751
1752 static inline void requantize_coeffs(MpegEncContext *s, DCTELEM block[64], int oldq, int newq, int n)
1753 {
1754 int i;
1755
1756 if(s->mb_intra){
1757 //FIXME requantize, note (mpeg1/h263/h263p-aic dont need it,...)
1758 i=1;
1759 }else
1760 i=0;
1761
1762 for(;i<=s->block_last_index[n]; i++){
1763 const int j = zigzag_direct[i];
1764 int level = block[j];
1765
1766 block[j]= ROUNDED_DIV(level*oldq, newq);
1767 }
1768
1769 for(i=s->block_last_index[n]; i>=0; i--){
1770 const int j = zigzag_direct[i]; //FIXME other scantabs
1771 if(block[j]) break;
1772 }
1773 s->block_last_index[n]= i;
1774 }
1775
1776 static inline void auto_requantize_coeffs(MpegEncContext *s, DCTELEM block[6][64])
1777 {
1778 int i,n, newq;
1779 const int maxlevel= s->max_qcoeff;
1780 const int minlevel= s->min_qcoeff;
1781 int largest=0, smallest=0;
1782
1783 assert(s->adaptive_quant);
1784
1785 for(n=0; n<6; n++){
1786 if(s->mb_intra) i=1;
1787 else i=0;
1788
1789 for(;i<=s->block_last_index[n]; i++){
1790 const int j = zigzag_direct[i]; //FIXME other scantabs
1791 int level = block[n][j];
1792 if(largest < level) largest = level;
1793 if(smallest > level) smallest= level;
1794 }
1795 }
1796
1797 for(newq=s->qscale+1; newq<32; newq++){
1798 if( ROUNDED_DIV(smallest*s->qscale, newq) >= minlevel
1799 && ROUNDED_DIV(largest *s->qscale, newq) <= maxlevel)
1800 break;
1801 }
1802
1803 if(s->out_format==FMT_H263){
1804 /* h263 like formats cannot change qscale by more than 2 easiely */
1805 if(s->avctx->qmin + 2 < newq)
1806 newq= s->avctx->qmin + 2;
1807 }
1808
1809 for(n=0; n<6; n++){
1810 requantize_coeffs(s, block[n], s->qscale, newq, n);
1811 clip_coeffs(s, block[n], s->block_last_index[n]);
1812 }
1813
1814 s->dquant+= newq - s->qscale;
1815 s->qscale= newq;
1816 }
1817 #if 0
1818 static int pix_vcmp16x8(UINT8 *s, int stride){ //FIXME move to dsputil & optimize
1819 int score=0;
1820 int x,y;
1821
1822 for(y=0; y<7; y++){
1823 for(x=0; x<16; x+=4){
1824 score+= ABS(s[x ] - s[x +stride]) + ABS(s[x+1] - s[x+1+stride])
1825 +ABS(s[x+2] - s[x+2+stride]) + ABS(s[x+3] - s[x+3+stride]);
1826 }
1827 s+= stride;
1828 }
1829
1830 return score;
1831 }
1832
1833 static int pix_diff_vcmp16x8(UINT8 *s1, UINT8*s2, int stride){ //FIXME move to dsputil & optimize
1834 int score=0;
1835 int x,y;
1836
1837 for(y=0; y<7; y++){
1838 for(x=0; x<16; x++){
1839 score+= ABS(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
1840 }
1841 s1+= stride;
1842 s2+= stride;
1843 }
1844
1845 return score;
1846 }
1847 #else
1848 #define SQ(a) ((a)*(a))
1849
1850 static int pix_vcmp16x8(UINT8 *s, int stride){ //FIXME move to dsputil & optimize
1851 int score=0;
1852 int x,y;
1853
1854 for(y=0; y<7; y++){
1855 for(x=0; x<16; x+=4){
1856 score+= SQ(s[x ] - s[x +stride]) + SQ(s[x+1] - s[x+1+stride])
1857 +SQ(s[x+2] - s[x+2+stride]) + SQ(s[x+3] - s[x+3+stride]);
1858 }
1859 s+= stride;
1860 }
1861
1862 return score;
1863 }
1864
1865 static int pix_diff_vcmp16x8(UINT8 *s1, UINT8*s2, int stride){ //FIXME move to dsputil & optimize
1866 int score=0;
1867 int x,y;
1868
1869 for(y=0; y<7; y++){
1870 for(x=0; x<16; x++){
1871 score+= SQ(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
1872 }
1873 s1+= stride;
1874 s2+= stride;
1875 }
1876
1877 return score;
1878 }
1879
1880 #endif
1750 static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) 1881 static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
1751 { 1882 {
1752 const int mb_x= s->mb_x; 1883 const int mb_x= s->mb_x;
1753 const int mb_y= s->mb_y; 1884 const int mb_y= s->mb_y;
1754 int i; 1885 int i;
1755 int skip_dct[6]; 1886 int skip_dct[6];
1756 #if 0 1887 int dct_offset = s->linesize*8; //default for progressive frames
1757 if (s->interlaced_dct) { 1888
1758 dct_linesize = s->linesize * 2;
1759 dct_offset = s->linesize;
1760 } else {
1761 dct_linesize = s->linesize;
1762 dct_offset = s->linesize * 8;
1763 }
1764 #endif
1765 for(i=0; i<6; i++) skip_dct[i]=0; 1889 for(i=0; i<6; i++) skip_dct[i]=0;
1766 1890
1767 if(s->adaptive_quant){ 1891 if(s->adaptive_quant){
1768 s->dquant= s->qscale_table[mb_x + mb_y*s->mb_width] - s->qscale; 1892 s->dquant= s->qscale_table[mb_x + mb_y*s->mb_width] - s->qscale;
1769 if(s->codec_id==CODEC_ID_MPEG4){ 1893
1894 if(s->out_format==FMT_H263){
1770 if (s->dquant> 2) s->dquant= 2; 1895 if (s->dquant> 2) s->dquant= 2;
1771 else if(s->dquant<-2) s->dquant=-2; 1896 else if(s->dquant<-2) s->dquant=-2;
1772 1897 }
1898
1899 if(s->codec_id==CODEC_ID_MPEG4){
1773 if(!s->mb_intra){ 1900 if(!s->mb_intra){
1774 assert(s->dquant==0 || s->mv_type!=MV_TYPE_8X8); 1901 assert(s->dquant==0 || s->mv_type!=MV_TYPE_8X8);
1775 1902
1776 if(s->mv_dir&MV_DIRECT) 1903 if(s->mv_dir&MV_DIRECT)
1777 s->dquant=0; 1904 s->dquant=0;
1782 s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; 1909 s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];
1783 } 1910 }
1784 1911
1785 if (s->mb_intra) { 1912 if (s->mb_intra) {
1786 UINT8 *ptr; 1913 UINT8 *ptr;
1787 int wrap; 1914 int wrap_y;
1788 int emu=0; 1915 int emu=0;
1789 1916
1790 wrap = s->linesize; 1917 wrap_y = s->linesize;
1791 ptr = s->new_picture[0] + (mb_y * 16 * wrap) + mb_x * 16; 1918 ptr = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
1919
1792 if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ 1920 if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
1793 emulated_edge_mc(s, ptr, wrap, 16, 16, mb_x*16, mb_y*16, s->width, s->height); 1921 emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
1794 ptr= s->edge_emu_buffer; 1922 ptr= s->edge_emu_buffer;
1795 emu=1; 1923 emu=1;
1796 } 1924 }
1797 get_pixels(s->block[0], ptr , wrap); 1925
1798 get_pixels(s->block[1], ptr + 8, wrap); 1926 if(s->flags&CODEC_FLAG_INTERLACED_DCT){
1799 get_pixels(s->block[2], ptr + 8 * wrap , wrap); 1927 int progressive_score, interlaced_score;
1800 get_pixels(s->block[3], ptr + 8 * wrap + 8, wrap); 1928
1929 progressive_score= pix_vcmp16x8(ptr, wrap_y ) + pix_vcmp16x8(ptr + wrap_y*8, wrap_y );
1930 interlaced_score = pix_vcmp16x8(ptr, wrap_y*2) + pix_vcmp16x8(ptr + wrap_y , wrap_y*2);
1931
1932 if(progressive_score > interlaced_score + 100){
1933 s->interlaced_dct=1;
1934
1935 dct_offset= wrap_y;
1936 wrap_y<<=1;
1937 }else
1938 s->interlaced_dct=0;
1939 }
1940
1941 get_pixels(s->block[0], ptr , wrap_y);
1942 get_pixels(s->block[1], ptr + 8, wrap_y);
1943 get_pixels(s->block[2], ptr + dct_offset , wrap_y);
1944 get_pixels(s->block[3], ptr + dct_offset + 8, wrap_y);
1801 1945
1802 if(s->flags&CODEC_FLAG_GRAY){ 1946 if(s->flags&CODEC_FLAG_GRAY){
1803 skip_dct[4]= 1; 1947 skip_dct[4]= 1;
1804 skip_dct[5]= 1; 1948 skip_dct[5]= 1;
1805 }else{ 1949 }else{
1806 wrap >>=1; 1950 int wrap_c = s->uvlinesize;
1807 ptr = s->new_picture[1] + (mb_y * 8 * wrap) + mb_x * 8; 1951 ptr = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
1808 if(emu){ 1952 if(emu){
1809 emulated_edge_mc(s, ptr, wrap, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); 1953 emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
1810 ptr= s->edge_emu_buffer; 1954 ptr= s->edge_emu_buffer;
1811 } 1955 }
1812 get_pixels(s->block[4], ptr, wrap); 1956 get_pixels(s->block[4], ptr, wrap_c);
1813 1957
1814 ptr = s->new_picture[2] + (mb_y * 8 * wrap) + mb_x * 8; 1958 ptr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
1815 if(emu){ 1959 if(emu){
1816 emulated_edge_mc(s, ptr, wrap, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); 1960 emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
1817 ptr= s->edge_emu_buffer; 1961 ptr= s->edge_emu_buffer;
1818 } 1962 }
1819 get_pixels(s->block[5], ptr, wrap); 1963 get_pixels(s->block[5], ptr, wrap_c);
1820 } 1964 }
1821 }else{ 1965 }else{
1822 op_pixels_func (*op_pix)[4]; 1966 op_pixels_func (*op_pix)[4];
1823 qpel_mc_func (*op_qpix)[16]; 1967 qpel_mc_func (*op_qpix)[16];
1824 UINT8 *dest_y, *dest_cb, *dest_cr; 1968 UINT8 *dest_y, *dest_cb, *dest_cr;
1828 1972
1829 dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize ) + mb_x * 16; 1973 dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize ) + mb_x * 16;
1830 dest_cb = s->current_picture[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; 1974 dest_cb = s->current_picture[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
1831 dest_cr = s->current_picture[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; 1975 dest_cr = s->current_picture[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
1832 wrap_y = s->linesize; 1976 wrap_y = s->linesize;
1833 wrap_c = wrap_y>>1; 1977 wrap_c = s->uvlinesize;
1834 ptr_y = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16; 1978 ptr_y = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
1835 ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8; 1979 ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
1836 ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8; 1980 ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
1837 1981
1838 if ((!s->no_rounding) || s->pict_type==B_TYPE){ 1982 if ((!s->no_rounding) || s->pict_type==B_TYPE){
1855 if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ 1999 if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
1856 emulated_edge_mc(s, ptr_y, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height); 2000 emulated_edge_mc(s, ptr_y, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
1857 ptr_y= s->edge_emu_buffer; 2001 ptr_y= s->edge_emu_buffer;
1858 emu=1; 2002 emu=1;
1859 } 2003 }
2004
2005 if(s->flags&CODEC_FLAG_INTERLACED_DCT){
2006 int progressive_score, interlaced_score;
2007
2008 progressive_score= pix_diff_vcmp16x8(ptr_y , dest_y , wrap_y )
2009 + pix_diff_vcmp16x8(ptr_y + wrap_y*8, dest_y + wrap_y*8, wrap_y );
2010 interlaced_score = pix_diff_vcmp16x8(ptr_y , dest_y , wrap_y*2)
2011 + pix_diff_vcmp16x8(ptr_y + wrap_y , dest_y + wrap_y , wrap_y*2);
2012
2013 if(progressive_score > interlaced_score + 600){
2014 s->interlaced_dct=1;
2015
2016 dct_offset= wrap_y;
2017 wrap_y<<=1;
2018 }else
2019 s->interlaced_dct=0;
2020 }
2021
1860 diff_pixels(s->block[0], ptr_y , dest_y , wrap_y); 2022 diff_pixels(s->block[0], ptr_y , dest_y , wrap_y);
1861 diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y); 2023 diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y);
1862 diff_pixels(s->block[2], ptr_y + 8 * wrap_y , dest_y + 8 * wrap_y , wrap_y); 2024 diff_pixels(s->block[2], ptr_y + dct_offset , dest_y + dct_offset , wrap_y);
1863 diff_pixels(s->block[3], ptr_y + 8 * wrap_y + 8, dest_y + 8 * wrap_y + 8, wrap_y); 2025 diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y);
1864 2026
1865 if(s->flags&CODEC_FLAG_GRAY){ 2027 if(s->flags&CODEC_FLAG_GRAY){
1866 skip_dct[4]= 1; 2028 skip_dct[4]= 1;
1867 skip_dct[5]= 1; 2029 skip_dct[5]= 1;
1868 }else{ 2030 }else{
1878 diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); 2040 diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
1879 } 2041 }
1880 2042
1881 /* pre quantization */ 2043 /* pre quantization */
1882 if(s->mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){ 2044 if(s->mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){
2045 //FIXME optimize
1883 if(pix_abs8x8(ptr_y , dest_y , wrap_y) < 20*s->qscale) skip_dct[0]= 1; 2046 if(pix_abs8x8(ptr_y , dest_y , wrap_y) < 20*s->qscale) skip_dct[0]= 1;
1884 if(pix_abs8x8(ptr_y + 8, dest_y + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1; 2047 if(pix_abs8x8(ptr_y + 8, dest_y + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1;
1885 if(pix_abs8x8(ptr_y + 8*wrap_y , dest_y + 8*wrap_y , wrap_y) < 20*s->qscale) skip_dct[2]= 1; 2048 if(pix_abs8x8(ptr_y +dct_offset , dest_y +dct_offset , wrap_y) < 20*s->qscale) skip_dct[2]= 1;
1886 if(pix_abs8x8(ptr_y + 8*wrap_y + 8, dest_y + 8*wrap_y + 8, wrap_y) < 20*s->qscale) skip_dct[3]= 1; 2049 if(pix_abs8x8(ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y) < 20*s->qscale) skip_dct[3]= 1;
1887 if(pix_abs8x8(ptr_cb , dest_cb , wrap_y) < 20*s->qscale) skip_dct[4]= 1; 2050 if(pix_abs8x8(ptr_cb , dest_cb , wrap_y) < 20*s->qscale) skip_dct[4]= 1;
1888 if(pix_abs8x8(ptr_cr , dest_cr , wrap_y) < 20*s->qscale) skip_dct[5]= 1; 2051 if(pix_abs8x8(ptr_cr , dest_cr , wrap_y) < 20*s->qscale) skip_dct[5]= 1;
1889 #if 0 2052 #if 0
1890 { 2053 {
1891 static int stat[7]; 2054 static int stat[7];