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 10ca16f5cbSbeveloper #define TRACE_THIS 1 11ca16f5cbSbeveloper #if TRACE_THIS 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 25*6e04e144Sbeveloper RawDecoder::GetCodecInfo(media_codec_info *info) 26a0a20160SAxel Dörfler { 27*6e04e144Sbeveloper strcpy(info->short_name, "raw"); 28a0a20160SAxel Dörfler 29a0a20160SAxel Dörfler if (fInputFormat.IsAudio()) 30*6e04e144Sbeveloper strcpy(info->pretty_name, "Raw audio decoder"); 31a0a20160SAxel Dörfler else 32*6e04e144Sbeveloper 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 101bb1d6ef2Sbeveloper if (ioDecodedFormat->type == B_MEDIA_RAW_VIDEO) 102bb1d6ef2Sbeveloper return NegotiateVideoOutputFormat(ioDecodedFormat); 103bb1d6ef2Sbeveloper if (ioDecodedFormat->type == B_MEDIA_RAW_AUDIO) 104bb1d6ef2Sbeveloper return NegotiateAudioOutputFormat(ioDecodedFormat); 105bb1d6ef2Sbeveloper return B_ERROR; 106bb1d6ef2Sbeveloper } 10725305239Sbeveloper 108bb1d6ef2Sbeveloper 109bb1d6ef2Sbeveloper status_t 110bb1d6ef2Sbeveloper RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat) 111bb1d6ef2Sbeveloper { 112bb1d6ef2Sbeveloper return B_ERROR; 113bb1d6ef2Sbeveloper } 114bb1d6ef2Sbeveloper 115bb1d6ef2Sbeveloper 116bb1d6ef2Sbeveloper status_t 117bb1d6ef2Sbeveloper RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat) 118bb1d6ef2Sbeveloper { 1194ba72fcdSbeveloper char s[1024]; 1204ba72fcdSbeveloper 1214ba72fcdSbeveloper string_for_format(*ioDecodedFormat, s, sizeof(s)); 122bb1d6ef2Sbeveloper TRACE("RawDecoder::NegotiateAudioOutputFormat enter: %s\n", s); 1234ba72fcdSbeveloper 124bb1d6ef2Sbeveloper ioDecodedFormat->type = B_MEDIA_RAW_AUDIO; 125bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 126bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_FLOAT: 127bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_SHORT: 128bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_UCHAR: 129bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_CHAR: 130bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.valid_bits = 0; 131bb1d6ef2Sbeveloper break; // we can produce this on request 132a3d7908eSbeveloper 133bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_INT: 134bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits; 135bb1d6ef2Sbeveloper break; // we can produce this on request 136bb1d6ef2Sbeveloper 137bb1d6ef2Sbeveloper default: 138bb1d6ef2Sbeveloper switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) { 139bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_SHORT: 140bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_UCHAR: 141bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_CHAR: 142bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK; 143bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.valid_bits = 0; 144bb1d6ef2Sbeveloper break; 145bb1d6ef2Sbeveloper 146bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_INT: 147bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT24: 148bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT; 149bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits; 150bb1d6ef2Sbeveloper break; 151bb1d6ef2Sbeveloper 152bb1d6ef2Sbeveloper case media_raw_audio_format::B_AUDIO_FLOAT: 153bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT64: 154bb1d6ef2Sbeveloper default: 155bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT; 156bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.valid_bits = 0; 157bb1d6ef2Sbeveloper break; 158bb1d6ef2Sbeveloper } 159bb1d6ef2Sbeveloper break; 160bb1d6ef2Sbeveloper } 161bb1d6ef2Sbeveloper 162bb1d6ef2Sbeveloper fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate; 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 166bb1d6ef2Sbeveloper fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK); 167bb1d6ef2Sbeveloper fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count; 168bb1d6ef2Sbeveloper 169bb1d6ef2Sbeveloper if (ioDecodedFormat->u.raw_audio.byte_order == 0) 170bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; 171bb1d6ef2Sbeveloper 172bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.channel_mask = 0; 173bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.matrix_mask = 0; 174bb1d6ef2Sbeveloper 175bb1d6ef2Sbeveloper if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) { 17654348708Sbeveloper ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize( 177bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.channel_count, 178bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.format, 179bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.frame_rate); 180bb1d6ef2Sbeveloper } else { 181bb1d6ef2Sbeveloper // round down to exact multiple of output frame size 182bb1d6ef2Sbeveloper ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize; 183bb1d6ef2Sbeveloper } 184bb1d6ef2Sbeveloper 185bb1d6ef2Sbeveloper fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize; 186bb1d6ef2Sbeveloper 187bb1d6ef2Sbeveloper // setup input swapping function 188bb1d6ef2Sbeveloper if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) { 189bb1d6ef2Sbeveloper fSwapInput = 0; 190bb1d6ef2Sbeveloper } else { 191bb1d6ef2Sbeveloper switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) { 192bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 193bb1d6ef2Sbeveloper fSwapInput = &swap_int16; 194bb1d6ef2Sbeveloper break; 195bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT24: 196bb1d6ef2Sbeveloper fSwapInput = &swap_int24; 197bb1d6ef2Sbeveloper break; 198bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 199bb1d6ef2Sbeveloper fSwapInput = &swap_int32; 200bb1d6ef2Sbeveloper break; 201bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 202bb1d6ef2Sbeveloper fSwapInput = &swap_float32; 203bb1d6ef2Sbeveloper break; 204bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT64: 205bb1d6ef2Sbeveloper fSwapInput = &swap_float64; 206bb1d6ef2Sbeveloper break; 207bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 208bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 209bb1d6ef2Sbeveloper fSwapInput = 0; 210bb1d6ef2Sbeveloper break; 211bb1d6ef2Sbeveloper default: 21216611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n"); 213bb1d6ef2Sbeveloper break; 214bb1d6ef2Sbeveloper } 215bb1d6ef2Sbeveloper } 216bb1d6ef2Sbeveloper 217bb1d6ef2Sbeveloper // setup output swapping function 218bb1d6ef2Sbeveloper if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) { 219bb1d6ef2Sbeveloper fSwapOutput = 0; 220bb1d6ef2Sbeveloper } else { 221bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 222bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 223bb1d6ef2Sbeveloper fSwapOutput = &swap_int16; 224bb1d6ef2Sbeveloper break; 225bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 226bb1d6ef2Sbeveloper fSwapOutput = &swap_int32; 227bb1d6ef2Sbeveloper break; 228bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 229bb1d6ef2Sbeveloper fSwapOutput = &swap_float32; 230bb1d6ef2Sbeveloper break; 231bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 232bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 233bb1d6ef2Sbeveloper fSwapOutput = 0; 234bb1d6ef2Sbeveloper break; 235bb1d6ef2Sbeveloper default: 23616611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 237bb1d6ef2Sbeveloper break; 238bb1d6ef2Sbeveloper } 239bb1d6ef2Sbeveloper } 240bb1d6ef2Sbeveloper 241bb1d6ef2Sbeveloper // setup sample conversation function 242bb1d6ef2Sbeveloper switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) { 243bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 244bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 245bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 246bb1d6ef2Sbeveloper fConvert = &uint8_to_uint8; 247bb1d6ef2Sbeveloper break; 248bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 249bb1d6ef2Sbeveloper fConvert = &uint8_to_int8; 250bb1d6ef2Sbeveloper break; 251bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 252bb1d6ef2Sbeveloper fConvert = &uint8_to_int16; 253bb1d6ef2Sbeveloper break; 254bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 255bb1d6ef2Sbeveloper fConvert = &uint8_to_int32; 256bb1d6ef2Sbeveloper break; 257bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 258bb1d6ef2Sbeveloper fConvert = &uint8_to_float32; 259bb1d6ef2Sbeveloper break; 260bb1d6ef2Sbeveloper default: 26116611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 262bb1d6ef2Sbeveloper break; 263bb1d6ef2Sbeveloper } 264bb1d6ef2Sbeveloper break; 265bb1d6ef2Sbeveloper 266bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 267bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 268bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 269bb1d6ef2Sbeveloper fConvert = &int8_to_uint8; 270bb1d6ef2Sbeveloper break; 271bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 272bb1d6ef2Sbeveloper fConvert = &int8_to_int8; 273bb1d6ef2Sbeveloper break; 274bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 275bb1d6ef2Sbeveloper fConvert = &int8_to_int16; 276bb1d6ef2Sbeveloper break; 277bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 278bb1d6ef2Sbeveloper fConvert = &int8_to_int32; 279bb1d6ef2Sbeveloper break; 280bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 281bb1d6ef2Sbeveloper fConvert = &int8_to_float32; 282bb1d6ef2Sbeveloper break; 283bb1d6ef2Sbeveloper default: 28416611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 285bb1d6ef2Sbeveloper break; 286bb1d6ef2Sbeveloper } 287bb1d6ef2Sbeveloper break; 288bb1d6ef2Sbeveloper 289bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 290bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 291bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 292bb1d6ef2Sbeveloper fConvert = &int16_to_uint8; 293bb1d6ef2Sbeveloper break; 294bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 295bb1d6ef2Sbeveloper fConvert = &int16_to_int8; 296bb1d6ef2Sbeveloper break; 297bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 298bb1d6ef2Sbeveloper fConvert = &int16_to_int16; 299bb1d6ef2Sbeveloper break; 300bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 301bb1d6ef2Sbeveloper fConvert = &int16_to_int32; 302bb1d6ef2Sbeveloper break; 303bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 304bb1d6ef2Sbeveloper fConvert = &int16_to_float32; 305bb1d6ef2Sbeveloper break; 306bb1d6ef2Sbeveloper default: 30716611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 308bb1d6ef2Sbeveloper break; 309bb1d6ef2Sbeveloper } 310bb1d6ef2Sbeveloper break; 311bb1d6ef2Sbeveloper 312bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT24: 313bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 314bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 315bb1d6ef2Sbeveloper fConvert = &int24_to_uint8; 316bb1d6ef2Sbeveloper break; 317bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 318bb1d6ef2Sbeveloper fConvert = &int24_to_int8; 319bb1d6ef2Sbeveloper break; 320bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 321bb1d6ef2Sbeveloper fConvert = &int24_to_int16; 322bb1d6ef2Sbeveloper break; 323bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 324bb1d6ef2Sbeveloper fConvert = &int24_to_int32; 325bb1d6ef2Sbeveloper break; 326bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 327bb1d6ef2Sbeveloper fConvert = &int24_to_float32; 328bb1d6ef2Sbeveloper break; 329bb1d6ef2Sbeveloper default: 33016611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 331bb1d6ef2Sbeveloper break; 332bb1d6ef2Sbeveloper } 333bb1d6ef2Sbeveloper break; 334bb1d6ef2Sbeveloper 335bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 336bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 337bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 338bb1d6ef2Sbeveloper fConvert = &int32_to_uint8; 339bb1d6ef2Sbeveloper break; 340bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 341bb1d6ef2Sbeveloper fConvert = &int32_to_int8; 342bb1d6ef2Sbeveloper break; 343bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 344bb1d6ef2Sbeveloper fConvert = &int32_to_int16; 345bb1d6ef2Sbeveloper break; 346bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 347bb1d6ef2Sbeveloper fConvert = &int32_to_int32; 348bb1d6ef2Sbeveloper break; 349bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 350bb1d6ef2Sbeveloper fConvert = &int32_to_float32; 351bb1d6ef2Sbeveloper break; 352bb1d6ef2Sbeveloper default: 35316611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 354bb1d6ef2Sbeveloper break; 355bb1d6ef2Sbeveloper } 356bb1d6ef2Sbeveloper break; 357bb1d6ef2Sbeveloper 358bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 359bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 360bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 361bb1d6ef2Sbeveloper fConvert = &float32_to_uint8; 362bb1d6ef2Sbeveloper break; 363bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 364bb1d6ef2Sbeveloper fConvert = &float32_to_int8; 365bb1d6ef2Sbeveloper break; 366bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 367bb1d6ef2Sbeveloper fConvert = &float32_to_int16; 368bb1d6ef2Sbeveloper break; 369bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 370bb1d6ef2Sbeveloper fConvert = &float32_to_int32; 371bb1d6ef2Sbeveloper break; 372bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 373bb1d6ef2Sbeveloper fConvert = &float32_to_float32; 374bb1d6ef2Sbeveloper break; 375bb1d6ef2Sbeveloper default: 37616611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 377bb1d6ef2Sbeveloper break; 378bb1d6ef2Sbeveloper } 379bb1d6ef2Sbeveloper break; 380bb1d6ef2Sbeveloper 381bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT64: 382bb1d6ef2Sbeveloper switch (ioDecodedFormat->u.raw_audio.format) { 383bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_UINT8: 384bb1d6ef2Sbeveloper fConvert = &float64_to_uint8; 385bb1d6ef2Sbeveloper break; 386bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT8: 387bb1d6ef2Sbeveloper fConvert = &float64_to_int8; 388bb1d6ef2Sbeveloper break; 389bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT16: 390bb1d6ef2Sbeveloper fConvert = &float64_to_int16; 391bb1d6ef2Sbeveloper break; 392bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_INT32: 393bb1d6ef2Sbeveloper fConvert = &float64_to_int32; 394bb1d6ef2Sbeveloper break; 395bb1d6ef2Sbeveloper case B_AUDIO_FORMAT_FLOAT32: 396bb1d6ef2Sbeveloper fConvert = &float64_to_float32; 397bb1d6ef2Sbeveloper break; 398bb1d6ef2Sbeveloper default: 39916611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n"); 400bb1d6ef2Sbeveloper break; 401bb1d6ef2Sbeveloper } 402bb1d6ef2Sbeveloper break; 403bb1d6ef2Sbeveloper 404bb1d6ef2Sbeveloper default: 40516611de7Sbeveloper debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n"); 406bb1d6ef2Sbeveloper break; 407bb1d6ef2Sbeveloper } 408bb1d6ef2Sbeveloper 409bb1d6ef2Sbeveloper fChunkBuffer = 0; 410bb1d6ef2Sbeveloper fChunkSize = 0; 411bb1d6ef2Sbeveloper fStartTime = 0; 4124ba72fcdSbeveloper 4134ba72fcdSbeveloper string_for_format(*ioDecodedFormat, s, sizeof(s)); 414bb1d6ef2Sbeveloper TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s); 415bb1d6ef2Sbeveloper /* 416bb1d6ef2Sbeveloper TRACE("fFrameRate %ld\n", fFrameRate); 417bb1d6ef2Sbeveloper TRACE("fInputFrameSize %ld\n", fInputFrameSize); 418bb1d6ef2Sbeveloper TRACE("fOutputFrameSize %ld\n", fOutputFrameSize); 419bb1d6ef2Sbeveloper TRACE("fInputSampleSize %ld\n", fInputSampleSize); 420bb1d6ef2Sbeveloper TRACE("fOutputSampleSize %ld\n", fOutputSampleSize); 421bb1d6ef2Sbeveloper TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount); 422bb1d6ef2Sbeveloper TRACE("fSwapInput %p\n", fSwapInput); 423bb1d6ef2Sbeveloper TRACE("fConvert %p\n", fConvert); 424bb1d6ef2Sbeveloper TRACE("fSwapOutput %p\n", fSwapOutput); 425bb1d6ef2Sbeveloper */ 426ca16f5cbSbeveloper return B_OK; 427ca16f5cbSbeveloper } 428ca16f5cbSbeveloper 429ca16f5cbSbeveloper 430ca16f5cbSbeveloper status_t 431d8591482Sbeveloper RawDecoder::Seek(uint32 seekTo, 432bce1ab5eSbeveloper int64 seekFrame, int64 *frame, 433bce1ab5eSbeveloper bigtime_t seekTime, bigtime_t *time) 434ca16f5cbSbeveloper { 435bb1d6ef2Sbeveloper fChunkSize = 0; 436bb1d6ef2Sbeveloper fStartTime = *time; 437ca16f5cbSbeveloper return B_OK; 438ca16f5cbSbeveloper } 439ca16f5cbSbeveloper 440ca16f5cbSbeveloper 441ca16f5cbSbeveloper status_t 442ca16f5cbSbeveloper RawDecoder::Decode(void *buffer, int64 *frameCount, 443d8591482Sbeveloper media_header *mediaHeader, media_decode_info *info /* = 0 */) 444ca16f5cbSbeveloper { 445bb1d6ef2Sbeveloper char *output_buffer = (char *)buffer; 446bb1d6ef2Sbeveloper mediaHeader->start_time = fStartTime; 447bb1d6ef2Sbeveloper *frameCount = 0; 448bb1d6ef2Sbeveloper while (*frameCount < fOutputBufferFrameCount) { 449bb1d6ef2Sbeveloper if (fChunkSize == 0) { 450bb1d6ef2Sbeveloper media_header mh; 4512d923d67Sbeveloper status_t err; 452bb1d6ef2Sbeveloper err = GetNextChunk((void **)&fChunkBuffer, &fChunkSize, &mh); 453bb1d6ef2Sbeveloper if (err != B_OK || fChunkSize < fInputFrameSize) { 454bb1d6ef2Sbeveloper fChunkSize = 0; 455bb1d6ef2Sbeveloper break; 456bb1d6ef2Sbeveloper } 457bb1d6ef2Sbeveloper if (fSwapInput) 458bb1d6ef2Sbeveloper fSwapInput(fChunkBuffer, fChunkSize / fInputSampleSize); 459bb1d6ef2Sbeveloper fStartTime = mh.start_time; 460bb1d6ef2Sbeveloper continue; 461bb1d6ef2Sbeveloper } 462bb1d6ef2Sbeveloper int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize); 463bb1d6ef2Sbeveloper int32 samples = frames * fInputFormat.u.raw_audio.channel_count; 464bb1d6ef2Sbeveloper fConvert(output_buffer, fChunkBuffer, samples); 465bb1d6ef2Sbeveloper fChunkBuffer += frames * fInputFrameSize; 466bb1d6ef2Sbeveloper fChunkSize -= frames * fInputFrameSize; 467bb1d6ef2Sbeveloper output_buffer += frames * fOutputFrameSize; 468bb1d6ef2Sbeveloper *frameCount += frames; 469bb1d6ef2Sbeveloper fStartTime += (1000000LL * frames) / fFrameRate; 470bb1d6ef2Sbeveloper } 471bb1d6ef2Sbeveloper // XXX should change channel order here for 472bb1d6ef2Sbeveloper // B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF 4732d923d67Sbeveloper 474bb1d6ef2Sbeveloper if (fSwapOutput) 475bb1d6ef2Sbeveloper fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count); 476bb1d6ef2Sbeveloper return *frameCount ? B_OK : B_ERROR; 477ca16f5cbSbeveloper } 478ca16f5cbSbeveloper 479ca16f5cbSbeveloper 480ca16f5cbSbeveloper Decoder * 481ca16f5cbSbeveloper RawDecoderPlugin::NewDecoder() 482ca16f5cbSbeveloper { 483ca16f5cbSbeveloper return new RawDecoder; 484ca16f5cbSbeveloper } 485ca16f5cbSbeveloper 486bce1ab5eSbeveloper status_t 487a0a20160SAxel Dörfler RawDecoderPlugin::RegisterDecoder() 488bce1ab5eSbeveloper { 489a0a20160SAxel Dörfler BMediaFormats formats; 490a0a20160SAxel Dörfler media_format_description description; 491a0a20160SAxel Dörfler media_format format; 492a0a20160SAxel Dörfler 493a0a20160SAxel Dörfler // audio decoder 494a0a20160SAxel Dörfler 49540d68dd2Sbeveloper description.family = B_BEOS_FORMAT_FAMILY; 496a0a20160SAxel Dörfler description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO; 49740d68dd2Sbeveloper format.type = B_MEDIA_RAW_AUDIO; 49840d68dd2Sbeveloper format.u.raw_audio = media_multi_audio_format::wildcard; 499a0a20160SAxel Dörfler 500a0a20160SAxel Dörfler status_t status = formats.MakeFormatFor(&description, 1, &format); 501a0a20160SAxel Dörfler if (status < B_OK) 502a0a20160SAxel Dörfler return status; 503a0a20160SAxel Dörfler 504a0a20160SAxel Dörfler // video decoder 505a0a20160SAxel Dörfler 506a0a20160SAxel Dörfler description.u.beos.format = B_BEOS_FORMAT_RAW_VIDEO; 50740d68dd2Sbeveloper format.type = B_MEDIA_RAW_VIDEO; 50840d68dd2Sbeveloper format.u.raw_video = media_raw_video_format::wildcard; 509a0a20160SAxel Dörfler 510a0a20160SAxel Dörfler return formats.MakeFormatFor(&description, 1, &format); 511bce1ab5eSbeveloper } 512ca16f5cbSbeveloper 513ca16f5cbSbeveloper MediaPlugin *instantiate_plugin() 514ca16f5cbSbeveloper { 515ca16f5cbSbeveloper return new RawDecoderPlugin; 516ca16f5cbSbeveloper } 517