diff Input/aac/libmp4v2/mp4info.cpp @ 2:6efb9e514224 trunk

[svn] Import AAC stuff.
author nenolod
date Mon, 24 Oct 2005 10:44:27 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Input/aac/libmp4v2/mp4info.cpp	Mon Oct 24 10:44:27 2005 -0700
@@ -0,0 +1,346 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		dmackie@cisco.com
+ */
+
+#include "mp4common.h"
+
+static char* PrintAudioInfo(
+	MP4FileHandle mp4File, 
+	MP4TrackId trackId)
+{
+	static const char* mpeg4AudioNames[] = {
+		"MPEG-4 Main @ L1",
+		"MPEG-4 Main @ L2",
+		"MPEG-4 Main @ L3",
+		"MPEG-4 Main @ L4",
+		"MPEG-4 Scalable @ L1",
+		"MPEG-4 Scalable @ L2",
+		"MPEG-4 Scalable @ L3",
+		"MPEG-4 Scalable @ L4",
+		"MPEG-4 Speech @ L1",
+		"MPEG-4 Speech @ L2",
+		"MPEG-4 Synthesis @ L1",
+		"MPEG-4 Synthesis @ L2",
+		"MPEG-4 Synthesis @ L3",
+	};
+	static u_int8_t numMpeg4AudioTypes = 
+		sizeof(mpeg4AudioNames) / sizeof(char*);
+
+	static u_int8_t mpegAudioTypes[] = {
+		MP4_MPEG2_AAC_MAIN_AUDIO_TYPE,	// 0x66
+		MP4_MPEG2_AAC_LC_AUDIO_TYPE,	// 0x67
+		MP4_MPEG2_AAC_SSR_AUDIO_TYPE,	// 0x68
+		MP4_MPEG2_AUDIO_TYPE,			// 0x69
+		MP4_MPEG1_AUDIO_TYPE,			// 0x6B
+		MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE,
+		MP4_VORBIS_AUDIO_TYPE,
+		MP4_ALAW_AUDIO_TYPE,
+		MP4_ULAW_AUDIO_TYPE,
+		MP4_G723_AUDIO_TYPE,
+		MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE,
+	};
+	static const char* mpegAudioNames[] = {
+		"MPEG-2 AAC Main",
+		"MPEG-2 AAC LC",
+		"MPEG-2 AAC SSR",
+		"MPEG-2 (MP3)",
+		"MPEG-1 (MP3)",
+		"PCM16 (little endian)",
+		"OGG VORBIS",
+		"G.711 aLaw",
+		"G.711 uLaw",
+		"G.723.1",
+		"PCM16 (big endian)",
+	};
+	static u_int8_t numMpegAudioTypes = 
+		sizeof(mpegAudioTypes) / sizeof(u_int8_t);
+
+	u_int8_t type =
+		MP4GetTrackAudioType(mp4File, trackId);
+	const char* typeName = "Unknown";
+
+	if (type == MP4_MPEG4_AUDIO_TYPE) {
+		type = MP4GetAudioProfileLevel(mp4File);
+		if (type > 0 && type <= numMpeg4AudioTypes) {
+			typeName = mpeg4AudioNames[type - 1];
+		} else {
+			typeName = "MPEG-4";
+		}
+	} else {
+		for (u_int8_t i = 0; i < numMpegAudioTypes; i++) {
+			if (type == mpegAudioTypes[i]) {
+				typeName = mpegAudioNames[i];
+				break;
+			}
+		}
+	}
+
+	u_int32_t timeScale =
+		MP4GetTrackTimeScale(mp4File, trackId);
+
+	MP4Duration trackDuration =
+		MP4GetTrackDuration(mp4File, trackId);
+
+	double msDuration =
+#ifdef _WIN32
+		(int64_t)
+#endif
+		MP4ConvertFromTrackDuration(mp4File, trackId, 
+			trackDuration, MP4_MSECS_TIME_SCALE);
+
+	u_int32_t avgBitRate =
+		MP4GetTrackBitRate(mp4File, trackId);
+
+	char *sInfo = (char*)MP4Malloc(256);
+
+	// type duration avgBitrate samplingFrequency
+	sprintf(sInfo,	
+		"%u\taudio\t%s, %.3f secs, %u kbps, %u Hz\n", 
+		trackId, 
+		typeName,
+		msDuration / 1000.0, 
+		(avgBitRate + 500) / 1000, 
+		timeScale);
+
+	return sInfo;
+}
+
+static char* PrintVideoInfo(
+	MP4FileHandle mp4File, 
+	MP4TrackId trackId)
+{
+	static const char* mpeg4VideoNames[] = {
+		"MPEG-4 Simple @ L3",
+		"MPEG-4 Simple @ L2",
+		"MPEG-4 Simple @ L1",
+		"MPEG-4 Simple Scalable @ L2",
+		"MPEG-4 Simple Scalable @ L1",
+		"MPEG-4 Core @ L2",
+		"MPEG-4 Core @ L1",
+		"MPEG-4 Main @ L4",
+		"MPEG-4 Main @ L3",
+		"MPEG-4 Main @ L2",
+		"MPEG-4 Main @ L1",
+		"MPEG-4 N-Bit @ L2",
+		"MPEG-4 Hybrid @ L2",
+		"MPEG-4 Hybrid @ L1",
+		"MPEG-4 Hybrid @ L1",
+	};
+	static u_int8_t numMpeg4VideoTypes = 
+		sizeof(mpeg4VideoNames) / sizeof(char*);
+
+	static u_int8_t mpegVideoTypes[] = {
+		MP4_MPEG2_SIMPLE_VIDEO_TYPE,	// 0x60
+		MP4_MPEG2_MAIN_VIDEO_TYPE,		// 0x61
+		MP4_MPEG2_SNR_VIDEO_TYPE,		// 0x62
+		MP4_MPEG2_SPATIAL_VIDEO_TYPE,	// 0x63
+		MP4_MPEG2_HIGH_VIDEO_TYPE,		// 0x64
+		MP4_MPEG2_442_VIDEO_TYPE,		// 0x65
+		MP4_MPEG1_VIDEO_TYPE,			// 0x6A
+		MP4_JPEG_VIDEO_TYPE,			// 0x6C
+		MP4_YUV12_VIDEO_TYPE,			
+		MP4_H264_VIDEO_TYPE,
+		MP4_H263_VIDEO_TYPE,		
+		MP4_H261_VIDEO_TYPE,
+	};
+	static const char* mpegVideoNames[] = {
+		"MPEG-2 Simple",
+		"MPEG-2 Main",
+		"MPEG-2 SNR",
+		"MPEG-2 Spatial",
+		"MPEG-2 High",
+		"MPEG-2 4:2:2",
+		"MPEG-1",
+		"JPEG",
+		"YUV12",
+		"H.264",
+		"H.263",
+		"H.261",
+	};
+	static u_int8_t numMpegVideoTypes = 
+		sizeof(mpegVideoTypes) / sizeof(u_int8_t);
+
+	u_int8_t type =
+		MP4GetTrackVideoType(mp4File, trackId);
+	const char* typeName = "Unknown";
+
+	if (type == MP4_MPEG4_VIDEO_TYPE) {
+		type = MP4GetVideoProfileLevel(mp4File);
+		if (type > 0 && type <= numMpeg4VideoTypes) {
+			typeName = mpeg4VideoNames[type - 1];
+		} else {
+			typeName = "MPEG-4";
+		}
+	} else {
+		for (u_int8_t i = 0; i < numMpegVideoTypes; i++) {
+			if (type == mpegVideoTypes[i]) {
+				typeName = mpegVideoNames[i];
+				break;
+			}
+		}
+	}
+
+	MP4Duration trackDuration =
+		MP4GetTrackDuration(mp4File, trackId);
+
+	double msDuration =
+#ifdef _WIN32
+		(int64_t)
+#endif
+		MP4ConvertFromTrackDuration(mp4File, trackId, 
+			trackDuration, MP4_MSECS_TIME_SCALE);
+
+	u_int32_t avgBitRate =
+		MP4GetTrackBitRate(mp4File, trackId);
+
+	// Note not all mp4 implementations set width and height correctly
+	// The real answer can be buried inside the ES configuration info
+	u_int16_t width = MP4GetTrackVideoWidth(mp4File, trackId); 
+
+	u_int16_t height = MP4GetTrackVideoHeight(mp4File, trackId); 
+
+	float fps = MP4GetTrackVideoFrameRate(mp4File, trackId);
+
+	char *sInfo = (char*)MP4Malloc(256);
+
+	// type duration avgBitrate frameSize frameRate
+	sprintf(sInfo, 
+		"%u\tvideo\t%s, %.3f secs, %u kbps, %ux%u @ %.2f fps\n", 
+		trackId, 
+		typeName,
+		msDuration / 1000.0, 
+		(avgBitRate + 500) / 1000,
+		width,	
+		height,
+		fps
+	);
+
+	return sInfo;
+}
+
+static char* PrintHintInfo(
+	MP4FileHandle mp4File, 
+	MP4TrackId trackId)
+{
+	MP4TrackId referenceTrackId =
+		MP4GetHintTrackReferenceTrackId(mp4File, trackId);
+
+	char* payloadName = NULL;
+	MP4GetHintTrackRtpPayload(mp4File, trackId, &payloadName);		
+
+	char *sInfo = (char*)MP4Malloc(256);
+
+	sprintf(sInfo,
+		"%u\thint\tPayload %s for track %u\n", 
+		trackId, 
+		payloadName,
+		referenceTrackId);
+
+	free(payloadName);
+
+	return sInfo;
+}
+
+static char* PrintTrackInfo(
+	MP4FileHandle mp4File,
+	MP4TrackId trackId)
+{
+	char* trackInfo = NULL;
+
+	const char* trackType = 
+		MP4GetTrackType(mp4File, trackId);
+
+	if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) {
+		trackInfo = PrintAudioInfo(mp4File, trackId);
+	} else if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) {
+		trackInfo = PrintVideoInfo(mp4File, trackId);
+	} else if (!strcmp(trackType, MP4_HINT_TRACK_TYPE)) {
+		trackInfo = PrintHintInfo(mp4File, trackId);
+	} else {
+		trackInfo = (char*)MP4Malloc(256);
+		if (!strcmp(trackType, MP4_OD_TRACK_TYPE)) {
+			sprintf(trackInfo, 
+				"%u\tod\tObject Descriptors\n", 
+				trackId);
+		} else if (!strcmp(trackType, MP4_SCENE_TRACK_TYPE)) {
+			sprintf(trackInfo,
+				"%u\tscene\tBIFS\n", 
+				trackId);
+		} else {
+			sprintf(trackInfo,
+					"%u\t%s\n", 
+					trackId, trackType);
+		}
+	}
+
+	return trackInfo;
+}
+
+extern "C" char* MP4Info(
+	MP4FileHandle mp4File,
+	MP4TrackId trackId)
+{
+	char* info = NULL;
+
+	if (MP4_IS_VALID_FILE_HANDLE(mp4File)) {
+		try {
+			if (trackId == MP4_INVALID_TRACK_ID) {
+				info = (char*)MP4Calloc(4*1024);
+
+				sprintf(info, "Track\tType\tInfo\n");
+
+				u_int32_t numTracks = MP4GetNumberOfTracks(mp4File);
+
+				for (u_int32_t i = 0; i < numTracks; i++) {
+					trackId = MP4FindTrackId(mp4File, i);
+					char* trackInfo = PrintTrackInfo(mp4File, trackId);
+					strcat(info, trackInfo);
+					MP4Free(trackInfo);
+				}
+			} else {
+				info = PrintTrackInfo(mp4File, trackId);
+			}
+		}
+		catch (MP4Error* e) {
+			delete e;
+		}
+	}
+
+	return info;
+}
+
+extern "C" char* MP4FileInfo(
+	const char* fileName,
+	MP4TrackId trackId)
+{
+	MP4FileHandle mp4File = 
+		MP4Read(fileName);
+
+	if (!mp4File) {
+		return NULL;
+	}
+
+	char* info = MP4Info(mp4File, trackId);
+
+	MP4Close(mp4File);
+
+	return info;	// caller should free this
+}
+