OSStatus AudioConverter::create(const AudioStreamBasicDescription* inSourceFormat, const AudioStreamBasicDescription* inDestinationFormat, AudioConverter** out) { TRACE2(inSourceFormat, inDestinationFormat); // TODO: non-interleaved audio AVCodec *codecIn, *codecOut; AVCodecContext *cIn; AVCodecContext *cOut; enum AVCodecID idIn, idOut; *out = nullptr; idIn = CACodecToAV(inSourceFormat); idOut = CACodecToAV(inDestinationFormat); if (idIn == AV_CODEC_ID_NONE || idOut == AV_CODEC_ID_NONE) { LOG << "AudioConverter::create(): Unsupported codec, format in = " << std::hex << inSourceFormat->mFormatID << ", out = " << inDestinationFormat->mFormatID << std::dec << std::endl; return paramErr; } codecIn = avcodec_find_decoder(idIn); codecOut = avcodec_find_encoder(idOut); if (!codecIn || !codecOut) { LOG << "AudioConverter::create(): avcodec_find_*() failed, format in = " << std::hex << inSourceFormat->mFormatID << ", out = " << inDestinationFormat->mFormatID << std::dec << std::endl; return paramErr; } *out = new AudioConverter(inSourceFormat, inDestinationFormat); (*out)->m_decoder = cIn = avcodec_alloc_context3(codecIn); if (inSourceFormat->mFormatID == kAudioFormatLinearPCM) { cIn->channels = inSourceFormat->mChannelsPerFrame; cIn->sample_rate = inSourceFormat->mSampleRate; LOG << "Converting from PCM with " << cIn->channels << " channels at " << cIn->sample_rate << " Hz\n"; } if (avcodec_open2((*out)->m_decoder, codecIn, nullptr) < 0) { delete *out; LOG << "AudioConverter::create(): avcodec_open() failed, format in = " << std::hex << inSourceFormat->mFormatID << ", out = " << inDestinationFormat->mFormatID << std::dec << std::endl; return paramErr; } // The encoder will be initialized after we process the first packet (*out)->m_encoder = cOut = avcodec_alloc_context3(codecOut); (*out)->m_codecIn = codecIn; (*out)->m_codecOut = codecOut; return noErr; }
OSStatus AudioConverter::create(const AudioStreamBasicDescription* inSourceFormat, const AudioStreamBasicDescription* inDestinationFormat, AudioConverter** out) { AVCodec *codecIn, *codecOut; enum AVCodecID idIn, idOut; *out = nullptr; idIn = CACodecToAV(inSourceFormat); idOut = CACodecToAV(inDestinationFormat); if (idIn == AV_CODEC_ID_NONE || idOut == AV_CODEC_ID_NONE) { LOG << "AudioConverter::create(): Unsupported codec, format in = " << std::hex << inSourceFormat->mFormatID << ", out = " << inDestinationFormat->mFormatID << std::dec << std::endl; return paramErr; } codecIn = avcodec_find_decoder(idIn); codecOut = avcodec_find_encoder(idOut); if (!codecIn || !codecOut) { LOG << "AudioConverter::create(): avcodec_find_*() failed, format in = " << std::hex << inSourceFormat->mFormatID << ", out = " << inDestinationFormat->mFormatID << std::dec << std::endl; return paramErr; } *out = new AudioConverter(inSourceFormat, inDestinationFormat); (*out)->m_decoder = avcodec_alloc_context3(codecIn); if (avcodec_open2((*out)->m_decoder, codecIn, nullptr) < 0) { delete *out; LOG << "AudioConverter::create(): avcodec_open() failed, format in = " << std::hex << inSourceFormat->mFormatID << ", out = " << inDestinationFormat->mFormatID << std::dec << std::endl; return paramErr; } // The encoder will be initialized after we process the first packet (*out)->m_encoder = avcodec_alloc_context3(codecOut); return noErr; }