1 #include <stdio.h> 2 #include <string.h> 3 #include <DataIO.h> 4 #include <OS.h> 5 #include <MediaRoster.h> 6 #include "RawFormats.h" 7 #include "RawDecoderPlugin.h" 8 #include "AudioConversion.h" 9 10 #define TRACE_THIS 0 11 #if TRACE_THIS 12 #define TRACE printf 13 #else 14 #define TRACE(a...) 15 #endif 16 17 inline size_t 18 AudioBufferSize(int32 channel_count, uint32 sample_format, float frame_rate, bigtime_t buffer_duration = 50000 /* 50 ms */) 19 { 20 return (sample_format & 0xf) * channel_count * (size_t)((frame_rate * buffer_duration) / 1000000.0); 21 } 22 23 24 void 25 RawDecoder::GetCodecInfo(media_codec_info *info) 26 { 27 strcpy(info->short_name, "raw"); 28 29 if (fInputFormat.IsAudio()) 30 strcpy(info->pretty_name, "Raw audio decoder"); 31 else 32 strcpy(info->pretty_name, "Raw video decoder"); 33 } 34 35 36 status_t 37 RawDecoder::Setup(media_format *ioEncodedFormat, 38 const void *infoBuffer, int32 infoSize) 39 { 40 char s[200]; 41 string_for_format(*ioEncodedFormat, s, sizeof(s)); 42 TRACE("RawDecoder::Setup: %s\n", s); 43 44 if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO) 45 return B_ERROR; 46 47 fInputFormat = *ioEncodedFormat; 48 49 if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO) { 50 fInputSampleSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row; 51 fInputFrameSize = fInputSampleSize; 52 } else { 53 fInputSampleSize = (ioEncodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK); 54 fInputFrameSize = fInputSampleSize * ioEncodedFormat->u.raw_audio.channel_count; 55 } 56 57 // since ioEncodedFormat is later passed to the application by BMediaTrack::EncodedFormat() 58 // we need to remove non public format specifications 59 60 // remove non format bits, like channel order 61 ioEncodedFormat->u.raw_audio.format &= B_AUDIO_FORMAT_MASK; 62 63 switch (ioEncodedFormat->u.raw_audio.format) { 64 case B_AUDIO_FORMAT_UINT8: 65 case B_AUDIO_FORMAT_INT8: 66 case B_AUDIO_FORMAT_INT16: 67 case B_AUDIO_FORMAT_INT32: 68 case B_AUDIO_FORMAT_FLOAT32: 69 break; // ok to pass through 70 71 case B_AUDIO_FORMAT_INT24: 72 ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_INT32; 73 break; 74 75 case B_AUDIO_FORMAT_FLOAT64: 76 ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_FLOAT32; 77 break; 78 79 default: 80 TRACE("RawDecoder::Setup: unknown input format\n"); 81 return B_ERROR; 82 } 83 84 // since we can translate to a different buffer size, 85 // suggest something nicer than delivered by the 86 // file reader (perhaps we should even report wildcard?) 87 ioEncodedFormat->u.raw_audio.buffer_size = AudioBufferSize( 88 ioEncodedFormat->u.raw_audio.channel_count, 89 ioEncodedFormat->u.raw_audio.format, 90 ioEncodedFormat->u.raw_audio.frame_rate); 91 return B_OK; 92 } 93 94 95 status_t 96 RawDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat) 97 { 98 // BeBook says: The codec will find and return in ioFormat its best matching format 99 // => This means, we never return an error, and always change the format values 100 // that we don't support to something more applicable 101 if (ioDecodedFormat->type == B_MEDIA_RAW_VIDEO) 102 return NegotiateVideoOutputFormat(ioDecodedFormat); 103 if (ioDecodedFormat->type == B_MEDIA_RAW_AUDIO) 104 return NegotiateAudioOutputFormat(ioDecodedFormat); 105 return B_ERROR; 106 } 107 108 109 status_t 110 RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat) 111 { 112 return B_ERROR; 113 } 114 115 116 status_t 117 RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat) 118 { 119 char s[1024]; 120 121 string_for_format(*ioDecodedFormat, s, sizeof(s)); 122 TRACE("RawDecoder::NegotiateAudioOutputFormat enter: %s\n", s); 123 124 ioDecodedFormat->type = B_MEDIA_RAW_AUDIO; 125 switch (ioDecodedFormat->u.raw_audio.format) { 126 case media_raw_audio_format::B_AUDIO_FLOAT: 127 case media_raw_audio_format::B_AUDIO_SHORT: 128 case media_raw_audio_format::B_AUDIO_UCHAR: 129 case media_raw_audio_format::B_AUDIO_CHAR: 130 ioDecodedFormat->u.raw_audio.valid_bits = 0; 131 break; // we can produce this on request 132 133 case media_raw_audio_format::B_AUDIO_INT: 134 ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits; 135 break; // we can produce this on request 136 137 default: 138 switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) { 139 case media_raw_audio_format::B_AUDIO_SHORT: 140 case media_raw_audio_format::B_AUDIO_UCHAR: 141 case media_raw_audio_format::B_AUDIO_CHAR: 142 ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK; 143 ioDecodedFormat->u.raw_audio.valid_bits = 0; 144 break; 145 146 case media_raw_audio_format::B_AUDIO_INT: 147 case B_AUDIO_FORMAT_INT24: 148 ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT; 149 ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits; 150 break; 151 152 case media_raw_audio_format::B_AUDIO_FLOAT: 153 case B_AUDIO_FORMAT_FLOAT64: 154 default: 155 ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT; 156 ioDecodedFormat->u.raw_audio.valid_bits = 0; 157 break; 158 } 159 break; 160 } 161 162 fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate; 163 ioDecodedFormat->u.raw_audio.frame_rate = fInputFormat.u.raw_audio.frame_rate; 164 ioDecodedFormat->u.raw_audio.channel_count = fInputFormat.u.raw_audio.channel_count; 165 166 fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK); 167 fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count; 168 169 if (ioDecodedFormat->u.raw_audio.byte_order == 0) 170 ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; 171 172 ioDecodedFormat->u.raw_audio.channel_mask = 0; 173 ioDecodedFormat->u.raw_audio.matrix_mask = 0; 174 175 if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) { 176 ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize( 177 ioDecodedFormat->u.raw_audio.channel_count, 178 ioDecodedFormat->u.raw_audio.format, 179 ioDecodedFormat->u.raw_audio.frame_rate); 180 } else { 181 // round down to exact multiple of output frame size 182 ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize; 183 } 184 185 fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize; 186 187 // setup input swapping function 188 if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) { 189 fSwapInput = 0; 190 } else { 191 switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) { 192 case B_AUDIO_FORMAT_INT16: 193 fSwapInput = &swap_int16; 194 break; 195 case B_AUDIO_FORMAT_INT24: 196 fSwapInput = &swap_int24; 197 break; 198 case B_AUDIO_FORMAT_INT32: 199 fSwapInput = &swap_int32; 200 break; 201 case B_AUDIO_FORMAT_FLOAT32: 202 fSwapInput = &swap_float32; 203 break; 204 case B_AUDIO_FORMAT_FLOAT64: 205 fSwapInput = &swap_float64; 206 break; 207 case B_AUDIO_FORMAT_UINT8: 208 case B_AUDIO_FORMAT_INT8: 209 fSwapInput = 0; 210 break; 211 default: 212 debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n"); 213 break; 214 } 215 } 216 217 // setup output swapping function 218 if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) { 219 fSwapOutput = 0; 220 } else { 221 switch (ioDecodedFormat->u.raw_audio.format) { 222 case B_AUDIO_FORMAT_INT16: 223 fSwapOutput = &swap_int16; 224 break; 225 case B_AUDIO_FORMAT_INT32: 226 fSwapOutput = &swap_int32; 227 break; 228 case B_AUDIO_FORMAT_FLOAT32: 229 fSwapOutput = &swap_float32; 230 break; 231 case B_AUDIO_FORMAT_UINT8: 232 case B_AUDIO_FORMAT_INT8: 233 fSwapOutput = 0; 234 break; 235 default: 236 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 237 break; 238 } 239 } 240 241 // setup sample conversation function 242 switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) { 243 case B_AUDIO_FORMAT_UINT8: 244 switch (ioDecodedFormat->u.raw_audio.format) { 245 case B_AUDIO_FORMAT_UINT8: 246 fConvert = &uint8_to_uint8; 247 break; 248 case B_AUDIO_FORMAT_INT8: 249 fConvert = &uint8_to_int8; 250 break; 251 case B_AUDIO_FORMAT_INT16: 252 fConvert = &uint8_to_int16; 253 break; 254 case B_AUDIO_FORMAT_INT32: 255 fConvert = &uint8_to_int32; 256 break; 257 case B_AUDIO_FORMAT_FLOAT32: 258 fConvert = &uint8_to_float32; 259 break; 260 default: 261 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 262 break; 263 } 264 break; 265 266 case B_AUDIO_FORMAT_INT8: 267 switch (ioDecodedFormat->u.raw_audio.format) { 268 case B_AUDIO_FORMAT_UINT8: 269 fConvert = &int8_to_uint8; 270 break; 271 case B_AUDIO_FORMAT_INT8: 272 fConvert = &int8_to_int8; 273 break; 274 case B_AUDIO_FORMAT_INT16: 275 fConvert = &int8_to_int16; 276 break; 277 case B_AUDIO_FORMAT_INT32: 278 fConvert = &int8_to_int32; 279 break; 280 case B_AUDIO_FORMAT_FLOAT32: 281 fConvert = &int8_to_float32; 282 break; 283 default: 284 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 285 break; 286 } 287 break; 288 289 case B_AUDIO_FORMAT_INT16: 290 switch (ioDecodedFormat->u.raw_audio.format) { 291 case B_AUDIO_FORMAT_UINT8: 292 fConvert = &int16_to_uint8; 293 break; 294 case B_AUDIO_FORMAT_INT8: 295 fConvert = &int16_to_int8; 296 break; 297 case B_AUDIO_FORMAT_INT16: 298 fConvert = &int16_to_int16; 299 break; 300 case B_AUDIO_FORMAT_INT32: 301 fConvert = &int16_to_int32; 302 break; 303 case B_AUDIO_FORMAT_FLOAT32: 304 fConvert = &int16_to_float32; 305 break; 306 default: 307 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 308 break; 309 } 310 break; 311 312 case B_AUDIO_FORMAT_INT24: 313 switch (ioDecodedFormat->u.raw_audio.format) { 314 case B_AUDIO_FORMAT_UINT8: 315 fConvert = &int24_to_uint8; 316 break; 317 case B_AUDIO_FORMAT_INT8: 318 fConvert = &int24_to_int8; 319 break; 320 case B_AUDIO_FORMAT_INT16: 321 fConvert = &int24_to_int16; 322 break; 323 case B_AUDIO_FORMAT_INT32: 324 fConvert = &int24_to_int32; 325 break; 326 case B_AUDIO_FORMAT_FLOAT32: 327 fConvert = &int24_to_float32; 328 break; 329 default: 330 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 331 break; 332 } 333 break; 334 335 case B_AUDIO_FORMAT_INT32: 336 switch (ioDecodedFormat->u.raw_audio.format) { 337 case B_AUDIO_FORMAT_UINT8: 338 fConvert = &int32_to_uint8; 339 break; 340 case B_AUDIO_FORMAT_INT8: 341 fConvert = &int32_to_int8; 342 break; 343 case B_AUDIO_FORMAT_INT16: 344 fConvert = &int32_to_int16; 345 break; 346 case B_AUDIO_FORMAT_INT32: 347 fConvert = &int32_to_int32; 348 break; 349 case B_AUDIO_FORMAT_FLOAT32: 350 fConvert = &int32_to_float32; 351 break; 352 default: 353 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 354 break; 355 } 356 break; 357 358 case B_AUDIO_FORMAT_FLOAT32: 359 switch (ioDecodedFormat->u.raw_audio.format) { 360 case B_AUDIO_FORMAT_UINT8: 361 fConvert = &float32_to_uint8; 362 break; 363 case B_AUDIO_FORMAT_INT8: 364 fConvert = &float32_to_int8; 365 break; 366 case B_AUDIO_FORMAT_INT16: 367 fConvert = &float32_to_int16; 368 break; 369 case B_AUDIO_FORMAT_INT32: 370 fConvert = &float32_to_int32; 371 break; 372 case B_AUDIO_FORMAT_FLOAT32: 373 fConvert = &float32_to_float32; 374 break; 375 default: 376 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 377 break; 378 } 379 break; 380 381 case B_AUDIO_FORMAT_FLOAT64: 382 switch (ioDecodedFormat->u.raw_audio.format) { 383 case B_AUDIO_FORMAT_UINT8: 384 fConvert = &float64_to_uint8; 385 break; 386 case B_AUDIO_FORMAT_INT8: 387 fConvert = &float64_to_int8; 388 break; 389 case B_AUDIO_FORMAT_INT16: 390 fConvert = &float64_to_int16; 391 break; 392 case B_AUDIO_FORMAT_INT32: 393 fConvert = &float64_to_int32; 394 break; 395 case B_AUDIO_FORMAT_FLOAT32: 396 fConvert = &float64_to_float32; 397 break; 398 default: 399 debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 400 break; 401 } 402 break; 403 404 default: 405 debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n"); 406 break; 407 } 408 409 fChunkBuffer = 0; 410 fChunkSize = 0; 411 fStartTime = 0; 412 413 string_for_format(*ioDecodedFormat, s, sizeof(s)); 414 TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s); 415 /* 416 TRACE("fFrameRate %ld\n", fFrameRate); 417 TRACE("fInputFrameSize %ld\n", fInputFrameSize); 418 TRACE("fOutputFrameSize %ld\n", fOutputFrameSize); 419 TRACE("fInputSampleSize %ld\n", fInputSampleSize); 420 TRACE("fOutputSampleSize %ld\n", fOutputSampleSize); 421 TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount); 422 TRACE("fSwapInput %p\n", fSwapInput); 423 TRACE("fConvert %p\n", fConvert); 424 TRACE("fSwapOutput %p\n", fSwapOutput); 425 */ 426 return B_OK; 427 } 428 429 430 status_t 431 RawDecoder::Seek(uint32 seekTo, 432 int64 seekFrame, int64 *frame, 433 bigtime_t seekTime, bigtime_t *time) 434 { 435 fChunkSize = 0; 436 fStartTime = *time; 437 return B_OK; 438 } 439 440 441 status_t 442 RawDecoder::Decode(void *buffer, int64 *frameCount, 443 media_header *mediaHeader, media_decode_info *info /* = 0 */) 444 { 445 char *output_buffer = (char *)buffer; 446 mediaHeader->start_time = fStartTime; 447 *frameCount = 0; 448 while (*frameCount < fOutputBufferFrameCount) { 449 if (fChunkSize == 0) { 450 media_header mh; 451 status_t err; 452 err = GetNextChunk((void **)&fChunkBuffer, &fChunkSize, &mh); 453 if (err != B_OK || fChunkSize < fInputFrameSize) { 454 fChunkSize = 0; 455 break; 456 } 457 if (fSwapInput) 458 fSwapInput(fChunkBuffer, fChunkSize / fInputSampleSize); 459 fStartTime = mh.start_time; 460 continue; 461 } 462 int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize); 463 int32 samples = frames * fInputFormat.u.raw_audio.channel_count; 464 fConvert(output_buffer, fChunkBuffer, samples); 465 fChunkBuffer += frames * fInputFrameSize; 466 fChunkSize -= frames * fInputFrameSize; 467 output_buffer += frames * fOutputFrameSize; 468 *frameCount += frames; 469 fStartTime += (1000000LL * frames) / fFrameRate; 470 } 471 // XXX should change channel order here for 472 // B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF 473 474 if (fSwapOutput) 475 fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count); 476 return *frameCount ? B_OK : B_ERROR; 477 } 478 479 480 Decoder * 481 RawDecoderPlugin::NewDecoder(uint index) 482 { 483 return new RawDecoder; 484 } 485 486 487 static media_format raw_formats[2]; 488 489 status_t 490 RawDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count) 491 { 492 BMediaFormats mediaFormats; 493 media_format_description description; 494 media_format format; 495 496 // audio decoder 497 498 description.family = B_BEOS_FORMAT_FAMILY; 499 description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO; 500 format.type = B_MEDIA_RAW_AUDIO; 501 format.u.raw_audio = media_multi_audio_format::wildcard; 502 503 status_t status = mediaFormats.MakeFormatFor(&description, 1, &format); 504 if (status < B_OK) 505 return status; 506 raw_formats[0] = format; 507 508 // video decoder 509 510 description.u.beos.format = B_BEOS_FORMAT_RAW_VIDEO; 511 format.type = B_MEDIA_RAW_VIDEO; 512 format.u.raw_video = media_raw_video_format::wildcard; 513 514 status = mediaFormats.MakeFormatFor(&description, 1, &format); 515 if (status < B_OK) 516 return status; 517 raw_formats[1] = format; 518 519 *formats = raw_formats; 520 *count = 2; 521 522 return B_OK; 523 } 524 525 MediaPlugin *instantiate_plugin() 526 { 527 return new RawDecoderPlugin; 528 } 529