Skip to content

Commit

Permalink
Resize byte array automatically while loading audio files
Browse files Browse the repository at this point in the history
This is considerably faster than using List<byte> with initial capacity
and returning the list as array with ToArray() (8659b43).
  • Loading branch information
GoaLitiuM committed Sep 27, 2016
1 parent a309279 commit 8c8221b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 38 deletions.
55 changes: 21 additions & 34 deletions Pulsus/FFmpeg/FFmpegContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,36 +486,8 @@ private bool ConvertFrame()

public byte[] GetFrameData()
{
sbyte* buffer = null;
int bufferSize = 0;

// point to the correct frame where our output is
AVFrame* sourceFrame = frame;
if (swsContext != null)
sourceFrame = convertedFrame;

if (swrContext != null)
{
buffer = convertedBuffer;
bufferSize = convertedBytes;
}
else
{
buffer = sourceFrame->data0;
if (type == AVMediaType.AVMEDIA_TYPE_VIDEO)
{
bufferSize = ffmpeg.av_image_get_buffer_size((AVPixelFormat)sourceFrame->format,
sourceFrame->width, sourceFrame->height, 1);
}
else if (type == AVMediaType.AVMEDIA_TYPE_AUDIO)
{
bufferSize = ffmpeg.av_samples_get_buffer_size(null, audioChannels,
sourceFrame->nb_samples, (AVSampleFormat)sourceFrame->format, 1);
}

if (bufferSize < 0)
throw new FFmpegException(bufferSize);
}
sbyte* buffer = GetFrameBuffer(out bufferSize);

// allocate and copy the data to managed memory
if (managedBuffer == null || managedBuffer.Length != bufferSize)
Expand All @@ -528,8 +500,24 @@ public byte[] GetFrameData()

public int GetFrameData(ref byte[] bytes, int startIndex)
{
sbyte* buffer = null;
int bufferSize = 0;
sbyte* buffer = GetFrameBuffer(out bufferSize);

Marshal.Copy((IntPtr)buffer, bytes, startIndex, bufferSize);

return bufferSize;
}

public int GetFrameBufferSize()
{
int bufferSize = 0;
GetFrameBuffer(out bufferSize);
return bufferSize;
}

private sbyte* GetFrameBuffer(out int bufferSize)
{
sbyte* buffer = null;

// point to the correct frame where our output is
AVFrame* sourceFrame = frame;
Expand All @@ -554,15 +542,14 @@ public int GetFrameData(ref byte[] bytes, int startIndex)
bufferSize = ffmpeg.av_samples_get_buffer_size(null, audioChannels,
sourceFrame->nb_samples, (AVSampleFormat)sourceFrame->format, 1);
}
else
bufferSize = -1;

if (bufferSize < 0)
throw new FFmpegException(bufferSize);
}

Marshal.Copy((IntPtr)buffer, bytes, startIndex, bufferSize);

//return managedBuffer;
return bufferSize;
return buffer;
}

// set output format from file extension
Expand Down
18 changes: 14 additions & 4 deletions Pulsus/FFmpeg/FFmpegHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,19 @@ public static byte[] SoundFromFile(string path, out int sampleRate, out int chan

// FFmpeg only approximates stream durations but is
// usually not far from the real duration.
byte[] bytes = new byte[ffContext.audioBytesTotal + 4096];
byte[] bytes = new byte[ffContext.audioBytesTotal];

// read all data from frames
long offset = 0;
while (ffContext.ReadFrame())
{
long frameSize = ffContext.GetFrameBufferSize();
if (offset + frameSize > bytes.Length)
Array.Resize(ref bytes, (int)(offset + frameSize));

offset += ffContext.GetFrameData(ref bytes, (int)offset);
}

Array.Resize(ref bytes, (int)offset);
return bytes;
}
}
Expand Down Expand Up @@ -173,14 +178,19 @@ public static byte[] SoundFromFileResample(string path, int sampleRate, int chan

// FFmpeg only approximates stream durations but is
// usually not far from the real duration.
byte[] bytes = new byte[ffContext.audioBytesTotal + 4096];
byte[] bytes = new byte[ffContext.audioBytesTotal];

// read all data from frames
long offset = 0;
while (ffContext.ReadFrame())
{
long frameSize = ffContext.GetFrameBufferSize();
if (offset + frameSize > bytes.Length)
Array.Resize(ref bytes, (int)(offset + frameSize));

offset += ffContext.GetFrameData(ref bytes, (int)offset);
}

Array.Resize(ref bytes, (int)offset);
return bytes;
}
}
Expand Down

0 comments on commit 8c8221b

Please sign in to comment.