Leaked source code of windows server 2003
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.

3625 lines
110 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1995 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. /*****************************************************************************
  15. * e3enc.cpp
  16. *
  17. * DESCRIPTION:
  18. * Specific encoder compression functions.
  19. *
  20. * Routines: Prototypes in:
  21. * H263InitEncoderInstance
  22. * H263Compress
  23. * H263TermEncoderInstance
  24. *
  25. *
  26. *
  27. * $Author: JMCVEIGH $
  28. * $Date: 05 Feb 1997 12:19:24 $
  29. * $Archive: S:\h26x\src\enc\e3mbenc.cpv $
  30. * $Header: S:\h26x\src\enc\e3mbenc.cpv 1.54 05 Feb 1997 12:19:24 JMCVEIGH $
  31. * $Log: S:\h26x\src\enc\e3mbenc.cpv $
  32. //
  33. // Rev 1.54 05 Feb 1997 12:19:24 JMCVEIGH
  34. // Support for separate improved PB-frame flag.
  35. //
  36. // Rev 1.53 19 Dec 1996 16:02:04 JMCVEIGH
  37. //
  38. // And'ed CodedBlocksB with 0x3f to surpress high bit that indicates
  39. // if only forward prediction is to be used in improved PB-frame mode.
  40. // This is done in the VLC generation of CBPB and the block coeffs.
  41. //
  42. // Rev 1.52 16 Dec 1996 17:50:38 JMCVEIGH
  43. // Encoding of MODB for improved PB-frame mode.
  44. //
  45. // Rev 1.51 05 Dec 1996 17:02:32 GMLIM
  46. //
  47. // Changed the way RTP packetization was done to guarantee proper packet
  48. // size. Calls to update bitstream info buffer were modified.
  49. //
  50. // Rev 1.50 06 Nov 1996 16:30:32 gmlim
  51. // Removed H263ModeC.
  52. //
  53. // Rev 1.49 05 Nov 1996 13:33:48 GMLIM
  54. // Added mode c support for mmx case.
  55. //
  56. // Rev 1.48 03 Nov 1996 18:47:02 gmlim
  57. // Modified to generate
  58. // rtp bs ext. for mode c.
  59. //
  60. // Rev 1.47 28 Oct 1996 12:03:16 KLILLEVO
  61. // fixed an EMV bug in the writing of motion vectors for the PB-frame
  62. //
  63. // Rev 1.46 24 Oct 1996 16:27:40 KLILLEVO
  64. //
  65. // changed from DBOUT to DbgLog
  66. //
  67. // Rev 1.45 22 Oct 1996 17:09:04 KLILLEVO
  68. // reversed the condition on whether or not to skip a macroblock.
  69. // Fall-through is now coded.
  70. // Set the pCurMB->COD member properly and use that in the coded/
  71. // not-coded test in the PB-frame encoding instead of repeating
  72. // the same test as in the P-frame case.
  73. //
  74. // Rev 1.44 14 Oct 1996 11:58:42 KLILLEVO
  75. // EMV bug fixed
  76. //
  77. // Rev 1.43 04 Oct 1996 08:43:16 KLILLEVO
  78. // initial support for extended motion vectors
  79. //
  80. // Rev 1.42 13 Sep 1996 12:48:04 KLILLEVO
  81. // cleaned up intra update code to make it more understandable
  82. //
  83. // Rev 1.41 10 Sep 1996 17:51:42 KLILLEVO
  84. // moved reset of InterCodeCnt to e3enc.cpp CalcGobChroma..._InterCodeCnt
  85. //
  86. // Rev 1.40 09 Sep 1996 17:05:50 KLILLEVO
  87. // changed small type in intercodecnt increment
  88. //
  89. // Rev 1.39 06 Sep 1996 16:12:24 KLILLEVO
  90. // fixed the logical problem that the inter code count was always
  91. // incremented no matter whether coefficients were transmitted or not
  92. //
  93. // Rev 1.38 03 May 1996 10:53:56 KLILLEVO
  94. //
  95. // cleaned up and fixed indentation in two routines which might
  96. // need to be rewritten for MMX PB-frames
  97. //
  98. // Rev 1.37 28 Apr 1996 20:19:30 BECHOLS
  99. //
  100. // Merged RTP code into Main Base.
  101. //
  102. // Rev 1.36 15 Mar 1996 15:58:56 BECHOLS
  103. //
  104. // added support for monolithic MMx code with separate passes over
  105. // luma and chroma.
  106. //
  107. // Rev 1.35 22 Feb 1996 18:52:44 BECHOLS
  108. //
  109. // Added boolean to switch between MMX and P5 quantization function.
  110. //
  111. // Rev 1.34 26 Jan 1996 16:25:42 TRGARDOS
  112. // Added conditional compilation code to count bits.
  113. //
  114. // Rev 1.33 12 Jan 1996 16:34:30 BNICKERS
  115. //
  116. // Fix numerous macroblock layer bugs w.r.t. PB encoding.
  117. //
  118. // Rev 1.32 22 Dec 1995 11:12:46 TRGARDOS
  119. // Fixed bug in MV prediction calculation for blocks 2-4 of
  120. // AP. Was not zeroing outside motion vectors when their
  121. // block was INTRA coded.
  122. //
  123. // Rev 1.31 18 Dec 1995 12:40:18 RMCKENZX
  124. // added copyright notice
  125. //
  126. // Rev 1.30 13 Dec 1995 22:00:58 TRGARDOS
  127. // Changed MV predictor to not use ME state variable.
  128. //
  129. // Rev 1.29 13 Dec 1995 12:18:38 RMCKENZX
  130. // Restored version 1.27
  131. //
  132. // Rev 1.27 11 Dec 1995 10:00:30 TRGARDOS
  133. // Fixed debug messages for motion vectors.
  134. //
  135. // Rev 1.26 06 Dec 1995 12:06:26 TRGARDOS
  136. // Finished 4MV support in MV delta and VLC/bit stream writing.
  137. //
  138. // Rev 1.25 05 Dec 1995 10:20:30 TRGARDOS
  139. // Fixed MV predictors in GOBs with headers.
  140. //
  141. // Rev 1.24 09 Nov 1995 14:11:24 AGUPTA2
  142. // PB-frame+performance+structure enhancements.
  143. //
  144. // Rev 1.23 19 Oct 1995 11:35:14 BNICKERS
  145. // Made some changes to MacroBlockActionDescriptor structure to support B-Fram
  146. // Motion Estimation and Frame Differencing. Added some arguments to ME and F
  147. //
  148. // Rev 1.22 12 Oct 1995 17:39:34 TRGARDOS
  149. // Fixed bug in MV prediction.
  150. //
  151. // Rev 1.21 03 Oct 1995 18:34:26 BECHOLS
  152. // Changed the table sizes to reduce the memory requirements for the
  153. // data to about half. This also required a change to the initialization
  154. // routine that sets up TCOEF_ and TCOEF_LAST_ tables.
  155. //
  156. // Rev 1.20 03 Oct 1995 09:21:34 TRGARDOS
  157. // Fixed bug VLC encoding regarding MV prediction.
  158. //
  159. // Rev 1.19 29 Sep 1995 17:14:06 TRGARDOS
  160. // Fixed offset value for cur to prev frame
  161. //
  162. // Rev 1.18 27 Sep 1995 19:10:02 TRGARDOS
  163. //
  164. // Fixed bug in writing MB headers.
  165. //
  166. // Rev 1.17 27 Sep 1995 11:26:30 TRGARDOS
  167. // Integrated motion estimation.
  168. //
  169. // Rev 1.16 18 Sep 1995 17:08:54 TRGARDOS
  170. // Debugged delta frames.
  171. //
  172. // Rev 1.15 15 Sep 1995 16:37:32 TRGARDOS
  173. //
  174. //
  175. // Rev 1.14 13 Sep 1995 10:26:44 AGUPTA2
  176. // Added blockType flag to QUANTRLE and changed the name to all upper-case.
  177. //
  178. // Rev 1.13 11 Sep 1995 14:10:42 BECHOLS
  179. //
  180. // Changed this module to call the VLC routine in E35VLC.ASM. I also
  181. // renamed a couple of tables for clarity, and moved tables that I needed
  182. // to the ASM module.
  183. //
  184. // Rev 1.12 08 Sep 1995 17:39:30 TRGARDOS
  185. // Added more decoder code to encoder.
  186. //
  187. // Rev 1.11 07 Sep 1995 17:46:30 TRGARDOS
  188. // Started adding delta frame support.
  189. //
  190. // Rev 1.10 05 Sep 1995 15:50:20 TRGARDOS
  191. //
  192. // Rev 1.9 05 Sep 1995 11:36:26 TRGARDOS
  193. //
  194. // Rev 1.8 01 Sep 1995 17:51:10 TRGARDOS
  195. // Added DCT print routine.
  196. //
  197. // Rev 1.7 01 Sep 1995 10:13:32 TRGARDOS
  198. // Debugging bit stream errors.
  199. //
  200. // Rev 1.6 31 Aug 1995 11:00:44 TRGARDOS
  201. // Cut out MB VLC code.
  202. //
  203. // Rev 1.5 30 Aug 1995 12:42:22 TRGARDOS
  204. // Fixed bugs in intra AC coef VLC coding.
  205. //
  206. // Rev 1.4 29 Aug 1995 17:19:16 TRGARDOS
  207. //
  208. //
  209. // Rev 1.3 25 Aug 1995 10:36:20 TRGARDOS
  210. //
  211. // Fixed bugs in integration.
  212. //
  213. // Rev 1.2 22 Aug 1995 17:20:14 TRGARDOS
  214. // Finished integrating asm quant & rle.
  215. //
  216. // Rev 1.1 22 Aug 1995 10:26:32 TRGARDOS
  217. // Removed compile errors for adding quantization asm code.
  218. //
  219. // Rev 1.0 21 Aug 1995 16:30:04 TRGARDOS
  220. // Initial revision.
  221. //
  222. // Add quantization hooks and call RTP MB packetization only if
  223. // the bRTPHeader boolean is true
  224. //
  225. */
  226. #include "precomp.h"
  227. /*
  228. * VLC table for MCBPC for INTRA pictures.
  229. * Table is stored as {number of bits, code}.
  230. * The index to the table is built as:
  231. * bit 2 = 1 if DQUANT is present, 0 else.
  232. * bit 1 = 1 if V block is coded, 0 if not coded
  233. * bit 0 = 1 if U block is coded, 0 if not coded.
  234. */
  235. // TODO : why int, why not const
  236. int VLC_MCBPC_INTRA[9][2] =
  237. { { 1, 1}, // 0
  238. { 3, 2}, // 1
  239. { 3, 1}, // 2
  240. { 3, 3}, // 3
  241. { 4, 1}, // 4
  242. { 6, 2}, // 5
  243. { 6, 1}, // 6
  244. { 6, 3}, // 7
  245. { 9, 1} };// 8 stuffing
  246. /*
  247. * VLC table for MCBPC for INTER pictures.
  248. * Table is stored as {number of bits, code}.
  249. * The index to the table is built as:
  250. * bits 3,2 = MB type <0,1,2,3>
  251. * bit 1 = 1 if V block is coded, 0 if not coded.
  252. * bit 0 = 1 if U block is coded, 0 if not coded.
  253. *
  254. * For INTER pictures, MB types are defined as:
  255. * 0: INTER
  256. * 1: INTER+Q
  257. * 2: INTER4V
  258. * 3: INTRA
  259. * 4: INTRA+Q
  260. */
  261. // TODO : why int, why not const
  262. const int VLC_MCBPC_INTER[20][2] =
  263. { { 1, 1}, // 0
  264. { 4, 2}, // 1
  265. { 4, 3}, // 2
  266. { 6, 5}, // 3
  267. { 3, 3}, // 4
  268. { 7, 6}, // 5
  269. { 7, 7}, // 6
  270. { 9, 5}, // 7
  271. { 3, 2}, // 8
  272. { 7, 4}, // 9
  273. { 7, 5}, // 10
  274. { 8, 5}, // 11
  275. { 5, 3}, // 12
  276. { 8, 3}, // 13
  277. { 8, 4}, // 14
  278. { 7, 3}, // 15
  279. { 6, 4}, // 16
  280. { 9, 3}, // 17
  281. { 9, 4}, // 18
  282. { 9, 2} };// 19
  283. /*
  284. * VLC's for motion vector delta's
  285. */
  286. // TODO : why int, why not const
  287. int vlc_mvd[] = {
  288. // Index: Vector Differences
  289. 13,5, // 0: -16 16
  290. 13,7,
  291. 12,5,
  292. 12,7,
  293. 12,9,
  294. 12,11,
  295. 12,13,
  296. 12,15,
  297. 11,9,
  298. 11,11,
  299. 11,13,
  300. 11,15,
  301. 11,17,
  302. 11,19,
  303. 11,21,
  304. 11,23,
  305. 11,25,
  306. 11,27,
  307. 11,29,
  308. 11,31,
  309. 11,33,
  310. 11,35,
  311. 10,19,
  312. 10,21,
  313. 10,23,
  314. 8,7,
  315. 8,9,
  316. 8,11,
  317. 7,7,
  318. 5,3,
  319. 4,3,
  320. 3,3,
  321. 1,1, // 32: 0
  322. 3,2,
  323. 4,2,
  324. 5,2,
  325. 7,6,
  326. 8,10,
  327. 8,8,
  328. 8,6,
  329. 10,22,
  330. 10,20,
  331. 10,18,
  332. 11,34,
  333. 11,32,
  334. 11,30,
  335. 11,28,
  336. 11,26,
  337. 11,24,
  338. 11,22,
  339. 11,20,
  340. 11,18,
  341. 11,16,
  342. 11,14,
  343. 11,12,
  344. 11,10,
  345. 11,8,
  346. 12,14,
  347. 12,12,
  348. 12,10,
  349. 12,8,
  350. 12,6,
  351. 12,4,
  352. 13,6,
  353. };
  354. /*
  355. * VLC table for CBPY
  356. * Table is stores as {number of bits, code}
  357. * Index into the table for INTRA macroblocks is the
  358. * coded block pattern for the blocks in the order
  359. * bit 3 = block 4
  360. * bit 2 = block 3
  361. * bit 1 = block 2
  362. * bit 0 = block 1
  363. *
  364. * For INTER macroblocks, a CBP is built as above and
  365. * then is subtracted from 15 to get the index into the
  366. * array: index = 15 - interCBP.
  367. */
  368. // TODO : why int, why not const
  369. int VLC_CBPY[16][2] =
  370. { { 4, 3}, // 0
  371. { 5, 2}, // 1
  372. { 5, 3}, // 2
  373. { 4, 4}, // 3
  374. { 5, 4}, // 4
  375. { 4, 5}, // 5
  376. { 6, 2}, // 6
  377. { 4, 6}, // 7
  378. { 5, 5}, // 8
  379. { 6, 3}, // 9
  380. { 4, 7}, // 10
  381. { 4, 8}, // 11
  382. { 4, 9}, // 12
  383. { 4, 10}, // 13
  384. { 4, 11}, // 14
  385. { 2, 3} // 15
  386. };
  387. /*
  388. * TODO : VLC tables for MODB and CBPB
  389. */
  390. const U8 VLC_MODB[4][2] =
  391. {
  392. {1, 0}, // 0
  393. {1, 0}, // should not happen
  394. {2, 2}, // 2
  395. {2, 3} // 3
  396. };
  397. #ifdef H263P
  398. /*
  399. * VLC table for MODB when improved PB-frame mode selected
  400. */
  401. const U8 VLC_IMPROVED_PB_MODB[4][2] =
  402. {
  403. {1, 0}, // Bidirectional prediction with all empty blocks (CBPB=0, MVDB=0)
  404. {2, 2}, // Forward prediction with all empty blocks (CBPB=0, MVDB=1)
  405. {3, 6}, // Forward prediction with some non-empty blocks (CBPB=1, MVDB=1)
  406. {3, 7} // Bidirectional prediction with some non-empty blocks (CBPB=1, MVDB=0)
  407. };
  408. #endif
  409. /*
  410. * TODO : VLC tables for CBPB; indexed using CodedBlocksB
  411. *
  412. */
  413. const U8 VLC_CBPB[64] =
  414. {
  415. 0, // 000000
  416. 32, // 000001
  417. 16, // 000010
  418. 48, // 000011
  419. 8, // 000100
  420. 40, // 000101
  421. 24, // 000110
  422. 56, // 000111
  423. 4, // 001000
  424. 36, // 001001
  425. 20, // 001010
  426. 52, // 001011
  427. 12, // 001100
  428. 44, // 001101
  429. 28, // 001110
  430. 60, // 001111
  431. 2, // 010000
  432. 34, // 010001
  433. 18, // 010010
  434. 50, // 010011
  435. 10, // 010100
  436. 42, // 010101
  437. 26, // 010110
  438. 58, // 010111
  439. 6, // 011000
  440. 38, // 011001
  441. 22, // 011010
  442. 54, // 011011
  443. 14, // 011100
  444. 46, // 011101
  445. 30, // 011110
  446. 62, // 011111
  447. 1, // 100000
  448. 33, // 100001
  449. 17, // 100010
  450. 49, // 100011
  451. 9, // 100100
  452. 41, // 100101
  453. 25, // 100110
  454. 57, // 100111
  455. 5, // 101000
  456. 37, // 101001
  457. 21, // 101010
  458. 53, // 101011
  459. 13, // 101100
  460. 45, // 101101
  461. 29, // 101110
  462. 61, // 101111
  463. 3, // 110000
  464. 35, // 110001
  465. 19, // 110010
  466. 51, // 110011
  467. 11, // 110100
  468. 43, // 110101
  469. 27, // 110110
  470. 59, // 110111
  471. 7, // 111000
  472. 39, // 111001
  473. 23, // 111010
  474. 55, // 111011
  475. 15, // 111100
  476. 47, // 111101
  477. 31, // 111110
  478. 63 // 111111
  479. };
  480. /*
  481. * VLC table for TCOEFs
  482. * Table entries are size, code.
  483. * Stored as (size, value)
  484. * BSE -- The "+ 1" and "<< 1" makes room for the sign bit. This permits
  485. * us to do a single write to the stream, versus two writes.
  486. */
  487. // TODO : why int, why not const
  488. int VLC_TCOEF[102*2] = {
  489. 2 + 1, 2 << 1, /* 0, runs of 0 *** table for nonlast coefficient */
  490. 4 + 1, 15 << 1,
  491. 6 + 1, 21 << 1,
  492. 7 + 1, 23 << 1,
  493. 8 + 1, 31 << 1,
  494. 9 + 1, 37 << 1,
  495. 9 + 1, 36 << 1,
  496. 10 + 1, 33 << 1,
  497. 10 + 1, 32 << 1,
  498. 11 + 1, 7 << 1,
  499. 11 + 1, 6 << 1,
  500. 11 + 1, 32 << 1,
  501. 3 + 1, 6 << 1, /* 24, runs of 1 */
  502. 6 + 1, 20 << 1,
  503. 8 + 1, 30 << 1,
  504. 10 + 1, 15 << 1,
  505. 11 + 1, 33 << 1,
  506. 12 + 1, 80 << 1,
  507. 4 + 1, 14 << 1, /* 36, runs of 2 */
  508. 8 + 1, 29 << 1,
  509. 10 + 1, 14 << 1,
  510. 12 + 1, 81 << 1,
  511. 5 + 1, 13 << 1, /* 44, runs of 3 */
  512. 9 + 1, 35 << 1,
  513. 10 + 1, 13 << 1,
  514. 5 + 1, 12 << 1, /* 50, runs of 4 */
  515. 9 + 1, 34 << 1,
  516. 12 + 1, 82 << 1,
  517. 5 + 1, 11 << 1, /* 56, runs of 5 */
  518. 10 + 1, 12 << 1,
  519. 12 + 1, 83 << 1,
  520. 6 + 1, 19 << 1, /* 62, runs of 6 */
  521. 10 + 1, 11 << 1,
  522. 12 + 1, 84 << 1,
  523. 6 + 1, 18 << 1, /* 68, runs of 7 */
  524. 10 + 1, 10 << 1,
  525. 6 + 1, 17 << 1, /* 72, runs of 8 */
  526. 10 + 1, 9 << 1,
  527. 6 + 1, 16 << 1, /* 76, runs of 9 */
  528. 10 + 1, 8 << 1,
  529. 7 + 1, 22 << 1, /* 80, runs of 10 */
  530. 12 + 1, 85 << 1,
  531. 7 + 1, 21 << 1, /* 84, runs of 11 */
  532. 7 + 1, 20 << 1, /* 86, runs of 12 */
  533. 8 + 1, 28 << 1, /* 88, runs of 13 */
  534. 8 + 1, 27 << 1, /* 90, runs of 14 */
  535. 9 + 1, 33 << 1,
  536. 9 + 1, 32 << 1,
  537. 9 + 1, 31 << 1,
  538. 9 + 1, 30 << 1,
  539. 9 + 1, 29 << 1,
  540. 9 + 1, 28 << 1,
  541. 9 + 1, 27 << 1,
  542. 9 + 1, 26 << 1,
  543. 11 + 1, 34 << 1,
  544. 11 + 1, 35 << 1,
  545. 12 + 1, 86 << 1,
  546. 12 + 1, 87 << 1,
  547. 4 + 1, 7 << 1, /* Table for last coeff */
  548. 9 + 1, 25 << 1,
  549. 11 + 1, 5 << 1,
  550. 6 + 1, 15 << 1,
  551. 11 + 1, 4 << 1,
  552. 6 + 1, 14 << 1,
  553. 6 + 1, 13 << 1,
  554. 6 + 1, 12 << 1,
  555. 7 + 1, 19 << 1,
  556. 7 + 1, 18 << 1,
  557. 7 + 1, 17 << 1,
  558. 7 + 1, 16 << 1,
  559. 8 + 1, 26 << 1,
  560. 8 + 1, 25 << 1,
  561. 8 + 1, 24 << 1,
  562. 8 + 1, 23 << 1,
  563. 8 + 1, 22 << 1,
  564. 8 + 1, 21 << 1,
  565. 8 + 1, 20 << 1,
  566. 8 + 1, 19 << 1,
  567. 9 + 1, 24 << 1,
  568. 9 + 1, 23 << 1,
  569. 9 + 1, 22 << 1,
  570. 9 + 1, 21 << 1,
  571. 9 + 1, 20 << 1,
  572. 9 + 1, 19 << 1,
  573. 9 + 1, 18 << 1,
  574. 9 + 1, 17 << 1,
  575. 10 + 1, 7 << 1,
  576. 10 + 1, 6 << 1,
  577. 10 + 1, 5 << 1,
  578. 10 + 1, 4 << 1,
  579. 11 + 1, 36 << 1,
  580. 11 + 1, 37 << 1,
  581. 11 + 1, 38 << 1,
  582. 11 + 1, 39 << 1,
  583. 12 + 1, 88 << 1,
  584. 12 + 1, 89 << 1,
  585. 12 + 1, 90 << 1,
  586. 12 + 1, 91 << 1,
  587. 12 + 1, 92 << 1,
  588. 12 + 1, 93 << 1,
  589. 12 + 1, 94 << 1,
  590. 12 + 1, 95 << 1
  591. };
  592. /*
  593. * This table lists the maximum level represented in the
  594. * VLC table for a given run. If the level exceeds the
  595. * max, then escape codes must be used to encode the
  596. * run & level.
  597. * The table entries are of the form {maxlevel, ptr to table for this run}.
  598. */
  599. T_MAXLEVEL_PTABLE TCOEF_RUN_MAXLEVEL[65] = {
  600. {12, &VLC_TCOEF[0]}, // run of 0
  601. { 6, &VLC_TCOEF[24]}, // run of 1
  602. { 4, &VLC_TCOEF[36]}, // run of 2
  603. { 3, &VLC_TCOEF[44]}, // run of 3
  604. { 3, &VLC_TCOEF[50]}, // run of 4
  605. { 3, &VLC_TCOEF[56]}, // run of 5
  606. { 3, &VLC_TCOEF[62]}, // run of 6
  607. { 2, &VLC_TCOEF[68]}, // run of 7
  608. { 2, &VLC_TCOEF[72]}, // run of 8
  609. { 2, &VLC_TCOEF[76]}, // run of 9
  610. { 2, &VLC_TCOEF[80]}, // run of 10
  611. { 1, &VLC_TCOEF[84]}, // run of 11
  612. { 1, &VLC_TCOEF[86]}, // run of 12
  613. { 1, &VLC_TCOEF[88]}, // run of 13
  614. { 1, &VLC_TCOEF[90]}, // run of 14
  615. { 1, &VLC_TCOEF[92]}, // run of 15
  616. { 1, &VLC_TCOEF[94]}, // run of 16
  617. { 1, &VLC_TCOEF[96]}, // run of 17
  618. { 1, &VLC_TCOEF[98]}, // run of 18
  619. { 1, &VLC_TCOEF[100]}, // run of 19
  620. { 1, &VLC_TCOEF[102]}, // run of 20
  621. { 1, &VLC_TCOEF[104]}, // run of 21
  622. { 1, &VLC_TCOEF[106]}, // run of 22
  623. { 1, &VLC_TCOEF[108]}, // run of 23
  624. { 1, &VLC_TCOEF[110]}, // run of 24
  625. { 1, &VLC_TCOEF[112]}, // run of 25
  626. { 1, &VLC_TCOEF[114]}, // run of 26
  627. { 0, 0}, // run of 27 not in VLC table
  628. { 0, 0}, // run of 28 not in VLC table
  629. { 0, 0}, // run of 29 not in VLC table
  630. { 0, 0}, // run of 30 not in VLC table
  631. { 0, 0}, // run of 31 not in VLC table
  632. { 0, 0}, // run of 32 not in VLC table
  633. { 0, 0}, // run of 33 not in VLC table
  634. { 0, 0}, // run of 34 not in VLC table
  635. { 0, 0}, // run of 35 not in VLC table
  636. { 0, 0}, // run of 36 not in VLC table
  637. { 0, 0}, // run of 37 not in VLC table
  638. { 0, 0}, // run of 38 not in VLC table
  639. { 0, 0}, // run of 39 not in VLC table
  640. { 0, 0}, // run of 40 not in VLC table
  641. { 0, 0}, // run of 41 not in VLC table
  642. { 0, 0}, // run of 42 not in VLC table
  643. { 0, 0}, // run of 43 not in VLC table
  644. { 0, 0}, // run of 44 not in VLC table
  645. { 0, 0}, // run of 45 not in VLC table
  646. { 0, 0}, // run of 46 not in VLC table
  647. { 0, 0}, // run of 47 not in VLC table
  648. { 0, 0}, // run of 48 not in VLC table
  649. { 0, 0}, // run of 49 not in VLC table
  650. { 0, 0}, // run of 50 not in VLC table
  651. { 0, 0}, // run of 51 not in VLC table
  652. { 0, 0}, // run of 52 not in VLC table
  653. { 0, 0}, // run of 53 not in VLC table
  654. { 0, 0}, // run of 54 not in VLC table
  655. { 0, 0}, // run of 55 not in VLC table
  656. { 0, 0}, // run of 56 not in VLC table
  657. { 0, 0}, // run of 57 not in VLC table
  658. { 0, 0}, // run of 58 not in VLC table
  659. { 0, 0}, // run of 59 not in VLC table
  660. { 0, 0}, // run of 60 not in VLC table
  661. { 0, 0}, // run of 61 not in VLC table
  662. { 0, 0}, // run of 62 not in VLC table
  663. { 0, 0}, // run of 63 not in VLC table
  664. { 0, 0} // run of 64 not in VLC table
  665. };
  666. static char __fastcall median(char v1, char v2, char v3);
  667. static I8 * MB_Quantize_RLE(
  668. I32 **DCTCoefs,
  669. I8 *MBRunValPairs,
  670. U8 *CodedBlocks,
  671. U8 BlockType,
  672. I32 QP
  673. );
  674. /*************************************************************
  675. * Name: writePB_MVD
  676. * Description: Writes out the VLC for horizontal and vertical motion vector
  677. * to the bit-stream addressed by (pPB_BitStream, pPB_BitOffset) in a
  678. * PB-frame (in a PB-frame, a predictor is NOT set to 0 for INTRABLOCKS).
  679. * In its current incarnation, it cannot be used to write MV for non-PB
  680. * frames.
  681. * Parameters:
  682. * curMB Write MV for the MB no. "curMB" in the frame. MBs are
  683. * numbererd from 0 in a frame.
  684. * pCurMB Pointer to the current MB action descriptor
  685. * NumMBPerRow No. of MBs in a row; e.g. 11 in QCIF.
  686. * pPB_BitStream Current byte being written
  687. * pPB_BitOffset Offset at which VLC code is written
  688. * Side-effects:
  689. * Modifies pPB_BitStream and pPB_BitOffset.
  690. *************************************************************/
  691. static void writePB_MVD(
  692. const U32 curMB,
  693. T_MBlockActionStream * const pCurMB,
  694. const U32 NumMBPerRow,
  695. const U32 NumMBs,
  696. U8 ** pPB_BitStream,
  697. U8 * pPB_BitOffset,
  698. U32 GOBHeaderFlag,
  699. const T_H263EncoderCatalog *EC
  700. );
  701. /*************************************************************
  702. * Name: writeP_MVD
  703. * Description: Writes out the VLC for horizontal and vertical motion vector
  704. * to the bit-stream addressed by (pP_BitStream, pP_BitOffset) in a
  705. * P-frame.
  706. * Parameters:
  707. * curMB Write MV for the MB no. "curMB" in the frame. MBs are
  708. * numbererd from 0 in a frame.
  709. * pCurMB Pointer to current MB action descriptor
  710. * NumMBPerRow No. of MBs in a row; e.g. 11 in QCIF.
  711. * pP_BitStream Current byte being written
  712. * pP_BitOffset Offset at which VLC code is written
  713. * GOBHeaderPresent IF true, then GOB header is present for this GOB.
  714. * Side-effects:
  715. * Modifies pP_BitStream and pP_BitOffset.
  716. *************************************************************/
  717. static void writeP_MVD(
  718. const U32 curMB,
  719. T_MBlockActionStream * const pCurMB,
  720. const U32 NumMBPerRow,
  721. const U32 NumMBs,
  722. U8 ** pP_BitStream,
  723. U8 * pP_BitOffset,
  724. U32 GOBHeaderPresent,
  725. T_H263EncoderCatalog *EC
  726. );
  727. /**********************************************************************
  728. * Quantize and RLE each macroblock, then VLC and write to stream.
  729. * This function is only used for P or I frames, not B.
  730. *
  731. * Parameters:
  732. * FutrPMBData
  733. **********************************************************************/
  734. void GOB_Q_RLE_VLC_WriteBS(
  735. T_H263EncoderCatalog *EC,
  736. I32 *DCTCoefs,
  737. U8 **pBitStream,
  738. U8 *pBitOffset,
  739. T_FutrPMBData *FutrPMBData, // Start of GOB
  740. U32 GOB,
  741. U32 QP,
  742. BOOL bRTPHeader,
  743. U32 StartingMB
  744. )
  745. {
  746. U32 MB, curMB, index;
  747. I8 MBRunValSign[65*3*6], * EndAddress, *rvs;
  748. U8 bUseDQUANT = 0; // Indicates if DQUANT is present.
  749. U8 MBType;
  750. U8 *pFrmStart = EC->pU8_BitStream; // TODO : should be a param.
  751. U32 GOBHeaderMask, GOBHeaderFlag;
  752. #ifdef COUNT_BITS
  753. U32 savebyteptr, savebitptr;
  754. #endif
  755. register T_MBlockActionStream *pCurMB;
  756. FX_ENTRY("GOB_Q_RLE_VLC_WriteBS")
  757. // Create GOB header mask to be used further down.
  758. GOBHeaderMask = 1 << GOB;
  759. // Loop through each macroblock of the GOB.
  760. for(MB = 0, curMB = GOB*EC->NumMBPerRow,
  761. pCurMB = EC->pU8_MBlockActionStream + curMB;
  762. MB < EC->NumMBPerRow;
  763. MB++, curMB++, pCurMB++)
  764. {
  765. DEBUGMSG(ZONE_ENCODE_MB, ("%s: MB #%d: QP=%d\r\n", _fx_, MB, QP));
  766. /*
  767. * Quantize and RLE each block in the macroblock,
  768. * skipping empty blocks as denoted by CodedBlocks.
  769. * If any more blocks are empty after quantization
  770. * then the appropriate CodedBlocks bit is cleared.
  771. */
  772. EndAddress = MB_Quantize_RLE(
  773. &DCTCoefs,
  774. (I8 *)MBRunValSign,
  775. &(pCurMB->CodedBlocks),
  776. pCurMB->BlockType,
  777. QP
  778. );
  779. // default COD is coded (= 0). Will be set to 1 only if skipped
  780. pCurMB->COD = 0;
  781. #ifdef ENCODE_STATS
  782. StatsUsedQuant(QP);
  783. #endif /* ENCODE_STATS */
  784. if(EC->PictureHeader.PicCodType == INTRAPIC)
  785. {
  786. pCurMB->MBType = INTRA;
  787. MBType = INTRA;
  788. }
  789. else // inter picture code type
  790. {
  791. if(pCurMB->BlockType == INTERBLOCK)
  792. {
  793. pCurMB->MBType = INTER;
  794. MBType = INTER;
  795. }
  796. else if(pCurMB->BlockType == INTER4MV)
  797. {
  798. pCurMB->MBType = INTER4V;
  799. MBType = INTER4V;
  800. }
  801. else if(pCurMB->BlockType == INTRABLOCK)
  802. {
  803. pCurMB->MBType = INTRA;
  804. MBType = INTRA;
  805. }
  806. else
  807. {
  808. ERRORMESSAGE(("%s: Unexpected MacroBlock Type found\r\n", _fx_));
  809. }
  810. }
  811. // Save starting bit offset of the macroblock data from start of
  812. // of the frame data. The offset for the first macroblock is saved
  813. // in e3enc.cpp before this routine is called.
  814. if (EC->u8EncodePBFrame == TRUE
  815. && MB != 0)
  816. {
  817. FutrPMBData[curMB].MBStartBitOff
  818. = (U32) (((*pBitStream - pFrmStart)<<3) + *pBitOffset);
  819. }
  820. /*
  821. * Write macroblock header to bit stream.
  822. */
  823. if( (MBType == INTER) || (MBType == INTER4V) )
  824. {
  825. // Check if entire macroblock is empty, including zero MV's.
  826. // If there is only one MV for the block, all block MVs in the
  827. // structure are still set but are equal.
  828. if( ((pCurMB->CodedBlocks & 0x3f) != 0)
  829. || (pCurMB->BlkY1.PHMV != 0)
  830. || (pCurMB->BlkY1.PVMV != 0)
  831. || (pCurMB->BlkY2.PHMV != 0)
  832. || (pCurMB->BlkY2.PVMV != 0)
  833. || (pCurMB->BlkY3.PHMV != 0)
  834. || (pCurMB->BlkY3.PVMV != 0)
  835. || (pCurMB->BlkY4.PHMV != 0)
  836. || (pCurMB->BlkY4.PVMV != 0)
  837. )
  838. {
  839. PutBits(0, 1, pBitStream, pBitOffset); // COD = 0, nonempty MB
  840. #ifdef COUNT_BITS
  841. if(MBType == INTER)
  842. EC->Bits.num_inter++;
  843. else if (MBType == INTER4V)
  844. EC->Bits.num_inter4v++;
  845. EC->Bits.MBHeader += 1;
  846. EC->Bits.Coded++;
  847. #endif
  848. // Increment the InterCoded block count if the block
  849. // is intercoded (not B frame) and is not empty.
  850. if (((pCurMB->CodedBlocks & 0x3f) != 0) &&
  851. ((pCurMB->BlockType == INTERBLOCK) || (pCurMB->BlockType == INTER4MV)))
  852. {
  853. // Macroblock is coded. Need to increment inter code count if
  854. // there are no coefficients: see section 4.4 of the H.263
  855. // recommendation
  856. pCurMB->InterCodeCnt++;
  857. }
  858. // pCurMB->InterCodeCnt is reset in calcGOBChromaVecs_InterCodeCnt
  859. /*******************************************
  860. * Write macroblock header to bit stream.
  861. *******************************************/
  862. // Write MCBPC to bitstream.
  863. // The rightmost two bits are the CBPC (65).
  864. // Note that this is the reverse of the order in the
  865. // VLC table in the H.263 spec.
  866. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  867. // Add the MB type to next two bits to the left.
  868. index |= (MBType << 2);
  869. // Write code to bitstream.
  870. PutBits(VLC_MCBPC_INTER[index][1], VLC_MCBPC_INTER[index][0],
  871. pBitStream, pBitOffset);
  872. #ifdef COUNT_BITS
  873. EC->Bits.MBHeader += VLC_MCBPC_INTER[index][0];
  874. EC->Bits.MCBPC += VLC_MCBPC_INTER[index][0];
  875. #endif
  876. // Save bit offset of CBPY data from start of macroblock data
  877. // if PB frame is on since we will reuse this later.
  878. if (EC->u8EncodePBFrame == TRUE)
  879. {
  880. FutrPMBData[curMB].CBPYBitOff
  881. = (U8)( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  882. - FutrPMBData[curMB].MBStartBitOff);
  883. }
  884. // Write CBPY to bitstream.
  885. index = pCurMB->CodedBlocks & 0xf;
  886. index = (~index) & 0xf;
  887. PutBits(VLC_CBPY[index][1], VLC_CBPY[index][0],
  888. pBitStream, pBitOffset);
  889. #ifdef COUNT_BITS
  890. EC->Bits.MBHeader += VLC_CBPY[index][0];
  891. EC->Bits.CBPY += VLC_CBPY[index][0];
  892. #endif
  893. //if( bUseDQUANT )
  894. //{
  895. // TODO: write DQUANT to bit stream here. We can only do
  896. // this if MBtype is not INTER4V since that type doesn't
  897. // allow quantizer as well.
  898. //}
  899. // Save bit offset of CBPY data from start of macroblock data
  900. if (EC->u8EncodePBFrame == TRUE)
  901. {
  902. FutrPMBData[curMB].MVDBitOff
  903. = (U8)( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  904. - FutrPMBData[curMB].MBStartBitOff);
  905. }
  906. // Write motion vectors to bit stream.
  907. if( (EC->GOBHeaderPresent & GOBHeaderMask) != 0 )
  908. {
  909. GOBHeaderFlag = TRUE;
  910. }
  911. else
  912. {
  913. GOBHeaderFlag = FALSE;
  914. }
  915. writeP_MVD(
  916. curMB, // Current MB number.
  917. pCurMB, // pointer to current MB action desc. struct.
  918. EC->NumMBPerRow,
  919. EC->NumMBs,
  920. pBitStream,
  921. pBitOffset,
  922. GOBHeaderFlag,
  923. EC
  924. );
  925. // Save bit offset of block data from start of MB data
  926. if (EC->u8EncodePBFrame == TRUE)
  927. {
  928. FutrPMBData[curMB].BlkDataBitOff
  929. = (U8) ( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  930. - FutrPMBData[curMB].MBStartBitOff);
  931. }
  932. /*
  933. * Encode intra DC and all run/val pairs.
  934. */
  935. #ifdef COUNT_BITS
  936. savebyteptr = (U32) *pBitStream;
  937. savebitptr = (U32) *pBitOffset;
  938. #endif
  939. rvs = MBRunValSign;
  940. MBEncodeVLC(&rvs,NULL, pCurMB->CodedBlocks,
  941. pBitStream, pBitOffset, 0, 0);
  942. #ifdef COUNT_BITS
  943. EC->Bits.Coefs += ((U32) *pBitStream - savebyteptr)*8 - savebitptr + *pBitOffset;
  944. #endif
  945. }
  946. else // Macroblock is empty.
  947. {
  948. PutBits(1, 1, pBitStream, pBitOffset); // COD = 1, empty MB
  949. // Instead of repeating the above test in the PB-frame encoding
  950. // pCurMB->COD can now be tested instead.
  951. pCurMB->COD = 1;
  952. if (EC->u8EncodePBFrame == TRUE)
  953. {
  954. FutrPMBData[curMB].CBPYBitOff = 1;
  955. FutrPMBData[curMB].MVDBitOff = 1;
  956. FutrPMBData[curMB].BlkDataBitOff = 1;
  957. }
  958. #ifdef COUNT_BITS
  959. EC->Bits.MBHeader += 1;
  960. #endif
  961. } // end of else
  962. } // end of if macroblock
  963. else if( (MBType == INTRA) && (EC->PictureHeader.PicCodType == INTERPIC))
  964. {
  965. // Stagger inter code count.
  966. pCurMB->InterCodeCnt = (unsigned char) (StartingMB & 0xf);
  967. /*******************************************
  968. * Write macroblock header to bit stream.
  969. *******************************************/
  970. PutBits(0, 1, pBitStream, pBitOffset); // COD = 0, nonempty MB
  971. #ifdef COUNT_BITS
  972. EC->Bits.num_intra++;
  973. EC->Bits.MBHeader += 1;
  974. EC->Bits.Coded++;
  975. #endif
  976. // Write MCBPC to bitstream.
  977. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  978. index |= (MBType << 2);
  979. PutBits(VLC_MCBPC_INTER[index][1], VLC_MCBPC_INTER[index][0],
  980. pBitStream, pBitOffset);
  981. #ifdef COUNT_BITS
  982. EC->Bits.MBHeader += VLC_MCBPC_INTER[index][0];
  983. EC->Bits.MCBPC += VLC_MCBPC_INTER[index][0];
  984. #endif
  985. // Save bit offset of CBPY data from start of macroblock data
  986. if (EC->u8EncodePBFrame == TRUE)
  987. {
  988. FutrPMBData[curMB].CBPYBitOff
  989. = (U8) ( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  990. - FutrPMBData[curMB].MBStartBitOff);
  991. }
  992. // Write CBPY to bitstream.
  993. index = pCurMB->CodedBlocks & 0xf;
  994. //index = pMBActionStream[curMB].CBPY;
  995. PutBits(VLC_CBPY[index][1], VLC_CBPY[index][0], pBitStream,
  996. pBitOffset);
  997. #ifdef COUNT_BITS
  998. EC->Bits.MBHeader += VLC_CBPY[index][0];
  999. EC->Bits.CBPY += VLC_CBPY[index][0];
  1000. #endif
  1001. //if( bUseDQUANT )
  1002. //{
  1003. // write DQUANT to bit stream here.
  1004. //}
  1005. // Save bit offset of block data from start of macroblock data
  1006. if (EC->u8EncodePBFrame == TRUE)
  1007. {
  1008. FutrPMBData[curMB].BlkDataBitOff = FutrPMBData[curMB].MVDBitOff
  1009. = (U8) ( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  1010. - FutrPMBData[curMB].MBStartBitOff);
  1011. }
  1012. #ifdef COUNT_BITS
  1013. savebyteptr = (U32) *pBitStream;
  1014. savebitptr = (U32) *pBitOffset;
  1015. #endif
  1016. // Encode run/val pairs
  1017. rvs = MBRunValSign;
  1018. MBEncodeVLC(&rvs, NULL, pCurMB->CodedBlocks, pBitStream,
  1019. pBitOffset, 1, 0);
  1020. #ifdef COUNT_BITS
  1021. EC->Bits.Coefs += ((U32) *pBitStream - savebyteptr)*8 - savebitptr + *pBitOffset;
  1022. #endif
  1023. } // end of else
  1024. else if ( (MBType == INTRA) && (EC->PictureHeader.PicCodType == INTRAPIC))
  1025. {
  1026. // Stagger inter code count.
  1027. pCurMB->InterCodeCnt = (unsigned char) (StartingMB & 0xf);
  1028. // An INTRA frame should not be the P-frame in a PB-frame
  1029. ASSERT(EC->u8SavedBFrame == FALSE)
  1030. /*******************************************
  1031. * Write macroblock header to bit stream.
  1032. *******************************************/
  1033. // Write MCBPC to bitstream.
  1034. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  1035. //index = pMBActionStream[curMB].CBPC;
  1036. //index |= bUseDQUANT << 2;
  1037. PutBits(VLC_MCBPC_INTRA[index][1], VLC_MCBPC_INTRA[index][0],
  1038. pBitStream, pBitOffset);
  1039. #ifdef COUNT_BITS
  1040. EC->Bits.num_intra++;
  1041. EC->Bits.MBHeader += VLC_MCBPC_INTRA[index][0];
  1042. EC->Bits.MCBPC += VLC_MCBPC_INTRA[index][0];
  1043. #endif
  1044. // Write CBPY to bitstream.
  1045. index = pCurMB->CodedBlocks & 0xf;
  1046. //index = pMBActionStream[curMB].CBPY;
  1047. PutBits(VLC_CBPY[index][1], VLC_CBPY[index][0],
  1048. pBitStream, pBitOffset);
  1049. #ifdef COUNT_BITS
  1050. EC->Bits.MBHeader += VLC_CBPY[index][0];
  1051. EC->Bits.CBPY += VLC_CBPY[index][0];
  1052. #endif
  1053. //if( bUseDQUANT )
  1054. //{
  1055. // write DQUANT to bit stream here.
  1056. //}
  1057. #ifdef COUNT_BITS
  1058. savebyteptr = (U32) *pBitStream;
  1059. savebitptr = (U32) *pBitOffset;
  1060. #endif
  1061. rvs = MBRunValSign;
  1062. MBEncodeVLC(&rvs, NULL, pCurMB->CodedBlocks,
  1063. pBitStream, pBitOffset, 1, 0);
  1064. #ifdef COUNT_BITS
  1065. EC->Bits.Coefs += ((U32) *pBitStream - savebyteptr)*8 - savebitptr + *pBitOffset;
  1066. #endif
  1067. } // end of else
  1068. else
  1069. ERRORMESSAGE(("%s: Unexpected case in writing MB header VLC\r\n", _fx_));
  1070. // Calculate DQUANT based on bits used in previous MBs.
  1071. // CalcDQUANT();
  1072. if (bRTPHeader)
  1073. H263RTP_UpdateBsInfo(EC, pCurMB, QP, MB, GOB, *pBitStream,
  1074. (U32) *pBitOffset);
  1075. } // for MB
  1076. } // end of GOB_Q_RLE_VLC_WriteBS()
  1077. void GOB_VLC_WriteBS(
  1078. T_H263EncoderCatalog *EC,
  1079. I8 *pMBRVS_Luma,
  1080. I8 *pMBRVS_Chroma,
  1081. U8 **pBitStream,
  1082. U8 *pBitOffset,
  1083. T_FutrPMBData *FutrPMBData, // Start of GOB
  1084. U32 GOB,
  1085. U32 QP,
  1086. BOOL bRTPHeader,
  1087. U32 StartingMB)
  1088. {
  1089. U32 MB, curMB, index;
  1090. U8 bUseDQUANT = 0; // Indicates if DQUANT is present.
  1091. U8 MBType;
  1092. U8 *pFrmStart = EC->pU8_BitStream; // TODO : should be a param.
  1093. U32 GOBHeaderMask, GOBHeaderFlag;
  1094. #ifdef COUNT_BITS
  1095. U32 savebyteptr, savebitptr;
  1096. #endif
  1097. register T_MBlockActionStream *pCurMB;
  1098. FX_ENTRY("GOB_VLC_WriteBS")
  1099. // Create GOB header mask to be used further down.
  1100. GOBHeaderMask = 1 << GOB;
  1101. // Loop through each macroblock of the GOB.
  1102. for(MB = 0, curMB = GOB*EC->NumMBPerRow, pCurMB = EC->pU8_MBlockActionStream + curMB;
  1103. MB < EC->NumMBPerRow; MB++, curMB++, pCurMB++)
  1104. {
  1105. DEBUGMSG(ZONE_ENCODE_MB, ("%s: MB #%d\r\n", _fx_, MB));
  1106. // default COD is coded (= 0). Will be set to 1 only if skipped
  1107. pCurMB->COD = 0;
  1108. if(EC->PictureHeader.PicCodType == INTRAPIC)
  1109. {
  1110. pCurMB->MBType = INTRA;
  1111. MBType = INTRA;
  1112. }
  1113. else
  1114. { // inter picture code type
  1115. if(pCurMB->BlockType == INTERBLOCK)
  1116. {
  1117. pCurMB->MBType = INTER;
  1118. MBType = INTER;
  1119. }
  1120. else if(pCurMB->BlockType == INTER4MV)
  1121. {
  1122. pCurMB->MBType = INTER4V;
  1123. MBType = INTER4V;
  1124. }
  1125. else if(pCurMB->BlockType == INTRABLOCK)
  1126. {
  1127. pCurMB->MBType = INTRA;
  1128. MBType = INTRA;
  1129. }
  1130. else
  1131. {
  1132. ERRORMESSAGE(("%s: Unexpected MacroBlock Type found\r\n", _fx_));
  1133. }
  1134. }
  1135. // Save starting bit offset of the macroblock data from start of
  1136. // of the frame data. The offset for the first macroblock is saved
  1137. // in e3enc.cpp before this routine is called.
  1138. if(EC->u8EncodePBFrame == TRUE && MB != 0)
  1139. {
  1140. FutrPMBData[curMB].MBStartBitOff
  1141. = (U32) (((*pBitStream - pFrmStart)<<3) + *pBitOffset);
  1142. }
  1143. /*
  1144. * Write macroblock header to bit stream.
  1145. */
  1146. if((MBType == INTER) || (MBType == INTER4V))
  1147. {
  1148. // Check if entire macroblock is empty, including zero MV's.
  1149. // If there is only one MV for the block, all block MVs in the
  1150. // structure are still set but are equal.
  1151. if(((pCurMB->CodedBlocks & 0x3f) != 0)
  1152. || (pCurMB->BlkY1.PHMV != 0)
  1153. || (pCurMB->BlkY1.PVMV != 0)
  1154. || (pCurMB->BlkY2.PHMV != 0)
  1155. || (pCurMB->BlkY2.PVMV != 0)
  1156. || (pCurMB->BlkY3.PHMV != 0)
  1157. || (pCurMB->BlkY3.PVMV != 0)
  1158. || (pCurMB->BlkY4.PHMV != 0)
  1159. || (pCurMB->BlkY4.PVMV != 0))
  1160. {
  1161. PutBits(0, 1, pBitStream, pBitOffset); // COD = 0, nonempty MB
  1162. #ifdef COUNT_BITS
  1163. if(MBType == INTER)
  1164. EC->Bits.num_inter++;
  1165. else if (MBType == INTER4V)
  1166. EC->Bits.num_inter4v++;
  1167. EC->Bits.MBHeader += 1;
  1168. EC->Bits.Coded++;
  1169. #endif
  1170. // Increment the InterCoded block count if the block
  1171. // is intercoded (not B frame) and is not empty.
  1172. if (((pCurMB->CodedBlocks & 0x3f) != 0) &&
  1173. ((pCurMB->BlockType == INTERBLOCK) || (pCurMB->BlockType == INTER4MV)))
  1174. {
  1175. // Macroblock is coded. Need to increment inter code count if
  1176. // there are no coefficients: see section 4.4 of the H.263
  1177. // recommendation
  1178. pCurMB->InterCodeCnt++;
  1179. }
  1180. // pCurMB->InterCodeCnt is reset in calcGOBChromaVecs_InterCodeCnt
  1181. /*******************************************
  1182. * Write macroblock header to bit stream.
  1183. *******************************************/
  1184. // Write MCBPC to bitstream.
  1185. // The rightmost two bits are the CBPC (65).
  1186. // Note that this is the reverse of the order in the
  1187. // VLC table in the H.263 spec.
  1188. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  1189. // Add the MB type to next two bits to the left.
  1190. index |= (MBType << 2);
  1191. // Write code to bitstream.
  1192. PutBits(VLC_MCBPC_INTER[index][1], VLC_MCBPC_INTER[index][0],
  1193. pBitStream, pBitOffset);
  1194. #ifdef COUNT_BITS
  1195. EC->Bits.MBHeader += VLC_MCBPC_INTER[index][0];
  1196. EC->Bits.MCBPC += VLC_MCBPC_INTER[index][0];
  1197. #endif
  1198. // Save bit offset of CBPY data from start of macroblock data
  1199. // if PB frame is on since we will reuse this later.
  1200. if(EC->u8EncodePBFrame == TRUE)
  1201. {
  1202. FutrPMBData[curMB].CBPYBitOff
  1203. = (U8)( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  1204. - FutrPMBData[curMB].MBStartBitOff);
  1205. }
  1206. // Write CBPY to bitstream.
  1207. index = pCurMB->CodedBlocks & 0xf;
  1208. index = (~index) & 0xf;
  1209. PutBits(VLC_CBPY[index][1], VLC_CBPY[index][0], pBitStream, pBitOffset);
  1210. #ifdef COUNT_BITS
  1211. EC->Bits.MBHeader += VLC_CBPY[index][0];
  1212. EC->Bits.CBPY += VLC_CBPY[index][0];
  1213. #endif
  1214. //if(bUseDQUANT)
  1215. //{
  1216. // TODO: write DQUANT to bit stream here. We can only do
  1217. // this if MBtype is not INTER4V since that type doesn't
  1218. // allow quantizer as well.
  1219. //}
  1220. // Save bit offset of CBPY data from start of macroblock data
  1221. if(EC->u8EncodePBFrame == TRUE)
  1222. {
  1223. FutrPMBData[curMB].MVDBitOff
  1224. = (U8)( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  1225. - FutrPMBData[curMB].MBStartBitOff);
  1226. }
  1227. // Write motion vectors to bit stream.
  1228. if((EC->GOBHeaderPresent & GOBHeaderMask) != 0)
  1229. {
  1230. GOBHeaderFlag = TRUE;
  1231. }
  1232. else
  1233. {
  1234. GOBHeaderFlag = FALSE;
  1235. }
  1236. writeP_MVD(
  1237. curMB, // Current MB number.
  1238. pCurMB, // pointer to current MB action desc. struct.
  1239. EC->NumMBPerRow,
  1240. EC->NumMBs,
  1241. pBitStream,
  1242. pBitOffset,
  1243. GOBHeaderFlag,
  1244. EC);
  1245. // Save bit offset of block data from start of MB data
  1246. if(EC->u8EncodePBFrame == TRUE)
  1247. {
  1248. FutrPMBData[curMB].BlkDataBitOff
  1249. = (U8) ( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  1250. - FutrPMBData[curMB].MBStartBitOff);
  1251. }
  1252. /*
  1253. * Encode intra DC and all run/val pairs.
  1254. */
  1255. #ifdef COUNT_BITS
  1256. savebyteptr = (U32) *pBitStream;
  1257. savebitptr = (U32) *pBitOffset;
  1258. #endif
  1259. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma, pCurMB->CodedBlocks,
  1260. pBitStream, pBitOffset, 0, 1);
  1261. #ifdef COUNT_BITS
  1262. EC->Bits.Coefs += ((U32) *pBitStream - savebyteptr)*8 - savebitptr + *pBitOffset;
  1263. #endif
  1264. }
  1265. else
  1266. { // Macroblock is empty.
  1267. PutBits(1, 1, pBitStream, pBitOffset); // COD = 1, empty MB
  1268. // Instead of repeating the above test in the PB-frame encoding
  1269. // pCurMB->COD can now be tested instead.
  1270. pCurMB->COD = 1;
  1271. if(EC->u8EncodePBFrame == TRUE)
  1272. {
  1273. FutrPMBData[curMB].CBPYBitOff = 1;
  1274. FutrPMBData[curMB].MVDBitOff = 1;
  1275. FutrPMBData[curMB].BlkDataBitOff = 1;
  1276. }
  1277. #ifdef COUNT_BITS
  1278. EC->Bits.MBHeader += 1;
  1279. #endif
  1280. } // end of else
  1281. }
  1282. else if( (MBType == INTRA) && (EC->PictureHeader.PicCodType == INTERPIC))
  1283. {
  1284. // Stagger inter code count.
  1285. pCurMB->InterCodeCnt = (unsigned char) (StartingMB & 0xf);
  1286. /*******************************************
  1287. * Write macroblock header to bit stream.
  1288. *******************************************/
  1289. PutBits(0, 1, pBitStream, pBitOffset); // COD = 0, nonempty MB
  1290. #ifdef COUNT_BITS
  1291. EC->Bits.num_intra++;
  1292. EC->Bits.MBHeader += 1;
  1293. EC->Bits.Coded++;
  1294. #endif
  1295. // Write MCBPC to bitstream.
  1296. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  1297. index |= (MBType << 2);
  1298. PutBits(VLC_MCBPC_INTER[index][1], VLC_MCBPC_INTER[index][0], pBitStream, pBitOffset);
  1299. #ifdef COUNT_BITS
  1300. EC->Bits.MBHeader += VLC_MCBPC_INTER[index][0];
  1301. EC->Bits.MCBPC += VLC_MCBPC_INTER[index][0];
  1302. #endif
  1303. // Save bit offset of CBPY data from start of macroblock data
  1304. if(EC->u8EncodePBFrame == TRUE)
  1305. {
  1306. FutrPMBData[curMB].CBPYBitOff
  1307. = (U8) ( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  1308. - FutrPMBData[curMB].MBStartBitOff);
  1309. }
  1310. // Write CBPY to bitstream.
  1311. index = pCurMB->CodedBlocks & 0xf;
  1312. //index = pMBActionStream[curMB].CBPY;
  1313. PutBits(VLC_CBPY[index][1], VLC_CBPY[index][0], pBitStream, pBitOffset);
  1314. #ifdef COUNT_BITS
  1315. EC->Bits.MBHeader += VLC_CBPY[index][0];
  1316. EC->Bits.CBPY += VLC_CBPY[index][0];
  1317. #endif
  1318. //if( bUseDQUANT )
  1319. //{
  1320. // write DQUANT to bit stream here.
  1321. //}
  1322. // Save bit offset of block data from start of macroblock data
  1323. if(EC->u8EncodePBFrame == TRUE)
  1324. {
  1325. FutrPMBData[curMB].BlkDataBitOff = FutrPMBData[curMB].MVDBitOff
  1326. = (U8) ( ((*pBitStream - pFrmStart)<<3) + *pBitOffset
  1327. - FutrPMBData[curMB].MBStartBitOff);
  1328. }
  1329. #ifdef COUNT_BITS
  1330. savebyteptr = (U32) *pBitStream;
  1331. savebitptr = (U32) *pBitOffset;
  1332. #endif
  1333. // Encode run/val pairs
  1334. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma, pCurMB->CodedBlocks,
  1335. pBitStream, pBitOffset, 1, 1);
  1336. #ifdef COUNT_BITS
  1337. EC->Bits.Coefs += ((U32) *pBitStream - savebyteptr)*8 - savebitptr + *pBitOffset;
  1338. #endif
  1339. }
  1340. else if ( (MBType == INTRA) && (EC->PictureHeader.PicCodType == INTRAPIC))
  1341. {
  1342. // Stagger inter code count.
  1343. pCurMB->InterCodeCnt = (unsigned char) (StartingMB & 0xf);
  1344. // An INTRA frame should not be the P-frame in a PB-frame
  1345. ASSERT(EC->u8SavedBFrame == FALSE)
  1346. /*******************************************
  1347. * Write macroblock header to bit stream.
  1348. *******************************************/
  1349. // Write MCBPC to bitstream.
  1350. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  1351. //index = pMBActionStream[curMB].CBPC;
  1352. //index |= bUseDQUANT << 2;
  1353. PutBits(VLC_MCBPC_INTRA[index][1], VLC_MCBPC_INTRA[index][0], pBitStream, pBitOffset);
  1354. #ifdef COUNT_BITS
  1355. EC->Bits.num_intra++;
  1356. EC->Bits.MBHeader += VLC_MCBPC_INTRA[index][0];
  1357. EC->Bits.MCBPC += VLC_MCBPC_INTRA[index][0];
  1358. #endif
  1359. // Write CBPY to bitstream.
  1360. index = pCurMB->CodedBlocks & 0xf;
  1361. //index = pMBActionStream[curMB].CBPY;
  1362. PutBits(VLC_CBPY[index][1], VLC_CBPY[index][0], pBitStream, pBitOffset);
  1363. #ifdef COUNT_BITS
  1364. EC->Bits.MBHeader += VLC_CBPY[index][0];
  1365. EC->Bits.CBPY += VLC_CBPY[index][0];
  1366. #endif
  1367. //if( bUseDQUANT )
  1368. //{
  1369. // write DQUANT to bit stream here.
  1370. //}
  1371. #ifdef COUNT_BITS
  1372. savebyteptr = (U32) *pBitStream;
  1373. savebitptr = (U32) *pBitOffset;
  1374. #endif
  1375. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma, pCurMB->CodedBlocks,
  1376. pBitStream, pBitOffset, 1, 1);
  1377. #ifdef COUNT_BITS
  1378. EC->Bits.Coefs += ((U32) *pBitStream - savebyteptr)*8 - savebitptr + *pBitOffset;
  1379. #endif
  1380. }
  1381. else
  1382. ERRORMESSAGE(("%s: Unexpected case in writing MB header VLC\r\n", _fx_));
  1383. // Calculate DQUANT based on bits used in previous MBs.
  1384. // CalcDQUANT();
  1385. if (bRTPHeader)
  1386. H263RTP_UpdateBsInfo(EC, pCurMB, QP, MB, GOB, *pBitStream,
  1387. (U32) *pBitOffset);
  1388. } // for MB
  1389. } // end of GOB_VLC_WriteBS()
  1390. /*************************************************************
  1391. * Name: PB_GOB_Q_RLE_VLC_WriteBS
  1392. * Description: Write out GOB layer bits for GOB number "GOB".
  1393. * Parameters:
  1394. * EC Encoder catalog
  1395. * DCTCoefs Pointer to DCT coefficients for the GOB
  1396. * pP_BitStreamStart Pointer to start of bit stream for the future
  1397. * P-frame. Some data from future P frame is copied over
  1398. * to PB-frame.
  1399. * pPB_BitStream Current PB-frame byte pointer
  1400. * pPB_BitOffset Bit offset in the current byte pointed by pPB_BitStream
  1401. * FutrPMBData Bit stream info on future P-frame. This info. is
  1402. * initialized in GOB_Q_RLE_VLC_WriteBS()
  1403. * GOB GOBs are numbered from 0 in a frame.
  1404. * QP Quantization value for B-block coefficients.
  1405. * Side-effects:
  1406. * pPB_BitStream and pPB_BitOffset are modified as a result of writing bits
  1407. * to the stream.
  1408. *************************************************************/
  1409. void PB_GOB_Q_RLE_VLC_WriteBS(
  1410. T_H263EncoderCatalog * EC,
  1411. I32 * DCTCoefs,
  1412. U8 * pP_BitStreamStart,
  1413. U8 ** pPB_BitStream,
  1414. U8 * pPB_BitOffset,
  1415. const T_FutrPMBData * const FutrPMBData,
  1416. const U32 GOB,
  1417. const U32 QP,
  1418. BOOL bRTPHeader
  1419. )
  1420. {
  1421. UN MB;
  1422. U32 curMB, index;
  1423. U32 GOBHeaderMask, GOBHeaderFlag;
  1424. I8 MBRunValSign[65*3*6], *EndAddress, *rvs;
  1425. U8 bUseDQUANT = 0; // Indicates if DQUANT is present.
  1426. U8 emitCBPB, emitMVDB;
  1427. register T_MBlockActionStream *pCurMB;
  1428. FX_ENTRY("PB_GOB_Q_RLE_VLC_WriteBS")
  1429. #ifdef H263P
  1430. // The H.263+ options are currently only available in MMX enabled
  1431. // encoders. If the improved PB-frame mode is desired in non-MMX
  1432. // implementations, the H263P-defined code in PB_GOB_VLC_WriteBS
  1433. // should be mimiced here.
  1434. #endif
  1435. // Create GOB header mask to be used further down.
  1436. GOBHeaderMask = 1 << GOB;
  1437. for (MB = 0, curMB = GOB*EC->NumMBPerRow,
  1438. pCurMB = EC->pU8_MBlockActionStream + curMB;
  1439. MB < EC->NumMBPerRow;
  1440. MB++, curMB++, pCurMB++)
  1441. {
  1442. /*
  1443. * Quantize and RLE each block in the macroblock,
  1444. * skipping empty blocks as denoted by CodedBlocks.
  1445. * If any more blocks are empty after quantization
  1446. * then the appropriate CodedBlocks bit is cleared.
  1447. */
  1448. EndAddress = (I8 *)MB_Quantize_RLE(
  1449. &DCTCoefs,
  1450. (I8 *)MBRunValSign,
  1451. &(pCurMB->CodedBlocksB),
  1452. INTERBLOCK, // B coeffs are INTER-coded
  1453. QP
  1454. );
  1455. #ifdef ENCODE_STATS
  1456. StatsUsedQuant(QP);
  1457. #endif /* ENCODE_STATS */
  1458. // Write MBlock data
  1459. // Check if entire macroblock is empty, including zero MV's.
  1460. if( ((pCurMB->MBType == INTER)
  1461. || (pCurMB->MBType == INTER4V))
  1462. && (pCurMB->COD == 1) )
  1463. {
  1464. if( ((pCurMB->CodedBlocksB & 0x3f) == 0)
  1465. && (pCurMB->BlkY1.BHMV == 0)
  1466. && (pCurMB->BlkY1.BVMV == 0))
  1467. {
  1468. // P-mblock not coded, and neither is PB-mblock.
  1469. // COD = 1, empty MB.
  1470. // If it is the first MB in the GOb, then GOB header
  1471. // is also copied
  1472. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1473. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff,// src
  1474. FutrPMBData[curMB+1].MBStartBitOff // len
  1475. - FutrPMBData[curMB].MBStartBitOff);
  1476. }
  1477. else // Macro block is not empty.
  1478. {
  1479. // Copy COD and MCBPC
  1480. // If it is the first MB in the GOB, then GOB header
  1481. // is also copied.
  1482. if (FutrPMBData[curMB+1].MBStartBitOff - FutrPMBData[curMB].MBStartBitOff != 1)
  1483. {
  1484. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1485. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff,// src
  1486. FutrPMBData[curMB+1].MBStartBitOff // len
  1487. - FutrPMBData[curMB].MBStartBitOff - 1);
  1488. }
  1489. PutBits(0, 1, pPB_BitStream, pPB_BitOffset); // COD = 0, nonempty MB
  1490. /*******************************************
  1491. * Write macroblock header to bit stream.
  1492. *******************************************/
  1493. // Write MCBPC to bitstream.
  1494. // The rightmost two bits are the CBPC (65).
  1495. // Note that this is the reverse of the order in the
  1496. // VLC table in the H.263 spec.
  1497. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  1498. // Add the MB type to next two bits to the left.
  1499. index |= (pCurMB->MBType << 2);
  1500. // Write code to bitstream.
  1501. PutBits(VLC_MCBPC_INTER[index][1], VLC_MCBPC_INTER[index][0],
  1502. pPB_BitStream, pPB_BitOffset);
  1503. // Write MODB
  1504. if ((pCurMB->CodedBlocksB & 0x3f) == 0)
  1505. {
  1506. emitCBPB = 0;
  1507. }
  1508. else
  1509. {
  1510. emitCBPB = 1;
  1511. }
  1512. if (((pCurMB->BlkY1.BHMV != 0)
  1513. || (pCurMB->BlkY1.BVMV != 0))
  1514. || emitCBPB == 1)
  1515. {
  1516. emitMVDB = 1;
  1517. }
  1518. else
  1519. {
  1520. emitMVDB = 0;
  1521. }
  1522. index = (emitMVDB<<1) | emitCBPB;
  1523. PutBits(VLC_MODB[index][1], VLC_MODB[index][0],
  1524. pPB_BitStream, pPB_BitOffset);
  1525. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: MB=%d emitCBPB=%d emitMVDB=%d MODB=%d\r\n", _fx_, curMB, (int)emitCBPB, (int)emitMVDB, (int)VLC_MODB[index][1]));
  1526. // Write CBPB
  1527. if (emitCBPB)
  1528. {
  1529. PutBits(VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)],
  1530. 6, pPB_BitStream, pPB_BitOffset);
  1531. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: CBPB=0x%x\r\n", _fx_, VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)]));
  1532. }
  1533. // The P blocks are all empty
  1534. PutBits(3, 2, pPB_BitStream, pPB_BitOffset); // CBPY = 11, no coded P blocks
  1535. //if( bUseDQUANT )
  1536. //{
  1537. // write DQUANT to bit stream here.
  1538. //}
  1539. // Write MVD{2-4}
  1540. // Note: MVD cannot be copied from future frame because
  1541. // predictors are different for PB-frame (G.2)
  1542. if( (EC->GOBHeaderPresent & GOBHeaderMask) != 0 )
  1543. {
  1544. GOBHeaderFlag = TRUE;
  1545. }
  1546. else
  1547. {
  1548. GOBHeaderFlag = FALSE;
  1549. }
  1550. writePB_MVD(curMB, pCurMB, EC->NumMBPerRow, EC->NumMBs,
  1551. pPB_BitStream, pPB_BitOffset, GOBHeaderFlag, EC);
  1552. // Write MVDB
  1553. if (emitMVDB)
  1554. {
  1555. ASSERT(pCurMB->BlkY1.BHMV >= -32 && pCurMB->BlkY1.BHMV <= 31)
  1556. ASSERT(pCurMB->BlkY1.BVMV >= -32 && pCurMB->BlkY1.BVMV <= 31)
  1557. // Write horizontal motion vector
  1558. index = (pCurMB->BlkY1.BHMV + 32)*2;
  1559. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index),
  1560. pPB_BitStream, pPB_BitOffset);
  1561. // Write vertical motion vector
  1562. index = (pCurMB->BlkY1.BVMV + 32)*2;
  1563. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index),
  1564. pPB_BitStream, pPB_BitOffset);
  1565. }
  1566. // There is no P-mblock blk data
  1567. // B-frame block data is always INTER-coded (last param is 0)
  1568. if (emitCBPB)
  1569. {
  1570. rvs = MBRunValSign;
  1571. #ifdef H263P
  1572. MBEncodeVLC(&rvs, NULL, (pCurMB->CodedBlocksB & 0x3f),
  1573. pPB_BitStream, pPB_BitOffset, 0, 0);
  1574. #else
  1575. MBEncodeVLC(&rvs, NULL, pCurMB->CodedBlocksB,
  1576. pPB_BitStream, pPB_BitOffset, 0, 0);
  1577. #endif
  1578. }
  1579. } // end of else
  1580. }
  1581. else
  1582. {
  1583. // Copy COD and MCBPC
  1584. // If it is the first MB in the GOB, then GOB header
  1585. // is also copied.
  1586. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1587. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff,// src
  1588. FutrPMBData[curMB].CBPYBitOff); // len
  1589. // Write MODB
  1590. if ((pCurMB->CodedBlocksB & 0x3f) == 0)
  1591. {
  1592. emitCBPB = 0;
  1593. }
  1594. else
  1595. {
  1596. emitCBPB = 1;
  1597. }
  1598. if (((pCurMB->BlkY1.BHMV != 0)
  1599. || (pCurMB->BlkY1.BVMV != 0))
  1600. || emitCBPB == 1)
  1601. {
  1602. emitMVDB = 1;
  1603. }
  1604. else
  1605. {
  1606. emitMVDB = 0;
  1607. }
  1608. index = (emitMVDB<<1) | emitCBPB;
  1609. PutBits(VLC_MODB[index][1], VLC_MODB[index][0],
  1610. pPB_BitStream, pPB_BitOffset);
  1611. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: MB=%d emitCBPB=%d emitMVDB=%d MODB=%d\r\n", _fx_, curMB, (int)emitCBPB, (int)emitMVDB, (int)VLC_MODB[index][1]));
  1612. // Write CBPB
  1613. if (emitCBPB)
  1614. {
  1615. PutBits(VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)],
  1616. 6, pPB_BitStream, pPB_BitOffset);
  1617. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: CBPB=0x%x\r\n", _fx_, VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)]));
  1618. }
  1619. // Copy CBPY, {DQUANT}
  1620. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1621. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff // src
  1622. + FutrPMBData[curMB].CBPYBitOff,
  1623. FutrPMBData[curMB].MVDBitOff // len
  1624. - FutrPMBData[curMB].CBPYBitOff);
  1625. // Write MVD{2-4}
  1626. // Note: MVD cannot be copied from future frame because
  1627. // predictors are different for PB-frame (G.2)
  1628. if( (EC->GOBHeaderPresent & GOBHeaderMask) != 0 )
  1629. {
  1630. GOBHeaderFlag = TRUE;
  1631. }
  1632. else
  1633. {
  1634. GOBHeaderFlag = FALSE;
  1635. }
  1636. writePB_MVD(curMB, pCurMB, EC->NumMBPerRow, EC->NumMBs,
  1637. pPB_BitStream, pPB_BitOffset, GOBHeaderFlag, EC);
  1638. // Write MVDB
  1639. if (emitMVDB)
  1640. {
  1641. ASSERT(pCurMB->BlkY1.BHMV >= -32 && pCurMB->BlkY1.BHMV <= 31)
  1642. ASSERT(pCurMB->BlkY1.BVMV >= -32 && pCurMB->BlkY1.BVMV <= 31)
  1643. // Write horizontal motion vector
  1644. index = (pCurMB->BlkY1.BHMV + 32)*2;
  1645. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index),
  1646. pPB_BitStream, pPB_BitOffset);
  1647. // Write vertical motion vector
  1648. index = (pCurMB->BlkY1.BVMV + 32)*2;
  1649. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index),
  1650. pPB_BitStream, pPB_BitOffset);
  1651. }
  1652. // Copy P-mblock blk data
  1653. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1654. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff // src
  1655. + FutrPMBData[curMB].BlkDataBitOff,
  1656. FutrPMBData[curMB+1].MBStartBitOff // len
  1657. - FutrPMBData[curMB].MBStartBitOff
  1658. - FutrPMBData[curMB].BlkDataBitOff);
  1659. // B-frame block data is always INTER-coded (last param is 0)
  1660. if (emitCBPB)
  1661. {
  1662. rvs = MBRunValSign;
  1663. #ifdef H263P
  1664. MBEncodeVLC(&rvs, NULL, (pCurMB->CodedBlocksB & 0x3f),
  1665. pPB_BitStream, pPB_BitOffset, 0, 0);
  1666. #else
  1667. MBEncodeVLC(&rvs, NULL, pCurMB->CodedBlocksB,
  1668. pPB_BitStream, pPB_BitOffset, 0, 0);
  1669. #endif
  1670. }
  1671. } // end of else
  1672. if (bRTPHeader)
  1673. H263RTP_UpdateBsInfo(EC, pCurMB, QP, MB, GOB, *pPB_BitStream,
  1674. (U32) *pPB_BitOffset);
  1675. } // for MB
  1676. } // end of PB_GOB_Q_RLE_VLC_WriteBS()
  1677. /*************************************************************
  1678. * Name: PB_GOB_VLC_WriteBS
  1679. * Description: Write out GOB layer bits for GOB number "GOB".
  1680. * Parameters:
  1681. * EC Encoder catalog
  1682. * pMBRVS_Luma Quantized DCT coeffs. of B-block luma
  1683. * pMBRVS_Chroma Quantized DCT coeffs. of B-block chroma
  1684. * pP_BitStreamStart Pointer to start of bit stream for the future
  1685. * P-frame. Some data from future P frame is copied over
  1686. * to PB-frame.
  1687. * pPB_BitStream Current PB-frame byte pointer
  1688. * pPB_BitOffset Bit offset in the current byte pointed by pPB_BitStream
  1689. * FutrPMBData Bit stream info on future P-frame. This info. is
  1690. * initialized in GOB_Q_RLE_VLC_WriteBS()
  1691. * GOB GOBs are numbered from 0 in a frame.
  1692. * QP Quantization value for B-block coefficients.
  1693. * Side-effects:
  1694. * pPB_BitStream and pPB_BitOffset are modified as a result of writing bits
  1695. * to the stream.
  1696. * Notes:
  1697. * The improved PB-frame mode of H.263+ is currently only available in
  1698. * MMX enabled versions of the encoder. This routine is the MMX equivalent
  1699. * of PB_GOB_Q_RLE_VLC_WriteBS(), which does not contain the H.263+
  1700. * modifications.
  1701. *************************************************************/
  1702. void PB_GOB_VLC_WriteBS(
  1703. T_H263EncoderCatalog * EC,
  1704. I8 * pMBRVS_Luma,
  1705. I8 * pMBRVS_Chroma,
  1706. U8 * pP_BitStreamStart,
  1707. U8 ** pPB_BitStream,
  1708. U8 * pPB_BitOffset,
  1709. const T_FutrPMBData * const FutrPMBData,
  1710. const U32 GOB,
  1711. const U32 QP,
  1712. BOOL bRTPHeader
  1713. )
  1714. {
  1715. UN MB;
  1716. U32 curMB, index;
  1717. U32 GOBHeaderMask, GOBHeaderFlag;
  1718. U8 bUseDQUANT = 0; // Indicates if DQUANT is present.
  1719. U8 emitCBPB, emitMVDB;
  1720. register T_MBlockActionStream *pCurMB;
  1721. FX_ENTRY("PB_GOB_VLC_WriteBS")
  1722. // Create GOB header mask to be used further down.
  1723. GOBHeaderMask = 1 << GOB;
  1724. for (MB = 0, curMB = GOB*EC->NumMBPerRow,
  1725. pCurMB = EC->pU8_MBlockActionStream + curMB;
  1726. MB < EC->NumMBPerRow;
  1727. MB++, curMB++, pCurMB++)
  1728. {
  1729. /*
  1730. * Quantize and RLE each block in the macroblock,
  1731. * skipping empty blocks as denoted by CodedBlocks.
  1732. * If any more blocks are empty after quantization
  1733. * then the appropriate CodedBlocks bit is cleared.
  1734. */
  1735. // Write MBlock data
  1736. // Check if entire macroblock is empty, including zero MV's.
  1737. if(((pCurMB->MBType == INTER)
  1738. || (pCurMB->MBType == INTER4V))
  1739. && (pCurMB->COD == 1) )
  1740. {
  1741. #ifdef H263P
  1742. // If forward prediction selected for B block, macroblock is not empty
  1743. if( ((pCurMB->CodedBlocksB & 0x3f) == 0)
  1744. && (pCurMB->BlkY1.BHMV == 0)
  1745. && (pCurMB->BlkY1.BVMV == 0)
  1746. && ((pCurMB->CodedBlocksB & 0x80) == 0)) // forward pred. not selected
  1747. #else
  1748. if( ((pCurMB->CodedBlocksB & 0x3f) == 0)
  1749. && (pCurMB->BlkY1.BHMV == 0)
  1750. && (pCurMB->BlkY1.BVMV == 0))
  1751. #endif
  1752. {
  1753. // P-mblock not coded, and neither is PB-mblock.
  1754. // COD = 1, empty MB.
  1755. // If it is the first MB in the GOb, then GOB header
  1756. // is also copied
  1757. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1758. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff, // src
  1759. FutrPMBData[curMB+1].MBStartBitOff // len
  1760. - FutrPMBData[curMB].MBStartBitOff);
  1761. }
  1762. else
  1763. { // Macro block is not empty.
  1764. // Copy COD and MCBPC
  1765. // If it is the first MB in the GOB, then GOB header
  1766. // is also copied.
  1767. if(FutrPMBData[curMB+1].MBStartBitOff - FutrPMBData[curMB].MBStartBitOff != 1)
  1768. {
  1769. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1770. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff, // src
  1771. FutrPMBData[curMB+1].MBStartBitOff // len
  1772. - FutrPMBData[curMB].MBStartBitOff - 1);
  1773. }
  1774. PutBits(0, 1, pPB_BitStream, pPB_BitOffset); // COD = 0, nonempty MB
  1775. /*******************************************
  1776. * Write macroblock header to bit stream.
  1777. *******************************************/
  1778. // Write MCBPC to bitstream.
  1779. // The rightmost two bits are the CBPC (65).
  1780. // Note that this is the reverse of the order in the
  1781. // VLC table in the H.263 spec.
  1782. index = (pCurMB->CodedBlocks >> 4) & 0x3;
  1783. // Add the MB type to next two bits to the left.
  1784. index |= (pCurMB->MBType << 2);
  1785. // Write code to bitstream.
  1786. PutBits(VLC_MCBPC_INTER[index][1], VLC_MCBPC_INTER[index][0], pPB_BitStream, pPB_BitOffset);
  1787. // Write MODB
  1788. if((pCurMB->CodedBlocksB & 0x3f) == 0)
  1789. {
  1790. emitCBPB = 0;
  1791. }
  1792. else
  1793. {
  1794. emitCBPB = 1;
  1795. }
  1796. #ifdef H263P
  1797. if (EC->PictureHeader.PB == ON && EC->PictureHeader.ImprovedPB == ON)
  1798. {
  1799. // include MVDB only if forward prediction selected
  1800. // for bidirectional prediction, MVd = [0, 0]
  1801. if (pCurMB->CodedBlocksB & 0x80)
  1802. {
  1803. emitMVDB = 1;
  1804. }
  1805. else
  1806. {
  1807. emitMVDB = 0;
  1808. }
  1809. }
  1810. else
  1811. #endif // H263P
  1812. {
  1813. if(((pCurMB->BlkY1.BHMV != 0) || (pCurMB->BlkY1.BVMV != 0)) || emitCBPB == 1)
  1814. {
  1815. emitMVDB = 1;
  1816. }
  1817. else {
  1818. emitMVDB = 0;
  1819. }
  1820. }
  1821. #ifdef H263P
  1822. if (EC->PictureHeader.PB == ON && EC->PictureHeader.ImprovedPB == ON)
  1823. {
  1824. if (!emitCBPB) {
  1825. if (!emitMVDB)
  1826. // Bidirectional prediction with all empty blocks
  1827. index = 0;
  1828. else
  1829. // Forward prediction with all empty blocks
  1830. index = 1;
  1831. } else {
  1832. if (emitMVDB)
  1833. // Forward prediction with non-empty blocks
  1834. index = 2;
  1835. else
  1836. // Bidirectional prediction with non-empty blocks
  1837. index = 3;
  1838. }
  1839. PutBits(VLC_IMPROVED_PB_MODB[index][1], VLC_IMPROVED_PB_MODB[index][0],
  1840. pPB_BitStream, pPB_BitOffset);
  1841. DbgLog((LOG_TRACE,6,TEXT("MB=%d emitCBPB=%d emitMVDB=%d MODB=%d"),
  1842. curMB, (int)emitCBPB, (int)emitMVDB,
  1843. (int)VLC_IMPROVED_PB_MODB[index][1]));
  1844. }
  1845. else // not using improved PB-frame mode
  1846. #endif // H263P
  1847. {
  1848. index = (emitMVDB<<1) | emitCBPB;
  1849. PutBits(VLC_MODB[index][1], VLC_MODB[index][0], pPB_BitStream, pPB_BitOffset);
  1850. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: MB=%d emitCBPB=%d emitMVDB=%d MODB=%d\r\n", _fx_, curMB, (int)emitCBPB, (int)emitMVDB, (int)VLC_MODB[index][1]));
  1851. }
  1852. // Write CBPB
  1853. if(emitCBPB) {
  1854. PutBits(VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)], 6, pPB_BitStream, pPB_BitOffset);
  1855. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: CBPB=0x%x\r\n", _fx_, VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)]));
  1856. }
  1857. PutBits(3, 2, pPB_BitStream, pPB_BitOffset); // CBPY = 11, no coded P blocks
  1858. //if( bUseDQUANT )
  1859. //{
  1860. // write DQUANT to bit stream here.
  1861. //}
  1862. // Write MVD{2-4}
  1863. // Note: MVD cannot be copied from future frame because
  1864. // predictors are different for PB-frame (G.2)
  1865. if((EC->GOBHeaderPresent & GOBHeaderMask) != 0)
  1866. {
  1867. GOBHeaderFlag = TRUE;
  1868. }
  1869. else
  1870. {
  1871. GOBHeaderFlag = FALSE;
  1872. }
  1873. writePB_MVD(curMB, pCurMB, EC->NumMBPerRow, EC->NumMBs,
  1874. pPB_BitStream, pPB_BitOffset, GOBHeaderFlag, EC);
  1875. // Write MVDB
  1876. if (emitMVDB)
  1877. {
  1878. ASSERT(pCurMB->BlkY1.BHMV >= -32 && pCurMB->BlkY1.BHMV <= 31)
  1879. ASSERT(pCurMB->BlkY1.BVMV >= -32 && pCurMB->BlkY1.BVMV <= 31)
  1880. // Write horizontal motion vector
  1881. index = (pCurMB->BlkY1.BHMV + 32)*2;
  1882. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  1883. // Write vertical motion vector
  1884. index = (pCurMB->BlkY1.BVMV + 32)*2;
  1885. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  1886. }
  1887. // There is no P-mblock blk data
  1888. // B-frame block data is always INTER-coded (last param is 0)
  1889. if (emitCBPB)
  1890. {
  1891. #ifdef H263P
  1892. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma, (pCurMB->CodedBlocksB & 0x3f),
  1893. pPB_BitStream, pPB_BitOffset, 0, 1);
  1894. #else
  1895. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma, pCurMB->CodedBlocksB,
  1896. pPB_BitStream, pPB_BitOffset, 0, 1);
  1897. #endif
  1898. }
  1899. } // end of else
  1900. }
  1901. else
  1902. {
  1903. // Copy COD and MCBPC
  1904. // If it is the first MB in the GOB, then GOB header
  1905. // is also copied.
  1906. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1907. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff, // src
  1908. FutrPMBData[curMB].CBPYBitOff); // len
  1909. // Write MODB
  1910. if((pCurMB->CodedBlocksB & 0x3f) == 0)
  1911. {
  1912. emitCBPB = 0;
  1913. }
  1914. else
  1915. {
  1916. emitCBPB = 1;
  1917. }
  1918. #ifdef H263P
  1919. if (EC->PictureHeader.PB == ON && EC->PictureHeader.ImprovedPB == ON)
  1920. {
  1921. // include MVDB only if forward prediction selected
  1922. // for bidirectional prediction, MVd = [0, 0]
  1923. if (pCurMB->CodedBlocksB & 0x80)
  1924. {
  1925. emitMVDB = 1;
  1926. }
  1927. else
  1928. {
  1929. emitMVDB = 0;
  1930. }
  1931. }
  1932. else
  1933. #endif // H263P
  1934. {
  1935. if(((pCurMB->BlkY1.BHMV != 0) || (pCurMB->BlkY1.BVMV != 0)) || emitCBPB == 1)
  1936. {
  1937. emitMVDB = 1;
  1938. }
  1939. else {
  1940. emitMVDB = 0;
  1941. }
  1942. }
  1943. #ifdef H263P
  1944. if (EC->PictureHeader.PB == ON && EC->PictureHeader.ImprovedPB == ON)
  1945. {
  1946. if (!emitCBPB) {
  1947. if (!emitMVDB)
  1948. // Bidirectional prediction with all empty blocks
  1949. index = 0;
  1950. else
  1951. // Forward prediction with all empty blocks
  1952. index = 1;
  1953. } else {
  1954. if (emitMVDB)
  1955. // Forward prediction with non-empty blocks
  1956. index = 2;
  1957. else
  1958. // Bidirectional prediction with non-empty blocks
  1959. index = 3;
  1960. }
  1961. PutBits(VLC_IMPROVED_PB_MODB[index][1], VLC_IMPROVED_PB_MODB[index][0],
  1962. pPB_BitStream, pPB_BitOffset);
  1963. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: MB=%d emitCBPB=%d emitMVDB=%d MODB=%d\r\n", _fx_, curMB, (int)emitCBPB, (int)emitMVDB, (int)VLC_IMPROVED_PB_MODB[index][1]));
  1964. }
  1965. else // not using improved PB-frame mode
  1966. #endif // H263P
  1967. {
  1968. index = (emitMVDB<<1) | emitCBPB;
  1969. PutBits(VLC_MODB[index][1], VLC_MODB[index][0], pPB_BitStream, pPB_BitOffset);
  1970. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: MB=%d emitCBPB=%d emitMVDB=%d MODB=%d\r\n", _fx_, curMB, (int)emitCBPB, (int)emitMVDB, (int)VLC_MODB[index][1]));
  1971. }
  1972. // Write CBPB
  1973. if (emitCBPB) {
  1974. PutBits(VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)], 6, pPB_BitStream, pPB_BitOffset);
  1975. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: CBPB=0x%x\r\n", _fx_, VLC_CBPB[(pCurMB->CodedBlocksB & 0x3f)]));
  1976. }
  1977. // Copy CBPY, {DQUANT}
  1978. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  1979. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff // src
  1980. + FutrPMBData[curMB].CBPYBitOff, FutrPMBData[curMB].MVDBitOff // len
  1981. - FutrPMBData[curMB].CBPYBitOff);
  1982. // Write MVD{2-4}
  1983. // Note: MVD cannot be copied from future frame because
  1984. // predictors are different for PB-frame (G.2)
  1985. if((EC->GOBHeaderPresent & GOBHeaderMask) != 0)
  1986. {
  1987. GOBHeaderFlag = TRUE;
  1988. }
  1989. else
  1990. {
  1991. GOBHeaderFlag = FALSE;
  1992. }
  1993. writePB_MVD(curMB, pCurMB, EC->NumMBPerRow, EC->NumMBs,
  1994. pPB_BitStream, pPB_BitOffset, GOBHeaderFlag, EC);
  1995. // Write MVDB
  1996. if (emitMVDB)
  1997. {
  1998. ASSERT(pCurMB->BlkY1.BHMV >= -32 && pCurMB->BlkY1.BHMV <= 31)
  1999. ASSERT(pCurMB->BlkY1.BVMV >= -32 && pCurMB->BlkY1.BVMV <= 31)
  2000. // Write horizontal motion vector
  2001. index = (pCurMB->BlkY1.BHMV + 32)*2;
  2002. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  2003. // Write vertical motion vector
  2004. index = (pCurMB->BlkY1.BVMV + 32)*2;
  2005. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  2006. }
  2007. // Copy P-mblock blk data
  2008. CopyBits(pPB_BitStream, pPB_BitOffset, // dest
  2009. pP_BitStreamStart, FutrPMBData[curMB].MBStartBitOff // src
  2010. + FutrPMBData[curMB].BlkDataBitOff,
  2011. FutrPMBData[curMB+1].MBStartBitOff // len
  2012. - FutrPMBData[curMB].MBStartBitOff
  2013. - FutrPMBData[curMB].BlkDataBitOff);
  2014. // B-frame block data is always INTER-coded (last param is 0)
  2015. if(emitCBPB)
  2016. {
  2017. #ifdef H263P
  2018. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma,
  2019. (pCurMB->CodedBlocksB & 0x3f),
  2020. pPB_BitStream, pPB_BitOffset, 0, 1);
  2021. #else
  2022. MBEncodeVLC(&pMBRVS_Luma, &pMBRVS_Chroma,
  2023. pCurMB->CodedBlocksB,
  2024. pPB_BitStream, pPB_BitOffset, 0, 1);
  2025. #endif
  2026. }
  2027. } // end of else
  2028. if (bRTPHeader)
  2029. H263RTP_UpdateBsInfo(EC, pCurMB, QP, MB, GOB, *pPB_BitStream,
  2030. (U32) *pPB_BitOffset);
  2031. } // for MB
  2032. } // end of PB_GOB_VLC_WriteBS()
  2033. /***************************************************************
  2034. * MB_Quantize_RLE
  2035. * Takes the list of coefficient pairs from the DCT routine
  2036. * and returns a list of Run/Level/Sign triples (each 1 byte)
  2037. * The end of the run/level/sign triples for a block
  2038. * is signalled by an illegal combination (TBD).
  2039. ****************************************************************/
  2040. static I8 * MB_Quantize_RLE(
  2041. I32 **DCTCoefs,
  2042. I8 *MBRunValPairs,
  2043. U8 *CodedBlocks,
  2044. U8 BlockType,
  2045. I32 QP
  2046. )
  2047. {
  2048. int b;
  2049. U8 bitmask = 1;
  2050. I8 * EndAddress;
  2051. #ifdef DEBUG_DCT
  2052. int DCTarray[64];
  2053. #endif
  2054. FX_ENTRY("MB_Quantize_RLE")
  2055. /*
  2056. * Loop through all 6 blocks of macroblock.
  2057. */
  2058. for(b = 0; b < 6; b++, bitmask <<= 1)
  2059. {
  2060. DEBUGMSG(ZONE_ENCODE_MB, ("%s: Block #%d\r\n", _fx_, b));
  2061. // Skip this block if not coded.
  2062. if( (*CodedBlocks & bitmask) == 0)
  2063. continue;
  2064. #ifdef DEBUG_DCT
  2065. cnvt_fdct_output((unsigned short *) *DCTCoefs, DCTarray, (int) BlockType);
  2066. #endif
  2067. /*
  2068. * Quantize and run-length encode a block.
  2069. */
  2070. EndAddress = QUANTRLE(*DCTCoefs, MBRunValPairs, QP, (int)BlockType);
  2071. #ifdef DEBUG
  2072. char *p;
  2073. for(p = (char *)MBRunValPairs; p < (char *)EndAddress; p+=3)
  2074. {
  2075. DEBUGMSG(ZONE_ENCODE_MB, ("%s: (%u, %u, %d)\r\n", _fx_, (unsigned char)*p, (unsigned char)*(p+1), (int)*(p+2)));
  2076. }
  2077. #endif
  2078. // Clear coded block bit for this block.
  2079. if ( EndAddress == MBRunValPairs)
  2080. {
  2081. ASSERT(BlockType != INTRABLOCK) // should have at least INTRADC in an INTRA blck
  2082. *CodedBlocks &= ~bitmask;
  2083. }
  2084. else if ( (EndAddress == (MBRunValPairs+3)) && (BlockType == INTRABLOCK) )
  2085. {
  2086. *CodedBlocks &= ~bitmask;
  2087. MBRunValPairs = EndAddress;
  2088. }
  2089. else
  2090. {
  2091. MBRunValPairs = EndAddress;
  2092. *MBRunValPairs = -1; // Assign an illegal run to signal end of block.
  2093. MBRunValPairs += 3; // Increment to the next triple.
  2094. }
  2095. *DCTCoefs += 32; // Increment DCT Coefficient pointer to next block.
  2096. }
  2097. return MBRunValPairs;
  2098. }
  2099. /*******************************************************************
  2100. * Variable length code teh run/level/sign triples and write the
  2101. * codes to the bitstream.
  2102. *******************************************************************/
  2103. /*
  2104. U8 * MB_VLC_WriteBS()
  2105. {
  2106. for(b = 0; b < 6; b++)
  2107. {
  2108. Block_VLC_WriteBS()
  2109. }
  2110. }
  2111. */
  2112. void InitVLC(void)
  2113. {
  2114. int i, size, code;
  2115. int run, level;
  2116. /*
  2117. * initialize INTRADC fixed length code table.
  2118. */
  2119. for(i = 1; i < 254; i++)
  2120. {
  2121. FLC_INTRADC[i] = i;
  2122. }
  2123. FLC_INTRADC[0] = 1;
  2124. FLC_INTRADC[128] = 255;
  2125. FLC_INTRADC[254] = 254;
  2126. FLC_INTRADC[255] = 254;
  2127. /*
  2128. * Initialize tcoef tables.
  2129. */
  2130. for(i=0; i < 64*12; i++)
  2131. {
  2132. VLC_TCOEF_TBL[i] = 0x0000FFFF;
  2133. }
  2134. for(run=0; run < 64; run++)
  2135. {
  2136. for(level=1; level <= TCOEF_RUN_MAXLEVEL[run].maxlevel; level++)
  2137. {
  2138. size = *(TCOEF_RUN_MAXLEVEL[run].ptable + (level - 1)*2);
  2139. size <<= 16;
  2140. code = *(TCOEF_RUN_MAXLEVEL[run].ptable + (level - 1)*2 +1);
  2141. VLC_TCOEF_TBL[ (run) + (level-1)*64 ] = code;
  2142. VLC_TCOEF_TBL[ (run) + (level-1)*64 ] |= size;
  2143. } // end of for level
  2144. } // end of for run
  2145. /*
  2146. * Initialize last tcoef tables.
  2147. */
  2148. for(i=0; i < 64*3; i++)
  2149. {
  2150. VLC_TCOEF_LAST_TBL[i] = 0x0000FFFF;
  2151. }
  2152. run = 0;
  2153. for(level=1; level <= 3; level++)
  2154. {
  2155. size = *(VLC_TCOEF + 58*2 + (level - 1)*2);
  2156. size <<= 16;
  2157. code = *(VLC_TCOEF + 58*2 + (level - 1)*2 +1);
  2158. VLC_TCOEF_LAST_TBL[ run + (level-1)*64 ] = code;
  2159. VLC_TCOEF_LAST_TBL[ run + (level-1)*64 ] |= size;
  2160. } // end of for level
  2161. run = 1;
  2162. for(level=1; level <= 2; level++)
  2163. {
  2164. size = *(VLC_TCOEF + 61*2 + (level - 1)*2);
  2165. size <<= 16;
  2166. code = *(VLC_TCOEF + 61*2 + (level - 1)*2 +1);
  2167. VLC_TCOEF_LAST_TBL[ run + (level-1)*64 ] = code;
  2168. VLC_TCOEF_LAST_TBL[ run + (level-1)*64 ] |= size;
  2169. } // end of for level
  2170. level=1;
  2171. for(run=2; run <= 40; run++)
  2172. {
  2173. size = *(VLC_TCOEF + 63*2+ (run - 2)*2);
  2174. size <<= 16;
  2175. code = *(VLC_TCOEF + 63*2 + (run - 2)*2 +1);
  2176. VLC_TCOEF_LAST_TBL[ run + (level-1)*64 ] = code;
  2177. VLC_TCOEF_LAST_TBL[ run + (level-1)*64 ] |= size;
  2178. } // end of for run
  2179. } // InitVLC.
  2180. /******************************************************************
  2181. * Name: median
  2182. *
  2183. * Description: Take the median of three signed chars. Implementation taken
  2184. * from the decoder.
  2185. *******************************************************************/
  2186. static char __fastcall median(char v1, char v2, char v3)
  2187. {
  2188. char temp;
  2189. if (v2 < v1)
  2190. {
  2191. temp = v2; v2 = v1; v1 = temp;
  2192. }
  2193. // Invariant : v1 < v2
  2194. if (v2 > v3)
  2195. {
  2196. v2 = (v1 < v3) ? v3 : v1;
  2197. }
  2198. return v2;
  2199. }
  2200. /*************************************************************
  2201. * Name: writeP_MVD
  2202. * Algorithm: See section 6.1.1
  2203. * This routine assumes that there are always four motion
  2204. * vectors per macroblock defined. If there is actually one
  2205. * motion vector in the macroblock, then the four MV fields
  2206. * should be equivalent. In this way the MV predictor for
  2207. * block 1 of the 4 MV case is calculated the same way as the
  2208. * MV predictor for the macroblock in the 1 MV case.
  2209. ************************************************************/
  2210. static void writeP_MVD(
  2211. const U32 curMB,
  2212. T_MBlockActionStream * const pCurMB,
  2213. const U32 NumMBPerRow,
  2214. const U32 NumMBs,
  2215. U8 ** pP_BitStream,
  2216. U8 * pP_BitOffset,
  2217. U32 GOBHeaderPresent,
  2218. T_H263EncoderCatalog *EC
  2219. )
  2220. {
  2221. I8 HMV, VMV, BHMV, BVMV, CHMV, CVMV, DHMV, DVMV;
  2222. I8 HMV1, HMV2, HMV3, VMV1, VMV2, VMV3;
  2223. FX_ENTRY("writeP_MVD")
  2224. //FirstMEState = pCurMB->FirstMEState;
  2225. /*
  2226. * Top left corner of picture of GOB.
  2227. */
  2228. if( (curMB == 0) ||
  2229. ( (GOBHeaderPresent == TRUE) && ((curMB % NumMBPerRow) == 0) ) )
  2230. {
  2231. HMV = 0;
  2232. VMV = 0;
  2233. if(pCurMB->MBType == INTER4V)
  2234. {
  2235. // Predictor for Block 2.
  2236. BHMV = pCurMB->BlkY1.PHMV;
  2237. BVMV = pCurMB->BlkY1.PVMV;
  2238. // Predictor for Block 3.
  2239. HMV1 = VMV1 = 0;
  2240. HMV2 = pCurMB->BlkY1.PHMV;
  2241. HMV3 = pCurMB->BlkY2.PHMV;
  2242. CHMV = median(HMV1, HMV2, HMV3);
  2243. VMV2 = pCurMB->BlkY1.PVMV;
  2244. VMV3 = pCurMB->BlkY2.PVMV;
  2245. CVMV = median(VMV1, VMV2, VMV3);
  2246. // Predictor for Block 4
  2247. HMV1 = pCurMB->BlkY3.PHMV;
  2248. HMV2 = pCurMB->BlkY1.PHMV;
  2249. HMV3 = pCurMB->BlkY2.PHMV;
  2250. DHMV = median(HMV1, HMV2, HMV3);
  2251. VMV1 = pCurMB->BlkY3.PVMV;
  2252. VMV2 = pCurMB->BlkY1.PVMV;
  2253. VMV3 = pCurMB->BlkY2.PVMV;
  2254. DVMV = median(VMV1, VMV2, VMV3);
  2255. } // end of if INTER4V
  2256. }
  2257. /*
  2258. * Upper edge (not corner) or upper right corner of picture
  2259. * or GOB.
  2260. */
  2261. else if( (curMB < NumMBPerRow) ||
  2262. ( (GOBHeaderPresent == TRUE) && ((curMB % NumMBPerRow) > 0) ) )
  2263. {
  2264. register T_MBlockActionStream *pMB1;
  2265. pMB1 = pCurMB - 1;
  2266. HMV = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PHMV : 0);
  2267. VMV = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PVMV : 0);
  2268. if(pCurMB->MBType == INTER4V)
  2269. {
  2270. // Predictor for Block 2.
  2271. BHMV = pCurMB->BlkY1.PHMV;
  2272. BVMV = pCurMB->BlkY1.PVMV;
  2273. // Predictor for Block 3.
  2274. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PHMV : 0);
  2275. HMV2 = pCurMB->BlkY1.PHMV;
  2276. HMV3 = pCurMB->BlkY2.PHMV;
  2277. CHMV = median(HMV1, HMV2, HMV3);
  2278. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PVMV : 0);
  2279. VMV2 = pCurMB->BlkY1.PVMV;
  2280. VMV3 = pCurMB->BlkY2.PVMV;
  2281. CVMV = median(VMV1, VMV2, VMV3);
  2282. // Predictor for Block 4
  2283. HMV1 = pCurMB->BlkY3.PHMV;
  2284. HMV2 = pCurMB->BlkY1.PHMV;
  2285. HMV3 = pCurMB->BlkY2.PHMV;
  2286. DHMV = median(HMV1, HMV2, HMV3);
  2287. VMV1 = pCurMB->BlkY3.PVMV;
  2288. VMV2 = pCurMB->BlkY1.PVMV;
  2289. VMV3 = pCurMB->BlkY2.PVMV;
  2290. DVMV = median(VMV1, VMV2, VMV3);
  2291. } // end of if INTER4V
  2292. }
  2293. /*
  2294. * Central portion of the picture, not next to any edge.
  2295. */
  2296. else if ( ((curMB % NumMBPerRow) != 0) && // not left edge
  2297. (curMB >= NumMBPerRow) && // not top row
  2298. ((curMB % NumMBPerRow) != (NumMBPerRow-1)) && // not right edge
  2299. (curMB < (NumMBs - NumMBPerRow)) ) // not bottom row
  2300. {
  2301. register T_MBlockActionStream *pMB1, *pMB2, *pMB3;
  2302. pMB1 = pCurMB - 1;
  2303. pMB2 = pCurMB - NumMBPerRow;
  2304. pMB3 = pMB2 + 1;
  2305. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PHMV : 0);
  2306. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PHMV : 0);
  2307. HMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PHMV : 0);
  2308. HMV = median(HMV1, HMV2, HMV3);
  2309. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PVMV : 0);
  2310. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PVMV : 0);
  2311. VMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PVMV : 0);
  2312. VMV = median(VMV1, VMV2, VMV3);
  2313. if(pCurMB->MBType == INTER4V)
  2314. {
  2315. // Predictor for Block 2.
  2316. HMV1 = pCurMB->BlkY1.PHMV;
  2317. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PHMV : 0);
  2318. HMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PHMV : 0);
  2319. BHMV = median(HMV1, HMV2, HMV3);
  2320. VMV1 = pCurMB->BlkY1.PVMV;
  2321. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PVMV : 0);
  2322. VMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PVMV : 0);
  2323. BVMV = median(VMV1, VMV2, VMV3);
  2324. // Predictor for Block 3.
  2325. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PHMV : 0);
  2326. HMV2 = pCurMB->BlkY1.PHMV;
  2327. HMV3 = pCurMB->BlkY2.PHMV;
  2328. CHMV = median(HMV1, HMV2, HMV3);
  2329. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PVMV : 0);
  2330. VMV2 = pCurMB->BlkY1.PVMV;
  2331. VMV3 = pCurMB->BlkY2.PVMV;
  2332. CVMV = median(VMV1, VMV2, VMV3);
  2333. // Predictor for Block 4
  2334. HMV1 = pCurMB->BlkY3.PHMV;
  2335. HMV2 = pCurMB->BlkY1.PHMV;
  2336. HMV3 = pCurMB->BlkY2.PHMV;
  2337. DHMV = median(HMV1, HMV2, HMV3);
  2338. VMV1 = pCurMB->BlkY3.PVMV;
  2339. VMV2 = pCurMB->BlkY1.PVMV;
  2340. VMV3 = pCurMB->BlkY2.PVMV;
  2341. DVMV = median(VMV1, VMV2, VMV3);
  2342. } // end of if INTER4V
  2343. }
  2344. /*
  2345. * Left edge or lower left corner.
  2346. */
  2347. else if( (curMB % NumMBPerRow) == 0 )
  2348. {
  2349. register T_MBlockActionStream *pMB2, *pMB3;
  2350. pMB2 = pCurMB - NumMBPerRow;
  2351. pMB3 = pMB2 + 1;
  2352. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PHMV : 0);
  2353. HMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PHMV : 0);
  2354. HMV = median(0, HMV2, HMV3);
  2355. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PVMV : 0);
  2356. VMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PVMV : 0);
  2357. VMV = median(0, VMV2, VMV3);
  2358. if(pCurMB->MBType == INTER4V)
  2359. {
  2360. // Predictor for Block 2.
  2361. HMV1 = pCurMB->BlkY1.PHMV;
  2362. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PHMV : 0);
  2363. HMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PHMV : 0);
  2364. BHMV = median(HMV1, HMV2, HMV3);
  2365. VMV1 = pCurMB->BlkY1.PVMV;
  2366. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PVMV : 0);
  2367. VMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PVMV : 0);
  2368. BVMV = median(VMV1, VMV2, VMV3);
  2369. // Predictor for Block 3.
  2370. HMV1 = 0;
  2371. HMV2 = pCurMB->BlkY1.PHMV;
  2372. HMV3 = pCurMB->BlkY2.PHMV;
  2373. CHMV = median(HMV1, HMV2, HMV3);
  2374. VMV1 = 0;
  2375. VMV2 = pCurMB->BlkY1.PVMV;
  2376. VMV3 = pCurMB->BlkY2.PVMV;
  2377. CVMV = median(VMV1, VMV2, VMV3);
  2378. // Predictor for Block 4
  2379. HMV1 = pCurMB->BlkY3.PHMV;
  2380. HMV2 = pCurMB->BlkY1.PHMV;
  2381. HMV3 = pCurMB->BlkY2.PHMV;
  2382. DHMV = median(HMV1, HMV2, HMV3);
  2383. VMV1 = pCurMB->BlkY3.PVMV;
  2384. VMV2 = pCurMB->BlkY1.PVMV;
  2385. VMV3 = pCurMB->BlkY2.PVMV;
  2386. DVMV = median(VMV1, VMV2, VMV3);
  2387. } // end of if INTER4V
  2388. }
  2389. /*
  2390. * Right edge or lower right corner.
  2391. */
  2392. else if( (curMB % NumMBPerRow) == (NumMBPerRow-1) )
  2393. {
  2394. register T_MBlockActionStream *pMB1, *pMB2;
  2395. pMB1 = pCurMB - 1;
  2396. pMB2 = pCurMB - NumMBPerRow;
  2397. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PHMV : 0);
  2398. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PHMV : 0);
  2399. HMV = median(HMV1, HMV2, 0);
  2400. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PVMV : 0);
  2401. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PVMV : 0);
  2402. VMV = median(VMV1, VMV2, 0);
  2403. if(pCurMB->MBType == INTER4V)
  2404. {
  2405. // Predictor for Block 2.
  2406. HMV1 = pCurMB->BlkY1.PHMV;
  2407. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PHMV : 0);
  2408. HMV3 = 0;
  2409. BHMV = median(HMV1, HMV2, HMV3);
  2410. VMV1 = pCurMB->BlkY1.PVMV;
  2411. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PVMV : 0);
  2412. VMV3 = 0;
  2413. BVMV = median(VMV1, VMV2, VMV3);
  2414. // Predictor for Block 3.
  2415. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PHMV : 0);
  2416. HMV2 = pCurMB->BlkY1.PHMV;
  2417. HMV3 = pCurMB->BlkY2.PHMV;
  2418. CHMV = median(HMV1, HMV2, HMV3);
  2419. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PVMV : 0);
  2420. VMV2 = pCurMB->BlkY1.PVMV;
  2421. VMV3 = pCurMB->BlkY2.PVMV;
  2422. CVMV = median(VMV1, VMV2, VMV3);
  2423. // Predictor for Block 4
  2424. HMV1 = pCurMB->BlkY3.PHMV;
  2425. HMV2 = pCurMB->BlkY1.PHMV;
  2426. HMV3 = pCurMB->BlkY2.PHMV;
  2427. DHMV = median(HMV1, HMV2, HMV3);
  2428. VMV1 = pCurMB->BlkY3.PVMV;
  2429. VMV2 = pCurMB->BlkY1.PVMV;
  2430. VMV3 = pCurMB->BlkY2.PVMV;
  2431. DVMV = median(VMV1, VMV2, VMV3);
  2432. } // end of if INTER4V
  2433. }
  2434. else
  2435. {
  2436. register T_MBlockActionStream *pMB1, *pMB2, *pMB3;
  2437. pMB1 = pCurMB - 1;
  2438. pMB2 = pCurMB - NumMBPerRow;
  2439. pMB3 = pMB2 + 1;
  2440. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PHMV : 0);
  2441. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PHMV : 0);
  2442. HMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PHMV : 0);
  2443. HMV = median(HMV1, HMV2, HMV3);
  2444. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY2.PVMV : 0);
  2445. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY3.PVMV : 0);
  2446. VMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PVMV : 0);
  2447. VMV = median(VMV1, VMV2, VMV3);
  2448. if(pCurMB->MBType == INTER4V)
  2449. {
  2450. // Predictor for Block 2.
  2451. HMV1 = pCurMB->BlkY1.PHMV;
  2452. HMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PHMV : 0);
  2453. HMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PHMV : 0);
  2454. BHMV = median(HMV1, HMV2, HMV3);
  2455. VMV1 = pCurMB->BlkY1.PVMV;
  2456. VMV2 = (pMB2->BlockType != INTRABLOCK ? pMB2->BlkY4.PVMV : 0);
  2457. VMV3 = (pMB3->BlockType != INTRABLOCK ? pMB3->BlkY3.PVMV : 0);
  2458. BVMV = median(VMV1, VMV2, VMV3);
  2459. // Predictor for Block 3.
  2460. HMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PHMV : 0);
  2461. HMV2 = pCurMB->BlkY1.PHMV;
  2462. HMV3 = pCurMB->BlkY2.PHMV;
  2463. CHMV = median(HMV1, HMV2, HMV3);
  2464. VMV1 = (pMB1->BlockType != INTRABLOCK ? pMB1->BlkY4.PVMV : 0);
  2465. VMV2 = pCurMB->BlkY1.PVMV;
  2466. VMV3 = pCurMB->BlkY2.PVMV;
  2467. CVMV = median(VMV1, VMV2, VMV3);
  2468. // Predictor for Block 4
  2469. HMV1 = pCurMB->BlkY3.PHMV;
  2470. HMV2 = pCurMB->BlkY1.PHMV;
  2471. HMV3 = pCurMB->BlkY2.PHMV;
  2472. DHMV = median(HMV1, HMV2, HMV3);
  2473. VMV1 = pCurMB->BlkY3.PVMV;
  2474. VMV2 = pCurMB->BlkY1.PVMV;
  2475. VMV3 = pCurMB->BlkY2.PVMV;
  2476. DVMV = median(VMV1, VMV2, VMV3);
  2477. } // end of if INTER4V
  2478. }
  2479. /******************************************************************
  2480. * Compute motion vector delta and write VLC out to the bitstream
  2481. ******************************************************************/
  2482. register I32 hdelta, vdelta;
  2483. register U32 index;
  2484. hdelta = pCurMB->BlkY1.PHMV - HMV;
  2485. vdelta = pCurMB->BlkY1.PVMV - VMV;
  2486. #ifdef DEBUG
  2487. if (EC->PictureHeader.UMV == OFF) {
  2488. ASSERT((pCurMB->BlkY2.PHMV >= -32 && pCurMB->BlkY2.PHMV <= 31));
  2489. ASSERT((pCurMB->BlkY2.PVMV >= -32 && pCurMB->BlkY2.PVMV <= 31));
  2490. } else {
  2491. if (HMV <= -32) {
  2492. ASSERT((pCurMB->BlkY2.PHMV >= -63 && pCurMB->BlkY2.PHMV <= 0));
  2493. } else if (HMV <= 32) {
  2494. ASSERT((hdelta >= -32 && hdelta <= 31));
  2495. } else {
  2496. ASSERT((pCurMB->BlkY2.PHMV >= 0 && pCurMB->BlkY2.PHMV <= 63));
  2497. }
  2498. if (VMV <= -32) {
  2499. ASSERT((pCurMB->BlkY2.PVMV >= -63 && pCurMB->BlkY2.PVMV <= 0));
  2500. } else if (VMV <= 32) {
  2501. ASSERT((vdelta >= -32 && vdelta <= 31));
  2502. } else {
  2503. ASSERT((pCurMB->BlkY2.PVMV >= 0 && pCurMB->BlkY2.PVMV <= 63));
  2504. }
  2505. }
  2506. #endif
  2507. if (EC->PictureHeader.UMV == ON)
  2508. {
  2509. if (HMV < -31 && hdelta < -63)
  2510. hdelta += 64;
  2511. else if (HMV > 32 && hdelta > 63)
  2512. hdelta -= 64;
  2513. if (VMV < -31 && vdelta < -63)
  2514. vdelta += 64;
  2515. else if (VMV > 32 && vdelta > 63)
  2516. vdelta -= 64;
  2517. }
  2518. // Adjust the deltas to be in the range of -32...+31
  2519. if(hdelta > 31)
  2520. hdelta -= 64;
  2521. if(hdelta < -32)
  2522. hdelta += 64;
  2523. if(vdelta > 31)
  2524. vdelta -= 64;
  2525. if(vdelta < -32)
  2526. vdelta += 64;
  2527. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (P Block 1) MB#=%d - MV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY1.PHMV, pCurMB->BlkY1.PVMV));
  2528. // Write horizontal motion vector delta here.
  2529. index = (hdelta + 32)*2;
  2530. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2531. #ifdef COUNT_BITS
  2532. EC->Bits.MBHeader += *(vlc_mvd+index);
  2533. EC->Bits.MV += *(vlc_mvd+index);
  2534. #endif
  2535. // Write horizontal motion vector delta here.
  2536. index = (vdelta + 32)*2;
  2537. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2538. #ifdef COUNT_BITS
  2539. EC->Bits.MBHeader += *(vlc_mvd+index);
  2540. EC->Bits.MV += *(vlc_mvd+index);
  2541. #endif
  2542. /*
  2543. * Deal with 4 MV case.
  2544. */
  2545. if(pCurMB->MBType == INTER4V)
  2546. {
  2547. /*--------------
  2548. * Block 2.
  2549. *--------------*/
  2550. hdelta = pCurMB->BlkY2.PHMV - BHMV;
  2551. vdelta = pCurMB->BlkY2.PVMV - BVMV;
  2552. #ifdef DEBUG
  2553. if (EC->PictureHeader.UMV == OFF) {
  2554. ASSERT((pCurMB->BlkY2.PHMV >= -32 && pCurMB->BlkY2.PHMV <= 31));
  2555. ASSERT((pCurMB->BlkY2.PVMV >= -32 && pCurMB->BlkY2.PVMV <= 31));
  2556. } else {
  2557. if (HMV <= -32) {
  2558. ASSERT((pCurMB->BlkY2.PHMV >= -63 && pCurMB->BlkY2.PHMV <= 0));
  2559. } else if (HMV <= 32) {
  2560. ASSERT((hdelta >= -32 && hdelta <= 31));
  2561. } else {
  2562. ASSERT((pCurMB->BlkY2.PHMV >= 0 && pCurMB->BlkY2.PHMV <= 63));
  2563. }
  2564. if (VMV <= -32) {
  2565. ASSERT((pCurMB->BlkY2.PVMV >= -63 && pCurMB->BlkY2.PVMV <= 0));
  2566. } else if (VMV <= 32) {
  2567. ASSERT((vdelta >= -32 && vdelta <= 31));
  2568. } else {
  2569. ASSERT((pCurMB->BlkY2.PVMV >= 0 && pCurMB->BlkY2.PVMV <= 63));
  2570. }
  2571. }
  2572. #endif
  2573. if (EC->PictureHeader.UMV == ON)
  2574. {
  2575. if (BHMV < -31 && hdelta < -63)
  2576. hdelta += 64;
  2577. else if (BHMV > 32 && hdelta > 63)
  2578. hdelta -= 64;
  2579. if (BVMV < -31 && vdelta < -63)
  2580. vdelta += 64;
  2581. else if (BVMV > 32 && vdelta > 63)
  2582. vdelta -= 64;
  2583. }
  2584. // Adjust the deltas to be in the range of -32...+31
  2585. if(hdelta > 31)
  2586. hdelta -= 64;
  2587. if(hdelta < -32)
  2588. hdelta += 64;
  2589. if(vdelta > 31)
  2590. vdelta -= 64;
  2591. if(vdelta < -32)
  2592. vdelta += 64;
  2593. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (P Block 2)MB#=%d - MV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY2.PHMV, pCurMB->BlkY2.PVMV));
  2594. // Write horizontal motion vector delta here.
  2595. index = (hdelta + 32)*2;
  2596. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2597. #ifdef COUNT_BITS
  2598. EC->Bits.MBHeader += *(vlc_mvd+index);
  2599. EC->Bits.MV += *(vlc_mvd+index);
  2600. #endif
  2601. // Write horizontal motion vector delta here.
  2602. index = (vdelta + 32)*2;
  2603. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2604. #ifdef COUNT_BITS
  2605. EC->Bits.MBHeader += *(vlc_mvd+index);
  2606. EC->Bits.MV += *(vlc_mvd+index);
  2607. #endif
  2608. /*----------------
  2609. * Block 3
  2610. *---------------*/
  2611. hdelta = pCurMB->BlkY3.PHMV - CHMV;
  2612. vdelta = pCurMB->BlkY3.PVMV - CVMV;
  2613. #ifdef DEBUG
  2614. if (EC->PictureHeader.UMV == OFF) {
  2615. ASSERT((pCurMB->BlkY3.PHMV >= -32 && pCurMB->BlkY3.PHMV <= 31));
  2616. ASSERT((pCurMB->BlkY3.PVMV >= -32 && pCurMB->BlkY3.PVMV <= 31));
  2617. } else {
  2618. if (HMV <= -32) {
  2619. ASSERT((pCurMB->BlkY3.PHMV >= -63 && pCurMB->BlkY3.PHMV <= 0));
  2620. } else if (HMV <= 32) {
  2621. ASSERT((hdelta >= -32 && hdelta <= 31));
  2622. } else {
  2623. ASSERT((pCurMB->BlkY3.PHMV >= 0 && pCurMB->BlkY3.PHMV <= 63));
  2624. }
  2625. if (VMV <= -32) {
  2626. ASSERT((pCurMB->BlkY3.PVMV >= -63 && pCurMB->BlkY3.PVMV <= 0));
  2627. } else if (VMV <= 32) {
  2628. ASSERT((vdelta >= -32 && vdelta <= 31));
  2629. } else {
  2630. ASSERT((pCurMB->BlkY3.PVMV >= 0 && pCurMB->BlkY3.PVMV <= 63));
  2631. }
  2632. }
  2633. #endif
  2634. if (EC->PictureHeader.UMV == ON)
  2635. {
  2636. if (CHMV < -31 && hdelta < -63)
  2637. hdelta += 64;
  2638. else if (CHMV > 32 && hdelta > 63)
  2639. hdelta -= 64;
  2640. if (CVMV < -31 && vdelta < -63)
  2641. vdelta += 64;
  2642. else if (CVMV > 32 && vdelta > 63)
  2643. vdelta -= 64;
  2644. }
  2645. // Adjust the deltas to be in the range of -32...+31
  2646. if(hdelta > 31)
  2647. hdelta -= 64;
  2648. if(hdelta < -32)
  2649. hdelta += 64;
  2650. if(vdelta > 31)
  2651. vdelta -= 64;
  2652. if(vdelta < -32)
  2653. vdelta += 64;
  2654. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (P Block 3)MB#=%d - MV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY3.PHMV, pCurMB->BlkY3.PVMV));
  2655. // Write horizontal motion vector delta here.
  2656. index = (hdelta + 32)*2;
  2657. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2658. #ifdef COUNT_BITS
  2659. EC->Bits.MBHeader += *(vlc_mvd+index);
  2660. EC->Bits.MV += *(vlc_mvd+index);
  2661. #endif
  2662. // Write horizontal motion vector delta here.
  2663. index = (vdelta + 32)*2;
  2664. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2665. #ifdef COUNT_BITS
  2666. EC->Bits.MBHeader += *(vlc_mvd+index);
  2667. EC->Bits.MV += *(vlc_mvd+index);
  2668. #endif
  2669. /*-----------------
  2670. * Block 4
  2671. *-------------------*/
  2672. hdelta = pCurMB->BlkY4.PHMV - DHMV;
  2673. vdelta = pCurMB->BlkY4.PVMV - DVMV;
  2674. #ifdef DEBUG
  2675. if (EC->PictureHeader.UMV == OFF) {
  2676. ASSERT((pCurMB->BlkY4.PHMV >= -32 && pCurMB->BlkY4.PHMV <= 31));
  2677. ASSERT((pCurMB->BlkY4.PVMV >= -32 && pCurMB->BlkY4.PVMV <= 31));
  2678. } else {
  2679. if (HMV <= -32) {
  2680. ASSERT((pCurMB->BlkY4.PHMV >= -63 && pCurMB->BlkY4.PHMV <= 0));
  2681. } else if (HMV <= 32) {
  2682. ASSERT((hdelta >= -32 && hdelta <= 31));
  2683. } else {
  2684. ASSERT((pCurMB->BlkY4.PHMV >= 0 && pCurMB->BlkY4.PHMV <= 63));
  2685. }
  2686. if (VMV <= -32) {
  2687. ASSERT((pCurMB->BlkY4.PVMV >= -63 && pCurMB->BlkY4.PVMV <= 0));
  2688. } else if (VMV <= 32) {
  2689. ASSERT((vdelta >= -32 && vdelta <= 31));
  2690. } else {
  2691. ASSERT((pCurMB->BlkY4.PVMV >= 0 && pCurMB->BlkY4.PVMV <= 63));
  2692. }
  2693. }
  2694. #endif
  2695. if (EC->PictureHeader.UMV == ON)
  2696. {
  2697. if (DHMV < -31 && hdelta < -63)
  2698. hdelta += 64;
  2699. else if (DHMV > 32 && hdelta > 63)
  2700. hdelta -= 64;
  2701. if (DVMV < -31 && vdelta < -63)
  2702. vdelta += 64;
  2703. else if (DVMV > 32 && vdelta > 63)
  2704. vdelta -= 64;
  2705. }
  2706. // Adjust the deltas to be in the range of -32...+31
  2707. if(hdelta > 31)
  2708. hdelta -= 64;
  2709. if(hdelta < -32)
  2710. hdelta += 64;
  2711. if(vdelta > 31)
  2712. vdelta -= 64;
  2713. if(vdelta < -32)
  2714. vdelta += 64;
  2715. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (P Block 4)MB#=%d - MV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY4.PHMV, pCurMB->BlkY4.PVMV));
  2716. // Write horizontal motion vector delta here.
  2717. index = (hdelta + 32)*2;
  2718. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2719. #ifdef COUNT_BITS
  2720. EC->Bits.MBHeader += *(vlc_mvd+index);
  2721. EC->Bits.MV += *(vlc_mvd+index);
  2722. #endif
  2723. // Write horizontal motion vector delta here.
  2724. index = (vdelta + 32)*2;
  2725. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pP_BitStream, pP_BitOffset);
  2726. #ifdef COUNT_BITS
  2727. EC->Bits.MBHeader += *(vlc_mvd+index);
  2728. EC->Bits.MV += *(vlc_mvd+index);
  2729. #endif
  2730. } // end of if INTER4V
  2731. }
  2732. /*************************************************************
  2733. * Name: writePB_MVD
  2734. * Algorithm: See section 6.1.1 and annex G
  2735. * This routine assumes that there are always four motion
  2736. * vectors per macroblock defined. If there is actually one
  2737. * motion vector in the macroblock, then the four MV fields
  2738. * should be equivalent. In this way the MV predictor for
  2739. * block 1 of the 4 MV case is calculated the same way as the
  2740. * MV predictor for the macroblock in the 1 MV case.
  2741. ************************************************************/
  2742. static void writePB_MVD(
  2743. const U32 curMB,
  2744. T_MBlockActionStream * const pCurMB,
  2745. const U32 NumMBPerRow,
  2746. const U32 NumMBs,
  2747. U8 ** pPB_BitStream,
  2748. U8 * pPB_BitOffset,
  2749. U32 GOBHeaderPresent,
  2750. const T_H263EncoderCatalog *EC
  2751. )
  2752. {
  2753. U8 FirstMEState;
  2754. I8 HMV, VMV, BHMV, BVMV, CHMV, CVMV, DHMV, DVMV;
  2755. I8 HMV1, HMV2, HMV3, VMV1, VMV2, VMV3;
  2756. FX_ENTRY("writePB_MVD")
  2757. FirstMEState = pCurMB->FirstMEState;
  2758. /*
  2759. * Top left corner of picture of GOB.
  2760. */
  2761. if( (curMB == 0) ||
  2762. ( (GOBHeaderPresent == TRUE) && ((curMB % NumMBPerRow) == 0) ) )
  2763. {
  2764. HMV = 0;
  2765. VMV = 0;
  2766. if(pCurMB->MBType == INTER4V)
  2767. {
  2768. // Predictor for Block 2.
  2769. BHMV = pCurMB->BlkY1.PHMV;
  2770. BVMV = pCurMB->BlkY1.PVMV;
  2771. // Predictor for Block 3.
  2772. HMV1 = VMV1 = 0;
  2773. HMV2 = pCurMB->BlkY1.PHMV;
  2774. HMV3 = pCurMB->BlkY2.PHMV;
  2775. CHMV = median(HMV1, HMV2, HMV3);
  2776. VMV2 = pCurMB->BlkY1.PVMV;
  2777. VMV3 = pCurMB->BlkY2.PVMV;
  2778. CVMV = median(VMV1, VMV2, VMV3);
  2779. // Predictor for Block 4
  2780. HMV1 = pCurMB->BlkY3.PHMV;
  2781. HMV2 = pCurMB->BlkY1.PHMV;
  2782. HMV3 = pCurMB->BlkY2.PHMV;
  2783. DHMV = median(HMV1, HMV2, HMV3);
  2784. VMV1 = pCurMB->BlkY3.PVMV;
  2785. VMV2 = pCurMB->BlkY1.PVMV;
  2786. VMV3 = pCurMB->BlkY2.PVMV;
  2787. DVMV = median(VMV1, VMV2, VMV3);
  2788. } // end of if INTER4V
  2789. }
  2790. /*
  2791. * Upper edge (not corner) or upper right corner of picture
  2792. * or GOB.
  2793. */
  2794. else if( (curMB < NumMBPerRow) ||
  2795. ( (GOBHeaderPresent == TRUE) && ((curMB % NumMBPerRow) > 0) ) )
  2796. {
  2797. register T_MBlockActionStream *pMB1;
  2798. pMB1 = pCurMB - 1;
  2799. HMV = pMB1->BlkY2.PHMV;
  2800. VMV = pMB1->BlkY2.PVMV;
  2801. if(pCurMB->MBType == INTER4V)
  2802. {
  2803. // Predictor for Block 2.
  2804. BHMV = pCurMB->BlkY1.PHMV;
  2805. BVMV = pCurMB->BlkY1.PVMV;
  2806. // Predictor for Block 3.
  2807. HMV1 = pMB1->BlkY4.PHMV;
  2808. HMV2 = pCurMB->BlkY1.PHMV;
  2809. HMV3 = pCurMB->BlkY2.PHMV;
  2810. CHMV = median(HMV1, HMV2, HMV3);
  2811. VMV1 = pMB1->BlkY4.PVMV;
  2812. VMV2 = pCurMB->BlkY1.PVMV;
  2813. VMV3 = pCurMB->BlkY2.PVMV;
  2814. CVMV = median(VMV1, VMV2, VMV3);
  2815. // Predictor for Block 4
  2816. HMV1 = pCurMB->BlkY3.PHMV;
  2817. HMV2 = pCurMB->BlkY1.PHMV;
  2818. HMV3 = pCurMB->BlkY2.PHMV;
  2819. DHMV = median(HMV1, HMV2, HMV3);
  2820. VMV1 = pCurMB->BlkY3.PVMV;
  2821. VMV2 = pCurMB->BlkY1.PVMV;
  2822. VMV3 = pCurMB->BlkY2.PVMV;
  2823. DVMV = median(VMV1, VMV2, VMV3);
  2824. } // end of if INTER4V
  2825. }
  2826. /*
  2827. * Central portion of the picture, not next to any edge.
  2828. */
  2829. else if ( ((curMB % NumMBPerRow) != 0) && // not left edge
  2830. (curMB >= NumMBPerRow) && // not top row
  2831. ((curMB % NumMBPerRow) != (NumMBPerRow-1)) && // not right edge
  2832. (curMB < (NumMBs - NumMBPerRow)) ) // not bottom row
  2833. {
  2834. register T_MBlockActionStream *pMB1, *pMB2, *pMB3;
  2835. pMB1 = pCurMB - 1;
  2836. pMB2 = pCurMB - NumMBPerRow;
  2837. pMB3 = pMB2 + 1;
  2838. HMV = median(pMB1->BlkY2.PHMV, pMB2->BlkY3.PHMV, pMB3->BlkY3.PHMV);
  2839. VMV = median(pMB1->BlkY2.PVMV, pMB2->BlkY3.PVMV, pMB3->BlkY3.PVMV);
  2840. if(pCurMB->MBType == INTER4V)
  2841. {
  2842. // Predictor for Block 2.
  2843. HMV1 = pCurMB->BlkY1.PHMV;
  2844. HMV2 = pMB2->BlkY4.PHMV;
  2845. HMV3 = pMB3->BlkY3.PHMV;
  2846. BHMV = median(HMV1, HMV2, HMV3);
  2847. VMV1 = pCurMB->BlkY1.PVMV;
  2848. VMV2 = pMB2->BlkY4.PVMV;
  2849. VMV3 = pMB3->BlkY3.PVMV;
  2850. BVMV = median(VMV1, VMV2, VMV3);
  2851. // Predictor for Block 3.
  2852. HMV1 = pMB1->BlkY4.PHMV;
  2853. HMV2 = pCurMB->BlkY1.PHMV;
  2854. HMV3 = pCurMB->BlkY2.PHMV;
  2855. CHMV = median(HMV1, HMV2, HMV3);
  2856. VMV1 = pMB1->BlkY4.PVMV;
  2857. VMV2 = pCurMB->BlkY1.PVMV;
  2858. VMV3 = pCurMB->BlkY2.PVMV;
  2859. CVMV = median(VMV1, VMV2, VMV3);
  2860. // Predictor for Block 4
  2861. HMV1 = pCurMB->BlkY3.PHMV;
  2862. HMV2 = pCurMB->BlkY1.PHMV;
  2863. HMV3 = pCurMB->BlkY2.PHMV;
  2864. DHMV = median(HMV1, HMV2, HMV3);
  2865. VMV1 = pCurMB->BlkY3.PVMV;
  2866. VMV2 = pCurMB->BlkY1.PVMV;
  2867. VMV3 = pCurMB->BlkY2.PVMV;
  2868. DVMV = median(VMV1, VMV2, VMV3);
  2869. } // end of if INTER4V
  2870. }
  2871. /*
  2872. * Left edge or lower left corner.
  2873. */
  2874. else if( (curMB % NumMBPerRow) == 0 )
  2875. {
  2876. register T_MBlockActionStream *pMB2, *pMB3;
  2877. pMB2 = pCurMB - NumMBPerRow;
  2878. pMB3 = pMB2 + 1;
  2879. HMV = median(0, pMB2->BlkY3.PHMV, pMB3->BlkY3.PHMV);
  2880. VMV = median(0, pMB2->BlkY3.PVMV, pMB3->BlkY3.PVMV);
  2881. if(pCurMB->MBType == INTER4V)
  2882. {
  2883. // Predictor for Block 2.
  2884. HMV1 = pCurMB->BlkY1.PHMV;
  2885. HMV2 = pMB2->BlkY4.PHMV;
  2886. HMV3 = pMB3->BlkY3.PHMV;
  2887. BHMV = median(HMV1, HMV2, HMV3);
  2888. VMV1 = pCurMB->BlkY1.PVMV;
  2889. VMV2 = pMB2->BlkY4.PVMV;
  2890. VMV3 = pMB3->BlkY3.PVMV;
  2891. BVMV = median(VMV1, VMV2, VMV3);
  2892. // Predictor for Block 3.
  2893. HMV1 = 0;
  2894. HMV2 = pCurMB->BlkY1.PHMV;
  2895. HMV3 = pCurMB->BlkY2.PHMV;
  2896. CHMV = median(HMV1, HMV2, HMV3);
  2897. VMV1 = 0;
  2898. VMV2 = pCurMB->BlkY1.PVMV;
  2899. VMV3 = pCurMB->BlkY2.PVMV;
  2900. CVMV = median(VMV1, VMV2, VMV3);
  2901. // Predictor for Block 4
  2902. HMV1 = pCurMB->BlkY3.PHMV;
  2903. HMV2 = pCurMB->BlkY1.PHMV;
  2904. HMV3 = pCurMB->BlkY2.PHMV;
  2905. DHMV = median(HMV1, HMV2, HMV3);
  2906. VMV1 = pCurMB->BlkY3.PVMV;
  2907. VMV2 = pCurMB->BlkY1.PVMV;
  2908. VMV3 = pCurMB->BlkY2.PVMV;
  2909. DVMV = median(VMV1, VMV2, VMV3);
  2910. } // end of if INTER4V
  2911. }
  2912. /*
  2913. * Right edge or lower right corner.
  2914. */
  2915. else if( (curMB % NumMBPerRow) == (NumMBPerRow-1) )
  2916. {
  2917. register T_MBlockActionStream *pMB1, *pMB2;
  2918. pMB1 = pCurMB - 1;
  2919. pMB2 = pCurMB - NumMBPerRow;
  2920. HMV = median(pMB1->BlkY2.PHMV, pMB2->BlkY3.PHMV, 0);
  2921. VMV = median(pMB1->BlkY2.PVMV, pMB2->BlkY3.PVMV, 0);
  2922. if(pCurMB->MBType == INTER4V)
  2923. {
  2924. // Predictor for Block 2.
  2925. HMV1 = pCurMB->BlkY1.PHMV;
  2926. HMV2 = pMB2->BlkY4.PHMV;
  2927. HMV3 = 0;
  2928. BHMV = median(HMV1, HMV2, HMV3);
  2929. VMV1 = pCurMB->BlkY1.PVMV;
  2930. VMV2 = pMB2->BlkY4.PVMV;
  2931. VMV3 = 0;
  2932. BVMV = median(VMV1, VMV2, VMV3);
  2933. // Predictor for Block 3.
  2934. HMV1 = pMB1->BlkY4.PHMV;
  2935. HMV2 = pCurMB->BlkY1.PHMV;
  2936. HMV3 = pCurMB->BlkY2.PHMV;
  2937. CHMV = median(HMV1, HMV2, HMV3);
  2938. VMV1 = pMB1->BlkY4.PVMV;
  2939. VMV2 = pCurMB->BlkY1.PVMV;
  2940. VMV3 = pCurMB->BlkY2.PVMV;
  2941. CVMV = median(VMV1, VMV2, VMV3);
  2942. // Predictor for Block 4
  2943. HMV1 = pCurMB->BlkY3.PHMV;
  2944. HMV2 = pCurMB->BlkY1.PHMV;
  2945. HMV3 = pCurMB->BlkY2.PHMV;
  2946. DHMV = median(HMV1, HMV2, HMV3);
  2947. VMV1 = pCurMB->BlkY3.PVMV;
  2948. VMV2 = pCurMB->BlkY1.PVMV;
  2949. VMV3 = pCurMB->BlkY2.PVMV;
  2950. DVMV = median(VMV1, VMV2, VMV3);
  2951. } // end of if INTER4V
  2952. }
  2953. else
  2954. {
  2955. register T_MBlockActionStream *pMB1, *pMB2, *pMB3;
  2956. pMB1 = pCurMB - 1;
  2957. pMB2 = pCurMB - NumMBPerRow;
  2958. pMB3 = pMB2 + 1;
  2959. HMV = median(pMB1->BlkY2.PHMV, pMB2->BlkY3.PHMV, pMB3->BlkY3.PHMV);
  2960. VMV = median(pMB1->BlkY2.PVMV, pMB2->BlkY3.PVMV, pMB3->BlkY3.PVMV);
  2961. if(pCurMB->MBType == INTER4V)
  2962. {
  2963. // Predictor for Block 2.
  2964. HMV1 = pCurMB->BlkY1.PHMV;
  2965. HMV2 = pMB2->BlkY4.PHMV;
  2966. HMV3 = pMB3->BlkY3.PHMV;
  2967. BHMV = median(HMV1, HMV2, HMV3);
  2968. VMV1 = pCurMB->BlkY1.PVMV;
  2969. VMV2 = pMB2->BlkY4.PVMV;
  2970. VMV3 = pMB3->BlkY3.PVMV;
  2971. BVMV = median(VMV1, VMV2, VMV3);
  2972. // Predictor for Block 3.
  2973. HMV1 = pMB1->BlkY4.PHMV;
  2974. HMV2 = pCurMB->BlkY1.PHMV;
  2975. HMV3 = pCurMB->BlkY2.PHMV;
  2976. CHMV = median(HMV1, HMV2, HMV3);
  2977. VMV1 = pMB1->BlkY4.PVMV;
  2978. VMV2 = pCurMB->BlkY1.PVMV;
  2979. VMV3 = pCurMB->BlkY2.PVMV;
  2980. CVMV = median(VMV1, VMV2, VMV3);
  2981. // Predictor for Block 4
  2982. HMV1 = pCurMB->BlkY3.PHMV;
  2983. HMV2 = pCurMB->BlkY1.PHMV;
  2984. HMV3 = pCurMB->BlkY2.PHMV;
  2985. DHMV = median(HMV1, HMV2, HMV3);
  2986. VMV1 = pCurMB->BlkY3.PVMV;
  2987. VMV2 = pCurMB->BlkY1.PVMV;
  2988. VMV3 = pCurMB->BlkY2.PVMV;
  2989. DVMV = median(VMV1, VMV2, VMV3);
  2990. } // end of if INTER4V
  2991. }
  2992. /******************************************************************
  2993. * Compute motion vector delta and write VLC out to the bitstream
  2994. ******************************************************************/
  2995. register I32 hdelta, vdelta;
  2996. register U32 index;
  2997. hdelta = pCurMB->BlkY1.PHMV - HMV;
  2998. vdelta = pCurMB->BlkY1.PVMV - VMV;
  2999. #ifdef DEBUG
  3000. if (EC->PictureHeader.UMV == OFF) {
  3001. ASSERT((pCurMB->BlkY1.PHMV >= -32 && pCurMB->BlkY1.PHMV <= 31));
  3002. ASSERT((pCurMB->BlkY1.PVMV >= -32 && pCurMB->BlkY1.PVMV <= 31));
  3003. } else {
  3004. if (HMV <= -32) {
  3005. ASSERT((pCurMB->BlkY1.PHMV >= -63 && pCurMB->BlkY1.PHMV <= 0));
  3006. } else if (HMV <= 32) {
  3007. ASSERT((hdelta >= -32 && hdelta <= 31));
  3008. } else {
  3009. ASSERT((pCurMB->BlkY1.PHMV >= 0 && pCurMB->BlkY1.PHMV <= 63));
  3010. }
  3011. if (VMV <= -32) {
  3012. ASSERT((pCurMB->BlkY1.PVMV >= -63 && pCurMB->BlkY1.PVMV <= 0));
  3013. } else if (VMV <= 32) {
  3014. ASSERT((vdelta >= -32 && vdelta <= 31));
  3015. } else {
  3016. ASSERT((pCurMB->BlkY1.PVMV >= 0 && pCurMB->BlkY1.PVMV <= 63));
  3017. }
  3018. }
  3019. #endif
  3020. // Adjust the deltas to be in the range of -32...+31
  3021. if (EC->PictureHeader.UMV == ON)
  3022. {
  3023. if (HMV < -31 && hdelta < -63)
  3024. hdelta += 64;
  3025. else if (HMV > 32 && hdelta > 63)
  3026. hdelta -= 64;
  3027. if (VMV < -31 && vdelta < -63)
  3028. vdelta += 64;
  3029. else if (VMV > 32 && vdelta > 63)
  3030. vdelta -= 64;
  3031. }
  3032. if(hdelta > 31)
  3033. hdelta -= 64;
  3034. if(hdelta < -32)
  3035. hdelta += 64;
  3036. if(vdelta > 31)
  3037. vdelta -= 64;
  3038. if(vdelta < -32)
  3039. vdelta += 64;
  3040. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (PB Block 1)MB#=%d - MV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY1.PHMV, pCurMB->BlkY1.PVMV));
  3041. // Write horizontal motion vector delta
  3042. index = (hdelta + 32)*2;
  3043. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3044. // Write vertical motion vector delta
  3045. index = (vdelta + 32)*2;
  3046. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3047. /*
  3048. * Deal with 4 MV case.
  3049. */
  3050. if(pCurMB->MBType == INTER4V)
  3051. {
  3052. /*--------------
  3053. * Block 2.
  3054. *--------------*/
  3055. hdelta = pCurMB->BlkY2.PHMV - BHMV;
  3056. vdelta = pCurMB->BlkY2.PVMV - BVMV;
  3057. #ifdef DEBUG
  3058. if (EC->PictureHeader.UMV == OFF) {
  3059. ASSERT((pCurMB->BlkY2.PHMV >= -32 && pCurMB->BlkY2.PHMV <= 31));
  3060. ASSERT((pCurMB->BlkY2.PVMV >= -32 && pCurMB->BlkY2.PVMV <= 31));
  3061. } else {
  3062. if (HMV <= -32) {
  3063. ASSERT((pCurMB->BlkY2.PHMV >= -63 && pCurMB->BlkY2.PHMV <= 0));
  3064. } else if (HMV <= 32) {
  3065. ASSERT((hdelta >= -32 && hdelta <= 31));
  3066. } else {
  3067. ASSERT((pCurMB->BlkY2.PHMV >= 0 && pCurMB->BlkY2.PHMV <= 63));
  3068. }
  3069. if (VMV <= -32) {
  3070. ASSERT((pCurMB->BlkY2.PVMV >= -63 && pCurMB->BlkY2.PVMV <= 0));
  3071. } else if (VMV <= 32) {
  3072. ASSERT((vdelta >= -32 && vdelta <= 31));
  3073. } else {
  3074. ASSERT((pCurMB->BlkY2.PVMV >= 0 && pCurMB->BlkY2.PVMV <= 63));
  3075. }
  3076. }
  3077. #endif
  3078. // Adjust the deltas to be in the range of -32...+31
  3079. if (EC->PictureHeader.UMV == ON)
  3080. {
  3081. if (BHMV < -31 && hdelta < -63)
  3082. hdelta += 64;
  3083. else if (BHMV > 32 && hdelta > 63)
  3084. hdelta -= 64;
  3085. if (BVMV < -31 && vdelta < -63)
  3086. vdelta += 64;
  3087. else if (BVMV > 32 && vdelta > 63)
  3088. vdelta -= 64;
  3089. }
  3090. if(hdelta > 31)
  3091. hdelta -= 64;
  3092. if(hdelta < -32)
  3093. hdelta += 64;
  3094. if(vdelta > 31)
  3095. vdelta -= 64;
  3096. if(vdelta < -32)
  3097. vdelta += 64;
  3098. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (PB Block 2)MB#=%d - MV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY2.PHMV, pCurMB->BlkY2.PVMV));
  3099. // Write horizontal motion vector delta here.
  3100. index = (hdelta + 32)*2;
  3101. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3102. // Write horizontal motion vector delta here.
  3103. index = (vdelta + 32)*2;
  3104. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3105. /*----------------
  3106. * Block 3
  3107. *---------------*/
  3108. hdelta = pCurMB->BlkY3.PHMV - CHMV;
  3109. vdelta = pCurMB->BlkY3.PVMV - CVMV;
  3110. #ifdef DEBUG
  3111. if (EC->PictureHeader.UMV == OFF) {
  3112. ASSERT((pCurMB->BlkY3.PHMV >= -32 && pCurMB->BlkY3.PHMV <= 31));
  3113. ASSERT((pCurMB->BlkY3.PVMV >= -32 && pCurMB->BlkY3.PVMV <= 31));
  3114. } else {
  3115. if (HMV <= -32) {
  3116. ASSERT((pCurMB->BlkY3.PHMV >= -63 && pCurMB->BlkY3.PHMV <= 0));
  3117. } else if (HMV <= 32) {
  3118. ASSERT((hdelta >= -32 && hdelta <= 31));
  3119. } else {
  3120. ASSERT((pCurMB->BlkY3.PHMV >= 0 && pCurMB->BlkY3.PHMV <= 63));
  3121. }
  3122. if (VMV <= -32) {
  3123. ASSERT((pCurMB->BlkY3.PVMV >= -63 && pCurMB->BlkY3.PVMV <= 0));
  3124. } else if (VMV <= 32) {
  3125. ASSERT((vdelta >= -32 && vdelta <= 31));
  3126. } else {
  3127. ASSERT((pCurMB->BlkY3.PVMV >= 0 && pCurMB->BlkY3.PVMV <= 63));
  3128. }
  3129. }
  3130. #endif
  3131. // Adjust the deltas to be in the range of -32...+31
  3132. if (EC->PictureHeader.UMV == ON)
  3133. {
  3134. if (CHMV < -31 && hdelta < -63)
  3135. hdelta += 64;
  3136. else if (CHMV > 32 && hdelta > 63)
  3137. hdelta -= 64;
  3138. if (CVMV < -31 && vdelta < -63)
  3139. vdelta += 64;
  3140. else if (CVMV > 32 && vdelta > 63)
  3141. vdelta -= 64;
  3142. }
  3143. if(hdelta > 31)
  3144. hdelta -= 64;
  3145. if(hdelta < -32)
  3146. hdelta += 64;
  3147. if(vdelta > 31)
  3148. vdelta -= 64;
  3149. if(vdelta < -32)
  3150. vdelta += 64;
  3151. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (PB Block 3)MB#=%d\nMV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY3.PHMV, pCurMB->BlkY3.PVMV));
  3152. // Write horizontal motion vector delta here.
  3153. index = (hdelta + 32)*2;
  3154. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3155. // Write horizontal motion vector delta here.
  3156. index = (vdelta + 32)*2;
  3157. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3158. /*-----------------
  3159. * Block 4
  3160. *-------------------*/
  3161. hdelta = pCurMB->BlkY4.PHMV - DHMV;
  3162. vdelta = pCurMB->BlkY4.PVMV - DVMV;
  3163. #ifdef DEBUG
  3164. if (EC->PictureHeader.UMV == OFF) {
  3165. ASSERT((pCurMB->BlkY4.PHMV >= -32 && pCurMB->BlkY4.PHMV <= 31));
  3166. ASSERT((pCurMB->BlkY4.PVMV >= -32 && pCurMB->BlkY4.PVMV <= 31));
  3167. } else {
  3168. if (HMV <= -32) {
  3169. ASSERT((pCurMB->BlkY4.PHMV >= -63 && pCurMB->BlkY4.PHMV <= 0));
  3170. } else if (HMV <= 32) {
  3171. ASSERT((hdelta >= -32 && hdelta <= 31));
  3172. } else {
  3173. ASSERT((pCurMB->BlkY4.PHMV >= 0 && pCurMB->BlkY4.PHMV <= 63));
  3174. }
  3175. if (VMV <= -32) {
  3176. ASSERT((pCurMB->BlkY4.PVMV >= -63 && pCurMB->BlkY4.PVMV <= 0));
  3177. } else if (VMV <= 32) {
  3178. ASSERT((vdelta >= -32 && vdelta <= 31));
  3179. } else {
  3180. ASSERT((pCurMB->BlkY4.PVMV >= 0 && pCurMB->BlkY4.PVMV <= 63));
  3181. }
  3182. }
  3183. #endif
  3184. // Adjust the deltas to be in the range of -32...+31
  3185. if (EC->PictureHeader.UMV == ON)
  3186. {
  3187. if (DHMV < -31 && hdelta < -63)
  3188. hdelta += 64;
  3189. else if (DHMV > 32 && hdelta > 63)
  3190. hdelta -= 64;
  3191. if (DVMV < -31 && vdelta < -63)
  3192. vdelta += 64;
  3193. else if (DVMV > 32 && vdelta > 63)
  3194. vdelta -= 64;
  3195. }
  3196. if(hdelta > 31)
  3197. hdelta -= 64;
  3198. if(hdelta < -32)
  3199. hdelta += 64;
  3200. if(vdelta > 31)
  3201. vdelta -= 64;
  3202. if(vdelta < -32)
  3203. vdelta += 64;
  3204. DEBUGMSG(ZONE_ENCODE_MV, ("%s: (PB Block 4)MB#=%d\nMV Delta: (%d, %d) Motion Vectors: (%d, %d)\r\n", _fx_, curMB, hdelta, vdelta, pCurMB->BlkY4.PHMV, pCurMB->BlkY4.PVMV));
  3205. // Write horizontal motion vector delta here.
  3206. index = (hdelta + 32)*2;
  3207. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3208. // Write horizontal motion vector delta here.
  3209. index = (vdelta + 32)*2;
  3210. PutBits( *(vlc_mvd+index+1), *(vlc_mvd+index), pPB_BitStream, pPB_BitOffset);
  3211. } // end of if INTER4V
  3212. }