Звуковой эквивалент SPS и PPS при мультиплексировании Приложение B MPEG-TS? Что такое «DecoderInfo»?

Я использую библиотеку Bento4 для загрузки файла потока TS (MPEG-2) приложения B с файлами h264 и AAC, которые генерируются из VideoToolbox и AVFoundation соответственно, в качестве исходных данных для HLS (HTTP Live Streaming) поток. Этот вопрос не обязательно специфичен для Bento4: я пытаюсь понять базовые понятия, чтобы выполнить задачу, желательно используя Apple libs.

До сих пор я выяснил, как создать AP4_AvcSampleDescription , получая различные данные из моего CMVideoFormatDescriptionRef и, самое главное, создавая SPS и PPS, используя индексы 0 и 1 соответственно CMVideoFormatDescriptionGetH264ParameterSetAtIndex которые я могу просто CMVideoFormatDescriptionGetH264ParameterSetAtIndex качестве байтовых буферов в Bento4. Отлично, это вся информация заголовка, в которой я нуждаюсь, чтобы я мог запросить Bento4 мультиплексирование видео в ts-файл!

Теперь я пытаюсь подключить аудио в один и тот же файл. Я использую свой CMAudioFormatDescriptionRef чтобы получить необходимую информацию для создания моей AP4_MpegAudioSampleDescription , которую Bento4 использует для создания необходимых QT-атомов и заголовков. Однако, если поля являются байтовым буфером «декодер информации», без объяснения того, что это такое, или код для генерации одного из данных. Я бы надеялся иметь CMAudioFormatDescriptionGetDecoderInfo или что-то в этом роде, но я не могу найти ничего подобного. Есть ли такая функция в любой библиотеке Apple? Или есть хорошая спецификация, которую я не нашел о том, как сгенерировать эти данные?

Или, наоборот, я иду по неправильному пути? Есть ли более простой способ для mux ts-файлов с базы данных Mac / iOS?

Мультимедийный звук в MPEG-TS на удивление прост и не требует сложного заголовка, подобного потоку видео! Для каждого буфера выборки требуется только 7-байтовый заголовок ADTS, прежде чем писать его как PES.

Bento4 использует буфер «DecoderInfo», чтобы проанализировать его в экземпляре AP4_Mp4AudioDecoderConfig , чтобы он мог извлечь информацию, необходимую для заголовка ADTS. Вместо того, чтобы AP4_Mpeg2TsAudioSampleStream::WriteSample эту информацию, я сделал копию в AP4_Mpeg2TsAudioSampleStream::WriteSample которая пишет CMSampleBufferRef . Его можно легко обобщить для других аудио-фреймворков, но я просто вставлю его как есть для ссылки:

 // These two functions are copy-pasted from Ap4Mpeg2Ts.cpp static unsigned int GetSamplingFrequencyIndex(unsigned int sampling_frequency) { ... } static void MakeAdtsHeader(unsigned char *bits, size_t frame_size, unsigned int sampling_frequency_index, unsigned int channel_configuration) { ... } static const size_t kAdtsHeaderLength = 7; - (void)appendAudioSampleBuffer2:(CMSampleBufferRef)sampleBuffer { // Get the actual audio data from the block buffer. CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); size_t blockBufferLength = CMBlockBufferGetDataLength(blockBuffer); // Get the audio meta-data from its AudioFormatDescRef CMAudioFormatDescriptionRef audioFormat = CMSampleBufferGetFormatDescription(sampleBuffer); const AudioStreamBasicDescription *asbd = CMAudioFormatDescriptionGetStreamBasicDescription(audioFormat); // These are the values we will need to build our ADTS header unsigned int sample_rate = asbd->mSampleRate; unsigned int channel_count = asbd->mChannelsPerFrame; unsigned int sampling_frequency_index = GetSamplingFrequencyIndex(sample_rate); unsigned int channel_configuration = channel_count; // Create a byte buffer with first the header, and then the sample data. NSMutableData *buffer = [NSMutableData dataWithLength:kAdtsHeaderLength + blockBufferLength]; MakeAdtsHeader((unsigned char*)[buffer mutableBytes], blockBufferLength, sampling_frequency_index, channel_configuration); CMBlockBufferCopyDataBytes(blockBuffer, 0, blockBufferLength, ((char*)[buffer mutableBytes])+kAdtsHeaderLength); // Calculate a timestamp int64 that Bento4 can use, by converting our CMTime into an Int64 in the timescale of the audio stream. CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); AP4_UI64 ts = CMTimeConvertScale(presentationTime, _audioStream->m_TimeScale, kCMTimeRoundingMethod_Default).value; _audioStream->WritePES( (const unsigned char*)[buffer bytes], (unsigned int)[buffer length], ts, false, // don't need a decode timestamp for audio ts, true, // do write a presentation timestamp so we can sync a/v *_output ); } 

Байт-буфер «декодера», необходимый Bento4 для создания экземпляра AP4_MpegAudioSampleDescription, представляет собой данные инициализации кодека, которые являются специфичными для кодека. Для аудио AAC-LC обычно это 2 байта данных (для HE-AAC вы получите еще несколько байтов), детали которых указаны в спецификации AAC. Например, потоки 44,1 кГц, стерео, AAC-LC будут иметь [0x12,0x10] в качестве данных инициализации. В большинстве API Apple этот тип данных инициализации кодека передается через то, что они называют «Magic Cookies». Вероятно, функция CMAudioFormatDescriptionGetMagicCookie вернет вам то, что вам нужно.

Interesting Posts

Исключение: «Недопустимая область <center: + inf, +0.00000000 span: +1.00000000, +0.50000000>» при попытке отобразить карту

ARC, ivars в блоках и эталонных циклах через захваченное я

Iphone CLLocationCoordinate2D

как перемещать курсор в UITextField после установки его значения

Ограничьте результаты фильтра массива Swift до X для производительности

Заполнение значения Selected в представлении Picker

iOS: setFrame больше не работает с viewDidLoad или viewWillAppear

Как сделать описание появлением при нажатии на точки графика iOS

как заблокировать пользователя, если он / она не подключен к интернет-соединению при загрузке приложения

iOS 8 (Swift) Как избавиться от этой ошибки: ImageIO: ошибка PNG zlib?

Добавление пакета MVVMCross Nuget к iOS Xamarin не выполняется на VS2015 RC

Как изменить анимацию перехода CurrentViewController

Проводка данных JSON с использованием AFNetworking 2.0

Как сделать аннотацию, например,

Запуск события / метода, когда UIWindow RootViewController изменяет SWIFT

Давайте будем гением компьютера.