Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * RV30 decoder motion compensation functions
  3.  * Copyright (c) 2007 Konstantin Shishkov
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. /**
  23.  * @file
  24.  * RV30 decoder motion compensation functions
  25.  */
  26.  
  27. #include "avcodec.h"
  28. #include "h264chroma.h"
  29. #include "h264qpel.h"
  30. #include "rv34dsp.h"
  31.  
  32. #define RV30_LOWPASS(OPNAME, OP) \
  33. static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
  34.     const int h = 8;\
  35.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
  36.     int i;\
  37.     for(i = 0; i < h; i++)\
  38.     {\
  39.         OP(dst[0], (-(src[-1]+src[2]) + src[0]*C1 + src[1]*C2 + 8)>>4);\
  40.         OP(dst[1], (-(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + 8)>>4);\
  41.         OP(dst[2], (-(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2 + 8)>>4);\
  42.         OP(dst[3], (-(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2 + 8)>>4);\
  43.         OP(dst[4], (-(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2 + 8)>>4);\
  44.         OP(dst[5], (-(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + 8)>>4);\
  45.         OP(dst[6], (-(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + 8)>>4);\
  46.         OP(dst[7], (-(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + 8)>>4);\
  47.         dst += dstStride;\
  48.         src += srcStride;\
  49.     }\
  50. }\
  51. \
  52. static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
  53.     const int w = 8;\
  54.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
  55.     int i;\
  56.     for(i = 0; i < w; i++)\
  57.     {\
  58.         const int srcA = src[-1*srcStride];\
  59.         const int src0 = src[0 *srcStride];\
  60.         const int src1 = src[1 *srcStride];\
  61.         const int src2 = src[2 *srcStride];\
  62.         const int src3 = src[3 *srcStride];\
  63.         const int src4 = src[4 *srcStride];\
  64.         const int src5 = src[5 *srcStride];\
  65.         const int src6 = src[6 *srcStride];\
  66.         const int src7 = src[7 *srcStride];\
  67.         const int src8 = src[8 *srcStride];\
  68.         const int src9 = src[9 *srcStride];\
  69.         OP(dst[0*dstStride], (-(srcA+src2) + src0*C1 + src1*C2 + 8)>>4);\
  70.         OP(dst[1*dstStride], (-(src0+src3) + src1*C1 + src2*C2 + 8)>>4);\
  71.         OP(dst[2*dstStride], (-(src1+src4) + src2*C1 + src3*C2 + 8)>>4);\
  72.         OP(dst[3*dstStride], (-(src2+src5) + src3*C1 + src4*C2 + 8)>>4);\
  73.         OP(dst[4*dstStride], (-(src3+src6) + src4*C1 + src5*C2 + 8)>>4);\
  74.         OP(dst[5*dstStride], (-(src4+src7) + src5*C1 + src6*C2 + 8)>>4);\
  75.         OP(dst[6*dstStride], (-(src5+src8) + src6*C1 + src7*C2 + 8)>>4);\
  76.         OP(dst[7*dstStride], (-(src6+src9) + src7*C1 + src8*C2 + 8)>>4);\
  77.         dst++;\
  78.         src++;\
  79.     }\
  80. }\
  81. \
  82. static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  83.     const int w = 8;\
  84.     const int h = 8;\
  85.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
  86.     int i, j;\
  87.     for(j = 0; j < h; j++){\
  88.         for(i = 0; i < w; i++){\
  89.             OP(dst[i], (\
  90.                   src[srcStride*-1+i-1]  -12*src[srcStride*-1+i]  -6*src[srcStride*-1+i+1]    +src[srcStride*-1+i+2]+\
  91.               -12*src[srcStride* 0+i-1] +144*src[srcStride* 0+i] +72*src[srcStride* 0+i+1] -12*src[srcStride* 0+i+2] +\
  92.                -6*src[srcStride* 1+i-1]  +72*src[srcStride* 1+i] +36*src[srcStride* 1+i+1]  -6*src[srcStride* 1+i+2] +\
  93.                   src[srcStride* 2+i-1]  -12*src[srcStride* 2+i]  -6*src[srcStride* 2+i+1]    +src[srcStride* 2+i+2] +\
  94.                   128)>>8);\
  95.         }\
  96.         src += srcStride;\
  97.         dst += dstStride;\
  98.     }\
  99. }\
  100. \
  101. static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  102.     const int w = 8;\
  103.     const int h = 8;\
  104.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
  105.     int i, j;\
  106.     for(j = 0; j < h; j++){\
  107.         for(i = 0; i < w; i++){\
  108.             OP(dst[i], (\
  109.                   src[srcStride*-1+i-1]  -12*src[srcStride*-1+i+1]  -6*src[srcStride*-1+i]    +src[srcStride*-1+i+2]+\
  110.               -12*src[srcStride* 0+i-1] +144*src[srcStride* 0+i+1] +72*src[srcStride* 0+i] -12*src[srcStride* 0+i+2]+\
  111.                -6*src[srcStride* 1+i-1]  +72*src[srcStride* 1+i+1] +36*src[srcStride* 1+i]  -6*src[srcStride* 1+i+2]+\
  112.                   src[srcStride* 2+i-1]  -12*src[srcStride* 2+i+1]  -6*src[srcStride* 2+i]    +src[srcStride* 2+i+2]+\
  113.                   128)>>8);\
  114.         }\
  115.         src += srcStride;\
  116.         dst += dstStride;\
  117.     }\
  118. }\
  119. \
  120. static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  121.     const int w = 8;\
  122.     const int h = 8;\
  123.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
  124.     int i, j;\
  125.     for(j = 0; j < h; j++){\
  126.         for(i = 0; i < w; i++){\
  127.             OP(dst[i], (\
  128.                   src[srcStride*-1+i-1]  -12*src[srcStride*-1+i]  -6*src[srcStride*-1+i+1]    +src[srcStride*-1+i+2]+\
  129.                -6*src[srcStride* 0+i-1]  +72*src[srcStride* 0+i] +36*src[srcStride* 0+i+1]  -6*src[srcStride* 0+i+2]+\
  130.               -12*src[srcStride* 1+i-1] +144*src[srcStride* 1+i] +72*src[srcStride* 1+i+1] -12*src[srcStride* 1+i+2]+\
  131.                   src[srcStride* 2+i-1]  -12*src[srcStride* 2+i]  -6*src[srcStride* 2+i+1]    +src[srcStride* 2+i+2]+\
  132.                   128)>>8);\
  133.         }\
  134.         src += srcStride;\
  135.         dst += dstStride;\
  136.     }\
  137. }\
  138. \
  139. static void OPNAME ## rv30_tpel8_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  140.     const int w = 8;\
  141.     const int h = 8;\
  142.     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
  143.     int i, j;\
  144.     for(j = 0; j < h; j++){\
  145.         for(i = 0; i < w; i++){\
  146.             OP(dst[i], (\
  147.                36*src[i+srcStride*0] +54*src[i+1+srcStride*0] +6*src[i+2+srcStride*0]+\
  148.                54*src[i+srcStride*1] +81*src[i+1+srcStride*1] +9*src[i+2+srcStride*1]+\
  149.                 6*src[i+srcStride*2] + 9*src[i+1+srcStride*2] +  src[i+2+srcStride*2]+\
  150.                128)>>8);\
  151.         }\
  152.         src += srcStride;\
  153.         dst += dstStride;\
  154.     }\
  155. }\
  156. \
  157. static void OPNAME ## rv30_tpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
  158.     OPNAME ## rv30_tpel8_v_lowpass(dst  , src  , dstStride, srcStride, C1, C2);\
  159.     OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\
  160.     src += 8*srcStride;\
  161.     dst += 8*dstStride;\
  162.     OPNAME ## rv30_tpel8_v_lowpass(dst  , src  , dstStride, srcStride, C1, C2);\
  163.     OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\
  164. }\
  165. \
  166. static void OPNAME ## rv30_tpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
  167.     OPNAME ## rv30_tpel8_h_lowpass(dst  , src  , dstStride, srcStride, C1, C2);\
  168.     OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\
  169.     src += 8*srcStride;\
  170.     dst += 8*dstStride;\
  171.     OPNAME ## rv30_tpel8_h_lowpass(dst  , src  , dstStride, srcStride, C1, C2);\
  172.     OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\
  173. }\
  174. \
  175. static void OPNAME ## rv30_tpel16_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  176.     OPNAME ## rv30_tpel8_hv_lowpass(dst  , src  , dstStride, srcStride);\
  177.     OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\
  178.     src += 8*srcStride;\
  179.     dst += 8*dstStride;\
  180.     OPNAME ## rv30_tpel8_hv_lowpass(dst  , src  , dstStride, srcStride);\
  181.     OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\
  182. }\
  183. \
  184. static void OPNAME ## rv30_tpel16_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  185.     OPNAME ## rv30_tpel8_hhv_lowpass(dst  , src  , dstStride, srcStride);\
  186.     OPNAME ## rv30_tpel8_hhv_lowpass(dst+8, src+8, dstStride, srcStride);\
  187.     src += 8*srcStride;\
  188.     dst += 8*dstStride;\
  189.     OPNAME ## rv30_tpel8_hhv_lowpass(dst  , src  , dstStride, srcStride);\
  190.     OPNAME ## rv30_tpel8_hhv_lowpass(dst+8, src+8, dstStride, srcStride);\
  191. }\
  192. \
  193. static void OPNAME ## rv30_tpel16_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  194.     OPNAME ## rv30_tpel8_hvv_lowpass(dst  , src  , dstStride, srcStride);\
  195.     OPNAME ## rv30_tpel8_hvv_lowpass(dst+8, src+8, dstStride, srcStride);\
  196.     src += 8*srcStride;\
  197.     dst += 8*dstStride;\
  198.     OPNAME ## rv30_tpel8_hvv_lowpass(dst  , src  , dstStride, srcStride);\
  199.     OPNAME ## rv30_tpel8_hvv_lowpass(dst+8, src+8, dstStride, srcStride);\
  200. }\
  201. \
  202. static void OPNAME ## rv30_tpel16_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
  203.     OPNAME ## rv30_tpel8_hhvv_lowpass(dst  , src  , dstStride, srcStride);\
  204.     OPNAME ## rv30_tpel8_hhvv_lowpass(dst+8, src+8, dstStride, srcStride);\
  205.     src += 8*srcStride;\
  206.     dst += 8*dstStride;\
  207.     OPNAME ## rv30_tpel8_hhvv_lowpass(dst  , src  , dstStride, srcStride);\
  208.     OPNAME ## rv30_tpel8_hhvv_lowpass(dst+8, src+8, dstStride, srcStride);\
  209. }\
  210. \
  211.  
  212. #define RV30_MC(OPNAME, SIZE) \
  213. static void OPNAME ## rv30_tpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  214. {\
  215.     OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 12, 6);\
  216. }\
  217. \
  218. static void OPNAME ## rv30_tpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  219. {\
  220.     OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 6, 12);\
  221. }\
  222. \
  223. static void OPNAME ## rv30_tpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  224. {\
  225.     OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\
  226. }\
  227. \
  228. static void OPNAME ## rv30_tpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  229. {\
  230.     OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 6, 12);\
  231. }\
  232. \
  233. static void OPNAME ## rv30_tpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  234. {\
  235.     OPNAME ## rv30_tpel ## SIZE ## _hv_lowpass(dst, src, stride, stride);\
  236. }\
  237. \
  238. static void OPNAME ## rv30_tpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  239. {\
  240.     OPNAME ## rv30_tpel ## SIZE ## _hvv_lowpass(dst, src, stride, stride);\
  241. }\
  242. \
  243. static void OPNAME ## rv30_tpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  244. {\
  245.     OPNAME ## rv30_tpel ## SIZE ## _hhv_lowpass(dst, src, stride, stride);\
  246. }\
  247. \
  248. static void OPNAME ## rv30_tpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
  249. {\
  250.     OPNAME ## rv30_tpel ## SIZE ## _hhvv_lowpass(dst, src, stride, stride);\
  251. }\
  252. \
  253.  
  254. #define op_avg(a, b)  a = (((a)+cm[b]+1)>>1)
  255. #define op_put(a, b)  a = cm[b]
  256.  
  257. RV30_LOWPASS(put_       , op_put)
  258. RV30_LOWPASS(avg_       , op_avg)
  259. RV30_MC(put_, 8)
  260. RV30_MC(put_, 16)
  261. RV30_MC(avg_, 8)
  262. RV30_MC(avg_, 16)
  263.  
  264. av_cold void ff_rv30dsp_init(RV34DSPContext *c)
  265. {
  266.     H264ChromaContext h264chroma;
  267.     H264QpelContext qpel;
  268.  
  269.     ff_rv34dsp_init(c);
  270.     ff_h264chroma_init(&h264chroma, 8);
  271.     ff_h264qpel_init(&qpel, 8);
  272.  
  273.     c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
  274.     c->put_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c;
  275.     c->put_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c;
  276.     c->put_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c;
  277.     c->put_pixels_tab[0][ 5] = put_rv30_tpel16_mc11_c;
  278.     c->put_pixels_tab[0][ 6] = put_rv30_tpel16_mc21_c;
  279.     c->put_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c;
  280.     c->put_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c;
  281.     c->put_pixels_tab[0][10] = put_rv30_tpel16_mc22_c;
  282.     c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
  283.     c->avg_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c;
  284.     c->avg_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c;
  285.     c->avg_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c;
  286.     c->avg_pixels_tab[0][ 5] = avg_rv30_tpel16_mc11_c;
  287.     c->avg_pixels_tab[0][ 6] = avg_rv30_tpel16_mc21_c;
  288.     c->avg_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c;
  289.     c->avg_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c;
  290.     c->avg_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c;
  291.     c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
  292.     c->put_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c;
  293.     c->put_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c;
  294.     c->put_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c;
  295.     c->put_pixels_tab[1][ 5] = put_rv30_tpel8_mc11_c;
  296.     c->put_pixels_tab[1][ 6] = put_rv30_tpel8_mc21_c;
  297.     c->put_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c;
  298.     c->put_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c;
  299.     c->put_pixels_tab[1][10] = put_rv30_tpel8_mc22_c;
  300.     c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
  301.     c->avg_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c;
  302.     c->avg_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c;
  303.     c->avg_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c;
  304.     c->avg_pixels_tab[1][ 5] = avg_rv30_tpel8_mc11_c;
  305.     c->avg_pixels_tab[1][ 6] = avg_rv30_tpel8_mc21_c;
  306.     c->avg_pixels_tab[1][ 8] = avg_rv30_tpel8_mc02_c;
  307.     c->avg_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c;
  308.     c->avg_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c;
  309.  
  310.     c->put_chroma_pixels_tab[0] = h264chroma.put_h264_chroma_pixels_tab[0];
  311.     c->put_chroma_pixels_tab[1] = h264chroma.put_h264_chroma_pixels_tab[1];
  312.     c->avg_chroma_pixels_tab[0] = h264chroma.avg_h264_chroma_pixels_tab[0];
  313.     c->avg_chroma_pixels_tab[1] = h264chroma.avg_h264_chroma_pixels_tab[1];
  314. }
  315.