/// <summary> /// actually write a packet to file /// timestamp sequence must be nondecreasing /// </summary> void writeActual(JmdPacket j) { if (j.Timestamp < _timestampOff) { throw new ArithmeticException("JMD Timestamp problem?"); } UInt64 timestampout = j.Timestamp - _timestampOff; while (timestampout > 0xffffffff) { timestampout -= 0xffffffff; // write timestamp skipper for (int i = 0; i < 6; i++) { _f.WriteByte(0xff); } } _timestampOff = j.Timestamp; WriteBe16(j.Stream); writeBE32((UInt32)timestampout); _f.WriteByte(j.Subtype); writeVar((UInt64)j.Data.LongLength); _f.Write(j.Data, 0, j.Data.Length); }
/// <summary> /// actually write a packet to file /// timestamp sequence must be non-decreasing /// </summary> private void WriteActual(JmdPacket j) { if (j.Timestamp < _timestampOff) { throw new ArithmeticException("JMD Timestamp problem?"); } var timeStampOut = j.Timestamp - _timestampOff; while (timeStampOut > 0xffffffff) { timeStampOut -= 0xffffffff; // write timestamp skipper for (int i = 0; i < 6; i++) { _f.WriteByte(0xff); } } _timestampOff = j.Timestamp; WriteBe16(j.Stream); WriteBe32((uint)timeStampOut); _f.WriteByte(j.Subtype); WriteVar((ulong)j.Data.LongLength); _f.Write(j.Data, 0, j.Data.Length); }
/// <summary> /// assemble JMDPacket and send to packetqueue /// </summary> /// <param name="source">zlibed frame with width and height prepended</param> public void AddVideo(byte[] source) { var j = new JmdPacket(); j.Stream = 0; j.Subtype = 1; // zlib compressed, other possibility is 0 = uncompressed j.Data = source; j.Timestamp = timestampcalc(_fpsNum, _fpsDen, (UInt64)_totalFrames); _totalFrames++; WriteVideo(j); }
/// <summary> /// assemble JMDPacket and send to PacketQueue /// </summary> /// <param name="source">zlibed frame with width and height prepended</param> public void AddVideo(byte[] source) { var j = new JmdPacket { Stream = 0, Subtype = 1, // zlib compressed, other possibility is 0 = uncompressed Data = source, Timestamp = TimestampCalc(_fpsNum, _fpsDen, _totalFrames) }; _totalFrames++; WriteVideo(j); }
// add a video packet to the file write queue // will be written when order-appropriate wrt audio // the video packets added must be internally ordered (but need not match audio order) private void WriteVideo(JmdPacket j) { while (_audioStorage.Count > 0) { var p = _audioStorage.Peek(); if (p.Timestamp <= j.Timestamp) { writeActual(_audioStorage.Dequeue()); } else { break; } } _videoStorage.Enqueue(j); }
/// <summary> /// helper function makes a JMDPacket out of one sample pair and adds it to the order queue /// </summary> /// <param name="l">left sample</param> /// <param name="r">right sample</param> void doaudiopacket(short l, short r) { var j = new JmdPacket(); j.Stream = 1; j.Subtype = 1; // raw PCM audio j.Data = new byte[4]; j.Data[0] = (byte)(l >> 8); j.Data[1] = (byte)(l & 255); j.Data[2] = (byte)(r >> 8); j.Data[3] = (byte)(r & 255); j.Timestamp = timestampcalc(_audioSamplerate, 1, _totalSamples); _totalSamples++; WriteSound(j); }
/// <summary> /// helper function makes a JMDPacket out of one sample pair and adds it to the order queue /// </summary> /// <param name="l">left sample</param> /// <param name="r">right sample</param> private void DoAudioPacket(short l, short r) { var j = new JmdPacket { Stream = 1, Subtype = 1, // raw PCM audio Data = new byte[4] }; j.Data[0] = (byte)(l >> 8); j.Data[1] = (byte)(l & 255); j.Data[2] = (byte)(r >> 8); j.Data[3] = (byte)(r & 255); j.Timestamp = TimestampCalc(_audioSamplerate, 1, _totalSamples); _totalSamples++; WriteSound(j); }