Проблемы CMSampleBufferRef и AVAssetReaderMixAudioOutput и PCM
Поэтому я использую AVAssetReaderMixAudioOutput для извлечения аудиосэмплов из файла быстрого времени. В данном случае это видео ProRes с несколькими звуковыми дорожками.
(4 дорожки, 16 бит, чередующиеся сэмплы littleEndian @ 48000)
Я могу получить видеокадры нормально, но когда я вызываю [myAssetReaderAudioMixOutput copyNextSampleBuffer], я сталкиваюсь с некоторыми странными проблемами.... Кажется, что возвращаемое аудио находится на первом канале?
Используя отдельные trackOutputReader, я получаю первые аудиосэмплы для каждой дорожки для первого кадра:
620B 700E 0000 0000
Но когда я использую AVAssetReaderMixAudioOutput, я получаю
D219 0000 0000 0000
(обратите внимание, что 620B + 700E = D219), поэтому похоже, что AVAssetReaderMixAudioOutput суммирует все значения по 4 каналам и дает результат в дорожке 1??
Кто-нибудь может объяснить почему? и как это исправить? Мне нужно решение, которое даст мне отображение каналов 1:1, как они есть в файле QuickTime, т.е. он должен работать с файлами как с 1-канальным, так и с 16-канальным аудио.
Я получил правильные значения для первого сэмпла, выполнив copyNextSampleBuffer для каждого аудио-канала / тэка отдельно
Это словарь, который я использовал для создания myAssetReaderAudioMixOutput....
NSDictionary *outputSettings =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithFloat:48000], AVSampleRateKey,
[NSNumber numberWithInt:4], AVNumberOfChannelsKey,
[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
[NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
nil];
myAssetReaderAudioMixOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:audioTracks audioSettings: outputSettings];
Я использую следующий бит кода, чтобы прочитать фактические аудиосэмплы / данные из CMSampleBuffer.
enteraudioBuffer = [assetReaderAudioMixOutput copyNextSampleBuffer]; if (audioBuffer) {CMBlockBufferRef audioBlockBuffer = CMSampleBufferGetDataBuffer (audioBuffer);
// lets get some more info about our SampleBuffer, or at least sample size for sample 0!
CMTime sampleDuration = CMSampleBufferGetDuration(audioBuffer);
size_t sampleSize = CMSampleBufferGetSampleSize(audioBuffer, 0);
CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples(audioBuffer);
bfAudioBuffer* pbfBuffer = new bfAudioBuffer();
int samplesNeededForThisFrame = 1920; // sample for FrameNo(frameNo, vidMode);
int sizeOfDataToBeCopied = samplesNeededForThisFrame * sampleSize
// Audio Samples for 1 frames worth of audio should be copied into pbfBuffer->pPcmBuffer
CMBlockBufferCopyDataBytes(audioBlockBuffer, 0, sizeOfDataToBeCopied, pbfBuffer->pPcmBuffer);
}
(Извините, похоже, что я искажаю код, когда я его вставляю, не знаю почему, я попробовал несколько разных вещей - извините)
Поэтому я думаю, что моя проблема либо в настройке словаря, либо в чтении примеров. Я использую ту же систему для чтения сэмплов для одного трека, так что я сомневаюсь, что это так? Я просто не могу понять, почему он дает мне правильное количество данных / сэмплов для 4 треков, а затем только помещает информацию в первый трек??
Наконец, я на OSX, не волнует iOS.
Спасибо за любую помощь, это было очень сложно!
- Джеймс
1 ответ
Правильно, я наконец нашел ответ на этот вопрос, так что я подумал, что обновлю My Q. решением.
Так что проблема была в моем понимании того, что на самом деле делает AVAssetReaderMixAudioOutput.
Я думал, что смогу дать мне микс из нескольких звуковых дорожек, но на самом деле это НЕОБХОДИМО, чтобы микшировать дорожки заданным пользователем способом, а затем возвращать звуковую дорожку. (имейте в виду, что "дорожка" здесь может быть одной дорожкой стереозвука)
Чтобы получить многодорожечный звук из файла, мне нужно иметь AVAssetReader для каждой дорожки, которую я хочу извлечь.
Надеюсь, кто-то найдет это полезным