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

流媒体/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. 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. #include "mp4common.h"
  22. #ifdef HAVE_FPOS_T_POS
  23. #define FPOS_TO_UINT64(x) ((u_int64_t)((x).__pos))
  24. #define UINT64_TO_FPOS(x, y) ((x).__pos = (y))
  25. #else 
  26. #define FPOS_TO_UINT64(x) ((u_int64_t)(x))
  27. #define UINT64_TO_FPOS(x, y) ((x) = (fpos)(y))
  28. #endif
  29. // MP4File low level IO support
  30. u_int64_t MP4File::GetPosition(FILE* pFile)
  31. {
  32. if (m_memoryBuffer == NULL) {
  33. if (pFile == NULL) {
  34. ASSERT(m_pFile);
  35. pFile = m_pFile;
  36. }
  37. fpos_t fpos;
  38. if (fgetpos(pFile, &fpos) < 0) {
  39. throw new MP4Error(errno, "MP4GetPosition");
  40. }
  41. return FPOS_TO_UINT64(fpos);
  42. } else {
  43. return m_memoryBufferPosition;
  44. }
  45. }
  46. void MP4File::SetPosition(u_int64_t pos, FILE* pFile)
  47. {
  48. if (m_memoryBuffer == NULL) {
  49. if (pFile == NULL) {
  50. ASSERT(m_pFile);
  51. pFile = m_pFile;
  52. }
  53. fpos_t fpos;
  54. VAR_TO_FPOS(fpos, pos);
  55. if (fsetpos(pFile, &fpos) < 0) {
  56. throw new MP4Error(errno, "MP4SetPosition");
  57. }
  58. } else {
  59. if (pos >= m_memoryBufferSize) {
  60. throw new MP4Error("position out of range", "MP4SetPosition");
  61. }
  62. m_memoryBufferPosition = pos;
  63. }
  64. }
  65. u_int64_t MP4File::GetSize()
  66. {
  67. if (m_mode == 'w') {
  68. // we're always positioned at the end of file in write mode
  69. // except for short intervals in ReadSample and FinishWrite routines
  70. // so we rely on the faster approach of GetPosition()
  71. // instead of flushing to disk, and then stat'ing the file
  72. m_fileSize = GetPosition();
  73. } // else read mode, fileSize was determined at Open()
  74. return m_fileSize;
  75. }
  76. u_int32_t MP4File::ReadBytes(u_int8_t* pBytes, u_int32_t numBytes, FILE* pFile)
  77. {
  78. // handle degenerate cases
  79. if (numBytes == 0) {
  80. return 0;
  81. }
  82. ASSERT(pBytes);
  83. WARNING(m_numReadBits > 0);
  84. if (pFile == NULL) {
  85. pFile = m_pFile;
  86. }
  87. ASSERT(pFile);
  88. if (m_memoryBuffer == NULL) {
  89. if (fread(pBytes, 1, numBytes, pFile) != numBytes) {
  90. if (feof(pFile)) {
  91. throw new MP4Error(
  92. "not enough bytes, reached end-of-file",
  93. "MP4ReadBytes");
  94. } else {
  95. throw new MP4Error(errno, "MP4ReadBytes");
  96. }
  97. }
  98. } else {
  99. if (m_memoryBufferPosition + numBytes > m_memoryBufferSize) {
  100. throw new MP4Error(
  101. "not enough bytes, reached end-of-memory",
  102. "MP4ReadBytes");
  103. }
  104. memcpy(pBytes, &m_memoryBuffer[m_memoryBufferPosition], numBytes);
  105. m_memoryBufferPosition += numBytes;
  106. }
  107. return numBytes;
  108. }
  109. u_int32_t MP4File::PeekBytes(u_int8_t* pBytes, u_int32_t numBytes, FILE* pFile)
  110. {
  111. u_int64_t pos = GetPosition(pFile);
  112. ReadBytes(pBytes, numBytes, pFile);
  113. SetPosition(pos, pFile);
  114. return numBytes;
  115. }
  116. void MP4File::EnableMemoryBuffer(u_int8_t* pBytes, u_int64_t numBytes) 
  117. {
  118. ASSERT(m_memoryBuffer == NULL);
  119. if (pBytes) {
  120. m_memoryBuffer = pBytes;
  121. m_memoryBufferSize = numBytes;
  122. } else {
  123. if (numBytes) {
  124. m_memoryBufferSize = numBytes;
  125. } else {
  126. m_memoryBufferSize = 1024;
  127. }
  128. m_memoryBuffer = (u_int8_t*)MP4Malloc(m_memoryBufferSize);
  129. }
  130. m_memoryBufferPosition = 0;
  131. }
  132. void MP4File::DisableMemoryBuffer(u_int8_t** ppBytes, u_int64_t* pNumBytes) 
  133. {
  134. ASSERT(m_memoryBuffer != NULL);
  135. if (ppBytes) {
  136. *ppBytes = m_memoryBuffer;
  137. }
  138. if (pNumBytes) {
  139. *pNumBytes = m_memoryBufferPosition;
  140. }
  141. m_memoryBuffer = NULL;
  142. m_memoryBufferSize = 0;
  143. m_memoryBufferPosition = 0;
  144. }
  145. void MP4File::WriteBytes(u_int8_t* pBytes, u_int32_t numBytes, FILE* pFile)
  146. {
  147. ASSERT(m_numWriteBits == 0 || m_numWriteBits >= 8);
  148. if (pBytes == NULL || numBytes == 0) {
  149. return;
  150. }
  151. if (m_memoryBuffer == NULL) {
  152. if (pFile == NULL) {
  153. ASSERT(m_pFile);
  154. pFile = m_pFile;
  155. }
  156. u_int32_t rc = fwrite(pBytes, 1, numBytes, pFile);
  157. if (rc != numBytes) {
  158. throw new MP4Error(errno, "MP4WriteBytes");
  159. }
  160. } else {
  161. if (m_memoryBufferPosition + numBytes > m_memoryBufferSize) {
  162. m_memoryBufferSize = 2 * (m_memoryBufferSize + numBytes);
  163. m_memoryBuffer = (u_int8_t*)
  164. MP4Realloc(m_memoryBuffer, m_memoryBufferSize);
  165. }
  166. memcpy(&m_memoryBuffer[m_memoryBufferPosition], pBytes, numBytes);
  167. m_memoryBufferPosition += numBytes;
  168. }
  169. }
  170. u_int64_t MP4File::ReadUInt(u_int8_t size)
  171. {
  172. switch (size) {
  173. case 1:
  174. return ReadUInt8();
  175. case 2:
  176. return ReadUInt16();
  177. case 3:
  178. return ReadUInt24();
  179. case 4:
  180. return ReadUInt32();
  181. case 8:
  182. return ReadUInt64();
  183. default:
  184. ASSERT(false);
  185. return 0;
  186. }
  187. }
  188. void MP4File::WriteUInt(u_int64_t value, u_int8_t size)
  189. {
  190. switch (size) {
  191. case 1:
  192. WriteUInt8(value);
  193. case 2:
  194. WriteUInt16(value);
  195. case 3:
  196. WriteUInt24(value);
  197. case 4:
  198. WriteUInt32(value);
  199. case 8:
  200. WriteUInt64(value);
  201. default:
  202. ASSERT(false);
  203. }
  204. }
  205. u_int8_t MP4File::ReadUInt8()
  206. {
  207. u_int8_t data;
  208. ReadBytes(&data, 1);
  209. return data;
  210. }
  211. void MP4File::WriteUInt8(u_int8_t value)
  212. {
  213. WriteBytes(&value, 1);
  214. }
  215. u_int16_t MP4File::ReadUInt16()
  216. {
  217. u_int8_t data[2];
  218. ReadBytes(&data[0], 2);
  219. return ((data[0] << 8) | data[1]);
  220. }
  221. void MP4File::WriteUInt16(u_int16_t value)
  222. {
  223. u_int8_t data[2];
  224. data[0] = (value >> 8) & 0xFF;
  225. data[1] = value & 0xFF;
  226. WriteBytes(data, 2);
  227. }
  228. u_int32_t MP4File::ReadUInt24()
  229. {
  230. u_int8_t data[3];
  231. ReadBytes(&data[0], 3);
  232. return ((data[0] << 16) | (data[1] << 8) | data[2]);
  233. }
  234. void MP4File::WriteUInt24(u_int32_t value)
  235. {
  236. u_int8_t data[3];
  237. data[0] = (value >> 16) & 0xFF;
  238. data[1] = (value >> 8) & 0xFF;
  239. data[2] = value & 0xFF;
  240. WriteBytes(data, 3);
  241. }
  242. u_int32_t MP4File::ReadUInt32()
  243. {
  244. u_int8_t data[4];
  245. ReadBytes(&data[0], 4);
  246. return ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
  247. }
  248. void MP4File::WriteUInt32(u_int32_t value)
  249. {
  250. u_int8_t data[4];
  251. data[0] = (value >> 24) & 0xFF;
  252. data[1] = (value >> 16) & 0xFF;
  253. data[2] = (value >> 8) & 0xFF;
  254. data[3] = value & 0xFF;
  255. WriteBytes(data, 4);
  256. }
  257. u_int64_t MP4File::ReadUInt64()
  258. {
  259. u_int8_t data[8];
  260. u_int64_t result = 0;
  261. u_int64_t temp;
  262. ReadBytes(&data[0], 8);
  263. for (int i = 0; i < 8; i++) {
  264. temp = data[i];
  265. result |= temp << ((7 - i) * 8);
  266. }
  267. return result;
  268. }
  269. void MP4File::WriteUInt64(u_int64_t value)
  270. {
  271. u_int8_t data[8];
  272. for (int i = 7; i >= 0; i--) {
  273. data[i] = value & 0xFF;
  274. value >>= 8;
  275. }
  276. WriteBytes(data, 8);
  277. }
  278. float MP4File::ReadFixed16()
  279. {
  280. u_int8_t iPart = ReadUInt8();
  281. u_int8_t fPart = ReadUInt8();
  282. return iPart + (((float)fPart) / 0x100);
  283. }
  284. void MP4File::WriteFixed16(float value)
  285. {
  286. if (value >= 0x100) {
  287. throw new MP4Error(ERANGE, "MP4WriteFixed16");
  288. }
  289. u_int8_t iPart = (u_int8_t)value;
  290. u_int8_t fPart = (u_int8_t)((value - iPart) * 0x100);
  291. WriteUInt8(iPart);
  292. WriteUInt8(fPart);
  293. }
  294. float MP4File::ReadFixed32()
  295. {
  296. u_int16_t iPart = ReadUInt16();
  297. u_int16_t fPart = ReadUInt16();
  298. return iPart + (((float)fPart) / 0x10000);
  299. }
  300. void MP4File::WriteFixed32(float value)
  301. {
  302. if (value >= 0x10000) {
  303. throw new MP4Error(ERANGE, "MP4WriteFixed32");
  304. }
  305. u_int16_t iPart = (u_int16_t)value;
  306. u_int16_t fPart = (u_int16_t)((value - iPart) * 0x10000);
  307. WriteUInt16(iPart);
  308. WriteUInt16(fPart);
  309. }
  310. float MP4File::ReadFloat()
  311. {
  312. union {
  313. float f;
  314. u_int32_t i;
  315. } u;
  316. u.i = ReadUInt32();
  317. return u.f;
  318. }
  319. void MP4File::WriteFloat(float value)
  320. {
  321. union {
  322. float f;
  323. u_int32_t i;
  324. } u;
  325. u.f = value;
  326. WriteUInt32(u.i);
  327. }
  328. char* MP4File::ReadString()
  329. {
  330. u_int32_t length = 0;
  331. u_int32_t alloced = 64;
  332. char* data = (char*)MP4Malloc(alloced);
  333. do {
  334. if (length == alloced) {
  335. data = (char*)MP4Realloc(data, alloced * 2);
  336. }
  337. ReadBytes((u_int8_t*)&data[length], 1);
  338. length++;
  339. } while (data[length - 1] != 0);
  340. data = (char*)MP4Realloc(data, length);
  341. return data;
  342. }
  343. void MP4File::WriteString(char* string)
  344. {
  345. if (string == NULL) {
  346. static u_int8_t zero = 0;
  347. WriteBytes(&zero, 1);
  348. } else {
  349. WriteBytes((u_int8_t*)string, strlen(string) + 1);
  350. }
  351. }
  352. char* MP4File::ReadCountedString(u_int8_t charSize, bool allowExpandedCount)
  353. {
  354. u_int32_t charLength;
  355. if (allowExpandedCount) {
  356. u_int8_t b;
  357. charLength = 0;
  358. do {
  359. b = ReadUInt8();
  360. charLength += b;
  361. } while (b == 255);
  362. } else {
  363. charLength = ReadUInt8();
  364. }
  365. u_int32_t byteLength = charLength * charSize;
  366. char* data = (char*)MP4Malloc(byteLength + 1);
  367. if (byteLength > 0) {
  368. ReadBytes((u_int8_t*)data, byteLength);
  369. }
  370. data[byteLength] = '';
  371. return data;
  372. }
  373. void MP4File::WriteCountedString(char* string, 
  374. u_int8_t charSize, bool allowExpandedCount)
  375. {
  376. u_int32_t byteLength;
  377. if (string) {
  378. byteLength = strlen(string);
  379. } else {
  380. byteLength = 0;
  381. }
  382. u_int32_t charLength = byteLength / charSize;
  383. if (allowExpandedCount) {
  384. while (charLength >= 0xFF) {
  385. WriteUInt8(0xFF);
  386. charLength -= 0xFF;
  387. }
  388. WriteUInt8(charLength);
  389. } else {
  390. if (charLength > 255) {
  391. throw new MP4Error(ERANGE, "MP4WriteCountedString");
  392. }
  393. WriteUInt8(charLength);
  394. }
  395. if (byteLength > 0) {
  396. WriteBytes((u_int8_t*)string, byteLength);
  397. }
  398. }
  399. u_int64_t MP4File::ReadBits(u_int8_t numBits)
  400. {
  401. ASSERT(numBits > 0);
  402. ASSERT(numBits <= 64);
  403. u_int64_t bits = 0;
  404. for (u_int8_t i = numBits; i > 0; i--) {
  405. if (m_numReadBits == 0) {
  406. ReadBytes(&m_bufReadBits, 1);
  407. m_numReadBits = 8;
  408. }
  409. bits = (bits << 1) | ((m_bufReadBits >> (--m_numReadBits)) & 1);
  410. }
  411. return bits;
  412. }
  413. void MP4File::FlushReadBits()
  414. {
  415. // eat any remaining bits in the read buffer
  416. m_numReadBits = 0;
  417. }
  418. void MP4File::WriteBits(u_int64_t bits, u_int8_t numBits)
  419. {
  420. ASSERT(numBits <= 64);
  421. for (u_int8_t i = numBits; i > 0; i--) {
  422. m_bufWriteBits |= 
  423. (((bits >> (i - 1)) & 1) << (8 - ++m_numWriteBits));
  424. if (m_numWriteBits == 8) {
  425. FlushWriteBits();
  426. }
  427. }
  428. }
  429. void MP4File::PadWriteBits(u_int8_t pad)
  430. {
  431. if (m_numWriteBits) {
  432. WriteBits(pad ? 0xFF : 0x00, 8 - m_numWriteBits);
  433. }
  434. }
  435. void MP4File::FlushWriteBits()
  436. {
  437. if (m_numWriteBits > 0) {
  438. WriteBytes(&m_bufWriteBits, 1);
  439. m_numWriteBits = 0;
  440. m_bufWriteBits = 0;
  441. }
  442. }
  443. u_int32_t MP4File::ReadMpegLength()
  444. {
  445. u_int32_t length = 0;
  446. u_int8_t numBytes = 0;
  447. u_int8_t b;
  448. do {
  449. b = ReadUInt8();
  450. length = (length << 7) | (b & 0x7F);
  451. numBytes++;
  452. } while ((b & 0x80) && numBytes < 4);
  453. return length;
  454. }
  455. void MP4File::WriteMpegLength(u_int32_t value, bool compact)
  456. {
  457. if (value > 0x0FFFFFFF) {
  458. throw new MP4Error(ERANGE, "MP4WriteMpegLength");
  459. }
  460. int8_t numBytes;
  461. if (compact) {
  462. if (value <= 0x7F) {
  463. numBytes = 1;
  464. } else if (value <= 0x3FFF) {
  465. numBytes = 2;
  466. } else if (value <= 0x1FFFFF) {
  467. numBytes = 3;
  468. } else {
  469. numBytes = 4;
  470. }
  471. } else {
  472. numBytes = 4;
  473. }
  474. int8_t i = numBytes;
  475. do {
  476. i--;
  477. u_int8_t b = (value >> (i * 7)) & 0x7F;
  478. if (i > 0) {
  479. b |= 0x80;
  480. }
  481. WriteUInt8(b);
  482. } while (i > 0);
  483. }