mbtransquant.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:12k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1.  /******************************************************************************
  2.   *                                                                            *
  3.   *  This file is part of XviD, a free MPEG-4 video encoder/decoder            *
  4.   *                                                                            *
  5.   *  XviD is an implementation of a part of one or more MPEG-4 Video tools     *
  6.   *  as specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
  7.   *  software module in hardware or software products are advised that its     *
  8.   *  use may infringe existing patents or copyrights, and any such use         *
  9.   *  would be at such party's own risk.  The original developer of this        *
  10.   *  software module and his/her company, and subsequent editors and their     *
  11.   *  companies, will have no liability for use of this software or             *
  12.   *  modifications or derivatives thereof.                                     *
  13.   *                                                                            *
  14.   *  XviD is free software; you can redistribute it and/or modify it           *
  15.   *  under the terms of the GNU General Public License as published by         *
  16.   *  the Free Software Foundation; either version 2 of the License, or         *
  17.   *  (at your option) any later version.                                       *
  18.   *                                                                            *
  19.   *  XviD is distributed in the hope that it will be useful, but               *
  20.   *  WITHOUT ANY WARRANTY; without even the implied warranty of                *
  21.   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
  22.   *  GNU General Public License for more details.                              *
  23.   *                                                                            *
  24.   *  You should have received a copy of the GNU General Public License         *
  25.   *  along with this program; if not, write to the Free Software               *
  26.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *
  27.   *                                                                            *
  28.   ******************************************************************************/
  29.  /******************************************************************************
  30.   *                                                                            *
  31.   *  mbtransquant.c                                                            *
  32.   *                                                                            *
  33.   *  Copyright (C) 2001 - Peter Ross <pross@cs.rmit.edu.au>                    *
  34.   *  Copyright (C) 2001 - Michael Militzer <isibaar@xvid.org>                  *
  35.   *                                                                            *
  36.   *  For more information visit the XviD homepage: http://www.xvid.org         *
  37.   *                                                                            *
  38.   ******************************************************************************/
  39.  /******************************************************************************
  40.   *                                                                            *
  41.   *  Revision history:                                                         *
  42.   *                                                                            *
  43.   *  29.03.2002 interlacing speedup - used transfer strides instead of
  44.   *             manual field-to-frame conversion
  45.   *  26.03.2002 interlacing support - moved transfers outside loops
  46.   *  22.12.2001 get_dc_scaler() moved to common.h
  47.   *  19.11.2001 introduced coefficient thresholding (Isibaar)                  *
  48.   *  17.11.2001 initial version                                                *
  49.   *                                                                            *
  50.   ******************************************************************************/
  51. #include <string.h>
  52. #include "../portab.h"
  53. #include "mbfunctions.h"
  54. #include "../global.h"
  55. #include "mem_transfer.h"
  56. #include "timer.h"
  57. #include "../dct/fdct.h"
  58. #include "../dct/idct.h"
  59. #include "../quant/quant_mpeg4.h"
  60. #include "../quant/quant_h263.h"
  61. #include "../encoder.h"
  62. #define MIN(X, Y) ((X)<(Y)?(X):(Y))
  63. #define MAX(X, Y) ((X)>(Y)?(X):(Y))
  64. #define TOOSMALL_LIMIT 1 /* skip blocks having a coefficient sum below this value */
  65. /* this isnt pretty, but its better than 20 ifdefs */
  66. void MBTransQuantIntra(const MBParam *pParam,
  67.        MACROBLOCK * pMB,
  68.        const uint32_t x_pos,
  69.        const uint32_t y_pos,
  70.        int16_t data[6*64], 
  71.        int16_t qcoeff[6*64], 
  72.        IMAGE * const pCurrent)
  73.    
  74. {
  75. uint32_t stride = pParam->edged_width;
  76. uint32_t stride2 = stride / 2;
  77. uint32_t next_block = stride * 8;
  78. uint32_t i;
  79. uint32_t iQuant = pParam->quant;
  80. uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
  81. pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);
  82. pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
  83. pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
  84. start_timer();
  85. transfer_8to16copy(&data[0*64], pY_Cur, stride);
  86. transfer_8to16copy(&data[1*64], pY_Cur + 8, stride);
  87. transfer_8to16copy(&data[2*64], pY_Cur + next_block, stride);
  88. transfer_8to16copy(&data[3*64], pY_Cur + next_block + 8,stride);
  89. transfer_8to16copy(&data[4*64], pU_Cur, stride2);
  90. transfer_8to16copy(&data[5*64], pV_Cur, stride2);
  91. stop_transfer_timer();
  92. start_timer();
  93. pMB->field_dct = 0;
  94. if (pParam->global_flags & XVID_INTERLACING)
  95. {
  96. pMB->field_dct = MBDecideFieldDCT(data);
  97. }
  98. stop_interlacing_timer();
  99. for(i = 0; i < 6; i++)
  100. {
  101. uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
  102. start_timer();
  103. fdct(&data[i*64]);
  104. stop_dct_timer();
  105. if (pParam->quant_type == H263_QUANT)
  106. {
  107. start_timer();
  108. quant_intra(&qcoeff[i*64], &data[i*64], iQuant, iDcScaler);
  109. stop_quant_timer();
  110. start_timer();
  111. dequant_intra(&data[i*64], &qcoeff[i*64], iQuant, iDcScaler);
  112. stop_iquant_timer();
  113. }
  114. else
  115. {
  116. start_timer();
  117. quant4_intra(&qcoeff[i*64], &data[i*64], iQuant, iDcScaler);
  118. stop_quant_timer();
  119. start_timer();
  120. dequant4_intra(&data[i*64], &qcoeff[i*64], iQuant, iDcScaler);
  121. stop_iquant_timer();
  122. }
  123. start_timer();
  124. idct(&data[i*64]);
  125. stop_idct_timer();
  126. }
  127. if (pMB->field_dct)
  128. {
  129. next_block = stride;
  130. stride *= 2;
  131. }
  132. start_timer();
  133. transfer_16to8copy(pY_Cur,                  &data[0*64], stride);
  134. transfer_16to8copy(pY_Cur + 8,              &data[1*64], stride);
  135. transfer_16to8copy(pY_Cur + next_block,     &data[2*64], stride);
  136. transfer_16to8copy(pY_Cur + next_block + 8, &data[3*64], stride);
  137. transfer_16to8copy(pU_Cur,                  &data[4*64], stride2);
  138. transfer_16to8copy(pV_Cur,                  &data[5*64], stride2);
  139. stop_transfer_timer();
  140. }
  141. uint8_t MBTransQuantInter(const MBParam *pParam, 
  142.   MACROBLOCK * pMB,
  143.   const uint32_t x_pos, const uint32_t y_pos,
  144.   int16_t data[6*64], 
  145.   int16_t qcoeff[6*64], 
  146.   IMAGE * const pCurrent)
  147. {
  148. uint32_t stride = pParam->edged_width;
  149. uint32_t stride2 = stride / 2;
  150. uint32_t next_block = stride * 8;
  151. uint32_t i;
  152. uint32_t iQuant = pParam->quant;
  153. uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
  154. uint8_t cbp = 0;
  155. uint32_t sum;
  156.     
  157. pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);
  158. pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);
  159. pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);
  160. start_timer();
  161. pMB->field_dct = 0;
  162. if (pParam->global_flags & XVID_INTERLACING)
  163. {
  164. pMB->field_dct = MBDecideFieldDCT(data);
  165. }
  166. stop_interlacing_timer();
  167. for(i = 0; i < 6; i++)
  168. {
  169. /* 
  170.  *  no need to transfer 8->16-bit
  171.  * (this is performed already in motion compensation) 
  172.  */
  173. start_timer();
  174. fdct(&data[i*64]);
  175. stop_dct_timer();
  176. if (pParam->quant_type == 0)
  177. {
  178. start_timer();
  179. sum = quant_inter(&qcoeff[i*64], &data[i*64], iQuant);
  180. stop_quant_timer();
  181. }
  182. else
  183. {
  184. start_timer();
  185. sum = quant4_inter(&qcoeff[i*64], &data[i*64], iQuant);
  186. stop_quant_timer();
  187. }
  188. if(sum >= TOOSMALL_LIMIT) { // skip block ?
  189. if (pParam->quant_type == H263_QUANT)
  190. {
  191. start_timer();
  192. dequant_inter(&data[i*64], &qcoeff[i*64], iQuant);
  193. stop_iquant_timer();
  194. }
  195. else
  196. {
  197. start_timer();
  198. dequant4_inter(&data[i*64], &qcoeff[i*64], iQuant);
  199. stop_iquant_timer();
  200. }
  201. cbp |= 1 << (5 - i);
  202. start_timer();
  203. idct(&data[i*64]);
  204. stop_idct_timer();
  205. }
  206. }
  207. if (pMB->field_dct)
  208. {
  209. next_block = stride;
  210. stride *= 2;
  211. }
  212. start_timer();
  213. if (cbp & 32)
  214. transfer_16to8add(pY_Cur,                  &data[0*64], stride);
  215. if (cbp & 16)
  216. transfer_16to8add(pY_Cur + 8,              &data[1*64], stride);
  217. if (cbp & 8)
  218. transfer_16to8add(pY_Cur + next_block,     &data[2*64], stride);
  219. if (cbp & 4)
  220. transfer_16to8add(pY_Cur + next_block + 8, &data[3*64], stride);
  221. if (cbp & 2)
  222. transfer_16to8add(pU_Cur,                  &data[4*64], stride2);
  223. if (cbp & 1)
  224. transfer_16to8add(pV_Cur,                  &data[5*64], stride2);
  225. stop_transfer_timer();
  226. return cbp;
  227. }
  228. /* if sum(diff between field lines) < sum(diff between frame lines), use field dct */
  229. #define ABS(X) (X)<0 ? -(X) : (X)
  230. uint32_t MBDecideFieldDCT(int16_t data[6*64])
  231. {
  232. const uint8_t blocks[] = {0*64, 0*64, 0*64, 0*64, 2*64, 2*64, 2*64, 2*64};
  233. const uint8_t lines[]  = {0, 16, 32, 48, 0, 16, 32, 48};
  234. int frame = 0, field = 0;
  235. int i, j;
  236. for (i=0 ; i<7 ; ++i)
  237. {
  238. for (j=0 ; j<8 ; ++j)
  239. {
  240. frame += ABS(data[0*64 + (i+1)*8 + j] - data[0*64 + i*8 + j]);
  241. frame += ABS(data[1*64 + (i+1)*8 + j] - data[1*64 + i*8 + j]);
  242. frame += ABS(data[2*64 + (i+1)*8 + j] - data[2*64 + i*8 + j]);
  243. frame += ABS(data[3*64 + (i+1)*8 + j] - data[3*64 + i*8 + j]);
  244. field += ABS(data[blocks[i+1] + lines[i+1] + j] -
  245.      data[blocks[i  ] + lines[i  ] + j]);
  246. field += ABS(data[blocks[i+1] + lines[i+1] + 8 + j] -
  247.      data[blocks[i  ] + lines[i  ] + 8 + j]);
  248. field += ABS(data[blocks[i+1] + 64 + lines[i+1] + j] -
  249.      data[blocks[i  ] + 64 + lines[i  ] + j]);
  250. field += ABS(data[blocks[i+1] + 64 + lines[i+1] + 8 + j] -
  251.      data[blocks[i  ] + 64 + lines[i  ] + 8 + j]);
  252. }
  253. }
  254. if (frame > field)
  255. {
  256. MBFrameToField(data);
  257. }
  258. return (frame > field);
  259. }
  260. /* deinterlace Y blocks vertically */
  261. #define MOVLINE(X,Y) memcpy(X, Y, sizeof(tmp))
  262. #define LINE(X,Y)    &data[X*64 + Y*8]
  263. void MBFrameToField(int16_t data[6*64])
  264. {
  265. int16_t tmp[8];
  266. /* left blocks */
  267. // 1=2, 2=4, 4=8, 8=1
  268. MOVLINE(tmp, LINE(0,1));
  269. MOVLINE(LINE(0,1), LINE(0,2));
  270. MOVLINE(LINE(0,2), LINE(0,4));
  271. MOVLINE(LINE(0,4), LINE(2,0));
  272. MOVLINE(LINE(2,0), tmp);
  273. // 3=6, 6=12, 12=9, 9=3
  274. MOVLINE(tmp, LINE(0,3));
  275. MOVLINE(LINE(0,3), LINE(0,6));
  276. MOVLINE(LINE(0,6), LINE(2,4));
  277. MOVLINE(LINE(2,4), LINE(2,1));
  278. MOVLINE(LINE(2,1), tmp);
  279. // 5=10, 10=5
  280. MOVLINE(tmp, LINE(0,5));
  281. MOVLINE(LINE(0,5), LINE(2,2));
  282. MOVLINE(LINE(2,2), tmp);
  283. // 7=14, 14=13, 13=11, 11=7
  284. MOVLINE(tmp, LINE(0,7));
  285. MOVLINE(LINE(0,7), LINE(2,6));
  286. MOVLINE(LINE(2,6), LINE(2,5));
  287. MOVLINE(LINE(2,5), LINE(2,3));
  288. MOVLINE(LINE(2,3), tmp);
  289. /* right blocks */
  290. // 1=2, 2=4, 4=8, 8=1
  291. MOVLINE(tmp, LINE(1,1));
  292. MOVLINE(LINE(1,1), LINE(1,2));
  293. MOVLINE(LINE(1,2), LINE(1,4));
  294. MOVLINE(LINE(1,4), LINE(3,0));
  295. MOVLINE(LINE(3,0), tmp);
  296. // 3=6, 6=12, 12=9, 9=3
  297. MOVLINE(tmp, LINE(1,3));
  298. MOVLINE(LINE(1,3), LINE(1,6));
  299. MOVLINE(LINE(1,6), LINE(3,4));
  300. MOVLINE(LINE(3,4), LINE(3,1));
  301. MOVLINE(LINE(3,1), tmp);
  302. // 5=10, 10=5
  303. MOVLINE(tmp, LINE(1,5));
  304. MOVLINE(LINE(1,5), LINE(3,2));
  305. MOVLINE(LINE(3,2), tmp);
  306. // 7=14, 14=13, 13=11, 11=7
  307. MOVLINE(tmp, LINE(1,7));
  308. MOVLINE(LINE(1,7), LINE(3,6));
  309. MOVLINE(LINE(3,6), LINE(3,5));
  310. MOVLINE(LINE(3,5), LINE(3,3));
  311. MOVLINE(LINE(3,3), tmp);
  312. }