public ErrorCode process(ISample sample) { while (samples_.Count == MAX_PACKETS && !eos_) { Thread.Sleep(1); } if (eos_) { clear(); return ErrorCode.EndOfStream; } Debug.Assert(sample.pointee().Length <= BUFFER_SIZE); if (buffer_ == IntPtr.Zero) { allocator_.alloc(out buffer_, BUFFER_SIZE); left_ = BUFFER_SIZE; Debug.Assert(buffer_ != IntPtr.Zero); } IntPtr dst = new IntPtr(buffer_.ToInt64() + BUFFER_SIZE - left_); //amcdx_u8* src = static_cast<amcdx_u8*>(sample->pointee()); if (left_ >= sample.pointee().Length) { //memcpy(dst, src, sample->size()); Marshal.Copy(sample.pointee(), 0, dst, sample.pointee().Length); left_ -= (uint)sample.pointee().Length; } else { if (left_ > 0) { Marshal.Copy(sample.pointee(), 0, dst, (int)left_); } PCMSample sampl = new PCMSample(); sampl.size = BUFFER_SIZE; sampl.pointer = buffer_; sampl.time = sample.endTime(); samples_.AddLast(sampl); allocator_.alloc(out buffer_, BUFFER_SIZE); Debug.Assert(buffer_ != IntPtr.Zero); Debug.Assert(sample.pointee().Length - left_ <= BUFFER_SIZE); Marshal.Copy(sample.pointee(), (int)left_, buffer_, (int)(sample.pointee().Length - left_)); left_ = (uint)(BUFFER_SIZE + left_ - sample.pointee().Length); Debug.Assert(left_ <= BUFFER_SIZE); } if ((stopped_ && samples_.Count > 2) || (stopped_ && eos_)) { lock(cs_) { int size = samples_.Count; if (renderer_ == IntPtr.Zero) { waveOutOpen(out renderer_, 0, ref wfx_, IntPtr.Zero, 0, 0); for (int i = 0; i < Math.Min(size, 2); ++i) { if (i == 0) { IntPtr ptr = AVUtils.readPtr(hdr0_, 0); AVUtils.memcpy(samples_.First.Value.pointer, ptr, (int)samples_.First.Value.size); allocator_.free(samples_.First.Value.pointer, BUFFER_SIZE); timeStamps_.AddLast(samples_.First.Value.time); waveOutPrepareHeader(renderer_, hdr0_, 5 * 4 + 3 * Marshal.SizeOf(typeof(IntPtr))); samples_.RemoveFirst(); } else { IntPtr ptr = AVUtils.readPtr(hdr1_, 0); AVUtils.memcpy(samples_.First.Value.pointer, ptr, (int)samples_.First.Value.size); allocator_.free(samples_.First.Value.pointer, BUFFER_SIZE); timeStamps_.AddLast(samples_.First.Value.time); waveOutPrepareHeader(renderer_, hdr1_, 5 * 4 + 3 * Marshal.SizeOf(typeof(IntPtr))); samples_.RemoveFirst(); } } } for (int i = 0; i < Math.Min(size, 2); ++i) { if (i == 0) { if (waveOutWrite(renderer_, hdr0_, 5 * 4 + 3 * Marshal.SizeOf(typeof(IntPtr))) != 0) { Debug.Assert(false); } } else { if (waveOutWrite(renderer_, hdr1_, 5 * 4 + 3 * Marshal.SizeOf(typeof(IntPtr))) != 0) { Debug.Assert(false); } } } thread_ = new Thread(threadFunc); stopped_ = false; thread_.Start(); } } return ErrorCode.Success; }
public ErrorCode endOfStream(bool flush) { if (!flush) { clear(); } else if (buffer_ != IntPtr.Zero) { PCMSample sampl = new PCMSample(); sampl.size = (uint)(BUFFER_SIZE); sampl.pointer = buffer_; sampl.time = 0; ; samples_.AddLast(sampl); buffer_ = IntPtr.Zero; left_ = 0; } return ErrorCode.Success; }