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