Browse code

Revert "removing lowres support"

There have been multiple user complaints about loosing this feature
while its not clear the 3% speedloss claims where real or fabricated.
My own testing indicates no statistically significant speed difference
both with mpeg2 and mpeg4, and if at all the code with lowres support
is a tiny bit faster than without.

This reverts commit 92ef4be4ab9fbb7d901b22e0036a4ca90b00a476, reversing
changes made to 2e07f42957666df6d7c63a62263b8447e97b1442.

Conflicts:

cmdutils.c
libavcodec/arm/vp8dsp_init_arm.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavutil/arm/Makefile

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/05/25 19:35:42
Showing 11 changed files
... ...
@@ -127,6 +127,7 @@ AVCodec ff_flv_decoder = {
127 127
     .close          = ff_h263_decode_end,
128 128
     .decode         = ff_h263_decode_frame,
129 129
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
130
+    .max_lowres     = 3,
130 131
     .long_name      = NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"),
131 132
     .pix_fmts       = ff_pixfmt_list_420,
132 133
 };
... ...
@@ -658,5 +658,6 @@ AVCodec ff_h261_decoder = {
658 658
     .close          = h261_decode_end,
659 659
     .decode         = h261_decode_frame,
660 660
     .capabilities   = CODEC_CAP_DR1,
661
+    .max_lowres     = 3,
661 662
     .long_name      = NULL_IF_CONFIG_SMALL("H.261"),
662 663
 };
... ...
@@ -151,7 +151,7 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size){
151 151
 
152 152
 static int decode_slice(MpegEncContext *s){
153 153
     const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
154
-    const int mb_size = 16;
154
+    const int mb_size= 16>>s->avctx->lowres;
155 155
     s->last_resync_gb= s->gb;
156 156
     s->first_slice_line= 1;
157 157
 
... ...
@@ -766,6 +766,7 @@ AVCodec ff_h263_decoder = {
766 766
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
767 767
                       CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
768 768
     .flush          = ff_mpeg_flush,
769
+    .max_lowres     = 3,
769 770
     .long_name      = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
770 771
     .pix_fmts       = ff_hwaccel_pixfmt_list_420,
771 772
 };
... ...
@@ -716,6 +716,7 @@ av_cold void ff_intrax8_common_end(IntraX8Context * w)
716 716
  * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function.
717 717
  * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function.
718 718
  * This function does not use MPV_decode_mb().
719
+ * lowres decoding is theoretically impossible.
719 720
  * @param w pointer to IntraX8Context
720 721
  * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
721 722
  * @param quant_offset offset away from zero
... ...
@@ -940,6 +940,21 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,
940 940
     return 0;
941 941
 }
942 942
 
943
+static av_always_inline void mjpeg_copy_block(uint8_t *dst, const uint8_t *src,
944
+                                              int linesize, int lowres)
945
+{
946
+    switch (lowres) {
947
+    case 0: copy_block8(dst, src, linesize, linesize, 8);
948
+        break;
949
+    case 1: copy_block4(dst, src, linesize, linesize, 4);
950
+        break;
951
+    case 2: copy_block2(dst, src, linesize, linesize, 2);
952
+        break;
953
+    case 3: *dst = *src;
954
+        break;
955
+    }
956
+}
957
+
943 958
 static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
944 959
                              int Al, const uint8_t *mb_bitmask,
945 960
                              const AVFrame *reference)
... ...
@@ -1010,8 +1025,8 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
1010 1010
                     ptr = data[c] + block_offset;
1011 1011
                     if (!s->progressive) {
1012 1012
                         if (copy_mb)
1013
-                            copy_block8(ptr, reference_data[c] + block_offset,
1014
-                                        linesize[c], linesize[c], 8);
1013
+                            mjpeg_copy_block(ptr, reference_data[c] + block_offset,
1014
+                                             linesize[c], s->avctx->lowres);
1015 1015
                         else {
1016 1016
                             s->dsp.clear_block(s->block);
1017 1017
                             if (decode_block(s, s->block, i,
... ...
@@ -1676,6 +1676,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
1676 1676
                              const uint8_t **buf, int buf_size)
1677 1677
 {
1678 1678
     AVCodecContext *avctx = s->avctx;
1679
+    const int lowres      = s->avctx->lowres;
1679 1680
     const int field_pic   = s->picture_structure != PICT_FRAME;
1680 1681
 
1681 1682
     s->resync_mb_x =
... ...
@@ -1798,14 +1799,14 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
1798 1798
             }
1799 1799
         }
1800 1800
 
1801
-        s->dest[0] += 16;
1802
-        s->dest[1] += 16 >> s->chroma_x_shift;
1803
-        s->dest[2] += 16 >> s->chroma_x_shift;
1801
+        s->dest[0] += 16 >> lowres;
1802
+        s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift;
1803
+        s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift;
1804 1804
 
1805 1805
         ff_MPV_decode_mb(s, s->block);
1806 1806
 
1807 1807
         if (++s->mb_x >= s->mb_width) {
1808
-            const int mb_size = 16;
1808
+            const int mb_size = 16 >> s->avctx->lowres;
1809 1809
 
1810 1810
             ff_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
1811 1811
             ff_MPV_report_decode_progress(s);
... ...
@@ -2590,6 +2591,7 @@ AVCodec ff_mpeg1video_decoder = {
2590 2590
                              CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
2591 2591
                              CODEC_CAP_SLICE_THREADS,
2592 2592
     .flush                 = flush,
2593
+    .max_lowres            = 3,
2593 2594
     .long_name             = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
2594 2595
     .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
2595 2596
 };
... ...
@@ -2606,6 +2608,7 @@ AVCodec ff_mpeg2video_decoder = {
2606 2606
                       CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
2607 2607
                       CODEC_CAP_SLICE_THREADS,
2608 2608
     .flush          = flush,
2609
+    .max_lowres     = 3,
2609 2610
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
2610 2611
     .profiles       = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
2611 2612
 };
... ...
@@ -2343,6 +2343,7 @@ AVCodec ff_mpeg4_decoder = {
2343 2343
                              CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
2344 2344
                              CODEC_CAP_FRAME_THREADS,
2345 2345
     .flush                 = ff_mpeg_flush,
2346
+    .max_lowres            = 3,
2346 2347
     .long_name             = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
2347 2348
     .pix_fmts              = ff_hwaccel_pixfmt_list_420,
2348 2349
     .profiles              = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
... ...
@@ -1784,6 +1784,381 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
1784 1784
     }
1785 1785
 }
1786 1786
 
1787
+static inline int hpel_motion_lowres(MpegEncContext *s,
1788
+                                     uint8_t *dest, uint8_t *src,
1789
+                                     int field_based, int field_select,
1790
+                                     int src_x, int src_y,
1791
+                                     int width, int height, int stride,
1792
+                                     int h_edge_pos, int v_edge_pos,
1793
+                                     int w, int h, h264_chroma_mc_func *pix_op,
1794
+                                     int motion_x, int motion_y)
1795
+{
1796
+    const int lowres   = s->avctx->lowres;
1797
+    const int op_index = FFMIN(lowres, 2);
1798
+    const int s_mask   = (2 << lowres) - 1;
1799
+    int emu = 0;
1800
+    int sx, sy;
1801
+
1802
+    if (s->quarter_sample) {
1803
+        motion_x /= 2;
1804
+        motion_y /= 2;
1805
+    }
1806
+
1807
+    sx = motion_x & s_mask;
1808
+    sy = motion_y & s_mask;
1809
+    src_x += motion_x >> lowres + 1;
1810
+    src_y += motion_y >> lowres + 1;
1811
+
1812
+    src   += src_y * stride + src_x;
1813
+
1814
+    if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w,                 0) ||
1815
+        (unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
1816
+        s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1,
1817
+                                (h + 1) << field_based, src_x,
1818
+                                src_y   << field_based,
1819
+                                h_edge_pos,
1820
+                                v_edge_pos);
1821
+        src = s->edge_emu_buffer;
1822
+        emu = 1;
1823
+    }
1824
+
1825
+    sx = (sx << 2) >> lowres;
1826
+    sy = (sy << 2) >> lowres;
1827
+    if (field_select)
1828
+        src += s->linesize;
1829
+    pix_op[op_index](dest, src, stride, h, sx, sy);
1830
+    return emu;
1831
+}
1832
+
1833
+/* apply one mpeg motion vector to the three components */
1834
+static av_always_inline void mpeg_motion_lowres(MpegEncContext *s,
1835
+                                                uint8_t *dest_y,
1836
+                                                uint8_t *dest_cb,
1837
+                                                uint8_t *dest_cr,
1838
+                                                int field_based,
1839
+                                                int bottom_field,
1840
+                                                int field_select,
1841
+                                                uint8_t **ref_picture,
1842
+                                                h264_chroma_mc_func *pix_op,
1843
+                                                int motion_x, int motion_y,
1844
+                                                int h, int mb_y)
1845
+{
1846
+    uint8_t *ptr_y, *ptr_cb, *ptr_cr;
1847
+    int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy,
1848
+        uvsx, uvsy;
1849
+    const int lowres     = s->avctx->lowres;
1850
+    const int op_index   = FFMIN(lowres-1+s->chroma_x_shift, 2);
1851
+    const int block_s    = 8>>lowres;
1852
+    const int s_mask     = (2 << lowres) - 1;
1853
+    const int h_edge_pos = s->h_edge_pos >> lowres;
1854
+    const int v_edge_pos = s->v_edge_pos >> lowres;
1855
+    linesize   = s->current_picture.f.linesize[0] << field_based;
1856
+    uvlinesize = s->current_picture.f.linesize[1] << field_based;
1857
+
1858
+    // FIXME obviously not perfect but qpel will not work in lowres anyway
1859
+    if (s->quarter_sample) {
1860
+        motion_x /= 2;
1861
+        motion_y /= 2;
1862
+    }
1863
+
1864
+    if(field_based){
1865
+        motion_y += (bottom_field - field_select)*((1 << lowres)-1);
1866
+    }
1867
+
1868
+    sx = motion_x & s_mask;
1869
+    sy = motion_y & s_mask;
1870
+    src_x = s->mb_x * 2 * block_s + (motion_x >> lowres + 1);
1871
+    src_y = (mb_y * 2 * block_s >> field_based) + (motion_y >> lowres + 1);
1872
+
1873
+    if (s->out_format == FMT_H263) {
1874
+        uvsx    = ((motion_x >> 1) & s_mask) | (sx & 1);
1875
+        uvsy    = ((motion_y >> 1) & s_mask) | (sy & 1);
1876
+        uvsrc_x = src_x >> 1;
1877
+        uvsrc_y = src_y >> 1;
1878
+    } else if (s->out_format == FMT_H261) {
1879
+        // even chroma mv's are full pel in H261
1880
+        mx      = motion_x / 4;
1881
+        my      = motion_y / 4;
1882
+        uvsx    = (2 * mx) & s_mask;
1883
+        uvsy    = (2 * my) & s_mask;
1884
+        uvsrc_x = s->mb_x * block_s + (mx >> lowres);
1885
+        uvsrc_y =    mb_y * block_s + (my >> lowres);
1886
+    } else {
1887
+        if(s->chroma_y_shift){
1888
+            mx      = motion_x / 2;
1889
+            my      = motion_y / 2;
1890
+            uvsx    = mx & s_mask;
1891
+            uvsy    = my & s_mask;
1892
+            uvsrc_x = s->mb_x * block_s                 + (mx >> lowres + 1);
1893
+            uvsrc_y =   (mb_y * block_s >> field_based) + (my >> lowres + 1);
1894
+        } else {
1895
+            if(s->chroma_x_shift){
1896
+            //Chroma422
1897
+                mx = motion_x / 2;
1898
+                uvsx = mx & s_mask;
1899
+                uvsy = motion_y & s_mask;
1900
+                uvsrc_y = src_y;
1901
+                uvsrc_x = s->mb_x*block_s               + (mx >> (lowres+1));
1902
+            } else {
1903
+            //Chroma444
1904
+                uvsx = motion_x & s_mask;
1905
+                uvsy = motion_y & s_mask;
1906
+                uvsrc_x = src_x;
1907
+                uvsrc_y = src_y;
1908
+            }
1909
+        }
1910
+    }
1911
+
1912
+    ptr_y  = ref_picture[0] + src_y   * linesize   + src_x;
1913
+    ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
1914
+    ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
1915
+
1916
+    if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s,       0) ||
1917
+        (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
1918
+        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
1919
+                                s->linesize, 17, 17 + field_based,
1920
+                                src_x, src_y << field_based, h_edge_pos,
1921
+                                v_edge_pos);
1922
+        ptr_y = s->edge_emu_buffer;
1923
+        if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
1924
+            uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize;
1925
+            s->dsp.emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9,
1926
+                                    9 + field_based,
1927
+                                    uvsrc_x, uvsrc_y << field_based,
1928
+                                    h_edge_pos >> 1, v_edge_pos >> 1);
1929
+            s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, 9,
1930
+                                    9 + field_based,
1931
+                                    uvsrc_x, uvsrc_y << field_based,
1932
+                                    h_edge_pos >> 1, v_edge_pos >> 1);
1933
+            ptr_cb = uvbuf;
1934
+            ptr_cr = uvbuf + 16;
1935
+        }
1936
+    }
1937
+
1938
+    // FIXME use this for field pix too instead of the obnoxious hack which changes picture.f.data
1939
+    if (bottom_field) {
1940
+        dest_y  += s->linesize;
1941
+        dest_cb += s->uvlinesize;
1942
+        dest_cr += s->uvlinesize;
1943
+    }
1944
+
1945
+    if (field_select) {
1946
+        ptr_y   += s->linesize;
1947
+        ptr_cb  += s->uvlinesize;
1948
+        ptr_cr  += s->uvlinesize;
1949
+    }
1950
+
1951
+    sx = (sx << 2) >> lowres;
1952
+    sy = (sy << 2) >> lowres;
1953
+    pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy);
1954
+
1955
+    if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
1956
+        uvsx = (uvsx << 2) >> lowres;
1957
+        uvsy = (uvsy << 2) >> lowres;
1958
+        if (h >> s->chroma_y_shift) {
1959
+            pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
1960
+            pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
1961
+        }
1962
+    }
1963
+    // FIXME h261 lowres loop filter
1964
+}
1965
+
1966
+static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
1967
+                                            uint8_t *dest_cb, uint8_t *dest_cr,
1968
+                                            uint8_t **ref_picture,
1969
+                                            h264_chroma_mc_func * pix_op,
1970
+                                            int mx, int my)
1971
+{
1972
+    const int lowres     = s->avctx->lowres;
1973
+    const int op_index   = FFMIN(lowres, 2);
1974
+    const int block_s    = 8 >> lowres;
1975
+    const int s_mask     = (2 << lowres) - 1;
1976
+    const int h_edge_pos = s->h_edge_pos >> lowres + 1;
1977
+    const int v_edge_pos = s->v_edge_pos >> lowres + 1;
1978
+    int emu = 0, src_x, src_y, offset, sx, sy;
1979
+    uint8_t *ptr;
1980
+
1981
+    if (s->quarter_sample) {
1982
+        mx /= 2;
1983
+        my /= 2;
1984
+    }
1985
+
1986
+    /* In case of 8X8, we construct a single chroma motion vector
1987
+       with a special rounding */
1988
+    mx = ff_h263_round_chroma(mx);
1989
+    my = ff_h263_round_chroma(my);
1990
+
1991
+    sx = mx & s_mask;
1992
+    sy = my & s_mask;
1993
+    src_x = s->mb_x * block_s + (mx >> lowres + 1);
1994
+    src_y = s->mb_y * block_s + (my >> lowres + 1);
1995
+
1996
+    offset = src_y * s->uvlinesize + src_x;
1997
+    ptr = ref_picture[1] + offset;
1998
+    if (s->flags & CODEC_FLAG_EMU_EDGE) {
1999
+        if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) ||
2000
+            (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) {
2001
+            s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
2002
+                                    9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
2003
+            ptr = s->edge_emu_buffer;
2004
+            emu = 1;
2005
+        }
2006
+    }
2007
+    sx = (sx << 2) >> lowres;
2008
+    sy = (sy << 2) >> lowres;
2009
+    pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy);
2010
+
2011
+    ptr = ref_picture[2] + offset;
2012
+    if (emu) {
2013
+        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
2014
+                                src_x, src_y, h_edge_pos, v_edge_pos);
2015
+        ptr = s->edge_emu_buffer;
2016
+    }
2017
+    pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy);
2018
+}
2019
+
2020
+/**
2021
+ * motion compensation of a single macroblock
2022
+ * @param s context
2023
+ * @param dest_y luma destination pointer
2024
+ * @param dest_cb chroma cb/u destination pointer
2025
+ * @param dest_cr chroma cr/v destination pointer
2026
+ * @param dir direction (0->forward, 1->backward)
2027
+ * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
2028
+ * @param pix_op halfpel motion compensation function (average or put normally)
2029
+ * the motion vectors are taken from s->mv and the MV type from s->mv_type
2030
+ */
2031
+static inline void MPV_motion_lowres(MpegEncContext *s,
2032
+                                     uint8_t *dest_y, uint8_t *dest_cb,
2033
+                                     uint8_t *dest_cr,
2034
+                                     int dir, uint8_t **ref_picture,
2035
+                                     h264_chroma_mc_func *pix_op)
2036
+{
2037
+    int mx, my;
2038
+    int mb_x, mb_y, i;
2039
+    const int lowres  = s->avctx->lowres;
2040
+    const int block_s = 8 >>lowres;
2041
+
2042
+    mb_x = s->mb_x;
2043
+    mb_y = s->mb_y;
2044
+
2045
+    switch (s->mv_type) {
2046
+    case MV_TYPE_16X16:
2047
+        mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2048
+                           0, 0, 0,
2049
+                           ref_picture, pix_op,
2050
+                           s->mv[dir][0][0], s->mv[dir][0][1],
2051
+                           2 * block_s, mb_y);
2052
+        break;
2053
+    case MV_TYPE_8X8:
2054
+        mx = 0;
2055
+        my = 0;
2056
+        for (i = 0; i < 4; i++) {
2057
+            hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) *
2058
+                               s->linesize) * block_s,
2059
+                               ref_picture[0], 0, 0,
2060
+                               (2 * mb_x + (i & 1)) * block_s,
2061
+                               (2 * mb_y + (i >> 1)) * block_s,
2062
+                               s->width, s->height, s->linesize,
2063
+                               s->h_edge_pos >> lowres, s->v_edge_pos >> lowres,
2064
+                               block_s, block_s, pix_op,
2065
+                               s->mv[dir][i][0], s->mv[dir][i][1]);
2066
+
2067
+            mx += s->mv[dir][i][0];
2068
+            my += s->mv[dir][i][1];
2069
+        }
2070
+
2071
+        if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY))
2072
+            chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture,
2073
+                                     pix_op, mx, my);
2074
+        break;
2075
+    case MV_TYPE_FIELD:
2076
+        if (s->picture_structure == PICT_FRAME) {
2077
+            /* top field */
2078
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2079
+                               1, 0, s->field_select[dir][0],
2080
+                               ref_picture, pix_op,
2081
+                               s->mv[dir][0][0], s->mv[dir][0][1],
2082
+                               block_s, mb_y);
2083
+            /* bottom field */
2084
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2085
+                               1, 1, s->field_select[dir][1],
2086
+                               ref_picture, pix_op,
2087
+                               s->mv[dir][1][0], s->mv[dir][1][1],
2088
+                               block_s, mb_y);
2089
+        } else {
2090
+            if (s->picture_structure != s->field_select[dir][0] + 1 &&
2091
+                s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) {
2092
+                ref_picture = s->current_picture_ptr->f.data;
2093
+
2094
+            }
2095
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2096
+                               0, 0, s->field_select[dir][0],
2097
+                               ref_picture, pix_op,
2098
+                               s->mv[dir][0][0],
2099
+                               s->mv[dir][0][1], 2 * block_s, mb_y >> 1);
2100
+            }
2101
+        break;
2102
+    case MV_TYPE_16X8:
2103
+        for (i = 0; i < 2; i++) {
2104
+            uint8_t **ref2picture;
2105
+
2106
+            if (s->picture_structure == s->field_select[dir][i] + 1 ||
2107
+                s->pict_type == AV_PICTURE_TYPE_B || s->first_field) {
2108
+                ref2picture = ref_picture;
2109
+            } else {
2110
+                ref2picture = s->current_picture_ptr->f.data;
2111
+            }
2112
+
2113
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2114
+                               0, 0, s->field_select[dir][i],
2115
+                               ref2picture, pix_op,
2116
+                               s->mv[dir][i][0], s->mv[dir][i][1] +
2117
+                               2 * block_s * i, block_s, mb_y >> 1);
2118
+
2119
+            dest_y  +=  2 * block_s *  s->linesize;
2120
+            dest_cb += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
2121
+            dest_cr += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
2122
+        }
2123
+        break;
2124
+    case MV_TYPE_DMV:
2125
+        if (s->picture_structure == PICT_FRAME) {
2126
+            for (i = 0; i < 2; i++) {
2127
+                int j;
2128
+                for (j = 0; j < 2; j++) {
2129
+                    mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2130
+                                       1, j, j ^ i,
2131
+                                       ref_picture, pix_op,
2132
+                                       s->mv[dir][2 * i + j][0],
2133
+                                       s->mv[dir][2 * i + j][1],
2134
+                                       block_s, mb_y);
2135
+                }
2136
+                pix_op = s->dsp.avg_h264_chroma_pixels_tab;
2137
+            }
2138
+        } else {
2139
+            for (i = 0; i < 2; i++) {
2140
+                mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
2141
+                                   0, 0, s->picture_structure != i + 1,
2142
+                                   ref_picture, pix_op,
2143
+                                   s->mv[dir][2 * i][0],s->mv[dir][2 * i][1],
2144
+                                   2 * block_s, mb_y >> 1);
2145
+
2146
+                // after put we make avg of the same block
2147
+                pix_op = s->dsp.avg_h264_chroma_pixels_tab;
2148
+
2149
+                // opposite parity is always in the same
2150
+                // frame if this is second field
2151
+                if (!s->first_field) {
2152
+                    ref_picture = s->current_picture_ptr->f.data;
2153
+                }
2154
+            }
2155
+        }
2156
+        break;
2157
+    default:
2158
+        assert(0);
2159
+    }
2160
+}
2161
+
1787 2162
 /**
1788 2163
  * find the lowest MB row referenced in the MVs
1789 2164
  */
... ...
@@ -1893,7 +2268,7 @@ void ff_clean_intra_table_entries(MpegEncContext *s)
1893 1893
  */
1894 1894
 static av_always_inline
1895 1895
 void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
1896
-                            int is_mpeg12)
1896
+                            int lowres_flag, int is_mpeg12)
1897 1897
 {
1898 1898
     const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
1899 1899
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
... ...
@@ -1938,8 +2313,8 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
1938 1938
         qpel_mc_func (*op_qpix)[16];
1939 1939
         const int linesize   = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
1940 1940
         const int uvlinesize = s->current_picture.f.linesize[1];
1941
-        const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || s->avctx->lowres;
1942
-        const int block_size= 8 >> s->avctx->lowres;
1941
+        const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
1942
+        const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8;
1943 1943
 
1944 1944
         /* avoid copy if macroblock skipped in last frame too */
1945 1945
         /* skip only during decoding as we might trash the buffers during encoding a bit */
... ...
@@ -1988,19 +2363,31 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
1988 1988
                     }
1989 1989
                 }
1990 1990
 
1991
-                op_qpix= s->me.qpel_put;
1992
-                if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
1993
-                    op_pix = s->dsp.put_pixels_tab;
1991
+                if(lowres_flag){
1992
+                    h264_chroma_mc_func *op_pix = s->dsp.put_h264_chroma_pixels_tab;
1993
+
1994
+                    if (s->mv_dir & MV_DIR_FORWARD) {
1995
+                        MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix);
1996
+                        op_pix = s->dsp.avg_h264_chroma_pixels_tab;
1997
+                    }
1998
+                    if (s->mv_dir & MV_DIR_BACKWARD) {
1999
+                        MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix);
2000
+                    }
1994 2001
                 }else{
1995
-                    op_pix = s->dsp.put_no_rnd_pixels_tab;
1996
-                }
1997
-                if (s->mv_dir & MV_DIR_FORWARD) {
1998
-                    MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix, op_qpix);
1999
-                    op_pix = s->dsp.avg_pixels_tab;
2000
-                    op_qpix= s->me.qpel_avg;
2001
-                }
2002
-                if (s->mv_dir & MV_DIR_BACKWARD) {
2003
-                    MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix, op_qpix);
2002
+                    op_qpix= s->me.qpel_put;
2003
+                    if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
2004
+                        op_pix = s->dsp.put_pixels_tab;
2005
+                    }else{
2006
+                        op_pix = s->dsp.put_no_rnd_pixels_tab;
2007
+                    }
2008
+                    if (s->mv_dir & MV_DIR_FORWARD) {
2009
+                        MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix, op_qpix);
2010
+                        op_pix = s->dsp.avg_pixels_tab;
2011
+                        op_qpix= s->me.qpel_avg;
2012
+                    }
2013
+                    if (s->mv_dir & MV_DIR_BACKWARD) {
2014
+                        MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix, op_qpix);
2015
+                    }
2004 2016
                 }
2005 2017
             }
2006 2018
 
... ...
@@ -2016,9 +2403,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
2016 2016
             if(s->encoding || !(   s->msmpeg4_version || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO
2017 2017
                                 || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){
2018 2018
                 add_dequant_dct(s, block[0], 0, dest_y                          , dct_linesize, s->qscale);
2019
-                add_dequant_dct(s, block[1], 1, dest_y              + 8         , dct_linesize, s->qscale);
2019
+                add_dequant_dct(s, block[1], 1, dest_y              + block_size, dct_linesize, s->qscale);
2020 2020
                 add_dequant_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize, s->qscale);
2021
-                add_dequant_dct(s, block[3], 3, dest_y + dct_offset + 8         , dct_linesize, s->qscale);
2021
+                add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale);
2022 2022
 
2023 2023
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
2024 2024
                     if (s->chroma_y_shift){
... ...
@@ -2035,9 +2422,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
2035 2035
                 }
2036 2036
             } else if(is_mpeg12 || (s->codec_id != CODEC_ID_WMV2)){
2037 2037
                 add_dct(s, block[0], 0, dest_y                          , dct_linesize);
2038
-                add_dct(s, block[1], 1, dest_y              + 8         , dct_linesize);
2038
+                add_dct(s, block[1], 1, dest_y              + block_size, dct_linesize);
2039 2039
                 add_dct(s, block[2], 2, dest_y + dct_offset             , dct_linesize);
2040
-                add_dct(s, block[3], 3, dest_y + dct_offset + 8         , dct_linesize);
2040
+                add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize);
2041 2041
 
2042 2042
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
2043 2043
                     if(s->chroma_y_shift){//Chroma420
... ...
@@ -2046,17 +2433,17 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
2046 2046
                     }else{
2047 2047
                         //chroma422
2048 2048
                         dct_linesize = uvlinesize << s->interlaced_dct;
2049
-                        dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize*8;
2049
+                        dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
2050 2050
 
2051 2051
                         add_dct(s, block[4], 4, dest_cb, dct_linesize);
2052 2052
                         add_dct(s, block[5], 5, dest_cr, dct_linesize);
2053 2053
                         add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize);
2054 2054
                         add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize);
2055 2055
                         if(!s->chroma_x_shift){//Chroma444
2056
-                            add_dct(s, block[8], 8, dest_cb+8, dct_linesize);
2057
-                            add_dct(s, block[9], 9, dest_cr+8, dct_linesize);
2058
-                            add_dct(s, block[10], 10, dest_cb+8+dct_offset, dct_linesize);
2059
-                            add_dct(s, block[11], 11, dest_cr+8+dct_offset, dct_linesize);
2056
+                            add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize);
2057
+                            add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize);
2058
+                            add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize);
2059
+                            add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize);
2060 2060
                         }
2061 2061
                     }
2062 2062
                 }//fi gray
... ...
@@ -2087,9 +2474,9 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
2087 2087
                 }
2088 2088
             }else{
2089 2089
                 s->dsp.idct_put(dest_y                          , dct_linesize, block[0]);
2090
-                s->dsp.idct_put(dest_y              + 8         , dct_linesize, block[1]);
2090
+                s->dsp.idct_put(dest_y              + block_size, dct_linesize, block[1]);
2091 2091
                 s->dsp.idct_put(dest_y + dct_offset             , dct_linesize, block[2]);
2092
-                s->dsp.idct_put(dest_y + dct_offset + 8         , dct_linesize, block[3]);
2092
+                s->dsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]);
2093 2093
 
2094 2094
                 if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
2095 2095
                     if(s->chroma_y_shift){
... ...
@@ -2098,17 +2485,17 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
2098 2098
                     }else{
2099 2099
 
2100 2100
                         dct_linesize = uvlinesize << s->interlaced_dct;
2101
-                        dct_offset   = s->interlaced_dct? uvlinesize : uvlinesize*8;
2101
+                        dct_offset   = s->interlaced_dct? uvlinesize : uvlinesize*block_size;
2102 2102
 
2103 2103
                         s->dsp.idct_put(dest_cb,              dct_linesize, block[4]);
2104 2104
                         s->dsp.idct_put(dest_cr,              dct_linesize, block[5]);
2105 2105
                         s->dsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]);
2106 2106
                         s->dsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]);
2107 2107
                         if(!s->chroma_x_shift){//Chroma444
2108
-                            s->dsp.idct_put(dest_cb + 8,              dct_linesize, block[8]);
2109
-                            s->dsp.idct_put(dest_cr + 8,              dct_linesize, block[9]);
2110
-                            s->dsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]);
2111
-                            s->dsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]);
2108
+                            s->dsp.idct_put(dest_cb + block_size,              dct_linesize, block[8]);
2109
+                            s->dsp.idct_put(dest_cr + block_size,              dct_linesize, block[9]);
2110
+                            s->dsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]);
2111
+                            s->dsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]);
2112 2112
                         }
2113 2113
                     }
2114 2114
                 }//gray
... ...
@@ -2126,10 +2513,12 @@ skip_idct:
2126 2126
 void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
2127 2127
 #if !CONFIG_SMALL
2128 2128
     if(s->out_format == FMT_MPEG1) {
2129
-        MPV_decode_mb_internal(s, block, 1);
2129
+        if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 1);
2130
+        else                 MPV_decode_mb_internal(s, block, 0, 1);
2130 2131
     } else
2131 2132
 #endif
2132
-        MPV_decode_mb_internal(s, block, 0);
2133
+    if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 0);
2134
+    else                  MPV_decode_mb_internal(s, block, 0, 0);
2133 2135
 }
2134 2136
 
2135 2137
 /**
... ...
@@ -1216,6 +1216,7 @@ AVCodec ff_msmpeg4v1_decoder = {
1216 1216
     .close          = ff_h263_decode_end,
1217 1217
     .decode         = ff_h263_decode_frame,
1218 1218
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
1219
+    .max_lowres     = 3,
1219 1220
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
1220 1221
     .pix_fmts       = ff_pixfmt_list_420,
1221 1222
 };
... ...
@@ -1229,6 +1230,7 @@ AVCodec ff_msmpeg4v2_decoder = {
1229 1229
     .close          = ff_h263_decode_end,
1230 1230
     .decode         = ff_h263_decode_frame,
1231 1231
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
1232
+    .max_lowres     = 3,
1232 1233
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
1233 1234
     .pix_fmts       = ff_pixfmt_list_420,
1234 1235
 };
... ...
@@ -1242,6 +1244,7 @@ AVCodec ff_msmpeg4v3_decoder = {
1242 1242
     .close          = ff_h263_decode_end,
1243 1243
     .decode         = ff_h263_decode_frame,
1244 1244
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
1245
+    .max_lowres     = 3,
1245 1246
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
1246 1247
     .pix_fmts       = ff_pixfmt_list_420,
1247 1248
 };
... ...
@@ -1255,6 +1258,7 @@ AVCodec ff_wmv1_decoder = {
1255 1255
     .close          = ff_h263_decode_end,
1256 1256
     .decode         = ff_h263_decode_frame,
1257 1257
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
1258
+    .max_lowres     = 3,
1258 1259
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
1259 1260
     .pix_fmts       = ff_pixfmt_list_420,
1260 1261
 };
... ...
@@ -339,4 +339,5 @@ AVCodec ff_mxpeg_decoder = {
339 339
     .close          = mxpeg_decode_end,
340 340
     .decode         = mxpeg_decode_frame,
341 341
     .capabilities   = CODEC_CAP_DR1,
342
+    .max_lowres     = 3,
342 343
 };
... ...
@@ -435,7 +435,8 @@ av_log(s->avctx, AV_LOG_DEBUG, "\n");*/
435 435
 //    s->obmc=1;
436 436
 //    s->umvplus=1;
437 437
     s->modified_quant=1;
438
-    s->loop_filter=1;
438
+    if(!s->avctx->lowres)
439
+        s->loop_filter=1;
439 440
 
440 441
     if(s->avctx->debug & FF_DEBUG_PICT_INFO){
441 442
             av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n",
... ...
@@ -754,6 +755,7 @@ AVCodec ff_rv10_decoder = {
754 754
     .close          = rv10_decode_end,
755 755
     .decode         = rv10_decode_frame,
756 756
     .capabilities   = CODEC_CAP_DR1,
757
+    .max_lowres     = 3,
757 758
     .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
758 759
     .pix_fmts       = ff_pixfmt_list_420,
759 760
 };
... ...
@@ -768,6 +770,7 @@ AVCodec ff_rv20_decoder = {
768 768
     .decode         = rv10_decode_frame,
769 769
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
770 770
     .flush          = ff_mpeg_flush,
771
+    .max_lowres     = 3,
771 772
     .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
772 773
     .pix_fmts       = ff_pixfmt_list_420,
773 774
 };