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

流媒体/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-2002.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. #include "mp4common.h"
  22. static char* PrintAudioInfo(
  23. MP4FileHandle mp4File, 
  24. MP4TrackId trackId)
  25. {
  26. static const char* mpeg4AudioNames[] = {
  27. "MPEG-4 Main @ L1",
  28. "MPEG-4 Main @ L2",
  29. "MPEG-4 Main @ L3",
  30. "MPEG-4 Main @ L4",
  31. "MPEG-4 Scalable @ L1",
  32. "MPEG-4 Scalable @ L2",
  33. "MPEG-4 Scalable @ L3",
  34. "MPEG-4 Scalable @ L4",
  35. "MPEG-4 Speech @ L1",
  36. "MPEG-4 Speech @ L2",
  37. "MPEG-4 Synthesis @ L1",
  38. "MPEG-4 Synthesis @ L2",
  39. "MPEG-4 Synthesis @ L3",
  40. };
  41. static u_int8_t numMpeg4AudioTypes = 
  42. sizeof(mpeg4AudioNames) / sizeof(char*);
  43. static u_int8_t mpegAudioTypes[] = {
  44. MP4_MPEG2_AAC_MAIN_AUDIO_TYPE, // 0x66
  45. MP4_MPEG2_AAC_LC_AUDIO_TYPE, // 0x67
  46. MP4_MPEG2_AAC_SSR_AUDIO_TYPE, // 0x68
  47. MP4_MPEG2_AUDIO_TYPE, // 0x69
  48. MP4_MPEG1_AUDIO_TYPE, // 0x6B
  49. MP4_PCM16_AUDIO_TYPE,
  50. MP4_VORBIS_AUDIO_TYPE,
  51. };
  52. static const char* mpegAudioNames[] = {
  53. "MPEG-2 AAC Main",
  54. "MPEG-2 AAC LC",
  55. "MPEG-2 AAC SSR",
  56. "MPEG-2 (MP3)",
  57. "MPEG-1 (MP3)",
  58. "PCM16",
  59. "OGG VORBIS",
  60. };
  61. static u_int8_t numMpegAudioTypes = 
  62. sizeof(mpegAudioTypes) / sizeof(u_int8_t);
  63. u_int8_t type =
  64. MP4GetTrackAudioType(mp4File, trackId);
  65. const char* typeName = "Unknown";
  66. if (type == MP4_MPEG4_AUDIO_TYPE) {
  67. type = MP4GetAudioProfileLevel(mp4File);
  68. if (type > 0 && type <= numMpeg4AudioTypes) {
  69. typeName = mpeg4AudioNames[type - 1];
  70. } else {
  71. typeName = "MPEG-4";
  72. }
  73. } else {
  74. for (u_int8_t i = 0; i < numMpegAudioTypes; i++) {
  75. if (type == mpegAudioTypes[i]) {
  76. typeName = mpegAudioNames[i];
  77. break;
  78. }
  79. }
  80. }
  81. u_int32_t timeScale =
  82. MP4GetTrackTimeScale(mp4File, trackId);
  83. MP4Duration trackDuration =
  84. MP4GetTrackDuration(mp4File, trackId);
  85. double msDuration =
  86. #ifdef _WIN32
  87. (int64_t)
  88. #endif
  89. MP4ConvertFromTrackDuration(mp4File, trackId, 
  90. trackDuration, MP4_MSECS_TIME_SCALE);
  91. u_int32_t avgBitRate =
  92. MP4GetTrackBitRate(mp4File, trackId);
  93. char *sInfo = (char*)MP4Malloc(256);
  94. // type duration avgBitrate samplingFrequency
  95. sprintf(sInfo,
  96. "%utaudiot%s, %.3f secs, %u kbps, %u Hzn", 
  97. trackId, 
  98. typeName,
  99. msDuration / 1000.0, 
  100. (avgBitRate + 500) / 1000, 
  101. timeScale);
  102. return sInfo;
  103. }
  104. static char* PrintVideoInfo(
  105. MP4FileHandle mp4File, 
  106. MP4TrackId trackId)
  107. {
  108. static const char* mpeg4VideoNames[] = {
  109. "MPEG-4 Simple @ L3",
  110. "MPEG-4 Simple @ L2",
  111. "MPEG-4 Simple @ L1",
  112. "MPEG-4 Simple Scalable @ L2",
  113. "MPEG-4 Simple Scalable @ L1",
  114. "MPEG-4 Core @ L2",
  115. "MPEG-4 Core @ L1",
  116. "MPEG-4 Main @ L4",
  117. "MPEG-4 Main @ L3",
  118. "MPEG-4 Main @ L2",
  119. "MPEG-4 Main @ L1",
  120. "MPEG-4 N-Bit @ L2",
  121. "MPEG-4 Hybrid @ L2",
  122. "MPEG-4 Hybrid @ L1",
  123. "MPEG-4 Hybrid @ L1",
  124. };
  125. static u_int8_t numMpeg4VideoTypes = 
  126. sizeof(mpeg4VideoNames) / sizeof(char*);
  127. static u_int8_t mpegVideoTypes[] = {
  128. MP4_MPEG2_SIMPLE_VIDEO_TYPE, // 0x60
  129. MP4_MPEG2_MAIN_VIDEO_TYPE, // 0x61
  130. MP4_MPEG2_SNR_VIDEO_TYPE, // 0x62
  131. MP4_MPEG2_SPATIAL_VIDEO_TYPE, // 0x63
  132. MP4_MPEG2_HIGH_VIDEO_TYPE, // 0x64
  133. MP4_MPEG2_442_VIDEO_TYPE, // 0x65
  134. MP4_MPEG1_VIDEO_TYPE, // 0x6A
  135. MP4_JPEG_VIDEO_TYPE, // 0x6C
  136. MP4_YUV12_VIDEO_TYPE,
  137. MP4_H26L_VIDEO_TYPE
  138. };
  139. static const char* mpegVideoNames[] = {
  140. "MPEG-2 Simple",
  141. "MPEG-2 Main",
  142. "MPEG-2 SNR",
  143. "MPEG-2 Spatial",
  144. "MPEG-2 High",
  145. "MPEG-2 4:2:2",
  146. "MPEG-1",
  147. "JPEG",
  148. "YUV12",
  149. "H26L"
  150. };
  151. static u_int8_t numMpegVideoTypes = 
  152. sizeof(mpegVideoTypes) / sizeof(u_int8_t);
  153. u_int8_t type =
  154. MP4GetTrackVideoType(mp4File, trackId);
  155. const char* typeName = "Unknown";
  156. if (type == MP4_MPEG4_VIDEO_TYPE) {
  157. type = MP4GetVideoProfileLevel(mp4File);
  158. if (type > 0 && type <= numMpeg4VideoTypes) {
  159. typeName = mpeg4VideoNames[type - 1];
  160. } else {
  161. typeName = "MPEG-4";
  162. }
  163. } else {
  164. for (u_int8_t i = 0; i < numMpegVideoTypes; i++) {
  165. if (type == mpegVideoTypes[i]) {
  166. typeName = mpegVideoNames[i];
  167. break;
  168. }
  169. }
  170. }
  171. MP4Duration trackDuration =
  172. MP4GetTrackDuration(mp4File, trackId);
  173. double msDuration =
  174. #ifdef _WIN32
  175. (int64_t)
  176. #endif
  177. MP4ConvertFromTrackDuration(mp4File, trackId, 
  178. trackDuration, MP4_MSECS_TIME_SCALE);
  179. u_int32_t avgBitRate =
  180. MP4GetTrackBitRate(mp4File, trackId);
  181. // Note not all mp4 implementations set width and height correctly
  182. // The real answer can be buried inside the ES configuration info
  183. u_int16_t width = MP4GetTrackVideoWidth(mp4File, trackId); 
  184. u_int16_t height = MP4GetTrackVideoHeight(mp4File, trackId); 
  185. float fps = MP4GetTrackVideoFrameRate(mp4File, trackId);
  186. char *sInfo = (char*)MP4Malloc(256);
  187. // type duration avgBitrate frameSize frameRate
  188. sprintf(sInfo, 
  189. "%utvideot%s, %.3f secs, %u kbps, %ux%u @ %.2f fpsn", 
  190. trackId, 
  191. typeName,
  192. msDuration / 1000.0, 
  193. (avgBitRate + 500) / 1000,
  194. width,
  195. height,
  196. fps
  197. );
  198. return sInfo;
  199. }
  200. static char* PrintHintInfo(
  201. MP4FileHandle mp4File, 
  202. MP4TrackId trackId)
  203. {
  204. MP4TrackId referenceTrackId =
  205. MP4GetHintTrackReferenceTrackId(mp4File, trackId);
  206. char* payloadName = NULL;
  207. MP4GetHintTrackRtpPayload(mp4File, trackId, &payloadName);
  208. char *sInfo = (char*)MP4Malloc(256);
  209. sprintf(sInfo,
  210. "%uthinttPayload %s for track %un", 
  211. trackId, 
  212. payloadName,
  213. referenceTrackId);
  214. free(payloadName);
  215. return sInfo;
  216. }
  217. static char* PrintTrackInfo(
  218. MP4FileHandle mp4File,
  219. MP4TrackId trackId)
  220. {
  221. char* trackInfo = NULL;
  222. const char* trackType = 
  223. MP4GetTrackType(mp4File, trackId);
  224. if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) {
  225. trackInfo = PrintAudioInfo(mp4File, trackId);
  226. } else if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) {
  227. trackInfo = PrintVideoInfo(mp4File, trackId);
  228. } else if (!strcmp(trackType, MP4_HINT_TRACK_TYPE)) {
  229. trackInfo = PrintHintInfo(mp4File, trackId);
  230. } else {
  231. trackInfo = (char*)MP4Malloc(256);
  232. if (!strcmp(trackType, MP4_OD_TRACK_TYPE)) {
  233. sprintf(trackInfo, 
  234. "%utodtObject Descriptorsn", 
  235. trackId);
  236. } else if (!strcmp(trackType, MP4_SCENE_TRACK_TYPE)) {
  237. sprintf(trackInfo,
  238. "%utscenetBIFSn", 
  239. trackId);
  240. } else {
  241. sprintf(trackInfo,
  242. "%ut%sn", 
  243. trackId, trackType);
  244. }
  245. }
  246. return trackInfo;
  247. }
  248. extern "C" char* MP4Info(
  249. MP4FileHandle mp4File,
  250. MP4TrackId trackId)
  251. {
  252. char* info = NULL;
  253. if (MP4_IS_VALID_FILE_HANDLE(mp4File)) {
  254. try {
  255. if (trackId == MP4_INVALID_TRACK_ID) {
  256. info = (char*)MP4Calloc(4*1024);
  257. sprintf(info, "TracktTypetInfon");
  258. u_int32_t numTracks = MP4GetNumberOfTracks(mp4File);
  259. for (u_int32_t i = 0; i < numTracks; i++) {
  260. trackId = MP4FindTrackId(mp4File, i);
  261. char* trackInfo = PrintTrackInfo(mp4File, trackId);
  262. strcat(info, trackInfo);
  263. MP4Free(trackInfo);
  264. }
  265. } else {
  266. info = PrintTrackInfo(mp4File, trackId);
  267. }
  268. }
  269. catch (MP4Error* e) {
  270. delete e;
  271. }
  272. }
  273. return info;
  274. }
  275. extern "C" char* MP4FileInfo(
  276. const char* fileName,
  277. MP4TrackId trackId)
  278. {
  279. MP4FileHandle mp4File = 
  280. MP4Read(fileName);
  281. if (!mp4File) {
  282. return NULL;
  283. }
  284. char* info = MP4Info(mp4File, trackId);
  285. MP4Close(mp4File);
  286. return info; // caller should free this
  287. }