AudioQueue回调中AudioQueueGetCurrentTime()获取到的时间戳的含义

问题描述 投票:0回答:1

我正在开发一个音频项目,并且对 AudioQueueGetCurrentTime() 检索到的时间戳的含义有疑问。

根据 Apple 开发人员文档,以下计算给出了正在播放的音频时间(自 AudioQueueStart 以来):

- (Float64) GetCurrentTime {
    AudioTimeStamp c;       
    AudioQueueGetCurrentTime(playState.queue, NULL, &c, NULL);  
    return c.mSampleTime / _av->audio.sample_rate;
}

但是,在我正在做的一个项目中,我注意到AudioQueue的fillAudioBuffer回调函数内部有以下代码:


static void fillAudioBuffer(AudioQueueRef queue, AudioQueueBufferRef buffer){
    
    int lengthCopied = INT32_MAX;
    int dts= 0;
    int isDone = 0;

    buffer->mAudioDataByteSize = 0;
    buffer->mPacketDescriptionCount = 0;
    
    OSStatus err = 0;
    AudioTimeStamp bufferStartTime;

    AudioQueueGetCurrentTime(queue, NULL, &bufferStartTime, NULL);
    

    
    while(buffer->mPacketDescriptionCount < numPacketsToRead && lengthCopied > 0){
        if (buffer->mAudioDataByteSize) {
            break;
        }
        
        lengthCopied = getNextAudio(_av,buffer->mAudioDataBytesCapacity-buffer->mAudioDataByteSize, (uint8_t*)buffer->mAudioData+buffer->mAudioDataByteSize,&dts,&isDone);
        if(!lengthCopied || isDone) break;
      
        if(aqStartDts < 0) aqStartDts = dts;
        if (dts>0) currentDts = dts;
        if(buffer->mPacketDescriptionCount ==0){
            bufferStartTime.mFlags = kAudioTimeStampSampleTimeValid;
            bufferStartTime.mSampleTime = (Float64)(dts-aqStartDts) * _av->audio.frame_size;
            
            if (bufferStartTime.mSampleTime <0 ) bufferStartTime.mSampleTime = 0;
            PMSG2("AQHandler.m fillAudioBuffer: DTS for %x: %lf time base: %lf StartDTS: %d\n", (unsigned int)buffer, bufferStartTime.mSampleTime, _av->audio.time_base, aqStartDts);
            
        }
        buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mStartOffset = buffer->mAudioDataByteSize;
        buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mDataByteSize = lengthCopied;
        buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mVariableFramesInPacket = _av->audio.frame_size;
        
        buffer->mPacketDescriptionCount++;
        buffer->mAudioDataByteSize += lengthCopied;
        
    }
    
#ifdef DEBUG
    int audioBufferCount, audioBufferTotal,  videoBufferCount, videoBufferTotal;
    bufferCheck(_av,&videoBufferCount, &videoBufferTotal, &audioBufferCount, &audioBufferTotal);
    
    PMSG2("AQHandler.m fillAudioBuffer: Video Buffer: %d/%d Audio Buffer: %d/%d\n", videoBufferCount, videoBufferTotal, audioBufferCount, audioBufferTotal);
    
    PMSG2("AQHandler.m fillAudioBuffer: Bytes copied for buffer 0x%x: %d\n",(unsigned int)buffer, (int)buffer->mAudioDataByteSize );
#endif  
    if(buffer->mAudioDataByteSize){
        
        if(err=AudioQueueEnqueueBufferWithParameters(queue, buffer, 0, NULL, 0, 0, 0, NULL, &bufferStartTime, NULL))
        {
#ifdef DEBUG
            char sErr[10];

            PMSG2(@"AQHandler.m fillAudioBuffer: Could not enqueue buffer 0x%x: %d %s.", buffer, err, FormatError(sErr, err));
#endif
        }
    }

}

根据

AudioQueueEnqueueBufferWithParameters
的文档和作者使用的变量命名,
bufferStartTime
似乎代表新填充的音频缓冲区开始播放的时间,即队列中当前所有音频播放完毕的时间然后新的音频开始。这种解释表明
bufferStartTime
与当前正在播放的音频的时间不同。

我已经浏览了很多相关的问题,但我仍然有一些疑问..我目前正在修复我的项目中的音视频同步问题,并且Apple开发者文档(或者可能是我的搜索)中没有太多详细信息缺乏技能)。

有人可以澄清在这种情况下 AudioQueueGetCurrentTime() 返回的时间戳的确切含义吗?是当前音频结束播放的时间,还是新音频开始播放的时间?任何详细解释这一点的其他资源或文档也将不胜感激。

ios objective-c ffmpeg core-audio audioqueue
1个回答
0
投票

您想知道的代码实际上并没有使用

AudioQueueGetCurrentTime()
返回的时间,尽管它有时会覆盖然后记录结果。

我将 this doco 解释为

AudioQueueGetCurrentTime
应返回
AudioQueue
输出(或捕获,如果您使用输入变体)的样本数,或者如果该数量为负数,则返回 中的样本数队列计划开始的未来(事实上
AudioQueueStart()
确实有一个可选的开始时间,所以这是令人放心的一致)。

负时间戳恶作剧让我相信这不是

AudioQueue
实际消耗的样本数量,但这没关系,因为你已经知道你提供了多少样本(可能是代码中的
dts-aqStartDts
) ).

© www.soinside.com 2019 - 2024. All rights reserved.