1/*
2** Copyright 2004, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3** Distributed under the terms of the MIT License.
4*/
5
6
7#include <MediaFormats.h>
8
9#include <stdio.h>
10#include <string.h>
11
12
13static const char *
14get_family_string(media_format_family family)
15{
16	switch (family) {
17		case B_BEOS_FORMAT_FAMILY:
18			return "BeOS";
19		case B_ANY_FORMAT_FAMILY:
20			return "any";
21		case B_QUICKTIME_FORMAT_FAMILY:
22			return "QuickTime";
23		case B_AVI_FORMAT_FAMILY:
24			return "AVI";
25		case B_ASF_FORMAT_FAMILY:
26			return "ASF";
27		case B_MPEG_FORMAT_FAMILY:
28			return "MPEG";
29		case B_WAV_FORMAT_FAMILY:
30			return "WAV";
31		case B_AIFF_FORMAT_FAMILY:
32			return "AIFF";
33		case B_AVR_FORMAT_FAMILY:
34			return "AVR";
35		case B_MISC_FORMAT_FAMILY:
36			return "misc";
37// these are Haiku specific:
38//		case B_OGG_FORMAT_FAMILY:
39//			return "OGG";
40//		case B_META_FORMAT_FAMILY:
41//			return "meta";
42		default:
43			return "unknown";
44	}
45}
46
47
48static const char *
49get_mpeg_string(int32 id)
50{
51	switch (id) {
52		case B_MPEG_ANY:
53			return "any";
54		case B_MPEG_1_AUDIO_LAYER_1:
55			return "mpeg 1 audio layer 1";
56		case B_MPEG_1_AUDIO_LAYER_2:
57			return "mpeg 1 audio layer 2";
58		case B_MPEG_1_AUDIO_LAYER_3:
59			return "mpeg 1 audio layer 3 (mp3)";
60		case B_MPEG_1_VIDEO:
61			return "mpeg 1 video";
62// these are Haiku specific:
63/*		case B_MPEG_2_AUDIO_LAYER_1:
64			return "mpeg 2 audio layer 1";
65		case B_MPEG_2_AUDIO_LAYER_2:
66			return "mpeg 2 audio layer 2";
67		case B_MPEG_2_AUDIO_LAYER_3:
68			return "mpeg 2 audio layer 3";
69		case B_MPEG_2_VIDEO:
70			return "mpeg 2 video";
71		case B_MPEG_2_5_AUDIO_LAYER_1:
72			return "mpeg 2.5 audio layer 1";
73		case B_MPEG_2_5_AUDIO_LAYER_2:
74			return "mpeg 2.5 audio layer 2";
75		case B_MPEG_2_5_AUDIO_LAYER_3:
76			return "mpeg 2.5 audio layer 3";
77*/		default:
78			return "unknown";
79	}
80}
81
82
83static void
84print_fourcc(uint32 id)
85{
86	char string[5];
87	for (int32 i = 0; i < 4; i++) {
88		uint8 c = uint8((id >> (24 - i * 8)) & 0xff);
89		if (c < ' ' || c > 0x7f)
90			string[i] = '.';
91		else
92			string[i] = (char)c;
93	}
94	string[4] = '\0';
95	printf("%s (0x%lx)\n", string, id);
96}
97
98
99void
100dump_media_format_description(media_format_description &description)
101{
102	printf("media_format_description:\n");
103	printf("\tfamily:\t%s\n", get_family_string(description.family));
104
105	switch (description.family) {
106		case B_BEOS_FORMAT_FAMILY:
107			printf("\tformat:\t");
108			print_fourcc(description.u.beos.format);
109			break;
110		case B_AVI_FORMAT_FAMILY:
111		case B_AIFF_FORMAT_FAMILY:
112		case B_WAV_FORMAT_FAMILY:
113			printf("\tcodec:\t");
114			print_fourcc(description.u.avi.codec);
115			break;
116		case B_AVR_FORMAT_FAMILY:
117			printf("\tid:\t");
118			print_fourcc(description.u.avr.id);
119			break;
120		case B_QUICKTIME_FORMAT_FAMILY:
121			printf("\tcodec:\t");
122			print_fourcc(description.u.quicktime.codec);
123			printf("\tvendor:\t");
124			print_fourcc(description.u.quicktime.vendor);
125			break;
126		case B_MISC_FORMAT_FAMILY:
127			printf("\tcodec:\t\t");
128			print_fourcc(description.u.misc.file_format);
129			printf("\tfile format:\t");
130			print_fourcc(description.u.misc.codec);
131			break;
132		case B_MPEG_FORMAT_FAMILY:
133			printf("\ttype:\t%s\n", get_mpeg_string(description.u.mpeg.id));
134			break;
135		case B_ASF_FORMAT_FAMILY:
136			// note, this is endian depended - you shouldn't do it this way for real...
137			printf("\tguid:\t0x%Lx%Lx\n", *(uint64 *)&description.u.asf.guid.data[0], *(uint64 *)&description.u.asf.guid.data[8]);
138		default:
139			break;
140	}
141}
142
143
144int
145main(int argc, char **argv)
146{
147	BMediaFormats formats;
148
149	status_t status = formats.InitCheck();
150	if (status != B_OK) {
151		fprintf(stderr, "BMediaFormats::InitCheck() failed: %s\n", strerror(status));
152		return -1;
153	}
154
155	media_format format;
156	status = formats.GetAVIFormatFor('DIVX', &format, B_MEDIA_ENCODED_VIDEO);
157	if (status != B_OK) {
158		fprintf(stderr, "BMediaFormats::GetAVIFormatFor() failed: %s\n", strerror(status));
159		return -1;
160	}
161
162	media_format_description description;
163	status = formats.GetCodeFor(format, B_AVI_FORMAT_FAMILY, &description);
164	if (status != B_OK) {
165		fprintf(stderr, "BMediaFormats::GetCodeFor() failed: %s\n", strerror(status));
166		return -1;
167	}
168	dump_media_format_description(description);
169
170	char desc[256];
171	string_for_format(format, desc, sizeof(desc));
172	printf("\tformat:\t%s\n", desc);
173
174	status = formats.GetCodeFor(format, B_MPEG_FORMAT_FAMILY, &description);
175	if (status == B_OK) {
176		fprintf(stderr, "BMediaFormats::GetCodeFor() succeded with wrong family!\n");
177		return -1;
178	}
179
180	puts("\n***** all supported formats *****");
181
182	// Rewind() should only work when the formats object is locked
183	status = formats.RewindFormats();
184	if (status == B_OK) {
185		fprintf(stderr, "BMediaFormats::RewindFormats() succeded unlocked!\n");
186		return -1;
187	}
188
189	if (!formats.Lock()) {
190		fprintf(stderr, "BMediaFormats::Lock() failed!\n");
191		return -1;
192	}
193
194	status = formats.RewindFormats();
195	if (status != B_OK) {
196		fprintf(stderr, "BMediaFormats::RewindFormats() failed: %s\n", strerror(status));
197		return -1;
198	}
199
200	int32 count = 0;
201	while ((status = formats.GetNextFormat(&format, &description)) == B_OK) {
202		dump_media_format_description(description);
203		string_for_format(format, desc, sizeof(desc));
204		printf("\tformat:\t%s\n", desc);
205		count++;
206	}
207	if (status != B_BAD_INDEX)
208		fprintf(stderr, "BMediaFormats::GetNextFormat() failed: %s\n", strerror(status));
209
210	printf("***** %ld supported formats *****\n", count);
211
212	formats.Unlock();
213	return 0;
214}
215