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