我的应用程序中有一个视频播放器。我对avi文件和mp3音频没有问题,但是当我播放mpg或wmv时,我必须使用avcodec_decode_audio3。前几秒钟播放,然后当缓冲区重新填充时,我会静默几秒钟,然后音频从同一个地方继续,每次缓冲区重新填充时都会发生这种情况。
这是音频队列格式:
playState.format.mSampleRate = _av->audio.sample_rate;
playState.format.mFormatID = kAudioFormatLinearPCM;
playState.format.mFormatFlags = kAudioFormatFlagsCanonical;
playState.format.mChannelsPerFrame = _av->audio.channels_per_frame;
playState.format.mBytesPerPacket = sizeof(AudioSampleType) *_av->audio.channels_per_frame;
playState.format.mBytesPerFrame = sizeof(AudioSampleType) *_av->audio.channels_per_frame;
playState.format.mBitsPerChannel = 8 * sizeof(AudioSampleType);
playState.format.mFramesPerPacket = 1;
playState.format.mReserved = 0;
填充音频缓冲区:
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){
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(buffer->mPacketDescriptionCount ==0){
bufferStartTime.mFlags = kAudioTimeStampSampleTimeValid;
bufferStartTime.mSampleTime = (Float64)(dts-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;
}
if(buffer->mAudioDataByteSize){
if((err=AudioQueueEnqueueBufferWithParameters(queue, buffer, 0, NULL, 0, 0, 0, NULL, &bufferStartTime, NULL)))
{
}
}
int getNextAudio(video_data_t* vInst, int maxlength, uint8_t* buf, int* pts, int* isDone) {
struct video_context_t *ctx = vInst->context;
int datalength = 0;
while(ctx->audio_ring.lock || ((ctx->audio_ring.count <= 0 && ((ctx->play_state & STATE_DIE) != STATE_DIE))&&((ctx->play_state & STATE_EOF) != STATE_EOF))){
PMSG1(stdout,"die get audio %d", ctx->play_state);
if((ctx->play_state & STATE_STOP) != STATE_STOP){
PMSG1(stdout,"die NO CARGADO %d",ctx->play_state);
return 0;
}
usleep(100);
}
*pts = 0;
ctx->audio_ring.lock = kLocked;
if(ctx->audio_ring.count>0 && maxlength > ctx->audio_buffer[ctx->audio_ring.read].size){
memcpy(buf, ctx->audio_buffer[ctx->audio_ring.read].data, ctx->audio_buffer[ctx->audio_ring.read].size);
datalength = ctx->audio_buffer[ctx->audio_ring.read].size;
*pts = ctx->audio_buffer[ctx->audio_ring.read].pts;
ctx->audio_ring.read++;
ctx->audio_ring.read %= ABUF_SIZE;
ctx->audio_ring.count--;
}
ctx->audio_ring.lock = kUnlocked;
if((ctx->play_state & STATE_EOF) == STATE_EOF && ctx->audio_ring.count == 0) *isDone = 1;
return datalength;
这是播放 mpg 文件的日志:
Input #0, mpeg, '1.MPG':
Duration: 00:03:14.74, start: 3370.475789, bitrate: 2489 kb/s
Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p, 544x576 [SAR 24:17 DAR 4:3], 9000 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16, 192 kb/s
mpeg2video MPEG-2 video
aspect 1.333333
startPlayback
DTS: 0.000000 time base: 0.000011 StartDTS: 303347520 Orig DTS: 303347520
Video Buffer: 157/1024 Audio Buffer: 33/1024
Bytes copied for buffer 0xc292ac0: 1046016
DTS: 490320.000000 time base: 0.000011 StartDTS: 303347520 Orig DTS: 303837840
Video Buffer: 276/1024 Audio Buffer: 2/1024
Bytes copied for buffer 0x1225f8b0: 1046016
DTS: 980640.000000 time base: 0.000011 StartDTS: 303347520 Orig DTS: 304328160
Video Buffer: 411/1024 Audio Buffer: 1/1024
Bytes copied for buffer 0x13380840: 1046016
DTS: 1470960.000000 time base: 0.000011 StartDTS: 303347520 Orig DTS: 304818480
Video Buffer: 885/1024 Audio Buffer: 797/1024
Bytes copied for buffer 0xc292ac0: 1046016
-----Here the audio stop for 4 or 5 seconds
-----then continues for 4 or 5 seconds
DTS: 1961280.000000 time base: 0.000011 StartDTS: 303347520 Orig DTS: 305308800
Video Buffer: 765/1024 Audio Buffer: 797/1024
Bytes copied for buffer 0x1225f8b0: 1046016
-----Here the audio stop for 4 or 5 seconds
-----then continues for 4 or 5 seconds
DTS: 2451600.000000 time base: 0.000011 StartDTS: 303347520 Orig DTS: 305799120
Video Buffer: 644/1024 Audio Buffer: 798/1024
Bytes copied for buffer 0x13380840: 1046016
...
如果我减少缓冲区,则静音和声音时间会减少。所以我想知道如何解决它?谢谢!!