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

流媒体/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. void MP4Error::Print(FILE* pFile)
  23. {
  24. fprintf(pFile, "MP4ERROR: ");
  25. if (m_where) {
  26. fprintf(pFile, "%s", m_where);
  27. }
  28. if (m_errstring) {
  29. if (m_where) {
  30. fprintf(pFile, ": ");
  31. }
  32. fprintf(pFile, "%s", m_errstring);
  33. }
  34. if (m_errno) {
  35. if (m_where || m_errstring) {
  36. fprintf(pFile, ": ");
  37. }
  38. fprintf(pFile, "%s", strerror(m_errno));
  39. }
  40. fprintf(pFile, "n");
  41. }
  42. void MP4HexDump(
  43. u_int8_t* pBytes, u_int32_t numBytes,
  44. FILE* pFile, u_int8_t indent)
  45. {
  46. if (pFile == NULL) {
  47. pFile = stdout;
  48. }
  49. Indent(pFile, indent);
  50. fprintf(pFile, "<%u bytes> ", numBytes);
  51. for (u_int32_t i = 0; i < numBytes; i++) {
  52. if ((i % 16) == 0 && numBytes > 16) {
  53. fprintf(pFile, "n");
  54. Indent(pFile, indent);
  55. }
  56. fprintf(pFile, "%02x ", pBytes[i]);
  57. }
  58. fprintf(pFile, "n");
  59. }
  60. bool MP4NameFirstMatches(const char* s1, const char* s2) 
  61. {
  62. if (s1 == NULL || *s1 == '' || s2 == NULL || *s2 == '') {
  63. return false;
  64. }
  65. if (*s2 == '*') {
  66. return true;
  67. }
  68. while (*s1 != '') {
  69. if (*s2 == '' || strchr("[.", *s2)) {
  70. break;
  71. }
  72. if (tolower(*s1) != tolower(*s2)) {
  73. return false;
  74. }
  75. s1++;
  76. s2++;
  77. }
  78. return true;
  79. }
  80. bool MP4NameFirstIndex(const char* s, u_int32_t* pIndex)
  81. {
  82. if (s == NULL) {
  83. return false;
  84. }
  85. while (*s != '' && *s != '.') {
  86. if (*s == '[') {
  87. s++;
  88. ASSERT(pIndex);
  89. if (sscanf(s, "%u", pIndex) != 1) {
  90. return false;
  91. }
  92. return true;
  93. }
  94. s++;
  95. }
  96. return false;
  97. }
  98. char* MP4NameFirst(const char *s)
  99. {
  100. if (s == NULL) {
  101. return NULL;
  102. }
  103. const char* end = s;
  104. while (*end != '' && *end != '.') {
  105. end++;
  106. }
  107. char* first = (char*)MP4Calloc((end - s) + 1);
  108. if (first) {
  109. strncpy(first, s, end - s);
  110. }
  111. return first;
  112. }
  113. const char* MP4NameAfterFirst(const char *s)
  114. {
  115. if (s == NULL) {
  116. return NULL;
  117. }
  118. while (*s != '') {
  119. if (*s == '.') {
  120. s++;
  121. if (*s == '') {
  122. return NULL;
  123. }
  124. return s;
  125. }
  126. s++;
  127. }
  128. return NULL;
  129. }
  130. char* MP4ToBase16(const u_int8_t* pData, u_int32_t dataSize)
  131. {
  132. if (dataSize) {
  133. ASSERT(pData);
  134. }
  135. char* s = (char*)MP4Calloc((2 * dataSize) + 1);
  136. u_int32_t i, j;
  137. for (i = 0, j = 0; i < dataSize; i++) {
  138. sprintf(&s[j], "%02x", pData[i]);
  139. j += 2;
  140. }
  141. return s; /* N.B. caller is responsible for free'ing s */
  142. }
  143. char* MP4ToBase64(const u_int8_t* pData, u_int32_t dataSize)
  144. {
  145. if (dataSize) {
  146. ASSERT(pData);
  147. }
  148. static char encoding[64] = {
  149. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
  150. 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
  151. 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
  152. 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
  153. };
  154. char* s = (char*)MP4Calloc((((dataSize + 2) * 4) / 3) + 1);
  155. const u_int8_t* src = pData;
  156. char* dest = s;
  157. u_int32_t numGroups = dataSize / 3;
  158. for (u_int32_t i = 0; i < numGroups; i++) {
  159. *dest++ = encoding[src[0] >> 2];
  160. *dest++ = encoding[((src[0] & 0x03) << 4) | (src[1] >> 4)];
  161. *dest++ = encoding[((src[1] & 0x0F) << 2) | (src[2] >> 6)];
  162. *dest++ = encoding[src[2] & 0x3F];
  163. src += 3;
  164. }
  165. if (dataSize % 3 == 1) {
  166. *dest++ = encoding[src[0] >> 2];
  167. *dest++ = encoding[((src[0] & 0x03) << 4)];
  168. *dest++ = '=';
  169. *dest++ = '=';
  170. } else if (dataSize % 3 == 2) {
  171. *dest++ = encoding[src[0] >> 2];
  172. *dest++ = encoding[((src[0] & 0x03) << 4) | (src[1] >> 4)];
  173. *dest++ = encoding[((src[1] & 0x0F) << 2)];
  174. *dest++ = '=';
  175. }
  176. return s; /* N.B. caller is responsible for free'ing s */
  177. }
  178. // log2 of value, rounded up
  179. static u_int8_t ilog2(u_int64_t value)
  180. {
  181. u_int64_t powerOf2 = 1;
  182. for (u_int8_t i = 0; i < 64; i++) {
  183. if (value <= powerOf2) {
  184. return i;
  185. }
  186. powerOf2 <<= 1;
  187. return 64;
  188. }
  189. u_int64_t MP4ConvertTime(u_int64_t t, 
  190. u_int32_t oldTimeScale, u_int32_t newTimeScale)
  191. {
  192. // avoid float point exception
  193. if (oldTimeScale == 0) {
  194. throw new MP4Error("division by zero", "MP4ConvertTime");
  195. }
  196. // check if we can safely use integer operations
  197. if (ilog2(t) + ilog2(newTimeScale) <= 64) {
  198. return (t * newTimeScale) / oldTimeScale;
  199. }
  200. // final resort is to use floating point
  201. double d = ((double)newTimeScale / (double)oldTimeScale) + 0.5;
  202. #ifdef _WINDOWS
  203. d *= (double)(int64_t)t;
  204. #else
  205. d *= (double)t;
  206. #endif
  207. return (u_int64_t)d;
  208. }