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

多媒体编程

开发平台:

Visual C++

  1. // Copyright 2003-2005 Gabest
  2. // http://www.gabest.org
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
  17. // http://www.gnu.org/copyleft/gpl.html
  18. #include "stdafx.h"
  19. #include <math.h>
  20. #include "DirectVobSubFilter.h"
  21. #include "......DSUtilDSUtil.h"
  22. #include "......DSUtilMediaTypes.h"
  23. #include <initguid.h>
  24. #include "........includemoreuuids.h"
  25. extern int c2y_yb[256];
  26. extern int c2y_yg[256];
  27. extern int c2y_yr[256];
  28. extern void ColorConvInit();
  29. void BltLineRGB32(DWORD* d, BYTE* sub, int w, const GUID& subtype)
  30. {
  31. if(subtype == MEDIASUBTYPE_YV12 || subtype == MEDIASUBTYPE_I420 || subtype == MEDIASUBTYPE_IYUV)
  32. {
  33. BYTE* db = (BYTE*)d;
  34. BYTE* dbtend = db + w;
  35. for(; db < dbtend; sub+=4, db++)
  36. {
  37. if(sub[3] < 0xff)
  38. {
  39. int y = (c2y_yb[sub[0]] + c2y_yg[sub[1]] + c2y_yr[sub[2]] + 0x108000) >> 16; 
  40. *db = y; // w/o colors 
  41. }
  42. }
  43. }
  44. else if(subtype == MEDIASUBTYPE_YUY2)
  45. {
  46. WORD* ds = (WORD*)d;
  47. WORD* dstend = ds + w;
  48. for(; ds < dstend; sub+=4, ds++)
  49. {
  50. if(sub[3] < 0xff)
  51. {
  52. int y = (c2y_yb[sub[0]] + c2y_yg[sub[1]] + c2y_yr[sub[2]] + 0x108000) >> 16; 
  53. *ds = 0x8000|y; // w/o colors 
  54. }
  55. }
  56. }
  57. else if(subtype == MEDIASUBTYPE_RGB555)
  58. {
  59. WORD* ds = (WORD*)d;
  60. WORD* dstend = ds + w;
  61. for(; ds < dstend; sub+=4, ds++)
  62. {
  63. if(sub[3] < 0xff)
  64. {
  65. *ds = ((*((DWORD*)sub)>>9)&0x7c00)|((*((DWORD*)sub)>>6)&0x03e0)|((*((DWORD*)sub)>>3)&0x001f);
  66. }
  67. }
  68. }
  69. else if(subtype == MEDIASUBTYPE_RGB565)
  70. {
  71. WORD* ds = (WORD*)d;
  72. WORD* dstend = ds + w;
  73. for(; ds < dstend; sub+=4, ds++)
  74. {
  75. if(sub[3] < 0xff)
  76. {
  77. *ds = ((*((DWORD*)sub)>>8)&0xf800)|((*((DWORD*)sub)>>5)&0x07e0)|((*((DWORD*)sub)>>3)&0x001f);
  78. }
  79. }
  80. }
  81. else if(subtype == MEDIASUBTYPE_RGB24)
  82. {
  83. BYTE* dt = (BYTE*)d;
  84. BYTE* dstend = dt + w*3;
  85. for(; dt < dstend; sub+=4, dt+=3)
  86. {
  87. if(sub[3] < 0xff)
  88. {
  89. dt[0] = sub[0];
  90. dt[1] = sub[1];
  91. dt[2] = sub[2];
  92. }
  93. }
  94. }
  95. else if(subtype == MEDIASUBTYPE_RGB32 || subtype == MEDIASUBTYPE_ARGB32)
  96. {
  97. DWORD* dstend = d + w;
  98. for(; d < dstend; sub+=4, d++)
  99. {
  100. if(sub[3] < 0xff) *d = *((DWORD*)sub)&0xffffff;
  101. }
  102. }
  103. }
  104. /* ResX2 */
  105. void Scale2x(const GUID& subtype, BYTE* d, int dpitch, BYTE* s, int spitch, int w, int h)
  106. {
  107. if(subtype == MEDIASUBTYPE_YV12 || subtype == MEDIASUBTYPE_I420 || subtype == MEDIASUBTYPE_IYUV)
  108. {
  109. BYTE* s1;
  110. BYTE* s2;
  111. BYTE* d1;
  112. for(s1 = s, s2 = s + h*spitch, d1 = d; s1 < s2; d1 += dpitch) // TODO: replace this mess with mmx code
  113. {
  114. BYTE* stmp = s1 + spitch;
  115. BYTE* dtmp = d1 + dpitch;
  116. for(BYTE* s3 = s1 + (w-1); s1 < s3; s1 += 1, d1 += 2)
  117. {
  118. d1[0] = s1[0]; 
  119. d1[1] = (s1[0]+s1[1])>>1;
  120. }
  121. d1[0] = d1[1] = s1[0]; 
  122. s1 += 1;
  123. d1 += 2;
  124. s1 = stmp;
  125. d1 = dtmp;
  126. }
  127. AvgLines8(d, h*2, dpitch);
  128. }
  129. else if(subtype == MEDIASUBTYPE_YUY2)
  130. {
  131. unsigned __int64 __0xffffffff00000000 = 0xffffffff00000000;
  132. unsigned __int64 __0x00000000ffffffff = 0x00000000ffffffff;
  133. unsigned __int64 __0x00ff00ff00ff00ff = 0x00ff00ff00ff00ff;
  134. BYTE* s1;
  135. BYTE* s2;
  136. BYTE* d1;
  137. for(s1 = s, s2 = s + h*spitch, d1 = d; s1 < s2; d1 += dpitch)
  138. {
  139. BYTE* stmp = s1 + spitch;
  140. BYTE* dtmp = d1 + dpitch;
  141. // row0, 4 pixels: y1|u1|y2|v1|y3|u2|y4|v2
  142. // ->
  143. // row0, 8 pixels: y1|u1|(y1+y2)/2|v1|y2|(u1+u2)/2|(y2+y3)/2|(v1+v2)/2
  144. __asm
  145. {
  146. mov esi, s1
  147. mov edi, d1
  148. mov ecx, w
  149. shr ecx, 1
  150. dec ecx
  151. movq mm4, __0x00ff00ff00ff00ff
  152. movq mm5, __0x00000000ffffffff
  153. movq mm6, __0xffffffff00000000
  154. row_loop1:
  155. movq mm0, [esi]
  156. movq mm2, mm0
  157. pand mm0, mm4 // mm0 = 00y400y300y200y1
  158. psrlw mm2, 8 // mm2 = 00u200v200u100v1
  159. movq mm1, mm0
  160. pand mm0, mm5 // mm0 = 0000000000y200y1
  161. psllq mm1, 16
  162. pand mm1, mm6 // mm1 = 00y300y200000000
  163. por mm1, mm0 // mm1 = 00y300y200y200y1
  164. punpcklwd mm0, mm0 // mm0 = 00y200y200y100y1
  165. paddw mm0, mm1
  166. psrlw mm0, 1 // mm0 = (mm0 + mm1) / 2
  167. movq mm1, mm2
  168. punpckldq mm1, mm1 // mm1 = 00u100v100u100v1
  169. paddw mm1, mm2
  170. psrlw mm1, 1 // mm1 = (mm1 + mm2) / 2
  171. psllw mm1, 8
  172. por mm0, mm1 // mm0 = (v1+v2)/2|(y2+y3)/2|(u1+u2)/2|y2|v1|(y1+y2)/2|u1|y1
  173. movq [edi], mm0
  174. lea esi, [esi+4]
  175. lea edi, [edi+8]
  176. dec ecx
  177. jnz row_loop1
  178. mov s1, esi
  179. mov d1, edi
  180. };
  181. *d1++ = s1[0];
  182. *d1++ = s1[1];
  183. *d1++ =(s1[0]+s1[2])>>1;
  184. *d1++ = s1[3];
  185. *d1++ = s1[2];
  186. *d1++ = s1[1];
  187. *d1++ = s1[2];
  188. *d1++ = s1[3];
  189. s1 += 4;
  190. s1 = stmp;
  191. d1 = dtmp;
  192. }
  193. AvgLines8(d, h*2, dpitch);
  194. }
  195. else if(subtype == MEDIASUBTYPE_RGB555)
  196. {
  197. BYTE* s1;
  198. BYTE* s2;
  199. BYTE* d1;
  200. for(s1 = s, s2 = s + h*spitch, d1 = d; s1 < s2; d1 += dpitch) // TODO: replace this mess with mmx code
  201. {
  202. BYTE* stmp = s1 + spitch;
  203. BYTE* dtmp = d1 + dpitch;
  204. for(BYTE* s3 = s1 + (w-1)*2; s1 < s3; s1 += 2, d1 += 4)
  205. {
  206. *((WORD*)d1) = *((WORD*)s1);
  207. *((WORD*)d1+1) = 
  208. ((((*((WORD*)s1)&0x7c00) + (*((WORD*)s1+1)&0x7c00)) >> 1)&0x7c00)|
  209. ((((*((WORD*)s1)&0x03e0) + (*((WORD*)s1+1)&0x03e0)) >> 1)&0x03e0)|
  210. ((((*((WORD*)s1)&0x001f) + (*((WORD*)s1+1)&0x001f)) >> 1)&0x001f);
  211. }
  212. *((WORD*)d1) = *((WORD*)s1);
  213. *((WORD*)d1+1) = *((WORD*)s1);
  214. s1 += 2;
  215. d1 += 4;
  216. s1 = stmp;
  217. d1 = dtmp;
  218. }
  219. AvgLines555(d, h*2, dpitch);
  220. }
  221. else if(subtype == MEDIASUBTYPE_RGB565)
  222. {
  223. BYTE* s1;
  224. BYTE* s2;
  225. BYTE* d1;
  226. for(s1 = s, s2 = s + h*spitch, d1 = d; s1 < s2; d1 += dpitch) // TODO: replace this mess with mmx code
  227. {
  228. BYTE* stmp = s1 + spitch;
  229. BYTE* dtmp = d1 + dpitch;
  230. for(BYTE* s3 = s1 + (w-1)*2; s1 < s3; s1 += 2, d1 += 4)
  231. {
  232. *((WORD*)d1) = *((WORD*)s1);
  233. *((WORD*)d1+1) = 
  234. ((((*((WORD*)s1)&0xf800) + (*((WORD*)s1+1)&0xf800)) >> 1)&0xf800)|
  235. ((((*((WORD*)s1)&0x07e0) + (*((WORD*)s1+1)&0x07e0)) >> 1)&0x07e0)|
  236. ((((*((WORD*)s1)&0x001f) + (*((WORD*)s1+1)&0x001f)) >> 1)&0x001f);
  237. }
  238. *((WORD*)d1) = *((WORD*)s1);
  239. *((WORD*)d1+1) = *((WORD*)s1);
  240. s1 += 2;
  241. d1 += 4;
  242. s1 = stmp;
  243. d1 = dtmp;
  244. }
  245. AvgLines565(d, h*2, dpitch);
  246. }
  247. else if(subtype == MEDIASUBTYPE_RGB24)
  248. {
  249. BYTE* s1;
  250. BYTE* s2;
  251. BYTE* d1;
  252. for(s1 = s, s2 = s + h*spitch, d1 = d; s1 < s2; d1 += dpitch) // TODO: replace this mess with mmx code
  253. {
  254. BYTE* stmp = s1 + spitch;
  255. BYTE* dtmp = d1 + dpitch;
  256. for(BYTE* s3 = s1 + (w-1)*3; s1 < s3; s1 += 3, d1 += 6)
  257. {
  258. d1[0] = s1[0]; 
  259. d1[1] = s1[1]; 
  260. d1[2] = s1[2];
  261. d1[3] = (s1[0]+s1[3])>>1;
  262. d1[4] = (s1[1]+s1[4])>>1;
  263. d1[5] = (s1[2]+s1[5])>>1;
  264. }
  265. d1[0] = d1[3] = s1[0]; 
  266. d1[1] = d1[4] = s1[1]; 
  267. d1[2] = d1[5] = s1[2];
  268. s1 += 3;
  269. d1 += 6;
  270. s1 = stmp;
  271. d1 = dtmp;
  272. }
  273. AvgLines8(d, h*2, dpitch);
  274. }
  275. else if(subtype == MEDIASUBTYPE_RGB32 || subtype == MEDIASUBTYPE_ARGB32)
  276. {
  277. BYTE* s1;
  278. BYTE* s2;
  279. BYTE* d1;
  280. for(s1 = s, s2 = s + h*spitch, d1 = d; s1 < s2; d1 += dpitch)
  281. {
  282. BYTE* stmp = s1 + spitch;
  283. BYTE* dtmp = d1 + dpitch;
  284. __asm
  285. {
  286. mov esi, s1
  287. mov edi, d1
  288. mov ecx, w
  289. dec ecx
  290. pxor mm0, mm0
  291. row_loop3:
  292. movq mm1, [esi]
  293. movq mm2, mm1
  294. punpcklbw mm1, mm0 // mm1 = 00xx00r100g100b1
  295. punpckhbw mm2, mm0 // mm2 = 00xx00r200g200b2
  296. paddw mm2, mm1
  297. psrlw mm2, 1 // mm2 = (mm1 + mm2) / 2
  298. packuswb mm1, mm2
  299. movq [edi], mm1
  300. lea esi, [esi+4]
  301. lea edi, [edi+8]
  302. dec ecx
  303. jnz row_loop3
  304. mov s1, esi
  305. mov d1, edi
  306. };
  307. *((DWORD*)d1) = *((DWORD*)s1);
  308. *((DWORD*)d1+1) = *((DWORD*)s1);
  309. s1 += 4;
  310. d1 += 8;
  311. s1 = stmp;
  312. d1 = dtmp;
  313. }
  314. AvgLines8(d, h*2, dpitch);
  315. }
  316. __asm emms;
  317. }
  318. HRESULT CDirectVobSubFilter::Copy(BYTE* pSub, BYTE* pIn, CSize sub, CSize in, int bpp, const GUID& subtype, DWORD black)
  319. {
  320. int wIn = in.cx, hIn = in.cy, pitchIn = ((wIn*bpp>>3)+3)&~3;
  321. int wSub = sub.cx, hSub = sub.cy, pitchSub = ((wSub*bpp>>3)+3)&~3;
  322. bool fScale2x = wIn*2 <= wSub;
  323. if(fScale2x) wIn <<= 1, hIn <<= 1;
  324. int left = ((wSub - wIn)>>1)&~1;
  325. int mid = wIn;
  326. int right = left + ((wSub - wIn)&1);
  327. int dpLeft = left*bpp>>3;
  328. int dpMid = mid*bpp>>3;
  329. int dpRight = right*bpp>>3;
  330. ASSERT(wSub >= wIn);
  331. {
  332. int i = 0, j = 0;
  333. j += (hSub - hIn) >> 1;
  334. for(; i < j; i++, pSub += pitchSub)
  335. {
  336. memsetd(pSub, black, dpLeft+dpMid+dpRight);
  337. }
  338. j += hIn;
  339. if(hIn > hSub)
  340. pIn += pitchIn * ((hIn - hSub) >> (fScale2x?2:1));
  341. if(fScale2x)
  342. {
  343. Scale2x(subtype, 
  344. pSub + dpLeft, pitchSub, pIn, pitchIn, 
  345. in.cx, (min(j, hSub) - i) >> 1);
  346.             
  347. for(int k = min(j, hSub); i < k; i++, pIn += pitchIn, pSub += pitchSub)
  348. {
  349. memsetd(pSub, black, dpLeft);
  350. memsetd(pSub + dpLeft+dpMid, black, dpRight);
  351. }
  352. }
  353. else
  354. {
  355. for(int k = min(j, hSub); i < k; i++, pIn += pitchIn, pSub += pitchSub)
  356. {
  357. memsetd(pSub, black, dpLeft);
  358. memcpy(pSub + dpLeft, pIn, dpMid);
  359. memsetd(pSub + dpLeft+dpMid, black, dpRight);
  360. }
  361. }
  362. j = hSub;
  363. for(; i < j; i++, pSub += pitchSub)
  364. {
  365. memsetd(pSub, black, dpLeft+dpMid+dpRight);
  366. }
  367. }
  368. return NOERROR;
  369. }
  370. void CDirectVobSubFilter::PrintMessages(BYTE* pOut)
  371. {
  372. if(!m_hdc || !m_hbm)
  373. return;
  374. ColorConvInit();
  375. const GUID& subtype = m_pOutput->CurrentMediaType().subtype;
  376. BITMAPINFOHEADER bihOut;
  377. ExtractBIH(&m_pOutput->CurrentMediaType(), &bihOut);
  378. CString msg, tmp;
  379. if(m_fOSD)
  380. {
  381. tmp.Format(_T("in: %dx%d %snout: %dx%d %sn"), 
  382. m_w, m_h, 
  383. Subtype2String(m_pInput->CurrentMediaType().subtype),
  384. bihOut.biWidth, bihOut.biHeight, 
  385. Subtype2String(m_pOutput->CurrentMediaType().subtype));
  386. msg += tmp;
  387. tmp.Format(_T("real fps: %.3f, current fps: %.3fnmedia time: %d, subtitle time: %d [ms]nframe number: %d (calculated)nrate: %.4fn"), 
  388. m_fps, m_fMediaFPSEnabled?m_MediaFPS:fabs(m_fps),
  389. (int)m_tPrev.Millisecs(), (int)(CalcCurrentTime()/10000),
  390. (int)(m_tPrev.m_time * m_fps / 10000000),
  391. m_pInput->CurrentRate());
  392. msg += tmp;
  393. CAutoLock cAutoLock(&m_csQueueLock);
  394. if(m_pSubPicQueue)
  395. {
  396. int nSubPics = -1;
  397. REFERENCE_TIME rtNow = -1, rtStart = -1, rtStop = -1;
  398. m_pSubPicQueue->GetStats(nSubPics, rtNow, rtStart, rtStop);
  399. tmp.Format(_T("queue stats: %I64d - %I64d [ms]n"), rtStart/10000, rtStop/10000);
  400. msg += tmp;
  401. for(int i = 0; i < nSubPics; i++)
  402. {
  403. m_pSubPicQueue->GetStats(i, rtStart, rtStop);
  404. tmp.Format(_T("%d: %I64d - %I64d [ms]n"), i, rtStart/10000, rtStop/10000);
  405. msg += tmp;
  406. }
  407. }
  408. }
  409. if(msg.IsEmpty()) return;
  410. HANDLE hOldBitmap = SelectObject(m_hdc, m_hbm);
  411. HANDLE hOldFont = SelectObject(m_hdc, m_hfont);
  412. SetTextColor(m_hdc, 0xffffff);
  413. SetBkMode(m_hdc, TRANSPARENT);
  414. SetMapMode(m_hdc, MM_TEXT);
  415. BITMAP bm;
  416. GetObject(m_hbm, sizeof(BITMAP), &bm);
  417. CRect r(0, 0, bm.bmWidth, bm.bmHeight);
  418. DrawText(m_hdc, msg, _tcslen(msg), &r, DT_CALCRECT|DT_EXTERNALLEADING|DT_NOPREFIX|DT_WORDBREAK);
  419. r += CPoint(10, 10);
  420. r &= CRect(0, 0, bm.bmWidth, bm.bmHeight);
  421. DrawText(m_hdc, msg, _tcslen(msg), &r, DT_LEFT|DT_TOP|DT_NOPREFIX|DT_WORDBREAK);
  422. BYTE* pIn = (BYTE*)bm.bmBits;
  423. int pitchIn = bm.bmWidthBytes;
  424. int pitchOut = bihOut.biWidth * bihOut.biBitCount >> 3;
  425. if(subtype == MEDIASUBTYPE_YV12 || subtype == MEDIASUBTYPE_I420 || subtype == MEDIASUBTYPE_IYUV)
  426. pitchOut = bihOut.biWidth;
  427. pitchIn = (pitchIn+3)&~3;
  428. pitchOut = (pitchOut+3)&~3;
  429. if(bihOut.biHeight > 0 && bihOut.biCompression <= 3) // flip if the dst bitmap is flipped rgb (m_hbm is a top-down bitmap, not like the subpictures)
  430. {
  431. pOut += pitchOut * (abs(bihOut.biHeight)-1);
  432. pitchOut = -pitchOut;
  433. }
  434. pIn += pitchIn * r.top;
  435. pOut += pitchOut * r.top;
  436. for(int w = min(r.right, m_w), h = r.Height(); h--; pIn += pitchIn, pOut += pitchOut)
  437. {
  438. BltLineRGB32((DWORD*)pOut, pIn, w, subtype);
  439. memsetd(pIn, 0xff000000, r.right*4);
  440. }
  441. SelectObject(m_hdc, hOldBitmap);
  442. SelectObject(m_hdc, hOldFont);
  443. }