github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/fbs-reader.go (about)

     1  package vnc2video
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"io"
     7  	"os"
     8  	//"vncproxy/common"
     9  	//"vncproxy/encodings"
    10  	"github.com/amitbet/vnc2video/logger"
    11  	//"vncproxy/encodings"
    12  	//"vncproxy/encodings"
    13  )
    14  
    15  type FbsReader struct {
    16  	reader           io.ReadCloser
    17  	buffer           bytes.Buffer
    18  	currentTimestamp int
    19  	//pixelFormat      *PixelFormat
    20  	//encodings        []IEncoding
    21  }
    22  
    23  func (fbs *FbsReader) Close() error {
    24  	return fbs.reader.Close()
    25  }
    26  
    27  func (fbs *FbsReader) CurrentTimestamp() int {
    28  	return fbs.currentTimestamp
    29  }
    30  
    31  func (fbs *FbsReader) Read(p []byte) (n int, err error) {
    32  	if fbs.buffer.Len() < len(p) {
    33  		seg, err := fbs.ReadSegment()
    34  
    35  		if err != nil {
    36  			logger.Error("FBSReader.Read: error reading FBSsegment: ", err)
    37  			return 0, err
    38  		}
    39  		fbs.buffer.Write(seg.bytes)
    40  		fbs.currentTimestamp = int(seg.timestamp)
    41  	}
    42  	return fbs.buffer.Read(p)
    43  }
    44  
    45  //func (fbs *FbsReader) CurrentPixelFormat() *PixelFormat { return fbs.pixelFormat }
    46  //func (fbs *FbsReader) CurrentColorMap() *common.ColorMap       { return &common.ColorMap{} }
    47  //func (fbs *FbsReader) Encodings() []IEncoding { return fbs.encodings }
    48  
    49  func NewFbsReader(fbsFile string) (*FbsReader, error) {
    50  
    51  	reader, err := os.OpenFile(fbsFile, os.O_RDONLY, 0644)
    52  	if err != nil {
    53  		logger.Error("NewFbsReader: can't open fbs file: ", fbsFile)
    54  		return nil, err
    55  	}
    56  	return &FbsReader{reader: reader}, //encodings: []IEncoding{
    57  		//	//&encodings.CopyRectEncoding{},
    58  		//	//&encodings.ZLibEncoding{},
    59  		//	//&encodings.ZRLEEncoding{},
    60  		//	//&encodings.CoRREEncoding{},
    61  		//	//&encodings.HextileEncoding{},
    62  		//	&TightEncoding{},
    63  		//	//&TightPngEncoding{},
    64  		//	//&EncCursorPseudo{},
    65  		//	&RawEncoding{},
    66  		//	//&encodings.RREEncoding{},
    67  		//},
    68  		nil
    69  
    70  }
    71  
    72  func (fbs *FbsReader) ReadStartSession() (*ServerInit, error) {
    73  
    74  	initMsg := ServerInit{}
    75  	reader := fbs.reader
    76  
    77  	var framebufferWidth uint16
    78  	var framebufferHeight uint16
    79  	var SecTypeNone uint32
    80  	//read rfb header information (the only part done without the [size|data|timestamp] block wrapper)
    81  	//.("FBS 001.000\n")
    82  	bytes := make([]byte, 12)
    83  	_, err := reader.Read(bytes)
    84  	if err != nil {
    85  		logger.Error("FbsReader.ReadStartSession: error reading rbs init message - FBS file Version:", err)
    86  		return nil, err
    87  	}
    88  
    89  	//read the version message into the buffer, it is written in the first fbs block
    90  	//RFB 003.008\n
    91  	bytes = make([]byte, 12)
    92  	_, err = fbs.Read(bytes)
    93  	if err != nil {
    94  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - RFB Version: ", err)
    95  		return nil, err
    96  	}
    97  
    98  	//push sec type and fb dimensions
    99  	binary.Read(fbs, binary.BigEndian, &SecTypeNone)
   100  	if err != nil {
   101  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - SecType: ", err)
   102  	}
   103  
   104  	//read frame buffer width, height
   105  	binary.Read(fbs, binary.BigEndian, &framebufferWidth)
   106  	if err != nil {
   107  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - FBWidth: ", err)
   108  		return nil, err
   109  	}
   110  	initMsg.FBWidth = framebufferWidth
   111  
   112  	binary.Read(fbs, binary.BigEndian, &framebufferHeight)
   113  	if err != nil {
   114  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - FBHeight: ", err)
   115  		return nil, err
   116  	}
   117  	initMsg.FBHeight = framebufferHeight
   118  
   119  	//read pixel format
   120  	pixelFormat := &PixelFormat{}
   121  	binary.Read(fbs, binary.BigEndian, pixelFormat)
   122  	if err != nil {
   123  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - Pixelformat: ", err)
   124  		return nil, err
   125  	}
   126  
   127  	initMsg.PixelFormat = *pixelFormat
   128  
   129  	//read desktop name
   130  	var desknameLen uint32
   131  	binary.Read(fbs, binary.BigEndian, &desknameLen)
   132  	if err != nil {
   133  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - deskname Len: ", err)
   134  		return nil, err
   135  	}
   136  	initMsg.NameLength = desknameLen
   137  
   138  	bytes = make([]byte, desknameLen)
   139  	fbs.Read(bytes)
   140  	if err != nil {
   141  		logger.Error("FbsReader.ReadStartSession: error reading rbs init - desktopName: ", err)
   142  		return nil, err
   143  	}
   144  
   145  	initMsg.NameText = bytes
   146  
   147  	return &initMsg, nil
   148  }
   149  
   150  func (fbs *FbsReader) ReadSegment() (*FbsSegment, error) {
   151  	reader := fbs.reader
   152  	var bytesLen uint32
   153  
   154  	//read length
   155  	err := binary.Read(reader, binary.BigEndian, &bytesLen)
   156  	if err != nil {
   157  		logger.Error("FbsReader.ReadSegment: reading len, error reading rbs file: ", err)
   158  		return nil, err
   159  	}
   160  
   161  	paddedSize := (bytesLen + 3) & 0x7FFFFFFC
   162  
   163  	//read bytes
   164  	bytes := make([]byte, paddedSize)
   165  	_, err = reader.Read(bytes)
   166  	if err != nil {
   167  		logger.Error("FbsReader.ReadSegment: reading bytes, error reading rbs file: ", err)
   168  		return nil, err
   169  	}
   170  
   171  	//remove padding
   172  	actualBytes := bytes[:bytesLen]
   173  
   174  	//read timestamp
   175  	var timeSinceStart uint32
   176  	binary.Read(reader, binary.BigEndian, &timeSinceStart)
   177  	if err != nil {
   178  		logger.Error("FbsReader.ReadSegment: read timestamp, error reading rbs file: ", err)
   179  		return nil, err
   180  	}
   181  
   182  	//timeStamp := time.Unix(timeSinceStart, 0)
   183  	seg := &FbsSegment{bytes: actualBytes, timestamp: timeSinceStart}
   184  	return seg, nil
   185  }
   186  
   187  type FbsSegment struct {
   188  	bytes     []byte
   189  	timestamp uint32
   190  }