public int Read(int count) { int offset = ReadCache(count, 0); while (count - offset > 0) { if (FFmpeg.av_read_frame(FormatPointer, PacketPointer) < 0) { break; } FFmpeg.AVPacket packet = (FFmpeg.AVPacket)Marshal.PtrToStructure(PacketPointer, typeof(FFmpeg.AVPacket)); Cache.Position = 0; CacheOffset = 0; CacheLength = 0; while (packet.size > 0) { int datasize = FFmpegBufferSize; int used = FFmpeg.avcodec_decode_audio2(AVStream.codec, FFmpegBuffer, ref datasize, packet.data, packet.size); packet.size -= used; packet.data = new IntPtr(packet.data.ToInt32() + used); if (datasize <= 0) { break; } int read = Math.Max(Math.Min(datasize, (count - offset) * 2 * Channels), 0); int left = datasize - read; if (read > 0) { int samples = read / 2 / Channels; short[] bitstream = new short[read / 2]; Marshal.Copy(FFmpegBuffer, bitstream, 0, read / 2); AudioBuffer.DeinterlaceFrom(bitstream, samples, offset); offset += samples; } if (left > 0) { Marshal.Copy(new IntPtr(FFmpegBuffer.ToInt32() + read), CacheBuffer, 0, left); Cache.Write(CacheBuffer, read, left); CacheLength += left; } } } return(offset); }
private int ReadCache(int count, int offset) { Cache.Position = CacheOffset; int bytesize = Math.Min((count - offset) * 2 * Channels, CacheLength - CacheOffset); if (bytesize <= 0) { return(offset); } short[] bitstream = new short[bytesize / 2]; int samples = bytesize / 2 / Channels; Buffer.BlockCopy(Cache.GetBuffer(), CacheOffset, bitstream, 0, bytesize); AudioBuffer.DeinterlaceFrom(bitstream, samples, offset); offset += samples; CacheOffset += bytesize; return(offset); }