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 #define UINT64_C(c) (c ## ULL) 31 extern "C" { 32 #include "avcodec.h" 33 34 #ifdef DEBUG 35 // Needed to fix debug build, otherwise the linker complains about 36 // "undefined reference to `ff_log2_tab'" 37 const uint8_t ff_log2_tab[256] = {0}; 38 #endif 39 40 } // extern "C" 41 42 void 43 PrintFormat(const media_format &format) 44 { 45 char s[200]; 46 string_for_format(format, s, sizeof(s)); 47 printf("%s\n", s); 48 } 49 50 51 void 52 PrintFormat(const media_output &output) 53 { 54 PrintFormat(output.format); 55 } 56 57 58 static status_t 59 GetHeaderFormatAc3Audio(media_format *out_format, const uint8 *header, size_t size) 60 { 61 printf("GetHeaderFormatAc3Audio\n"); 62 63 status_t status; 64 media_format_description desc; 65 // desc.family = B_WAV_FORMAT_FAMILY; 66 // desc.u.wav.codec = 0x2000; 67 desc.family = B_MISC_FORMAT_FAMILY; 68 desc.u.misc.file_format = 'ffmp'; 69 desc.u.misc.codec = CODEC_ID_AC3; 70 71 BMediaFormats formats; 72 status = formats.InitCheck(); 73 if (status) { 74 printf("formats.InitCheck failed, error %lu\n", status); 75 return status; 76 } 77 78 status = formats.GetFormatFor(desc, out_format); 79 if (status) { 80 printf("formats.GetFormatFor failed, error %lu\n", status); 81 return status; 82 } 83 84 return B_OK; 85 } 86 87 88 89 static status_t 90 GetHeaderFormatDtsAudio(media_format *out_format, const uint8 *header, size_t size) 91 { 92 printf("GetHeaderFormatDtsAudio: unsupported\n"); 93 return B_ERROR; 94 } 95 96 97 static status_t 98 GetHeaderFormatLpcmAudio(media_format *out_format, const uint8 *header, size_t size) 99 { 100 printf("GetHeaderFormatLpcmAudio: unsupported\n"); 101 return B_ERROR; 102 } 103 104 105 static status_t 106 GetHeaderFormatPrivateStream(media_format *out_format, const uint8 *header, size_t size) 107 { 108 printf("GetHeaderFormatPrivateStream: unsupported, assuming AC3\n"); 109 return GetHeaderFormatAc3Audio(out_format, header, size); 110 } 111 112 113 static status_t 114 GetHeaderFormatMpegAudio(media_format *out_format, const uint8 *header, size_t size) 115 { 116 printf("GetHeaderFormatMpegAudio\n"); 117 118 status_t status; 119 media_format_description desc; 120 // desc.family = B_MPEG_FORMAT_FAMILY; 121 // desc.u.mpeg.id = B_MPEG_2_AUDIO_LAYER_2; 122 desc.family = B_MISC_FORMAT_FAMILY; 123 desc.u.misc.file_format = 'ffmp'; 124 desc.u.misc.codec = CODEC_ID_MP3; 125 126 127 BMediaFormats formats; 128 status = formats.InitCheck(); 129 if (status) { 130 printf("formats.InitCheck failed, error %lu\n", status); 131 return status; 132 } 133 134 status = formats.GetFormatFor(desc, out_format); 135 if (status) { 136 printf("formats.GetFormatFor failed, error %lu\n", status); 137 return status; 138 } 139 140 out_format->u.encoded_audio.output.frame_rate = 48000; 141 out_format->u.encoded_audio.output.channel_count = 2; 142 out_format->u.encoded_audio.output.buffer_size = 1024; 143 return B_OK; 144 } 145 146 147 static status_t 148 GetHeaderFormatMpegVideo(media_format *out_format, const uint8 *header, size_t size) 149 { 150 printf("GetHeaderFormatMpegVideo\n"); 151 152 status_t status; 153 media_format_description desc; 154 // desc.family = B_MPEG_FORMAT_FAMILY; 155 // desc.u.mpeg.id = B_MPEG_2_VIDEO; 156 desc.family = B_MISC_FORMAT_FAMILY; 157 desc.u.misc.file_format = 'ffmp'; 158 desc.u.misc.codec = CODEC_ID_MPEG2VIDEO; 159 160 BMediaFormats formats; 161 status = formats.InitCheck(); 162 if (status) { 163 printf("formats.InitCheck failed, error %lu\n", status); 164 return status; 165 } 166 167 status = formats.GetFormatFor(desc, out_format); 168 if (status) { 169 printf("formats.GetFormatFor failed, error %lu\n", status); 170 return status; 171 } 172 173 return B_OK; 174 } 175 176 177 status_t 178 GetHeaderFormat(media_format *out_format, const void *header, size_t size, int stream_id) 179 { 180 const uint8 *h = (const uint8 *)header; 181 status_t status; 182 183 printf("GetHeaderFormat: stream_id %02x\n", stream_id); 184 printf("inner frame header: " 185 "%02x %02x %02x %02x %02x %02x %02x %02x " 186 "%02x %02x %02x %02x %02x %02x %02x %02x\n", 187 h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], 188 h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]); 189 190 if (stream_id >= 0x80 && stream_id <= 0x87) 191 status = GetHeaderFormatAc3Audio(out_format, h, size); 192 else if (stream_id >= 0x88 && stream_id <= 0x8F) 193 status = GetHeaderFormatDtsAudio(out_format, h, size); 194 else if (stream_id >= 0xA0 && stream_id <= 0xA7) 195 status = GetHeaderFormatLpcmAudio(out_format, h, size); 196 else if (stream_id == 0xBD) 197 status = GetHeaderFormatPrivateStream(out_format, h, size); 198 else if (stream_id >= 0xC0 && stream_id <= 0xDF) 199 status = GetHeaderFormatMpegAudio(out_format, h, size); 200 else if (stream_id >= 0xE0 && stream_id <= 0xEF) 201 status = GetHeaderFormatMpegVideo(out_format, h, size); 202 else { 203 printf("GetHeaderFormat: don't know what this stream_id means\n"); 204 status = B_ERROR; 205 } 206 207 if (status != B_OK) { 208 printf("GetHeaderFormat: failed!\n"); 209 } else { 210 printf("GetHeaderFormat: out_format "); 211 PrintFormat(*out_format); 212 } 213 return status; 214 } 215