status_t MusePackReader::AllocateCookie(int32 streamNumber, void **_cookie) { // we don't need a cookie - we only know one single stream *_cookie = NULL; media_format_description description; description.family = B_MISC_FORMAT_FAMILY; description.u.misc.file_format = 'mpc '; description.u.misc.codec = 'MPC7'; // 7 is the most recent stream version status_t status = BMediaFormats().GetFormatFor(description, &fFormat); if (status < B_OK) return status; // allocate and initialize internal decoder fDecoder = new MPC_decoder(static_cast<BPositionIO *>(Source())); fDecoder->RESET_Globals(); fDecoder->RESET_Synthesis(); fDecoder->SetStreamInfo(&fInfo); if (!fDecoder->FileInit()) { delete fDecoder; fDecoder = 0; return B_ERROR; } #if 0 // not required to report fFormat.u.encoded_audio.output.frame_rate = fInfo.simple.SampleFreq; fFormat.u.encoded_audio.output.channel_count = fInfo.simple.Channels; fFormat.u.encoded_audio.output.format = media_raw_audio_format::B_AUDIO_FLOAT; fFormat.u.encoded_audio.output.byte_order = B_MEDIA_HOST_ENDIAN; fFormat.u.encoded_audio.output.buffer_size = sizeof(MPC_SAMPLE_FORMAT) * FRAMELEN * 2; #endif return B_OK; }
status_t AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer, size_t infoSize) { if (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO && ioEncodedFormat->type != B_MEDIA_ENCODED_VIDEO) return B_ERROR; fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO); TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v')); #ifdef TRACE_AV_CODEC char buffer[1024]; string_for_format(*ioEncodedFormat, buffer, sizeof(buffer)); TRACE("[%c] input_format = %s\n", fIsAudio?('a'):('v'), buffer); TRACE("[%c] infoSize = %ld\n", fIsAudio?('a'):('v'), infoSize); TRACE("[%c] user_data_type = %08lx\n", fIsAudio?('a'):('v'), ioEncodedFormat->user_data_type); TRACE("[%c] meta_data_size = %ld\n", fIsAudio?('a'):('v'), ioEncodedFormat->MetaDataSize()); #endif media_format_description description; if (BMediaFormats().GetCodeFor(*ioEncodedFormat, B_MISC_FORMAT_FAMILY, &description) == B_OK) { if (description.u.misc.file_format != 'ffmp') return B_NOT_SUPPORTED; fCodec = avcodec_find_decoder(static_cast<CodecID>( description.u.misc.codec)); if (fCodec == NULL) { TRACE(" unable to find the correct FFmpeg " "decoder (id = %lu)\n", description.u.misc.codec); return B_ERROR; } TRACE(" found decoder %s\n", fCodec->name); const void* extraData = infoBuffer; fExtraDataSize = infoSize; if (description.family == B_WAV_FORMAT_FAMILY && infoSize >= sizeof(wave_format_ex)) { TRACE(" trying to use wave_format_ex\n"); // Special case extra data in B_WAV_FORMAT_FAMILY const wave_format_ex* waveFormatData = (const wave_format_ex*)infoBuffer; size_t waveFormatSize = infoSize; if (waveFormatData != NULL && waveFormatSize > 0) { fBlockAlign = waveFormatData->block_align; TRACE(" found block align: %d\n", fBlockAlign); fExtraDataSize = waveFormatData->extra_size; // skip the wave_format_ex from the extra data. extraData = waveFormatData + 1; } } else { if (fIsAudio) { fBlockAlign = ioEncodedFormat->u.encoded_audio.output .buffer_size; TRACE(" using buffer_size as block align: %d\n", fBlockAlign); } } if (extraData != NULL && fExtraDataSize > 0) { TRACE("AVCodecDecoder: extra data size %ld\n", infoSize); delete[] fExtraData; fExtraData = new(std::nothrow) char[fExtraDataSize]; if (fExtraData != NULL) memcpy(fExtraData, infoBuffer, fExtraDataSize); else fExtraDataSize = 0; } fInputFormat = *ioEncodedFormat; return B_OK; } else { TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n"); } printf("AVCodecDecoder::Setup failed!\n"); return B_ERROR; }