Mercurial > libavcodec.hg
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]; |