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