У меня есть видеопроигрыватель в моем приложении. У меня нет проблем с файлами avi и mp3-аудио, но когда я играю в mpg или wmv, и мне приходится использовать avcodec_decode_audio3. Первые секунды воспроизводятся, а затем, когда заполняется буфер, я получаю тишину в течение нескольких секунд, а затем звук продолжается с одного и того же места, это происходит каждый раз, когда буфер заполняется.FFmpeg: аудиосинхронизация с звуковым сигналом
Это звуковых сообщений Формат:
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;
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){
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;
Это журнал играет файл миль на галлон:
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
...
если я уменьшить буфер, тишина и время звучания уменьшается. Итак, я хочу знать, как это исправить? Благодаря!!
Вы уверены, что аудио буфер достаточно большой, если (buffer-> mAudioDataByteSize) { если ((ERR = AudioQueueEnqueueBufferWithParameters (очередь, буфер, 0, NULL, 0, 0, 0, NULL, & bufferStartTime, NULL))) возможно, взгляните на этот https://github.com/mooncatventures-group/sampleDecoder { } } –
Я попытался увеличить буфер без везения. Спасибо за этот код. Я стараюсь сделать это как этот код, но у меня все еще есть одна и та же проблема, и интересно, что молчание - это такое же количество времени, что и звук. Дело в том, что этот код заключается в том, что он игнорирует точки, это нормально только для воспроизведения звука, но если я так делаю, то получаю десинхронизированное аудио/видео. – juanramoney
Возможно, проблема с реализацией вашего буфера буфера –