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