我正在使用kxmovie(这是一个基于ffmpeg的视频播放器)作为应用程序的基础,我正在试图找出当唯一连接到的东西时,RemoteI / O单元如何在iOS上运行设备是耳机,我们正在播放超过2个频道的音轨(比如环绕声6声道)。它似乎与输出通道设置一致,缓冲区只有2个通道。这是因为Core Audio的拉结构吗?如果是这样,赛道上的其他频道会发生什么?他们是在混淆还是被忽视?
连接到remoteio设备的渲染回调代码如下:
- (BOOL) renderFrames: (UInt32) numFrames
ioData: (AudioBufferList *) ioData
{
NSLog(@"Number of channels in buffer: %lu",ioData->mNumberBuffers);
for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {
memset(ioData->mBuffers[iBuffer].mData, 0, ioData->mBuffers[iBuffer].mDataByteSize);
}
if (_playing && _outputBlock ) {
// Collect data to render from the callbacks
_outputBlock(_outData, numFrames, _numOutputChannels);
// Put the rendered data into the output buffer
if (_numBytesPerSample == 4) // then we've already got floats
{
float zero = 0.0;
for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {
int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;
for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
vDSP_vsadd(_outData+iChannel, _numOutputChannels, &zero, (float *)ioData->mBuffers[iBuffer].mData, thisNumChannels, numFrames);
}
}
}
else if (_numBytesPerSample == 2) // then we need to convert SInt16 -> Float (and also scale)
{
float scale = (float)INT16_MAX;
vDSP_vsmul(_outData, 1, &scale, _outData, 1, numFrames*_numOutputChannels);
for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {
int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;
for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
vDSP_vfix16(_outData+iChannel, _numOutputChannels, (SInt16 *)ioData->mBuffers[iBuffer].mData+iChannel, thisNumChannels, numFrames);
}
}
}
}
return noErr;
}
谢谢!
编辑:这是ASBD的代码(_ouputFormat)。它直接从remoteio获得它的价值。您还可以检查整个方法文件here。
if (checkError(AudioUnitGetProperty(_audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&_outputFormat,
&size),
"Couldn't get the hardware output stream format"))
return NO;
_outputFormat.mSampleRate = _samplingRate;
if (checkError(AudioUnitSetProperty(_audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&_outputFormat,
size),
"Couldn't set the hardware output stream format")) {
// just warning
}
_numBytesPerSample = _outputFormat.mBitsPerChannel / 8;
_numOutputChannels = _outputFormat.mChannelsPerFrame;
NSLog(@"Current output bytes per sample: %ld", _numBytesPerSample);
NSLog(@"Current output num channels: %ld", _numOutputChannels);
// Slap a render callback on the unit
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = renderCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
if (checkError(AudioUnitSetProperty(_audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&callbackStruct,
sizeof(callbackStruct)),
"Couldn't set the render callback on the audio unit"))
return NO;
答案 0 :(得分:0)
我终于找到了将它重新混音为立体声的代码片段。它使用RIO的ASBD在KxAudioManager中设置属性。然后,在KxMovieDecoder.m中,它使用相同的变量设置ffmpeg选项。这是代码:
id<KxAudioManager> audioManager = [KxAudioManager audioManager];
swrContext = swr_alloc_set_opts(NULL,
av_get_default_channel_layout(audioManager.numOutputChannels),
AV_SAMPLE_FMT_S16,
audioManager.samplingRate,
av_get_default_channel_layout(codecCtx->channels),
codecCtx->sample_fmt,
codecCtx->sample_rate,
0,
NULL);
现在关于ffmpeg如何进行解码已经开始了。有趣的时光。