MemSubPic.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:14k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program 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
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include "MemSubPic.h"
  23. // color conv
  24. unsigned char Clip_base[256*3];
  25. unsigned char* Clip = Clip_base + 256;
  26. const int c2y_cyb = int(0.114*219/255*65536+0.5);
  27. const int c2y_cyg = int(0.587*219/255*65536+0.5);
  28. const int c2y_cyr = int(0.299*219/255*65536+0.5);
  29. const int c2y_cu = int(1.0/2.018*1024+0.5);
  30. const int c2y_cv = int(1.0/1.596*1024+0.5);
  31. int c2y_yb[256];
  32. int c2y_yg[256];
  33. int c2y_yr[256];
  34. const int y2c_cbu = int(2.018*65536+0.5);
  35. const int y2c_cgu = int(0.391*65536+0.5);
  36. const int y2c_cgv = int(0.813*65536+0.5);
  37. const int y2c_crv = int(1.596*65536+0.5);
  38. int y2c_bu[256];
  39. int y2c_gu[256];
  40. int y2c_gv[256];
  41. int y2c_rv[256];
  42. const int cy_cy = int(255.0/219.0*65536+0.5);
  43. const int cy_cy2 = int(255.0/219.0*32768+0.5);
  44. bool fColorConvInitOK = false;
  45. void ColorConvInit()
  46. {
  47. if(fColorConvInitOK) return;
  48. int i;
  49. for(i = 0; i < 256; i++) 
  50. {
  51. Clip_base[i] = 0;
  52. Clip_base[i+256] = i;
  53. Clip_base[i+512] = 255;
  54. }
  55. for(i = 0; i < 256; i++)
  56. {
  57. c2y_yb[i] = c2y_cyb*i;
  58. c2y_yg[i] = c2y_cyg*i;
  59. c2y_yr[i] = c2y_cyr*i;
  60. y2c_bu[i] = y2c_cbu*(i-128);
  61. y2c_gu[i] = y2c_cgu*(i-128);
  62. y2c_gv[i] = y2c_cgv*(i-128);
  63. y2c_rv[i] = y2c_crv*(i-128);
  64. }
  65. fColorConvInitOK = true;
  66. }
  67. #define rgb2yuv(r1,g1,b1,r2,g2,b2) 
  68. int y1 = (c2y_yb[b1] + c2y_yg[g1] + c2y_yr[r1] + 0x108000) >> 16; 
  69. int y2 = (c2y_yb[b2] + c2y_yg[g2] + c2y_yr[r2] + 0x108000) >> 16; 
  70. int scaled_y = (y1+y2-32) * cy_cy2; 
  71. unsigned char u = Clip[(((((b1+b2)<<15) - scaled_y) >> 10) * c2y_cu + 0x800000 + 0x8000) >> 16]; 
  72. unsigned char v = Clip[(((((r1+r2)<<15) - scaled_y) >> 10) * c2y_cv + 0x800000 + 0x8000) >> 16]; 
  73. //
  74. // CMemSubPic
  75. //
  76. CMemSubPic::CMemSubPic(SubPicDesc& spd)
  77. : m_spd(spd)
  78. {
  79. m_maxsize.SetSize(spd.w, spd.h);
  80. m_rcDirty.SetRect(0, 0, spd.w, spd.h);
  81. }
  82. CMemSubPic::~CMemSubPic()
  83. {
  84. delete [] m_spd.bits, m_spd.bits = NULL;
  85. }
  86. // ISubPic
  87. STDMETHODIMP_(void*) CMemSubPic::GetObject()
  88. {
  89. return (void*)&m_spd;
  90. }
  91. STDMETHODIMP CMemSubPic::GetDesc(SubPicDesc& spd)
  92. {
  93. spd.type = m_spd.type;
  94. spd.w = m_size.cx;
  95. spd.h = m_size.cy;
  96. spd.bpp = m_spd.bpp;
  97. spd.pitch = m_spd.pitch;
  98. spd.bits = m_spd.bits;
  99. spd.bitsU = m_spd.bitsU;
  100. spd.bitsV = m_spd.bitsV;
  101. spd.vidrect = m_vidrect;
  102. return S_OK;
  103. }
  104. STDMETHODIMP CMemSubPic::CopyTo(ISubPic* pSubPic)
  105. {
  106. HRESULT hr;
  107. if(FAILED(hr = __super::CopyTo(pSubPic)))
  108. return hr;
  109. SubPicDesc src, dst;
  110. if(FAILED(GetDesc(src)) || FAILED(pSubPic->GetDesc(dst)))
  111. return E_FAIL;
  112. int w = m_rcDirty.Width(), h = m_rcDirty.Height();
  113. BYTE* s = (BYTE*)src.bits + src.pitch*m_rcDirty.top + m_rcDirty.left*4;
  114. BYTE* d = (BYTE*)dst.bits + dst.pitch*m_rcDirty.top + m_rcDirty.left*4;
  115. for(int j = 0; j < h; j++, s += src.pitch, d += dst.pitch)
  116. memcpy(d, s, w*4);
  117. return S_OK;
  118. }
  119. STDMETHODIMP CMemSubPic::ClearDirtyRect(DWORD color)
  120. {
  121. if(m_rcDirty.IsRectEmpty())
  122. return S_FALSE;
  123. BYTE* p = (BYTE*)m_spd.bits + m_spd.pitch*m_rcDirty.top + m_rcDirty.left*(m_spd.bpp>>3);
  124. for(int j = 0, h = m_rcDirty.Height(); j < h; j++, p += m_spd.pitch)
  125. {
  126. //        memsetd(p, 0, m_rcDirty.Width());
  127. int w = m_rcDirty.Width();
  128. __asm
  129. {
  130. mov eax, color
  131. mov ecx, w
  132. mov edi, p
  133. cld
  134. rep stosd
  135. }
  136. }
  137. m_rcDirty.SetRectEmpty();
  138. return S_OK;
  139. }
  140. STDMETHODIMP CMemSubPic::Lock(SubPicDesc& spd)
  141. {
  142. return GetDesc(spd);
  143. }
  144. STDMETHODIMP CMemSubPic::Unlock(RECT* pDirtyRect)
  145. {
  146. m_rcDirty = pDirtyRect ? *pDirtyRect : CRect(0,0,m_spd.w,m_spd.h);
  147. if(m_rcDirty.IsRectEmpty())
  148. return S_OK;
  149.     if(m_spd.type == MSP_YUY2 || m_spd.type == MSP_YV12 || m_spd.type == MSP_IYUV || m_spd.type == MSP_AYUV)
  150. {
  151. ColorConvInit();
  152. if(m_spd.type == MSP_YUY2 || m_spd.type == MSP_YV12 || m_spd.type == MSP_IYUV)
  153. {
  154. m_rcDirty.left &= ~1;
  155. m_rcDirty.right = (m_rcDirty.right+1)&~1;
  156. if(m_spd.type == MSP_YV12 || m_spd.type == MSP_IYUV)
  157. {
  158. m_rcDirty.top &= ~1;
  159. m_rcDirty.bottom = (m_rcDirty.bottom+1)&~1;
  160. }
  161. }
  162. }
  163. int w = m_rcDirty.Width(), h = m_rcDirty.Height();
  164. BYTE* top = (BYTE*)m_spd.bits + m_spd.pitch*m_rcDirty.top + m_rcDirty.left*4;
  165. BYTE* bottom = top + m_spd.pitch*h;
  166. if(m_spd.type == MSP_RGB16)
  167. {
  168. for(; top < bottom ; top += m_spd.pitch)
  169. {
  170. DWORD* s = (DWORD*)top;
  171. DWORD* e = s + w;
  172. for(; s < e; s++)
  173. {
  174. *s = ((*s>>3)&0x1f000000)|((*s>>8)&0xf800)|((*s>>5)&0x07e0)|((*s>>3)&0x001f);
  175. // *s = (*s&0xff000000)|((*s>>8)&0xf800)|((*s>>5)&0x07e0)|((*s>>3)&0x001f);
  176. }
  177. }
  178. }
  179. else if(m_spd.type == MSP_RGB15)
  180. {
  181. for(; top < bottom; top += m_spd.pitch)
  182. {
  183. DWORD* s = (DWORD*)top;
  184. DWORD* e = s + w;
  185. for(; s < e; s++)
  186. {
  187. *s = ((*s>>3)&0x1f000000)|((*s>>9)&0x7c00)|((*s>>6)&0x03e0)|((*s>>3)&0x001f);
  188. // *s = (*s&0xff000000)|((*s>>9)&0x7c00)|((*s>>6)&0x03e0)|((*s>>3)&0x001f);
  189. }
  190. }
  191. }
  192. else if(m_spd.type == MSP_YUY2 || m_spd.type == MSP_YV12 || m_spd.type == MSP_IYUV)
  193. {
  194. for(; top < bottom ; top += m_spd.pitch)
  195. {
  196. BYTE* s = top;
  197. BYTE* e = s + w*4;
  198. for(; s < e; s+=8) // ARGB ARGB -> AxYU AxYV
  199. {
  200. if((s[3]+s[7]) < 0x1fe)
  201. {
  202. s[1] = (c2y_yb[s[0]] + c2y_yg[s[1]] + c2y_yr[s[2]] + 0x108000) >> 16;
  203. s[5] = (c2y_yb[s[4]] + c2y_yg[s[5]] + c2y_yr[s[6]] + 0x108000) >> 16;
  204. int scaled_y = (s[1]+s[5]-32) * cy_cy2;
  205. s[0] = Clip[(((((s[0]+s[4])<<15) - scaled_y) >> 10) * c2y_cu + 0x800000 + 0x8000) >> 16];
  206. s[4] = Clip[(((((s[2]+s[6])<<15) - scaled_y) >> 10) * c2y_cv + 0x800000 + 0x8000) >> 16];
  207. }
  208. else
  209. {
  210. s[1] = s[5] = 0x10;
  211. s[0] = s[4] = 0x80;
  212. }
  213. }
  214. }
  215. }
  216. else if(m_spd.type == MSP_AYUV)
  217. {
  218. for(; top < bottom ; top += m_spd.pitch)
  219. {
  220. BYTE* s = top;
  221. BYTE* e = s + w*4;
  222. for(; s < e; s+=4) // ARGB -> AYUV
  223. {
  224. if(s[3] < 0xff)
  225. {
  226. int y = (c2y_yb[s[0]] + c2y_yg[s[1]] + c2y_yr[s[2]] + 0x108000) >> 16;
  227. int scaled_y = (y-32) * cy_cy;
  228. s[1] = Clip[((((s[0]<<16) - scaled_y) >> 10) * c2y_cu + 0x800000 + 0x8000) >> 16];
  229. s[0] = Clip[((((s[2]<<16) - scaled_y) >> 10) * c2y_cv + 0x800000 + 0x8000) >> 16];
  230. s[2] = y;
  231. }
  232. else
  233. {
  234. s[0] = s[1] = 0x80;
  235. s[2] = 0x10;
  236. }
  237. }
  238. }
  239. }
  240. return S_OK;
  241. }
  242. STDMETHODIMP CMemSubPic::AlphaBlt(RECT* pSrc, RECT* pDst, SubPicDesc* pTarget)
  243. {
  244. ASSERT(pTarget);
  245. if(!pSrc || !pDst || !pTarget)
  246. return E_POINTER;
  247. const SubPicDesc& src = m_spd;
  248. SubPicDesc dst = *pTarget; // copy, because we might modify it
  249. if(src.type != dst.type)
  250. return E_INVALIDARG;
  251. CRect rs(*pSrc), rd(*pDst);
  252. if(dst.h < 0)
  253. {
  254. dst.h = -dst.h;
  255. rd.bottom = dst.h - rd.bottom;
  256. rd.top = dst.h - rd.top;
  257. }
  258. if(rs.Width() != rd.Width() || rs.Height() != abs(rd.Height()))
  259. return E_INVALIDARG;
  260. int w = rs.Width(), h = rs.Height();
  261. BYTE* s = (BYTE*)src.bits + src.pitch*rs.top + rs.left*4;
  262. BYTE* d = (BYTE*)dst.bits + dst.pitch*rd.top + ((rd.left*dst.bpp)>>3);
  263. if(rd.top > rd.bottom)
  264. {
  265. if(dst.type == MSP_RGB32 || dst.type == MSP_RGB24
  266. || dst.type == MSP_RGB16 || dst.type == MSP_RGB15
  267. || dst.type == MSP_YUY2 || dst.type == MSP_AYUV)
  268. {
  269. d = (BYTE*)dst.bits + dst.pitch*(rd.top-1) + (rd.left*dst.bpp>>3);
  270. }
  271. else if(dst.type == MSP_YV12 || dst.type == MSP_IYUV)
  272. {
  273. d = (BYTE*)dst.bits + dst.pitch*(rd.top-1) + (rd.left*8>>3);
  274. }
  275. else 
  276. {
  277. return E_NOTIMPL;
  278. }
  279. dst.pitch = -dst.pitch;
  280. }
  281. for(int j = 0; j < h; j++, s += src.pitch, d += dst.pitch)
  282. {
  283. if(dst.type == MSP_RGB32 || dst.type == MSP_AYUV)
  284. {
  285. BYTE* s2 = s;
  286. BYTE* s2end = s2 + w*4;
  287. DWORD* d2 = (DWORD*)d;
  288. for(; s2 < s2end; s2 += 4, d2++)
  289. {
  290. if(s2[3] < 0xff)
  291. {
  292. *d2 = (((((*d2&0x00ff00ff)*s2[3])>>8) + (*((DWORD*)s2)&0x00ff00ff))&0x00ff00ff)
  293. | (((((*d2&0x0000ff00)*s2[3])>>8) + (*((DWORD*)s2)&0x0000ff00))&0x0000ff00);
  294. }
  295. }
  296. }
  297. else if(dst.type == MSP_RGB24)
  298. {
  299. BYTE* s2 = s;
  300. BYTE* s2end = s2 + w*4;
  301. BYTE* d2 = d;
  302. for(; s2 < s2end; s2 += 4, d2 += 3)
  303. {
  304. if(s2[3] < 0xff)
  305. {
  306. d2[0] = ((d2[0]*s2[3])>>8) + s2[0];
  307. d2[1] = ((d2[1]*s2[3])>>8) + s2[1];
  308. d2[2] = ((d2[2]*s2[3])>>8) + s2[2];
  309. }
  310. }
  311. }
  312. else if(dst.type == MSP_RGB16)
  313. {
  314. BYTE* s2 = s;
  315. BYTE* s2end = s2 + w*4;
  316. WORD* d2 = (WORD*)d;
  317. for(; s2 < s2end; s2 += 4, d2++)
  318. {
  319. if(s2[3] < 0x1f)
  320. {
  321. *d2 = (WORD)((((((*d2&0xf81f)*s2[3])>>5) + (*(DWORD*)s2&0xf81f))&0xf81f)
  322. | (((((*d2&0x07e0)*s2[3])>>5) + (*(DWORD*)s2&0x07e0))&0x07e0));
  323. /* *d2 = (WORD)((((((*d2&0xf800)*s2[3])>>8) + (*(DWORD*)s2&0xf800))&0xf800)
  324. | (((((*d2&0x07e0)*s2[3])>>8) + (*(DWORD*)s2&0x07e0))&0x07e0)
  325. | (((((*d2&0x001f)*s2[3])>>8) + (*(DWORD*)s2&0x001f))&0x001f));
  326. */
  327. }
  328. }
  329. }
  330. else if(dst.type == MSP_RGB15)
  331. {
  332. BYTE* s2 = s;
  333. BYTE* s2end = s2 + w*4;
  334. WORD* d2 = (WORD*)d;
  335. for(; s2 < s2end; s2 += 4, d2++)
  336. {
  337. if(s2[3] < 0x1f)
  338. {
  339. *d2 = (WORD)((((((*d2&0x7c1f)*s2[3])>>5) + (*(DWORD*)s2&0x7c1f))&0x7c1f)
  340. | (((((*d2&0x03e0)*s2[3])>>5) + (*(DWORD*)s2&0x03e0))&0x03e0));
  341. /* *d2 = (WORD)((((((*d2&0x7c00)*s2[3])>>8) + (*(DWORD*)s2&0x7c00))&0x7c00)
  342. | (((((*d2&0x03e0)*s2[3])>>8) + (*(DWORD*)s2&0x03e0))&0x03e0)
  343. | (((((*d2&0x001f)*s2[3])>>8) + (*(DWORD*)s2&0x001f))&0x001f));
  344. */ }
  345. }
  346. }
  347. else if(dst.type == MSP_YUY2)
  348. {
  349. // BYTE y1, y2, u, v;
  350. unsigned int ia, c;
  351. BYTE* s2 = s;
  352. BYTE* s2end = s2 + w*4;
  353. DWORD* d2 = (DWORD*)d;
  354. for(; s2 < s2end; s2 += 8, d2++)
  355. {
  356. ia = (s2[3]+s2[7])>>1;
  357. if(ia < 0xff)
  358. {
  359. /* y1 = (BYTE)(((((*d2&0xff)-0x10)*s2[3])>>8) + s2[1]); // + y1;
  360. y2 = (BYTE)((((((*d2>>16)&0xff)-0x10)*s2[7])>>8) + s2[5]); // + y2;
  361. u = (BYTE)((((((*d2>>8)&0xff)-0x80)*ia)>>8) + s2[0]); // + u;
  362. v = (BYTE)((((((*d2>>24)&0xff)-0x80)*ia)>>8) + s2[4]); // + v;
  363. *d2 = (v<<24)|(y2<<16)|(u<<8)|y1;
  364. */
  365. static const __int64 _8181 = 0x0080001000800010i64;
  366. ia = (ia<<24)|(s2[7]<<16)|(ia<<8)|s2[3];
  367. c = (s2[4]<<24)|(s2[5]<<16)|(s2[0]<<8)|s2[1]; // (v<<24)|(y2<<16)|(u<<8)|y1;
  368. __asm
  369. {
  370. mov esi, s2
  371. mov edi, d2
  372. pxor mm0, mm0
  373. movq mm1, _8181
  374. movd mm2, c
  375. punpcklbw mm2, mm0
  376. movd mm3, [edi]
  377. punpcklbw mm3, mm0
  378. movd mm4, ia
  379. punpcklbw mm4, mm0
  380. psrlw mm4, 1
  381. psubsw mm3, mm1
  382. pmullw mm3, mm4
  383. psraw mm3, 7
  384. paddsw mm3, mm2
  385. packuswb mm3, mm3
  386. movd [edi], mm3
  387. };
  388. }
  389. }
  390. }
  391. else if(dst.type == MSP_YV12 || dst.type == MSP_IYUV)
  392. {
  393. BYTE* s2 = s;
  394. BYTE* s2end = s2 + w*4;
  395. BYTE* d2 = d;
  396. for(; s2 < s2end; s2 += 4, d2++)
  397. {
  398. if(s2[3] < 0xff)
  399. {
  400. d2[0] = (((d2[0]-0x10)*s2[3])>>8) + s2[1];
  401. }
  402. }
  403. }
  404. else
  405. {
  406. return E_NOTIMPL;
  407. }
  408. }
  409. dst.pitch = abs(dst.pitch);
  410. if(dst.type == MSP_YV12 || dst.type == MSP_IYUV)
  411. {
  412. int w2 = w/2, h2 = h/2;
  413. if(!dst.pitchUV)
  414. {
  415. dst.pitchUV = dst.pitch/2;
  416. }
  417. int sizep4 = dst.pitchUV*dst.h/2;
  418. BYTE* ss[2];
  419. ss[0] = (BYTE*)src.bits + src.pitch*rs.top + rs.left*4;
  420. ss[1] = ss[0] + 4;
  421. if(!dst.bitsU || !dst.bitsV)
  422. {
  423. dst.bitsU = (BYTE*)dst.bits + dst.pitch*dst.h;
  424. dst.bitsV = dst.bitsU + dst.pitchUV*dst.h/2;
  425. if(dst.type == MSP_YV12)
  426. {
  427. BYTE* p = dst.bitsU; 
  428. dst.bitsU = dst.bitsV; 
  429. dst.bitsV = p;
  430. }
  431. }
  432. BYTE* dd[2];
  433. dd[0] = dst.bitsU + dst.pitchUV*rd.top/2 + rd.left/2;
  434. dd[1] = dst.bitsV + dst.pitchUV*rd.top/2 + rd.left/2;
  435. if(rd.top > rd.bottom)
  436. {
  437. dd[0] = dst.bitsU + dst.pitchUV*(rd.top/2-1) + rd.left/2;
  438. dd[1] = dst.bitsV + dst.pitchUV*(rd.top/2-1) + rd.left/2;
  439. dst.pitchUV = -dst.pitchUV;
  440. }
  441. for(int i = 0; i < 2; i++)
  442. {
  443. s = ss[i]; d = dd[i];
  444. BYTE* is = ss[1-i];
  445. for(int j = 0; j < h2; j++, s += src.pitch*2, d += dst.pitchUV, is += src.pitch*2)
  446. {
  447. BYTE* s2 = s;
  448. BYTE* s2end = s2 + w*4;
  449. BYTE* d2 = d;
  450. BYTE* is2 = is;
  451. for(; s2 < s2end; s2 += 8, d2++, is2 += 8)
  452. {
  453. unsigned int ia = (s2[3]+s2[3+src.pitch]+is2[3]+is2[3+src.pitch])>>2;
  454. if(ia < 0xff)
  455. {
  456. *d2 = (((*d2-0x80)*ia)>>8) + ((s2[0]+s2[src.pitch])>>1);
  457. }
  458. }
  459. }
  460. }
  461. }
  462. __asm emms;
  463.     return S_OK;
  464. }
  465. //
  466. // CMemSubPicAllocator
  467. //
  468. CMemSubPicAllocator::CMemSubPicAllocator(int type, SIZE maxsize) 
  469. : ISubPicAllocatorImpl(maxsize, false, false)
  470. , m_type(type)
  471. , m_maxsize(maxsize)
  472. {
  473. }
  474. // ISubPicAllocatorImpl
  475. bool CMemSubPicAllocator::Alloc(bool fStatic, ISubPic** ppSubPic)
  476. {
  477. if(!ppSubPic) 
  478. return(false);
  479. SubPicDesc spd;
  480. spd.w = m_maxsize.cx;
  481. spd.h = m_maxsize.cy;
  482. spd.bpp = 32;
  483. spd.pitch = (spd.w*spd.bpp)>>3;
  484. spd.type = m_type;
  485. if(!(spd.bits = new BYTE[spd.pitch*spd.h]))
  486. return(false);
  487. if(!(*ppSubPic = new CMemSubPic(spd)))
  488. return(false);
  489. (*ppSubPic)->AddRef();
  490. return(true);
  491. }