private byte[] GetSubImageBuffer(RunLengthTwoParts twoPartBuffer, NikseBitmap nbmp, Paragraph p, ContentAlignment alignment, Point?overridePosition) { var ms = new MemoryStream(); // sup picture data size WriteEndianWord(twoPartBuffer.Length + 34, ms); // first display control sequence table address int startDisplayControlSequenceTableAddress = twoPartBuffer.Length + 4; WriteEndianWord(startDisplayControlSequenceTableAddress, ms); // Write image const int imageTopFieldDataAddress = 4; ms.Write(twoPartBuffer.Buffer1, 0, twoPartBuffer.Buffer1.Length); int imageBottomFieldDataAddress = 4 + twoPartBuffer.Buffer1.Length; ms.Write(twoPartBuffer.Buffer2, 0, twoPartBuffer.Buffer2.Length); // Write zero delay ms.WriteByte(0); ms.WriteByte(0); // next display control sequence table address (use current is last) WriteEndianWord(startDisplayControlSequenceTableAddress + 24, ms); // start of display control sequence table address // Control command start ms.WriteByte(p.Forced ? (byte)0 : (byte)1); // Control command 3 = SetColor WriteColors(ms); // 3 bytes // Control command 4 = SetContrast WriteContrast(ms); // 3 bytes // Control command 5 = SetDisplayArea WriteDisplayArea(ms, nbmp, alignment, overridePosition); // 7 bytes // Control command 6 = SetPixelDataAddress WritePixelDataAddress(ms, imageTopFieldDataAddress, imageBottomFieldDataAddress); // 5 bytes // Control command exit ms.WriteByte(255); // 1 byte // Control Sequence Table // Write delay - subtitle duration WriteEndianWord(Convert.ToInt32(p.Duration.TotalMilliseconds * 90.0) >> 10, ms); // next display control sequence table address (use current is last) WriteEndianWord(startDisplayControlSequenceTableAddress + 24, ms); // start of display control sequence table address // Control command 2 = StopDisplay ms.WriteByte(2); // extra byte - for compatibility with gpac/MP4BOX ms.WriteByte(255); // 1 byte return(ms.ToArray()); }
private byte[] GetSubImageBuffer(RunLengthTwoParts twoPartBuffer, NikseBitmap nbmp, Paragraph p, ContentAlignment alignment) { var ms = new MemoryStream(); // sup picture datasize WriteEndianWord(twoPartBuffer.Length + 34, ms); // first display control sequence table address int startDisplayControlSequenceTableAddress = twoPartBuffer.Length + 4; WriteEndianWord(startDisplayControlSequenceTableAddress, ms); // Write image const int imageTopFieldDataAddress = 4; ms.Write(twoPartBuffer.Buffer1, 0, twoPartBuffer.Buffer1.Length); int imageBottomFieldDataAddress = 4 + twoPartBuffer.Buffer1.Length; ms.Write(twoPartBuffer.Buffer2, 0, twoPartBuffer.Buffer2.Length); // Write zero delay ms.WriteByte(0); ms.WriteByte(0); // next display control sequence table address (use current is last) WriteEndianWord(startDisplayControlSequenceTableAddress + 24, ms); // start of display control sequence table address // Control command start if (p.Forced) ms.WriteByte(0); // ForcedStartDisplay==0 else ms.WriteByte(1); // StartDisplay==1 // Control command 3 = SetColor WriteColors(ms); // 3 bytes // Control command 4 = SetContrast WriteContrast(ms); // 3 bytes // Control command 5 = SetDisplayArea WriteDisplayArea(ms, nbmp, alignment); // 7 bytes // Control command 6 = SetPixelDataAddress WritePixelDataAddress(ms, imageTopFieldDataAddress, imageBottomFieldDataAddress); // 5 bytes // Control command exit ms.WriteByte(255); // 1 byte // Control Sequence Table // Write delay - subtitle duration WriteEndianWord(Convert.ToInt32(p.Duration.TotalMilliseconds * 90.0 - 1023) >> 10, ms); // next display control sequence table address (use current is last) WriteEndianWord(startDisplayControlSequenceTableAddress + 24, ms); // start of display control sequence table address // Control command 2 = StopDisplay ms.WriteByte(2); // extra byte - for compatability with gpac/MP4BOX ms.WriteByte(255); // 1 byte return ms.ToArray(); }