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