| bool arda::AudioStream::UpdateBuffers() | |
| { | |
| auto& format_ctx = m_internals->format_ctx; | |
| auto& avstream = m_internals->avstream; | |
| auto& codec_ctx = m_internals->codec_ctx; | |
| auto& codec = m_internals->codec; | |
| auto& frame = m_internals->audioFrame; | |
| auto& bufferchain = m_internals->bufferchain; | |
| auto& source = m_internals->source; | |
| auto& needsResample = m_internals->needsResample; | |
| auto& resampler = m_internals->resampler; | |
| auto& out_fmt = m_internals->out_fmt; | |
| auto& cbuffer = m_internals->cbuffer; | |
| int frameFinished; | |
| AVPacket packet; | |
| bool updatedColor = false, updatedAlpha = false; | |
| ARDA_LOG("Update buffers"); | |
| while (av_read_frame(format_ctx, &packet) >= 0) | |
| { | |
| AVPacket decodingPacket = packet; | |
| while(decodingPacket.size > 0) | |
| { | |
| // Decode audio frame | |
| int consumed = avcodec_decode_audio4(codec_ctx, frame, &frameFinished, &packet); | |
| double pts = packet.pts; | |
| double duration = frame->pkt_duration / static_cast<double>(AV_TIME_BASE); | |
| int data_size = av_samples_get_buffer_size(NULL, codec_ctx->channels,frame->nb_samples, codec_ctx->sample_fmt, 1); | |
| if (consumed>=0 && frameFinished) | |
| { | |
| decodingPacket.size -= consumed; | |
| decodingPacket.data += consumed; | |
| uint8_t* data; | |
| int linesize = 0; | |
| //check if we must resample: | |
| if (needsResample) | |
| { | |
| av_samples_alloc(&data,NULL, 1, frame->nb_samples, out_fmt, 0); | |
| int frame_count = swr_convert(resampler, &data, frame->nb_samples, (const uint8_t**)frame->data, frame->nb_samples); | |
| data_size = av_samples_get_buffer_size(&linesize, m_channels, frame->nb_samples, out_fmt, 0); | |
| } | |
| else | |
| { | |
| data = frame->data[0]; | |
| } | |
| //got a finished frame here | |
| auto& buffer = bufferchain[cbuffer]; | |
| buffer->Upload(data, data_size); | |
| if (needsResample) | |
| { | |
| //Crash here, data is a valid pointer at that time | |
| av_freep(&data); | |
| } | |
| ALuint handle = buffer->GetHandle(); | |
| alSourceQueueBuffers(source, 1, &handle); | |
| Audio::checkErrorAl("Failed to query buffer to source"); | |
| ++cbuffer; | |
| cbuffer %= 3; | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| return false; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment