AVAssetWriterInput appendSampleBuffer успешно выполняется, но регистрирует ошибку kCMSampleBufferError_BufferHasNoSampleSizes from CMSampleBufferGetSampleSize - PullRequest
0 голосов
/ 30 июня 2019

Начиная с бета-версий iOS 12.4, вызов appendSampleBuffer на AVAssetWriterInput регистрирует следующую ошибку:

CMSampleBufferGetSampleSize сигнализировал err = -12735 (kCMSampleBufferError_BufferHasNoSampleSizes) (sbuf-> numSampleSizeEntries == 0) в /BuildRoot/Library/Caches/com/apple.x/ 4153

Мы не видим эту ошибку в предыдущей версии, а также в бета-версии iOS 13. Кто-нибудь еще сталкивался с этим и может предоставить любую информацию, которая поможет нам это исправить?

Подробнее

Наше приложение записывает видео и аудио, используя два объекта AVAssetWriterInput, один для видеовхода (добавление пиксельных буферов) и один для аудиовхода - добавление аудиобуферов, созданных с помощью CMSampleBufferCreate. (См. Код ниже.)

Поскольку наши аудиоданные не перемежаются, после создания мы конвертируем их в формат с перемежением и передаем appendSampleBuffer.

Соответствующий код

// Creating the audio buffer:
CMSampleBufferRef buff = NULL;
CMSampleTimingInfo timing = {
        CMTimeMake(1, _asbdFormat.mSampleRate),
        currentAudioTime,
        kCMTimeInvalid };


OSStatus status = CMSampleBufferCreate(kCFAllocatorDefault,
                                           NULL,
                                           false,
                                           NULL,
                                           NULL,
                                           _cmFormat,
                                           (CMItemCount)(*inNumberFrames),
                                           1,
                                           &timing,
                                           0,
                                           NULL,
                                           &buff);

// checking for error... (non returned)

// Converting from non-interleaved to interleaved.
    float zero = 0.f;
    vDSP_vclr(_interleavedABL.mBuffers[0].mData, 1, numFrames * 2);
    // Channel L
    vDSP_vsadd(ioData->mBuffers[0].mData, 1, &zero, _interleavedABL.mBuffers[0].mData, 2, numFrames);
    // Channel R
    vDSP_vsadd(ioData->mBuffers[0].mData, 1, &zero, (float*)(_interleavedABL.mBuffers[0].mData) + 1, 2, numFrames);

    _interleavedABL.mBuffers[0].mDataByteSize =  _interleavedASBD.mBytesPerFrame * numFrames;
    status = CMSampleBufferSetDataBufferFromAudioBufferList(buff,
                                                            kCFAllocatorDefault,
                                                            kCFAllocatorDefault,
                                                            0,
                                                            &_interleavedABL);

// checking for error... (non returned)

if (_assetWriterAudioInput.readyForMoreMediaData) {

    BOOL success = [_assetWriterAudioInput appendSampleBuffer:audioBuffer];  // THIS PRODUCES THE ERROR.

// success is returned true, but the above specified error is logged - on iOS 12.4 betas (not on 12.3 or before)
}

Прежде всего, вот как создается _assetWriterAudioInput:

-(BOOL) initializeAudioWriting
{
    BOOL success = YES;

    NSDictionary *audioCompressionSettings = // settings dictionary, see below.

    if ([_assetWriter canApplyOutputSettings:audioCompressionSettings forMediaType:AVMediaTypeAudio]) {
        _assetWriterAudioInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio outputSettings:audioCompressionSettings];
        _assetWriterAudioInput.expectsMediaDataInRealTime = YES;

        if ([_assetWriter canAddInput:_assetWriterAudioInput]) {
            [_assetWriter addInput:_assetWriterAudioInput];
        }
        else {
            // return error
        }
    }
    else {
        // return error
    }

    return success;
}

audioCompressionSettings определяется как:

+ (NSDictionary*)audioSettingsForRecording
{
    AVAudioSession *sharedAudioSession = [AVAudioSession sharedInstance];
    double preferredHardwareSampleRate;

    if ([sharedAudioSession respondsToSelector:@selector(sampleRate)])
    {
        preferredHardwareSampleRate = [sharedAudioSession sampleRate];
    }
    else
    {
        preferredHardwareSampleRate = [[AVAudioSession sharedInstance] currentHardwareSampleRate];
    }

    AudioChannelLayout acl;
    bzero( &acl, sizeof(acl));
    acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;


    return @{
         AVFormatIDKey: @(kAudioFormatMPEG4AAC),
         AVNumberOfChannelsKey: @2,
         AVSampleRateKey: @(preferredHardwareSampleRate),
         AVChannelLayoutKey: [ NSData dataWithBytes: &acl length: sizeof( acl ) ],
         AVEncoderBitRateKey: @160000
         };
}

appendSampleBuffer регистрирует следующую ошибку и стек вызовов (соответствующая часть):

CMSampleBufferGetSampleSize сигнализировал err = -12735 (kCMSampleBufferError_BufferHasNoSampleSizes) (sbuf-> numSampleSizeEntries == 0) в /BuildRoot/Library/Caches/com/apple.xer/FerSBR&SignSBRXSBRFBC_WR_SyS_SyS_SySe_SySe_SySe_SySe_Se_SyS_S_S_S_S_S_S_Med_Med_Med_Med_Med_Med_Med_Med_Med_Med_D_Ty_Se_Te_Se_Be_Ty_Ty_Ty_Ty_Ty_Ty_Ty_Ty_Ty_Te_Se.Emp.Emp. 4153

0 CoreMedia 0x00000001aff75194 CMSampleBufferGetSampleSize + 268 [0x1aff34000 + 266644]

1 Мое приложение 0x0000000103212dfc - [MyClassName writeAudioFrames: audioBuffers:] + 1788 [0x102aec000 + 7499260] ...

Любая помощь будет оценена.

РЕДАКТИРОВАТЬ: Добавление следующей информации: мы передаем 0 и NULL для numSampleSizeEntries и sampleSizeArray параметров CMSampleBufferCreate - что в соответствии с документом - это то, что мы должны передать при создании буфера без чередования данных (хотя этот документ немного смущает меня ).

Мы попытались передать 1 и указатель на параметр size_t, например:

size_t sampleSize = 4;

но это не помогло: В журнале произошла ошибка:

figSampleBufferCheckDataSize сигнализировал err = -12731 (kFigSampleBufferError_RequiredParameterMissing) (несоответствие размера данных bbuf и sbuf)

и нам не ясно, какое значение должно быть (как узнать размер выборки для каждой выборки), или это правильное решение вообще.

1 Ответ

0 голосов
/ 01 июля 2019

Я думаю, что у нас есть ответ:

Передача numSampleSizeEntries и sampleSizeArray параметров CMSampleBufferCreate следующим образомкажется, это исправляет (все еще требует полной проверки).

Насколько я понимаю, причина в том, что мы в конце добавляем чередуемый буфер, он должен иметь размеры выборки (по крайней мере, в версии 12.4).

// _asbdFormat is the AudioStreamBasicDescription.
size_t sampleSize = _asbdFormat.mBytesPerFrame;
OSStatus status = CMSampleBufferCreate(kCFAllocatorDefault,
                                           NULL,
                                           false,
                                           NULL,
                                           NULL,
                                           _cmFormat,
                                           (CMItemCount)(*inNumberFrames),
                                           1,
                                           &timing,
                                           1,
                                           &sampleSize,
                                           &buff);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...