xref: /haiku/src/add-ons/media/media-add-ons/dvb/MediaFormat.cpp (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
1 /*
2  * Copyright (c) 2004-2010 Marcus Overhagen <marcus@overhagen.de>
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify,
8  * merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <media/MediaFormats.h>
26 #include <media/MediaNode.h>
27 #include <stdio.h>
28 #include "MediaFormat.h"
29 
30 extern "C" {
31   #include "avcodec.h"
32 
33 #ifdef DEBUG
34   // Needed to fix debug build, otherwise the linker complains about
35   // "undefined reference to `ff_log2_tab'"
36   const uint8_t ff_log2_tab[256] = {0};
37 #endif
38 
39 }  // extern "C"
40 
41 
42 #if LIBAVCODEC_VERSION_INT <= ((54 << 16) | (50 << 8))
43 #define AV_CODEC_ID_AC3 CODEC_ID_AC3
44 #define AV_CODEC_ID_MP3 CODEC_ID_MP3
45 #define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
46 #endif
47 
48 
49 void
50 PrintFormat(const media_format &format)
51 {
52 	char s[200];
53 	string_for_format(format, s, sizeof(s));
54 	printf("%s\n", s);
55 }
56 
57 
58 void
59 PrintFormat(const media_output &output)
60 {
61 	PrintFormat(output.format);
62 }
63 
64 
65 static status_t
66 GetHeaderFormatAc3Audio(media_format *out_format, const uint8 *header, size_t size)
67 {
68 	printf("GetHeaderFormatAc3Audio\n");
69 
70 	status_t status;
71 	media_format_description desc;
72 //	desc.family = B_WAV_FORMAT_FAMILY;
73 //	desc.u.wav.codec = 0x2000;
74 	desc.family = B_MISC_FORMAT_FAMILY;
75 	desc.u.misc.file_format = 'ffmp';
76 	desc.u.misc.codec = AV_CODEC_ID_AC3;
77 
78 	BMediaFormats formats;
79 	status = formats.InitCheck();
80 	if (status) {
81 		printf("formats.InitCheck failed, error %lu\n", status);
82 		return status;
83 	}
84 
85 	status = formats.GetFormatFor(desc, out_format);
86 	if (status) {
87 		printf("formats.GetFormatFor failed, error %lu\n", status);
88 		return status;
89 	}
90 
91 	return B_OK;
92 }
93 
94 
95 
96 static status_t
97 GetHeaderFormatDtsAudio(media_format *out_format, const uint8 *header, size_t size)
98 {
99 	printf("GetHeaderFormatDtsAudio: unsupported\n");
100 	return B_ERROR;
101 }
102 
103 
104 static status_t
105 GetHeaderFormatLpcmAudio(media_format *out_format, const uint8 *header, size_t size)
106 {
107 	printf("GetHeaderFormatLpcmAudio: unsupported\n");
108 	return B_ERROR;
109 }
110 
111 
112 static status_t
113 GetHeaderFormatPrivateStream(media_format *out_format, const uint8 *header, size_t size)
114 {
115 	printf("GetHeaderFormatPrivateStream: unsupported, assuming AC3\n");
116 	return GetHeaderFormatAc3Audio(out_format, header, size);
117 }
118 
119 
120 static status_t
121 GetHeaderFormatMpegAudio(media_format *out_format, const uint8 *header, size_t size)
122 {
123 	printf("GetHeaderFormatMpegAudio\n");
124 
125 	status_t status;
126 	media_format_description desc;
127 //	desc.family = B_MPEG_FORMAT_FAMILY;
128 //	desc.u.mpeg.id = B_MPEG_2_AUDIO_LAYER_2;
129 	desc.family = B_MISC_FORMAT_FAMILY;
130 	desc.u.misc.file_format = 'ffmp';
131 	desc.u.misc.codec = AV_CODEC_ID_MP3;
132 
133 
134 	BMediaFormats formats;
135 	status = formats.InitCheck();
136 	if (status) {
137 		printf("formats.InitCheck failed, error %lu\n", status);
138 		return status;
139 	}
140 
141 	status = formats.GetFormatFor(desc, out_format);
142 	if (status) {
143 		printf("formats.GetFormatFor failed, error %lu\n", status);
144 		return status;
145 	}
146 
147 	out_format->u.encoded_audio.output.frame_rate = 48000;
148 	out_format->u.encoded_audio.output.channel_count = 2;
149 	out_format->u.encoded_audio.output.buffer_size = 1024;
150 	return B_OK;
151 }
152 
153 
154 static status_t
155 GetHeaderFormatMpegVideo(media_format *out_format, const uint8 *header, size_t size)
156 {
157 	printf("GetHeaderFormatMpegVideo\n");
158 
159 	status_t status;
160 	media_format_description desc;
161 //	desc.family = B_MPEG_FORMAT_FAMILY;
162 //	desc.u.mpeg.id = B_MPEG_2_VIDEO;
163 	desc.family = B_MISC_FORMAT_FAMILY;
164 	desc.u.misc.file_format = 'ffmp';
165 	desc.u.misc.codec = AV_CODEC_ID_MPEG2VIDEO;
166 
167 	BMediaFormats formats;
168 	status = formats.InitCheck();
169 	if (status) {
170 		printf("formats.InitCheck failed, error %lu\n", status);
171 		return status;
172 	}
173 
174 	status = formats.GetFormatFor(desc, out_format);
175 	if (status) {
176 		printf("formats.GetFormatFor failed, error %lu\n", status);
177 		return status;
178 	}
179 
180 	return B_OK;
181 }
182 
183 
184 status_t
185 GetHeaderFormat(media_format *out_format, const void *header, size_t size, int stream_id)
186 {
187 	const uint8 *h = (const uint8 *)header;
188 	status_t status;
189 
190 	printf("GetHeaderFormat: stream_id %02x\n", stream_id);
191 	printf("inner frame header: "
192 		   "%02x %02x %02x %02x %02x %02x %02x %02x "
193 		   "%02x %02x %02x %02x %02x %02x %02x %02x\n",
194 		   h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7],
195 		   h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]);
196 
197 	if (stream_id >= 0x80 && stream_id <= 0x87)
198 		status = GetHeaderFormatAc3Audio(out_format, h, size);
199 	else if (stream_id >= 0x88 && stream_id <= 0x8F)
200 		status = GetHeaderFormatDtsAudio(out_format, h, size);
201 	else if (stream_id >= 0xA0 && stream_id <= 0xA7)
202 		status = GetHeaderFormatLpcmAudio(out_format, h, size);
203 	else if (stream_id == 0xBD)
204 		status = GetHeaderFormatPrivateStream(out_format, h, size);
205 	else if (stream_id >= 0xC0 && stream_id <= 0xDF)
206 		status = GetHeaderFormatMpegAudio(out_format, h, size);
207 	else if (stream_id >= 0xE0 && stream_id <= 0xEF)
208 		status = GetHeaderFormatMpegVideo(out_format, h, size);
209 	else {
210 		printf("GetHeaderFormat: don't know what this stream_id means\n");
211 		status = B_ERROR;
212 	}
213 
214 	if (status != B_OK) {
215 		printf("GetHeaderFormat: failed!\n");
216 	} else {
217 		printf("GetHeaderFormat: out_format ");
218 		PrintFormat(*out_format);
219 	}
220 	return status;
221 }
222