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>
... | ... |
@@ -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 |
}; |
... | ... |
@@ -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 |
}; |
... | ... |
@@ -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 |
}; |