You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

567 lines
17KB

  1. /*
  2. * The simplest mpeg encoder (well, it was the simplest!)
  3. * Copyright (c) 2000,2001 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. * Optimized for ia32 cpus by Nick Kurshev <nickols_k@mail.ru>
  20. * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer <michaelni@gmx.at>
  21. */
  22. #include "../dsputil.h"
  23. #include "../mpegvideo.h"
  24. #include "../avcodec.h"
  25. #include "../simple_idct.h"
  26. extern UINT8 zigzag_direct_noperm[64];
  27. extern UINT16 inv_zigzag_direct16[64];
  28. extern UINT32 inverse[256];
  29. static const unsigned long long int mm_wabs __attribute__ ((aligned(8))) = 0xffffffffffffffffULL;
  30. static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001ULL;
  31. static void dct_unquantize_h263_mmx(MpegEncContext *s,
  32. DCTELEM *block, int n, int qscale)
  33. {
  34. int level, qmul, qadd, nCoeffs;
  35. qmul = qscale << 1;
  36. qadd = (qscale - 1) | 1;
  37. assert(s->block_last_index[n]>=0);
  38. if (s->mb_intra) {
  39. if (!s->h263_aic) {
  40. if (n < 4)
  41. level = block[0] * s->y_dc_scale;
  42. else
  43. level = block[0] * s->c_dc_scale;
  44. }else{
  45. qadd = 0;
  46. level= block[0];
  47. }
  48. nCoeffs=63;
  49. } else {
  50. nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
  51. level = 0;/* keep gcc quiet */
  52. }
  53. //printf("%d %d ", qmul, qadd);
  54. asm volatile(
  55. "movd %1, %%mm6 \n\t" //qmul
  56. "packssdw %%mm6, %%mm6 \n\t"
  57. "packssdw %%mm6, %%mm6 \n\t"
  58. "movd %2, %%mm5 \n\t" //qadd
  59. "pxor %%mm7, %%mm7 \n\t"
  60. "packssdw %%mm5, %%mm5 \n\t"
  61. "packssdw %%mm5, %%mm5 \n\t"
  62. "psubw %%mm5, %%mm7 \n\t"
  63. "pxor %%mm4, %%mm4 \n\t"
  64. ".balign 16\n\t"
  65. "1: \n\t"
  66. "movq (%0, %3), %%mm0 \n\t"
  67. "movq 8(%0, %3), %%mm1 \n\t"
  68. "pmullw %%mm6, %%mm0 \n\t"
  69. "pmullw %%mm6, %%mm1 \n\t"
  70. "movq (%0, %3), %%mm2 \n\t"
  71. "movq 8(%0, %3), %%mm3 \n\t"
  72. "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0
  73. "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0
  74. "pxor %%mm2, %%mm0 \n\t"
  75. "pxor %%mm3, %%mm1 \n\t"
  76. "paddw %%mm7, %%mm0 \n\t"
  77. "paddw %%mm7, %%mm1 \n\t"
  78. "pxor %%mm0, %%mm2 \n\t"
  79. "pxor %%mm1, %%mm3 \n\t"
  80. "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0
  81. "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0
  82. "pandn %%mm2, %%mm0 \n\t"
  83. "pandn %%mm3, %%mm1 \n\t"
  84. "movq %%mm0, (%0, %3) \n\t"
  85. "movq %%mm1, 8(%0, %3) \n\t"
  86. "addl $16, %3 \n\t"
  87. "jng 1b \n\t"
  88. ::"r" (block+nCoeffs), "g"(qmul), "g" (qadd), "r" (2*(-nCoeffs))
  89. : "memory"
  90. );
  91. if(s->mb_intra)
  92. block[0]= level;
  93. }
  94. /*
  95. NK:
  96. Note: looking at PARANOID:
  97. "enable all paranoid tests for rounding, overflows, etc..."
  98. #ifdef PARANOID
  99. if (level < -2048 || level > 2047)
  100. fprintf(stderr, "unquant error %d %d\n", i, level);
  101. #endif
  102. We can suppose that result of two multiplications can't be greate of 0xFFFF
  103. i.e. is 16-bit, so we use here only PMULLW instruction and can avoid
  104. a complex multiplication.
  105. =====================================================
  106. Full formula for multiplication of 2 integer numbers
  107. which are represent as high:low words:
  108. input: value1 = high1:low1
  109. value2 = high2:low2
  110. output: value3 = value1*value2
  111. value3=high3:low3 (on overflow: modulus 2^32 wrap-around)
  112. this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4
  113. but this algorithm will compute only 0x66cb0ce4
  114. this limited by 16-bit size of operands
  115. ---------------------------------
  116. tlow1 = high1*low2
  117. tlow2 = high2*low1
  118. tlow1 = tlow1 + tlow2
  119. high3:low3 = low1*low2
  120. high3 += tlow1
  121. */
  122. static void dct_unquantize_mpeg1_mmx(MpegEncContext *s,
  123. DCTELEM *block, int n, int qscale)
  124. {
  125. int nCoeffs;
  126. const UINT16 *quant_matrix;
  127. assert(s->block_last_index[n]>=0);
  128. nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1;
  129. if (s->mb_intra) {
  130. int block0;
  131. if (n < 4)
  132. block0 = block[0] * s->y_dc_scale;
  133. else
  134. block0 = block[0] * s->c_dc_scale;
  135. /* XXX: only mpeg1 */
  136. quant_matrix = s->intra_matrix;
  137. asm volatile(
  138. "pcmpeqw %%mm7, %%mm7 \n\t"
  139. "psrlw $15, %%mm7 \n\t"
  140. "movd %2, %%mm6 \n\t"
  141. "packssdw %%mm6, %%mm6 \n\t"
  142. "packssdw %%mm6, %%mm6 \n\t"
  143. "movl %3, %%eax \n\t"
  144. ".balign 16\n\t"
  145. "1: \n\t"
  146. "movq (%0, %%eax), %%mm0 \n\t"
  147. "movq 8(%0, %%eax), %%mm1 \n\t"
  148. "movq (%1, %%eax), %%mm4 \n\t"
  149. "movq 8(%1, %%eax), %%mm5 \n\t"
  150. "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i]
  151. "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i]
  152. "pxor %%mm2, %%mm2 \n\t"
  153. "pxor %%mm3, %%mm3 \n\t"
  154. "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0
  155. "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0
  156. "pxor %%mm2, %%mm0 \n\t"
  157. "pxor %%mm3, %%mm1 \n\t"
  158. "psubw %%mm2, %%mm0 \n\t" // abs(block[i])
  159. "psubw %%mm3, %%mm1 \n\t" // abs(block[i])
  160. "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q
  161. "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q
  162. "pxor %%mm4, %%mm4 \n\t"
  163. "pxor %%mm5, %%mm5 \n\t" // FIXME slow
  164. "pcmpeqw (%0, %%eax), %%mm4 \n\t" // block[i] == 0 ? -1 : 0
  165. "pcmpeqw 8(%0, %%eax), %%mm5 \n\t" // block[i] == 0 ? -1 : 0
  166. "psraw $3, %%mm0 \n\t"
  167. "psraw $3, %%mm1 \n\t"
  168. "psubw %%mm7, %%mm0 \n\t"
  169. "psubw %%mm7, %%mm1 \n\t"
  170. "por %%mm7, %%mm0 \n\t"
  171. "por %%mm7, %%mm1 \n\t"
  172. "pxor %%mm2, %%mm0 \n\t"
  173. "pxor %%mm3, %%mm1 \n\t"
  174. "psubw %%mm2, %%mm0 \n\t"
  175. "psubw %%mm3, %%mm1 \n\t"
  176. "pandn %%mm0, %%mm4 \n\t"
  177. "pandn %%mm1, %%mm5 \n\t"
  178. "movq %%mm4, (%0, %%eax) \n\t"
  179. "movq %%mm5, 8(%0, %%eax) \n\t"
  180. "addl $16, %%eax \n\t"
  181. "js 1b \n\t"
  182. ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)
  183. : "%eax", "memory"
  184. );
  185. block[0]= block0;
  186. } else {
  187. quant_matrix = s->inter_matrix;
  188. asm volatile(
  189. "pcmpeqw %%mm7, %%mm7 \n\t"
  190. "psrlw $15, %%mm7 \n\t"
  191. "movd %2, %%mm6 \n\t"
  192. "packssdw %%mm6, %%mm6 \n\t"
  193. "packssdw %%mm6, %%mm6 \n\t"
  194. "movl %3, %%eax \n\t"
  195. ".balign 16\n\t"
  196. "1: \n\t"
  197. "movq (%0, %%eax), %%mm0 \n\t"
  198. "movq 8(%0, %%eax), %%mm1 \n\t"
  199. "movq (%1, %%eax), %%mm4 \n\t"
  200. "movq 8(%1, %%eax), %%mm5 \n\t"
  201. "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i]
  202. "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i]
  203. "pxor %%mm2, %%mm2 \n\t"
  204. "pxor %%mm3, %%mm3 \n\t"
  205. "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0
  206. "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0
  207. "pxor %%mm2, %%mm0 \n\t"
  208. "pxor %%mm3, %%mm1 \n\t"
  209. "psubw %%mm2, %%mm0 \n\t" // abs(block[i])
  210. "psubw %%mm3, %%mm1 \n\t" // abs(block[i])
  211. "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2
  212. "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2
  213. "paddw %%mm7, %%mm0 \n\t" // abs(block[i])*2 + 1
  214. "paddw %%mm7, %%mm1 \n\t" // abs(block[i])*2 + 1
  215. "pmullw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q
  216. "pmullw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q
  217. "pxor %%mm4, %%mm4 \n\t"
  218. "pxor %%mm5, %%mm5 \n\t" // FIXME slow
  219. "pcmpeqw (%0, %%eax), %%mm4 \n\t" // block[i] == 0 ? -1 : 0
  220. "pcmpeqw 8(%0, %%eax), %%mm5 \n\t" // block[i] == 0 ? -1 : 0
  221. "psraw $4, %%mm0 \n\t"
  222. "psraw $4, %%mm1 \n\t"
  223. "psubw %%mm7, %%mm0 \n\t"
  224. "psubw %%mm7, %%mm1 \n\t"
  225. "por %%mm7, %%mm0 \n\t"
  226. "por %%mm7, %%mm1 \n\t"
  227. "pxor %%mm2, %%mm0 \n\t"
  228. "pxor %%mm3, %%mm1 \n\t"
  229. "psubw %%mm2, %%mm0 \n\t"
  230. "psubw %%mm3, %%mm1 \n\t"
  231. "pandn %%mm0, %%mm4 \n\t"
  232. "pandn %%mm1, %%mm5 \n\t"
  233. "movq %%mm4, (%0, %%eax) \n\t"
  234. "movq %%mm5, 8(%0, %%eax) \n\t"
  235. "addl $16, %%eax \n\t"
  236. "js 1b \n\t"
  237. ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)
  238. : "%eax", "memory"
  239. );
  240. }
  241. }
  242. static void dct_unquantize_mpeg2_mmx(MpegEncContext *s,
  243. DCTELEM *block, int n, int qscale)
  244. {
  245. int nCoeffs;
  246. const UINT16 *quant_matrix;
  247. assert(s->block_last_index[n]>=0);
  248. if(s->alternate_scan) nCoeffs= 63; //FIXME
  249. else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
  250. if (s->mb_intra) {
  251. int block0;
  252. if (n < 4)
  253. block0 = block[0] * s->y_dc_scale;
  254. else
  255. block0 = block[0] * s->c_dc_scale;
  256. quant_matrix = s->intra_matrix;
  257. asm volatile(
  258. "pcmpeqw %%mm7, %%mm7 \n\t"
  259. "psrlw $15, %%mm7 \n\t"
  260. "movd %2, %%mm6 \n\t"
  261. "packssdw %%mm6, %%mm6 \n\t"
  262. "packssdw %%mm6, %%mm6 \n\t"
  263. "movl %3, %%eax \n\t"
  264. ".balign 16\n\t"
  265. "1: \n\t"
  266. "movq (%0, %%eax), %%mm0 \n\t"
  267. "movq 8(%0, %%eax), %%mm1 \n\t"
  268. "movq (%1, %%eax), %%mm4 \n\t"
  269. "movq 8(%1, %%eax), %%mm5 \n\t"
  270. "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i]
  271. "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i]
  272. "pxor %%mm2, %%mm2 \n\t"
  273. "pxor %%mm3, %%mm3 \n\t"
  274. "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0
  275. "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0
  276. "pxor %%mm2, %%mm0 \n\t"
  277. "pxor %%mm3, %%mm1 \n\t"
  278. "psubw %%mm2, %%mm0 \n\t" // abs(block[i])
  279. "psubw %%mm3, %%mm1 \n\t" // abs(block[i])
  280. "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q
  281. "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q
  282. "pxor %%mm4, %%mm4 \n\t"
  283. "pxor %%mm5, %%mm5 \n\t" // FIXME slow
  284. "pcmpeqw (%0, %%eax), %%mm4 \n\t" // block[i] == 0 ? -1 : 0
  285. "pcmpeqw 8(%0, %%eax), %%mm5 \n\t" // block[i] == 0 ? -1 : 0
  286. "psraw $3, %%mm0 \n\t"
  287. "psraw $3, %%mm1 \n\t"
  288. "pxor %%mm2, %%mm0 \n\t"
  289. "pxor %%mm3, %%mm1 \n\t"
  290. "psubw %%mm2, %%mm0 \n\t"
  291. "psubw %%mm3, %%mm1 \n\t"
  292. "pandn %%mm0, %%mm4 \n\t"
  293. "pandn %%mm1, %%mm5 \n\t"
  294. "movq %%mm4, (%0, %%eax) \n\t"
  295. "movq %%mm5, 8(%0, %%eax) \n\t"
  296. "addl $16, %%eax \n\t"
  297. "jng 1b \n\t"
  298. ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)
  299. : "%eax", "memory"
  300. );
  301. block[0]= block0;
  302. //Note, we dont do mismatch control for intra as errors cannot accumulate
  303. } else {
  304. quant_matrix = s->inter_matrix;
  305. asm volatile(
  306. "pcmpeqw %%mm7, %%mm7 \n\t"
  307. "psrlq $48, %%mm7 \n\t"
  308. "movd %2, %%mm6 \n\t"
  309. "packssdw %%mm6, %%mm6 \n\t"
  310. "packssdw %%mm6, %%mm6 \n\t"
  311. "movl %3, %%eax \n\t"
  312. ".balign 16\n\t"
  313. "1: \n\t"
  314. "movq (%0, %%eax), %%mm0 \n\t"
  315. "movq 8(%0, %%eax), %%mm1 \n\t"
  316. "movq (%1, %%eax), %%mm4 \n\t"
  317. "movq 8(%1, %%eax), %%mm5 \n\t"
  318. "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i]
  319. "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i]
  320. "pxor %%mm2, %%mm2 \n\t"
  321. "pxor %%mm3, %%mm3 \n\t"
  322. "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0
  323. "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0
  324. "pxor %%mm2, %%mm0 \n\t"
  325. "pxor %%mm3, %%mm1 \n\t"
  326. "psubw %%mm2, %%mm0 \n\t" // abs(block[i])
  327. "psubw %%mm3, %%mm1 \n\t" // abs(block[i])
  328. "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2
  329. "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2
  330. "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*2*q
  331. "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*2*q
  332. "paddw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q
  333. "paddw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q
  334. "pxor %%mm4, %%mm4 \n\t"
  335. "pxor %%mm5, %%mm5 \n\t" // FIXME slow
  336. "pcmpeqw (%0, %%eax), %%mm4 \n\t" // block[i] == 0 ? -1 : 0
  337. "pcmpeqw 8(%0, %%eax), %%mm5 \n\t" // block[i] == 0 ? -1 : 0
  338. "psrlw $4, %%mm0 \n\t"
  339. "psrlw $4, %%mm1 \n\t"
  340. "pxor %%mm2, %%mm0 \n\t"
  341. "pxor %%mm3, %%mm1 \n\t"
  342. "psubw %%mm2, %%mm0 \n\t"
  343. "psubw %%mm3, %%mm1 \n\t"
  344. "pandn %%mm0, %%mm4 \n\t"
  345. "pandn %%mm1, %%mm5 \n\t"
  346. "pxor %%mm4, %%mm7 \n\t"
  347. "pxor %%mm5, %%mm7 \n\t"
  348. "movq %%mm4, (%0, %%eax) \n\t"
  349. "movq %%mm5, 8(%0, %%eax) \n\t"
  350. "addl $16, %%eax \n\t"
  351. "jng 1b \n\t"
  352. "movd 124(%0, %3), %%mm0 \n\t"
  353. "movq %%mm7, %%mm6 \n\t"
  354. "psrlq $32, %%mm7 \n\t"
  355. "pxor %%mm6, %%mm7 \n\t"
  356. "movq %%mm7, %%mm6 \n\t"
  357. "psrlq $16, %%mm7 \n\t"
  358. "pxor %%mm6, %%mm7 \n\t"
  359. "pslld $31, %%mm7 \n\t"
  360. "psrlq $15, %%mm7 \n\t"
  361. "pxor %%mm7, %%mm0 \n\t"
  362. "movd %%mm0, 124(%0, %3) \n\t"
  363. ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "r" (-2*nCoeffs)
  364. : "%eax", "memory"
  365. );
  366. }
  367. }
  368. /* draw the edges of width 'w' of an image of size width, height
  369. this mmx version can only handle w==8 || w==16 */
  370. static void draw_edges_mmx(UINT8 *buf, int wrap, int width, int height, int w)
  371. {
  372. UINT8 *ptr, *last_line;
  373. int i;
  374. last_line = buf + (height - 1) * wrap;
  375. /* left and right */
  376. ptr = buf;
  377. if(w==8)
  378. {
  379. asm volatile(
  380. "1: \n\t"
  381. "movd (%0), %%mm0 \n\t"
  382. "punpcklbw %%mm0, %%mm0 \n\t"
  383. "punpcklwd %%mm0, %%mm0 \n\t"
  384. "punpckldq %%mm0, %%mm0 \n\t"
  385. "movq %%mm0, -8(%0) \n\t"
  386. "movq -8(%0, %2), %%mm1 \n\t"
  387. "punpckhbw %%mm1, %%mm1 \n\t"
  388. "punpckhwd %%mm1, %%mm1 \n\t"
  389. "punpckhdq %%mm1, %%mm1 \n\t"
  390. "movq %%mm1, (%0, %2) \n\t"
  391. "addl %1, %0 \n\t"
  392. "cmpl %3, %0 \n\t"
  393. " jb 1b \n\t"
  394. : "+r" (ptr)
  395. : "r" (wrap), "r" (width), "r" (ptr + wrap*height)
  396. );
  397. }
  398. else
  399. {
  400. asm volatile(
  401. "1: \n\t"
  402. "movd (%0), %%mm0 \n\t"
  403. "punpcklbw %%mm0, %%mm0 \n\t"
  404. "punpcklwd %%mm0, %%mm0 \n\t"
  405. "punpckldq %%mm0, %%mm0 \n\t"
  406. "movq %%mm0, -8(%0) \n\t"
  407. "movq %%mm0, -16(%0) \n\t"
  408. "movq -8(%0, %2), %%mm1 \n\t"
  409. "punpckhbw %%mm1, %%mm1 \n\t"
  410. "punpckhwd %%mm1, %%mm1 \n\t"
  411. "punpckhdq %%mm1, %%mm1 \n\t"
  412. "movq %%mm1, (%0, %2) \n\t"
  413. "movq %%mm1, 8(%0, %2) \n\t"
  414. "addl %1, %0 \n\t"
  415. "cmpl %3, %0 \n\t"
  416. " jb 1b \n\t"
  417. : "+r" (ptr)
  418. : "r" (wrap), "r" (width), "r" (ptr + wrap*height)
  419. );
  420. }
  421. for(i=0;i<w;i+=4) {
  422. /* top and bottom (and hopefully also the corners) */
  423. ptr= buf - (i + 1) * wrap - w;
  424. asm volatile(
  425. "1: \n\t"
  426. "movq (%1, %0), %%mm0 \n\t"
  427. "movq %%mm0, (%0) \n\t"
  428. "movq %%mm0, (%0, %2) \n\t"
  429. "movq %%mm0, (%0, %2, 2) \n\t"
  430. "movq %%mm0, (%0, %3) \n\t"
  431. "addl $8, %0 \n\t"
  432. "cmpl %4, %0 \n\t"
  433. " jb 1b \n\t"
  434. : "+r" (ptr)
  435. : "r" ((int)buf - (int)ptr - w), "r" (-wrap), "r" (-wrap*3), "r" (ptr+width+2*w)
  436. );
  437. ptr= last_line + (i + 1) * wrap - w;
  438. asm volatile(
  439. "1: \n\t"
  440. "movq (%1, %0), %%mm0 \n\t"
  441. "movq %%mm0, (%0) \n\t"
  442. "movq %%mm0, (%0, %2) \n\t"
  443. "movq %%mm0, (%0, %2, 2) \n\t"
  444. "movq %%mm0, (%0, %3) \n\t"
  445. "addl $8, %0 \n\t"
  446. "cmpl %4, %0 \n\t"
  447. " jb 1b \n\t"
  448. : "+r" (ptr)
  449. : "r" ((int)last_line - (int)ptr - w), "r" (wrap), "r" (wrap*3), "r" (ptr+width+2*w)
  450. );
  451. }
  452. }
  453. #undef HAVE_MMX2
  454. #define RENAME(a) a ## _MMX
  455. #include "mpegvideo_mmx_template.c"
  456. #define HAVE_MMX2
  457. #undef RENAME
  458. #define RENAME(a) a ## _MMX2
  459. #include "mpegvideo_mmx_template.c"
  460. /* external functions, from idct_mmx.c */
  461. void ff_mmx_idct(DCTELEM *block);
  462. void ff_mmxext_idct(DCTELEM *block);
  463. /* XXX: those functions should be suppressed ASAP when all IDCTs are
  464. converted */
  465. static void ff_libmpeg2mmx_idct_put(UINT8 *dest, int line_size, DCTELEM *block)
  466. {
  467. ff_mmx_idct (block);
  468. put_pixels_clamped_mmx(block, dest, line_size);
  469. }
  470. static void ff_libmpeg2mmx_idct_add(UINT8 *dest, int line_size, DCTELEM *block)
  471. {
  472. ff_mmx_idct (block);
  473. add_pixels_clamped_mmx(block, dest, line_size);
  474. }
  475. static void ff_libmpeg2mmx2_idct_put(UINT8 *dest, int line_size, DCTELEM *block)
  476. {
  477. ff_mmxext_idct (block);
  478. put_pixels_clamped_mmx(block, dest, line_size);
  479. }
  480. static void ff_libmpeg2mmx2_idct_add(UINT8 *dest, int line_size, DCTELEM *block)
  481. {
  482. ff_mmxext_idct (block);
  483. add_pixels_clamped_mmx(block, dest, line_size);
  484. }
  485. void MPV_common_init_mmx(MpegEncContext *s)
  486. {
  487. if (mm_flags & MM_MMX) {
  488. const int dct_algo = s->avctx->dct_algo;
  489. const int idct_algo= s->avctx->idct_algo;
  490. s->dct_unquantize_h263 = dct_unquantize_h263_mmx;
  491. s->dct_unquantize_mpeg1 = dct_unquantize_mpeg1_mmx;
  492. s->dct_unquantize_mpeg2 = dct_unquantize_mpeg2_mmx;
  493. draw_edges = draw_edges_mmx;
  494. if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){
  495. s->fdct = ff_fdct_mmx;
  496. if(mm_flags & MM_MMXEXT){
  497. s->dct_quantize= dct_quantize_MMX2;
  498. } else {
  499. s->dct_quantize= dct_quantize_MMX;
  500. }
  501. }
  502. if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SIMPLEMMX){
  503. s->idct_put= ff_simple_idct_put_mmx;
  504. s->idct_add= ff_simple_idct_add_mmx;
  505. s->idct_permutation_type= FF_SIMPLE_IDCT_PERM;
  506. }else if(idct_algo==FF_IDCT_LIBMPEG2MMX){
  507. if(mm_flags & MM_MMXEXT){
  508. s->idct_put= ff_libmpeg2mmx2_idct_put;
  509. s->idct_add= ff_libmpeg2mmx2_idct_add;
  510. }else{
  511. s->idct_put= ff_libmpeg2mmx_idct_put;
  512. s->idct_add= ff_libmpeg2mmx_idct_add;
  513. }
  514. s->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;
  515. }
  516. }
  517. }