Skip to content

Instantly share code, notes, and snippets.

@feliwir
Created September 29, 2017 16:12
Show Gist options
  • Select an option

  • Save feliwir/0431412ab1419b17e9bd69df6b0c2fd8 to your computer and use it in GitHub Desktop.

Select an option

Save feliwir/0431412ab1419b17e9bd69df6b0c2fd8 to your computer and use it in GitHub Desktop.
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