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
PrintFormat(const media_format & format)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
PrintFormat(const media_output & output)59 PrintFormat(const media_output &output)
60 {
61 PrintFormat(output.format);
62 }
63
64
65 static status_t
GetHeaderFormatAc3Audio(media_format * out_format,const uint8 * header,size_t size)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
GetHeaderFormatDtsAudio(media_format * out_format,const uint8 * header,size_t size)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
GetHeaderFormatLpcmAudio(media_format * out_format,const uint8 * header,size_t size)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
GetHeaderFormatPrivateStream(media_format * out_format,const uint8 * header,size_t size)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
GetHeaderFormatMpegAudio(media_format * out_format,const uint8 * header,size_t size)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
GetHeaderFormatMpegVideo(media_format * out_format,const uint8 * header,size_t size)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
GetHeaderFormat(media_format * out_format,const void * header,size_t size,int stream_id)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