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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. /* 
  22.  * Notes:
  23.  *  - file formatted with tabstops == 4 spaces 
  24.  */
  25. #include <mp4av_common.h>
  26. extern "C" bool MP4AV_Mpeg4ParseVosh(
  27.      u_int8_t* pVoshBuf, 
  28.      u_int32_t voshSize,
  29.      u_int8_t* pProfileLevel)
  30. {
  31. CMemoryBitstream vosh;
  32. vosh.SetBytes(pVoshBuf, voshSize);
  33. try {
  34. vosh.GetBits(32); // start code
  35. *pProfileLevel = vosh.GetBits(8);
  36. }
  37. catch (int e) {
  38. return false;
  39. }
  40. return true;
  41. }
  42. extern "C" bool MP4AV_Mpeg4CreateVosh(
  43. u_int8_t** ppBytes,
  44. u_int32_t* pNumBytes,
  45. u_int8_t profileLevel)
  46. {
  47. CMemoryBitstream vosh;
  48. try {
  49. if (*ppBytes) {
  50. // caller must guarantee buffer against overrun
  51. memset((*ppBytes) + (*pNumBytes), 0, 5);
  52. vosh.SetBytes(*ppBytes, (*pNumBytes) + 5);
  53. vosh.SetBitPosition((*pNumBytes) << 3);
  54. } else {
  55. vosh.AllocBytes(5);
  56. }
  57. vosh.PutBits(MP4AV_MPEG4_SYNC, 24);
  58. vosh.PutBits(MP4AV_MPEG4_VOSH_START, 8);
  59. vosh.PutBits(profileLevel, 8);
  60. *ppBytes = vosh.GetBuffer();
  61. *pNumBytes = vosh.GetNumberOfBytes();
  62. }
  63. catch (int e) {
  64. return false;
  65. }
  66. return true;
  67. }
  68. extern "C" bool MP4AV_Mpeg4CreateVo(
  69. u_int8_t** ppBytes,
  70. u_int32_t* pNumBytes,
  71. u_int8_t objectId)
  72. {
  73. CMemoryBitstream vo;
  74. try {
  75. if (*ppBytes) {
  76. // caller must guarantee buffer against overrun
  77. memset((*ppBytes) + (*pNumBytes), 0, 9);
  78. vo.SetBytes(*ppBytes, *pNumBytes + 9);
  79. vo.SetBitPosition((*pNumBytes) << 3);
  80. } else {
  81. vo.AllocBytes(9);
  82. }
  83. vo.PutBits(MP4AV_MPEG4_SYNC, 24);
  84. vo.PutBits(MP4AV_MPEG4_VO_START, 8);
  85. vo.PutBits(0x08, 8); // no verid, priority, or signal type
  86. vo.PutBits(MP4AV_MPEG4_SYNC, 24);
  87. vo.PutBits(objectId - 1, 8);
  88. *ppBytes = vo.GetBuffer();
  89. *pNumBytes = vo.GetNumberOfBytes();
  90. }
  91. catch (int e) {
  92. return false;
  93. }
  94. return true;
  95. }
  96. extern "C" bool MP4AV_Mpeg4ParseVol(
  97. u_int8_t* pVolBuf, 
  98. u_int32_t volSize,
  99. u_int8_t* pTimeBits, 
  100. u_int16_t* pTimeTicks, 
  101. u_int16_t* pFrameDuration, 
  102. u_int16_t* pFrameWidth, 
  103. u_int16_t* pFrameHeight)
  104. {
  105. CMemoryBitstream vol;
  106. vol.SetBytes(pVolBuf, volSize);
  107. try {
  108. vol.SkipBits(32); // start code
  109. vol.SkipBits(1); // random accessible vol
  110. vol.SkipBits(8); // object type id
  111. u_int8_t verid = 0;
  112. if (vol.GetBits(1)) { // is object layer id
  113. verid = vol.GetBits(4); // object layer verid
  114. vol.SkipBits(3); // object layer priority
  115. }
  116. if (vol.GetBits(4) == 0xF) {  // aspect ratio info
  117. vol.SkipBits(8); // par width
  118. vol.SkipBits(8); // par height
  119. }
  120. if (vol.GetBits(1)) { // vol control parameters
  121. vol.SkipBits(2); // chroma format
  122. vol.SkipBits(1); // low delay
  123. if (vol.GetBits(1)) { // vbv parameters
  124. vol.SkipBits(15); // first half bit rate
  125. vol.SkipBits(1); // marker bit
  126. vol.SkipBits(15); // latter half bit rate
  127. vol.SkipBits(1); // marker bit
  128. vol.SkipBits(15); // first half vbv buffer size
  129. vol.SkipBits(1); // marker bit
  130. vol.SkipBits(3); // latter half vbv buffer size
  131. vol.SkipBits(11); // first half vbv occupancy
  132. vol.SkipBits(1); // marker bit
  133. vol.SkipBits(15); // latter half vbv occupancy
  134. vol.SkipBits(1); // marker bit
  135. }
  136. }
  137. u_int8_t shape = vol.GetBits(2); // object layer shape
  138. if (shape == 3 /* GRAYSCALE */ && verid != 1) {
  139. vol.SkipBits(4); // object layer shape extension
  140. }
  141. vol.SkipBits(1); // marker bit
  142. *pTimeTicks = vol.GetBits(16); // vop time increment resolution 
  143. u_int8_t i;
  144. u_int32_t powerOf2 = 1;
  145. for (i = 0; i < 16; i++) {
  146. if (*pTimeTicks < powerOf2) {
  147. break;
  148. }
  149. powerOf2 <<= 1;
  150. }
  151. *pTimeBits = i;
  152. vol.SkipBits(1); // marker bit
  153. if (vol.GetBits(1)) { // fixed vop rate
  154. // fixed vop time increment
  155. *pFrameDuration = vol.GetBits(*pTimeBits); 
  156. } else {
  157. *pFrameDuration = 0;
  158. }
  159. if (shape == 0 /* RECTANGULAR */) {
  160. vol.SkipBits(1); // marker bit
  161. *pFrameWidth = vol.GetBits(13); // object layer width
  162. vol.SkipBits(1); // marker bit
  163. *pFrameHeight = vol.GetBits(13);// object layer height
  164. vol.SkipBits(1); // marker bit
  165. } else {
  166. *pFrameWidth = 0;
  167. *pFrameHeight = 0;
  168. }
  169. // there's more, but we don't need it
  170. }
  171. catch (int e) {
  172. return false;
  173. }
  174. return true;
  175. }
  176. extern "C" bool MP4AV_Mpeg4CreateVol(
  177. u_int8_t** ppBytes,
  178. u_int32_t* pNumBytes,
  179. u_int8_t profile,
  180. float frameRate,
  181. bool shortTime,
  182. bool variableRate,
  183. u_int16_t width,
  184. u_int16_t height,
  185. u_int8_t quantType,
  186. u_int8_t* pTimeBits)
  187. {
  188. CMemoryBitstream vol;
  189. try {
  190. if (*ppBytes) {
  191. // caller must guarantee buffer against overrun
  192. memset((*ppBytes) + (*pNumBytes), 0, 20);
  193. vol.SetBytes(*ppBytes, *pNumBytes + 20);
  194. vol.SetBitPosition((*pNumBytes) << 3);
  195. } else {
  196. vol.AllocBytes(20);
  197. }
  198. /* VOL - Video Object Layer */
  199. vol.PutBits(MP4AV_MPEG4_SYNC, 24);
  200. vol.PutBits(MP4AV_MPEG4_VOL_START, 8);
  201. /* 1 bit - random access = 0 (1 only if every VOP is an I frame) */
  202. vol.PutBits(0, 1);
  203. /*
  204.  * 8 bits - type indication 
  205.  *  = 1 (simple profile)
  206.  *  = 4 (main profile)
  207.  */
  208. vol.PutBits(profile, 8);
  209. /* 1 bit - is object layer id = 1 */
  210. vol.PutBits(1, 1);
  211. /* 4 bits - visual object layer ver id = 2 */
  212. vol.PutBits(2, 4); 
  213. /* 3 bits - visual object layer priority = 1 */
  214. vol.PutBits(1, 3); 
  215. /* 4 bits - aspect ratio info = 1 (square pixels) */
  216. vol.PutBits(1, 4);
  217. /* 1 bit - VOL control params = 0 */
  218. vol.PutBits(0, 1);
  219. /* 2 bits - VOL shape = 0 (rectangular) */
  220. vol.PutBits(0, 2);
  221. /* 1 bit - marker = 1 */
  222. vol.PutBits(1, 1);
  223. u_int16_t ticks;
  224. if (shortTime /* && frameRate == (float)((int)frameRate) */) {
  225. ticks = (u_int16_t)(frameRate + 0.5);
  226. } else {
  227. ticks = 30000;
  228. }
  229. /* 16 bits - VOP time increment resolution */
  230. vol.PutBits(ticks, 16);
  231. /* 1 bit - marker = 1 */
  232. vol.PutBits(1, 1);
  233. u_int8_t rangeBits = 1;
  234. while (ticks > (1 << rangeBits)) {
  235. rangeBits++;
  236. }
  237. if (pTimeBits) {
  238. *pTimeBits = rangeBits;
  239. }
  240. /* 1 bit - fixed vop rate = 0 or 1 */
  241. if (variableRate) {
  242. vol.PutBits(0, 1);
  243. } else {
  244. vol.PutBits(1, 1);
  245. u_int16_t frameDuration = 
  246. (u_int16_t)((float)ticks / frameRate);
  247. /* 1-16 bits - fixed vop time increment in ticks */
  248. vol.PutBits(frameDuration, rangeBits);
  249. }
  250. /* 1 bit - marker = 1 */
  251. vol.PutBits(1, 1);
  252. /* 13 bits - VOL width */
  253. vol.PutBits(width, 13);
  254. /* 1 bit - marker = 1 */
  255. vol.PutBits(1, 1);
  256. /* 13 bits - VOL height */
  257. vol.PutBits(height, 13);
  258. /* 1 bit - marker = 1 */
  259. vol.PutBits(1, 1);
  260. /* 1 bit - interlaced = 0 */
  261. vol.PutBits(0, 1);
  262. /* 1 bit - overlapped block motion compensation disable = 1 */
  263. vol.PutBits(1, 1);
  264. /* 2 bits - sprite usage = 0 */
  265. vol.PutBits(0, 2);
  266. /* 1 bit - not 8 bit pixels = 0 */
  267. vol.PutBits(0, 1);
  268. /* 1 bit - quant type = 0 */
  269. vol.PutBits(quantType, 1);
  270. if (quantType) {
  271. /* 1 bit - load intra quant mat = 0 */
  272. vol.PutBits(0, 1);
  273. /* 1 bit - load inter quant mat = 0 */
  274. vol.PutBits(0, 1);
  275. }
  276. /* 1 bit - quarter pixel = 0 */
  277. vol.PutBits(0, 1);
  278. /* 1 bit - complexity estimation disable = 1 */
  279. vol.PutBits(1, 1);
  280. /* 1 bit - resync marker disable = 1 */
  281. vol.PutBits(1, 1);
  282. /* 1 bit - data partitioned = 0 */
  283. vol.PutBits(0, 1);
  284. /* 1 bit - newpred = 0 */
  285. vol.PutBits(0, 1);
  286. /* 1 bit - reduced resolution vop = 0 */
  287. vol.PutBits(0, 1);
  288. /* 1 bit - scalability = 0 */
  289. vol.PutBits(0, 1);
  290. /* pad to byte boundary with 0 then as many 1's as needed */
  291. vol.PutBits(0, 1);
  292. if ((vol.GetBitPosition() & 7) != 0) {
  293. vol.PutBits(0xFF, 8 - (vol.GetBitPosition() & 7));
  294. }
  295. *ppBytes = vol.GetBuffer();
  296. *pNumBytes = vol.GetBitPosition() >> 3;
  297. }
  298. catch (int e) {
  299. return false;
  300. }
  301. return true;
  302. }
  303. extern "C" bool MP4AV_Mpeg4ParseGov(
  304. u_int8_t* pGovBuf, 
  305. u_int32_t govSize,
  306. u_int8_t* pHours, 
  307. u_int8_t* pMinutes, 
  308. u_int8_t* pSeconds)
  309. {
  310. CMemoryBitstream gov;
  311. gov.SetBytes(pGovBuf, govSize);
  312. try {
  313. gov.SkipBits(32); // start code
  314. *pHours = gov.GetBits(5);
  315. *pMinutes = gov.GetBits(6);
  316. gov.SkipBits(1); // marker bit
  317. *pSeconds = gov.GetBits(6);
  318. }
  319. catch (int e) {
  320. return false;
  321. }
  322. return true;
  323. }
  324. extern "C" bool MP4AV_Mpeg4ParseVop(
  325. u_int8_t* pVopBuf, 
  326. u_int32_t vopSize,
  327. u_char* pVopType, 
  328. u_int8_t timeBits, 
  329. u_int16_t timeTicks, 
  330. u_int32_t* pVopTimeIncrement)
  331. {
  332. CMemoryBitstream vop;
  333. vop.SetBytes(pVopBuf, vopSize);
  334. try {
  335. vop.SkipBits(32); // skip start code
  336. switch (vop.GetBits(2)) {
  337. case 0:
  338. /* Intra */
  339. *pVopType = 'I';
  340. break;
  341. case 1:
  342. /* Predictive */
  343. *pVopType = 'P';
  344. break;
  345. case 2:
  346. /* Bidirectional Predictive */
  347. *pVopType = 'B';
  348. break;
  349. case 3:
  350. /* Sprite */
  351. *pVopType = 'S';
  352. break;
  353. }
  354. if (!pVopTimeIncrement) {
  355. return true;
  356. }
  357. u_int8_t numSecs = 0;
  358. while (vop.GetBits(1) != 0) {
  359. numSecs++;
  360. }
  361. vop.SkipBits(1); // skip marker
  362. u_int16_t numTicks = vop.GetBits(timeBits);
  363. *pVopTimeIncrement = (numSecs * timeTicks) + numTicks; 
  364. }
  365. catch (int e) {
  366. return false;
  367. }
  368. return true;
  369. }
  370. // Map from ISO IEC 14496-2:2000 Appendix G 
  371. // to ISO IEC 14496-1:2001 8.6.4.2 Table 6
  372. extern "C" u_int8_t 
  373. MP4AV_Mpeg4VideoToSystemsProfileLevel(u_int8_t videoProfileLevel)
  374. {
  375. switch (videoProfileLevel) {
  376. // Simple Profile
  377. case 0x01: // L1
  378. return 0x03;
  379. case 0x02: // L2
  380. return 0x02;
  381. case 0x03: // L3
  382. return 0x01;
  383. // Simple Scalable Profile
  384. case 0x11: // L1
  385. return 0x05;
  386. case 0x12: // L2
  387. return 0x04;
  388. // Core Profile
  389. case 0x21: // L1
  390. return 0x07;
  391. case 0x22: // L2
  392. return 0x06;
  393. // Main Profile
  394. case 0x32: // L2
  395. return 0x0A;
  396. case 0x33: // L3
  397. return 0x09;
  398. case 0x34: // L4
  399. return 0x08;
  400. // N-bit Profile
  401. case 0x42: // L2
  402. return 0x0B;
  403. // Scalable Texture
  404. case 0x51: // L1
  405. return 0x12;
  406. case 0x52: // L2
  407. return 0x11;
  408. case 0x53: // L3
  409. return 0x10;
  410. // Simple Face Animation Profile
  411. case 0x61: // L1
  412. return 0x14;
  413. case 0x62: // L2
  414. return 0x13;
  415. // Simple FBA Profile
  416. case 0x63: // L1
  417. case 0x64: // L2
  418. return 0xFE;
  419. // Basic Animated Texture Profile
  420. case 0x71: // L1
  421. return 0x0F;
  422. case 0x72: // L2
  423. return 0x0E;
  424. // Hybrid Profile
  425. case 0x81: // L1
  426. return 0x0D;
  427. case 0x82: // L2
  428. return 0x0C;
  429. // Advanced Real Time Simple Profile
  430. case 0x91: // L1
  431. case 0x92: // L2
  432. case 0x93: // L3
  433. case 0x94: // L4
  434. // Core Scalable Profile
  435. case 0xA1: // L1
  436. case 0xA2: // L2
  437. case 0xA3: // L3
  438. // Advanced Coding Efficiency Profle
  439. case 0xB1: // L1
  440. case 0xB2: // L2
  441. case 0xB3: // L3
  442. case 0xB4: // L4
  443. // Advanced Core Profile
  444. case 0xC1: // L1
  445. case 0xC2: // L2
  446. // Advanced Scalable Texture Profile
  447. case 0xD1: // L1
  448. case 0xD2: // L2
  449. case 0xD3: // L3
  450. // from draft amendments
  451. // Simple Studio
  452. case 0xE1: // L1
  453. case 0xE2: // L2
  454. case 0xE3: // L3
  455. case 0xE4: // L4
  456. // Core Studio Profile
  457. case 0xE5: // L1
  458. case 0xE6: // L2
  459. case 0xE7: // L3
  460. case 0xE8: // L4
  461. // Advanced Simple Profile
  462. case 0xF1: // L0
  463. case 0xF2: // L1
  464. case 0xF3: // L2
  465. case 0xF4: // L3
  466. case 0xF5: // L4
  467. // Fine Granularity Scalable Profile
  468. case 0xF6: // L0
  469. case 0xF7: // L1
  470. case 0xF8: // L2
  471. case 0xF9: // L3
  472. case 0xFA: // L4
  473. default:
  474. return 0xFE;
  475. }
  476. }
  477. extern "C" u_char MP4AV_Mpeg4GetVopType(u_int8_t* pVopBuf, u_int32_t vopSize)
  478. {
  479. u_char vopType;
  480. if (MP4AV_Mpeg4ParseVop(pVopBuf, vopSize, &vopType, 0, 0, NULL)) {
  481. return vopType;
  482. }
  483. return 0;
  484. }