mirror of
https://github.com/amitbet/vnc2video.git
synced 2025-04-27 18:25:10 +00:00
191 lines
5.0 KiB
Go
191 lines
5.0 KiB
Go
package vnc2video
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
"os"
|
|
//"vncproxy/common"
|
|
//"vncproxy/encodings"
|
|
"github.com/amitbet/vnc2video/logger"
|
|
//"vncproxy/encodings"
|
|
//"vncproxy/encodings"
|
|
)
|
|
|
|
type FbsReader struct {
|
|
reader io.ReadCloser
|
|
buffer bytes.Buffer
|
|
currentTimestamp int
|
|
//pixelFormat *PixelFormat
|
|
//encodings []IEncoding
|
|
}
|
|
|
|
func (fbs *FbsReader) Close() error {
|
|
return fbs.reader.Close()
|
|
}
|
|
|
|
func (fbs *FbsReader) CurrentTimestamp() int {
|
|
return fbs.currentTimestamp
|
|
}
|
|
|
|
func (fbs *FbsReader) Read(p []byte) (n int, err error) {
|
|
if fbs.buffer.Len() < len(p) {
|
|
seg, err := fbs.ReadSegment()
|
|
|
|
if err != nil {
|
|
logger.Error("FBSReader.Read: error reading FBSsegment: ", err)
|
|
return 0, err
|
|
}
|
|
fbs.buffer.Write(seg.bytes)
|
|
fbs.currentTimestamp = int(seg.timestamp)
|
|
}
|
|
return fbs.buffer.Read(p)
|
|
}
|
|
|
|
//func (fbs *FbsReader) CurrentPixelFormat() *PixelFormat { return fbs.pixelFormat }
|
|
//func (fbs *FbsReader) CurrentColorMap() *common.ColorMap { return &common.ColorMap{} }
|
|
//func (fbs *FbsReader) Encodings() []IEncoding { return fbs.encodings }
|
|
|
|
func NewFbsReader(fbsFile string) (*FbsReader, error) {
|
|
|
|
reader, err := os.OpenFile(fbsFile, os.O_RDONLY, 0644)
|
|
if err != nil {
|
|
logger.Error("NewFbsReader: can't open fbs file: ", fbsFile)
|
|
return nil, err
|
|
}
|
|
return &FbsReader{reader: reader}, //encodings: []IEncoding{
|
|
// //&encodings.CopyRectEncoding{},
|
|
// //&encodings.ZLibEncoding{},
|
|
// //&encodings.ZRLEEncoding{},
|
|
// //&encodings.CoRREEncoding{},
|
|
// //&encodings.HextileEncoding{},
|
|
// &TightEncoding{},
|
|
// //&TightPngEncoding{},
|
|
// //&EncCursorPseudo{},
|
|
// &RawEncoding{},
|
|
// //&encodings.RREEncoding{},
|
|
//},
|
|
nil
|
|
|
|
}
|
|
|
|
func (fbs *FbsReader) ReadStartSession() (*ServerInit, error) {
|
|
|
|
initMsg := ServerInit{}
|
|
reader := fbs.reader
|
|
|
|
var framebufferWidth uint16
|
|
var framebufferHeight uint16
|
|
var SecTypeNone uint32
|
|
//read rfb header information (the only part done without the [size|data|timestamp] block wrapper)
|
|
//.("FBS 001.000\n")
|
|
bytes := make([]byte, 12)
|
|
_, err := reader.Read(bytes)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init message - FBS file Version:", err)
|
|
return nil, err
|
|
}
|
|
|
|
//read the version message into the buffer, it is written in the first fbs block
|
|
//RFB 003.008\n
|
|
bytes = make([]byte, 12)
|
|
_, err = fbs.Read(bytes)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - RFB Version: ", err)
|
|
return nil, err
|
|
}
|
|
|
|
//push sec type and fb dimensions
|
|
binary.Read(fbs, binary.BigEndian, &SecTypeNone)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - SecType: ", err)
|
|
}
|
|
|
|
//read frame buffer width, height
|
|
binary.Read(fbs, binary.BigEndian, &framebufferWidth)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - FBWidth: ", err)
|
|
return nil, err
|
|
}
|
|
initMsg.FBWidth = framebufferWidth
|
|
|
|
binary.Read(fbs, binary.BigEndian, &framebufferHeight)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - FBHeight: ", err)
|
|
return nil, err
|
|
}
|
|
initMsg.FBHeight = framebufferHeight
|
|
|
|
//read pixel format
|
|
pixelFormat := &PixelFormat{}
|
|
binary.Read(fbs, binary.BigEndian, pixelFormat)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - Pixelformat: ", err)
|
|
return nil, err
|
|
}
|
|
|
|
initMsg.PixelFormat = *pixelFormat
|
|
|
|
//read desktop name
|
|
var desknameLen uint32
|
|
binary.Read(fbs, binary.BigEndian, &desknameLen)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - deskname Len: ", err)
|
|
return nil, err
|
|
}
|
|
initMsg.NameLength = desknameLen
|
|
|
|
bytes = make([]byte, desknameLen)
|
|
fbs.Read(bytes)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadStartSession: error reading rbs init - desktopName: ", err)
|
|
return nil, err
|
|
}
|
|
|
|
initMsg.NameText = bytes
|
|
|
|
return &initMsg, nil
|
|
}
|
|
|
|
func (fbs *FbsReader) ReadSegment() (*FbsSegment, error) {
|
|
reader := fbs.reader
|
|
var bytesLen uint32
|
|
|
|
//read length
|
|
err := binary.Read(reader, binary.BigEndian, &bytesLen)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadSegment: reading len, error reading rbs file: ", err)
|
|
return nil, err
|
|
}
|
|
|
|
paddedSize := (bytesLen + 3) & 0x7FFFFFFC
|
|
|
|
//read bytes
|
|
bytes := make([]byte, paddedSize)
|
|
_, err = reader.Read(bytes)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadSegment: reading bytes, error reading rbs file: ", err)
|
|
return nil, err
|
|
}
|
|
|
|
//remove padding
|
|
actualBytes := bytes[:bytesLen]
|
|
|
|
//read timestamp
|
|
var timeSinceStart uint32
|
|
binary.Read(reader, binary.BigEndian, &timeSinceStart)
|
|
if err != nil {
|
|
logger.Error("FbsReader.ReadSegment: read timestamp, error reading rbs file: ", err)
|
|
return nil, err
|
|
}
|
|
|
|
//timeStamp := time.Unix(timeSinceStart, 0)
|
|
seg := &FbsSegment{bytes: actualBytes, timestamp: timeSinceStart}
|
|
return seg, nil
|
|
}
|
|
|
|
type FbsSegment struct {
|
|
bytes []byte
|
|
timestamp uint32
|
|
}
|