mp4stream.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* ///////////////////////////////////////////////////////////////////////
  2. //
  3. // INTEL CORPORATION PROPRIETARY INFORMATION
  4. // This software is supplied under the terms of a license agreement or
  5. // nondisclosure agreement with Intel Corporation and may not be copied
  6. // or disclosed except in accordance with the terms of that agreement.
  7. // Copyright (c) 2001-2008 Intel Corporation. All Rights Reserved.
  8. //
  9. // Description: Decodes MPEG-4 bitstream.
  10. //
  11. */
  12. #include "mp4def.h"
  13. #ifndef USE_INLINE_BITS_FUNC
  14. uint32_t mp4_ShowBits(mp4_Info* pInfo, int32_t n)
  15. {
  16. uint8_t* ptr = pInfo->bufptr;
  17. uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
  18. tmp <<= pInfo->bitoff;
  19. tmp >>= 32 - n;
  20. return tmp;
  21. }
  22. uint32_t mp4_ShowBit(mp4_Info* pInfo)
  23. {
  24. uint32_t tmp = pInfo->bufptr[0];
  25. tmp >>= 7 - pInfo->bitoff;
  26. return (tmp & 1);
  27. }
  28. uint32_t mp4_ShowBits9(mp4_Info* pInfo, int32_t n)
  29. {
  30. uint8_t* ptr = pInfo->bufptr;
  31. uint32_t tmp = (ptr[0] << 8) | ptr[1];
  32. tmp <<= (pInfo->bitoff + 16);
  33. tmp >>= 32 - n;
  34. return tmp;
  35. }
  36. void mp4_FlushBits(mp4_Info* pInfo, int32_t n)
  37. {
  38. n = n + pInfo->bitoff;
  39. pInfo->bufptr += n >> 3;
  40. pInfo->bitoff = n & 7;
  41. }
  42. uint32_t mp4_GetBits(mp4_Info* pInfo, int32_t n)
  43. {
  44. uint8_t* ptr = pInfo->bufptr;
  45. uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
  46. tmp <<= pInfo->bitoff;
  47. tmp >>= 32 - n;
  48. n = n + pInfo->bitoff;
  49. pInfo->bufptr += n >> 3;
  50. pInfo->bitoff = n & 7;
  51. return tmp;
  52. }
  53. uint32_t mp4_GetBits9(mp4_Info* pInfo, int32_t n)
  54. {
  55. uint8_t* ptr = pInfo->bufptr;
  56. uint32_t tmp = (ptr[0] << 8) | ptr[1];
  57. tmp <<= (pInfo->bitoff + 16);
  58. tmp >>= 32 - n;
  59. n = n + pInfo->bitoff;
  60. pInfo->bufptr += n >> 3;
  61. pInfo->bitoff = n & 7;
  62. return tmp;
  63. }
  64. void mp4_AlignBits(mp4_Info* pInfo)
  65. {
  66. if (pInfo->bitoff > 0) {
  67. pInfo->bitoff = 0;
  68. (pInfo->bufptr)++;
  69. }
  70. }
  71. void mp4_AlignBits7F(mp4_Info* pInfo)
  72. {
  73. if (pInfo->bitoff > 0) {
  74. pInfo->bitoff = 0;
  75. (pInfo->bufptr)++;
  76. } else {
  77. if (*pInfo->bufptr == 0x7F)
  78. (pInfo->bufptr)++;
  79. }
  80. }
  81. uint32_t mp4_ShowBitsAlign(mp4_Info* pInfo, int32_t n)
  82. {
  83. uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
  84. uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
  85. tmp >>= 32 - n;
  86. return tmp;
  87. }
  88. uint32_t mp4_ShowBitsAlign7F(mp4_Info* pInfo, int32_t n)
  89. {
  90. uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
  91. uint32_t tmp;
  92. if (!pInfo->bitoff) {
  93. if (*ptr == 0x7F)
  94. ptr ++;
  95. }
  96. tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
  97. tmp >>= 32 - n;
  98. return tmp;
  99. }
  100. #endif
  101. uint8_t* mp4_FindStartCodePtr(mp4_Info* pInfo)
  102. {
  103. int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
  104. uint8_t* ptr = pInfo->bufptr;
  105. for (i = 0; i < len - 3; i++) {
  106. if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 1) {
  107. return ptr + i + 3;
  108. }
  109. }
  110. return NULL;
  111. }
  112. uint8_t* mp4_FindStartCodeOrShortPtr(mp4_Info* pInfo)
  113. {
  114. int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
  115. uint8_t* ptr = pInfo->bufptr;
  116. for (i = 0; i < len - 3; i++) {
  117. if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 1) {
  118. return ptr + i + 3;
  119. }
  120. // short_video_header
  121. if (ptr[i] == 0 && ptr[i + 1] == 0 && (ptr[i + 2] & 0xFC) == 0x80) {
  122. return ptr + i;
  123. }
  124. }
  125. return NULL;
  126. }
  127. int32_t mp4_SeekStartCodePtr(mp4_Info* pInfo)
  128. {
  129. uint8_t* ptr;
  130. if (pInfo->bitoff) {
  131. pInfo->bufptr ++;
  132. pInfo->bitoff = 0;
  133. }
  134. ptr = mp4_FindStartCodePtr(pInfo);
  135. if (ptr) {
  136. pInfo->bufptr = ptr;
  137. return 1;
  138. } else {
  139. pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0);
  140. return 0;
  141. }
  142. }
  143. int32_t mp4_SeekStartCodeOrShortPtr(mp4_Info* pInfo)
  144. {
  145. uint8_t* ptr;
  146. if (pInfo->bitoff) {
  147. pInfo->bufptr ++;
  148. pInfo->bitoff = 0;
  149. }
  150. ptr = mp4_FindStartCodeOrShortPtr(pInfo);
  151. if (ptr) {
  152. pInfo->bufptr = ptr;
  153. return 1;
  154. } else {
  155. pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0);
  156. return 0;
  157. }
  158. }
  159. int32_t mp4_SeekStartCodeValue(mp4_Info* pInfo, uint8_t code)
  160. {
  161. while (mp4_SeekStartCodePtr(pInfo)) {
  162. if (*(pInfo->bufptr) == code) {
  163. (pInfo->bufptr) ++;
  164. return 1;
  165. }
  166. }
  167. return 0;
  168. }
  169. uint8_t* mp4_FindShortVideoStartMarkerPtr(mp4_Info* pInfo)
  170. {
  171. int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
  172. uint8_t* ptr = pInfo->bufptr;
  173. for (i = 0; i < len - 3; i++) {
  174. if (ptr[i] == 0 && ptr[i + 1] == 0 && (ptr[i + 2] & (~3)) == 0x80) {
  175. return ptr + i + 2;
  176. }
  177. }
  178. return NULL;
  179. }
  180. int32_t mp4_SeekShortVideoStartMarker(mp4_Info* pInfo)
  181. {
  182. uint8_t* ptr;
  183. if (pInfo->bitoff) {
  184. pInfo->bufptr ++;
  185. pInfo->bitoff = 0;
  186. }
  187. ptr = mp4_FindShortVideoStartMarkerPtr(pInfo);
  188. if (ptr) {
  189. pInfo->bufptr = ptr;
  190. return 1;
  191. } else {
  192. pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0);
  193. return 0;
  194. }
  195. }
  196. //changed pInfo->len on pInfo->buflen!!!
  197. int32_t mp4_SeekGOBMarker(mp4_Info* pInfo)
  198. {
  199. for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) {
  200. if (pInfo->bufptr[0] == 0) {
  201. pInfo->bitoff = 0;
  202. if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && (pInfo->bufptr[2] & (~3)) == 0x80)
  203. return 0;
  204. pInfo->bufptr --;
  205. for (pInfo->bitoff = 1; pInfo->bitoff <= 7; pInfo->bitoff ++) {
  206. if (mp4_ShowBits(pInfo, 17) == 1)
  207. return 1;
  208. }
  209. pInfo->bufptr ++;
  210. for (pInfo->bitoff = 0; pInfo->bitoff <= 7; pInfo->bitoff ++) {
  211. if (mp4_ShowBits(pInfo, 17) == 1)
  212. return 1;
  213. }
  214. pInfo->bufptr ++;
  215. }
  216. }
  217. return 0;
  218. }
  219. int32_t mp4_SeekResyncMarker(mp4_Info* pInfo)
  220. {
  221. int32_t rml;
  222. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I)
  223. rml = 17;
  224. else if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
  225. rml = 16 + IPP_MAX(pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward, pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward);
  226. else
  227. rml = 16 + pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
  228. pInfo->bitoff = 0;
  229. for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) {
  230. if (pInfo->bufptr[0] == 0) {
  231. if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && pInfo->bufptr[2] == 1)
  232. return 0;
  233. if (mp4_ShowBits(pInfo, rml) == 1) {
  234. // check stuffing bits
  235. pInfo->bufptr --;
  236. pInfo->bitoff = 7;
  237. while (pInfo->bitoff > 0 && mp4_ShowBit(pInfo))
  238. pInfo->bitoff --;
  239. if (pInfo->bitoff == 0 && mp4_ShowBit(pInfo)) {
  240. // stuffing bits are invalid
  241. pInfo->bufptr[0] = 0x7f;
  242. }
  243. return 1;
  244. }
  245. pInfo->bufptr += 2;
  246. }
  247. }
  248. return 0;
  249. }
  250. int32_t mp4_FindResyncMarker(mp4_Info* pInfo)
  251. {
  252. int32_t rml;
  253. if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I)
  254. rml = 17;
  255. else if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
  256. rml = 16 + IPP_MAX(pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward, pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward);
  257. else
  258. rml = 16 + pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
  259. pInfo->bitoff = 0;
  260. for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) {
  261. if (pInfo->bufptr[0] == 0)
  262. {
  263. if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && pInfo->bufptr[2] == 1)
  264. return 0;
  265. if (mp4_ShowBits(pInfo, rml) == 1)
  266. {
  267. return rml;
  268. }
  269. }
  270. }
  271. return 0;
  272. }
  273. int mp4_IsStartCodeOrShort(mp4_Info* pInfo)
  274. {
  275. if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && (pInfo->bufptr[2] == 1 || ((pInfo->bufptr[2] & 0xFC) == 0x80)))
  276. return 1;
  277. return 0;
  278. }
  279. int mp4_IsStartCodeValue(mp4_Info* pInfo, int min, int max)
  280. {
  281. if (pInfo->bufptr[0-3] == 0 && pInfo->bufptr[1-3] == 0 && pInfo->bufptr[2-3] == 1)
  282. if (pInfo->bufptr[3-3] >= min && pInfo->bufptr[3-3] <= max)
  283. return 1;
  284. return 0;
  285. }
  286. int mp4_IsShortCode(mp4_Info* pInfo)
  287. {
  288. if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && ((pInfo->bufptr[2] & 0xFC) == 0x80))
  289. return 1;
  290. return 0;
  291. }