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