mirror of
https://github.com/amitbet/vnc2video.git
synced 2025-08-30 19:32:26 +00:00
ppm optimizatio, added trace logging level
This commit is contained in:
parent
634fd73fb2
commit
88ff26e513
10
client.go
10
client.go
@ -256,7 +256,7 @@ type DefaultClientMessageHandler struct{}
|
|||||||
|
|
||||||
// Handle handles server messages.
|
// Handle handles server messages.
|
||||||
func (*DefaultClientMessageHandler) Handle(c Conn) error {
|
func (*DefaultClientMessageHandler) Handle(c Conn) error {
|
||||||
logger.Debug("starting DefaultClientMessageHandler")
|
logger.Trace("starting DefaultClientMessageHandler")
|
||||||
cfg := c.Config().(*ClientConfig)
|
cfg := c.Config().(*ClientConfig)
|
||||||
var err error
|
var err error
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@ -291,7 +291,7 @@ func (*DefaultClientMessageHandler) Handle(c Conn) error {
|
|||||||
cfg.ErrorCh <- err
|
cfg.ErrorCh <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Debugf("got server message, msgType=%d", messageType)
|
logger.Infof("========got server message, msgType=%d", messageType)
|
||||||
msg, ok := serverMessages[messageType]
|
msg, ok := serverMessages[messageType]
|
||||||
if !ok {
|
if !ok {
|
||||||
err = fmt.Errorf("unknown message-type: %v", messageType)
|
err = fmt.Errorf("unknown message-type: %v", messageType)
|
||||||
@ -302,7 +302,7 @@ func (*DefaultClientMessageHandler) Handle(c Conn) error {
|
|||||||
canvas.RemoveCursor()
|
canvas.RemoveCursor()
|
||||||
parsedMsg, err := msg.Read(c)
|
parsedMsg, err := msg.Read(c)
|
||||||
canvas.PaintCursor()
|
canvas.PaintCursor()
|
||||||
logger.Infof("============== End Message: type=%d ==============", messageType)
|
logger.Debugf("============== End Message: type=%d ==============", messageType)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cfg.ErrorCh <- err
|
cfg.ErrorCh <- err
|
||||||
@ -323,11 +323,11 @@ func (*DefaultClientMessageHandler) Handle(c Conn) error {
|
|||||||
for _, value := range encTypes {
|
for _, value := range encTypes {
|
||||||
v = append(v, value)
|
v = append(v, value)
|
||||||
}
|
}
|
||||||
logger.Debugf("setting encodings: %v", v)
|
logger.Tracef("setting encodings: %v", v)
|
||||||
c.SetEncodings(v)
|
c.SetEncodings(v)
|
||||||
|
|
||||||
firstMsg := FramebufferUpdateRequest{Inc: 0, X: 0, Y: 0, Width: c.Width(), Height: c.Height()}
|
firstMsg := FramebufferUpdateRequest{Inc: 0, X: 0, Y: 0, Width: c.Width(), Height: c.Height()}
|
||||||
logger.Debugf("sending initial req message: %v", firstMsg)
|
logger.Tracef("sending initial req message: %v", firstMsg)
|
||||||
firstMsg.Write(c)
|
firstMsg.Write(c)
|
||||||
|
|
||||||
//wg.Wait()
|
//wg.Wait()
|
||||||
|
@ -9,13 +9,13 @@ import (
|
|||||||
"vnc2video/logger"
|
"vnc2video/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DV8ImageEncoder struct {
|
type VP8ImageEncoder struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
binaryPath string
|
binaryPath string
|
||||||
input io.WriteCloser
|
input io.WriteCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
func (enc *DV8ImageEncoder) Init(videoFileName string) {
|
func (enc *VP8ImageEncoder) Init(videoFileName string) {
|
||||||
fileExt := ".webm"
|
fileExt := ".webm"
|
||||||
if !strings.HasSuffix(videoFileName, fileExt) {
|
if !strings.HasSuffix(videoFileName, fileExt) {
|
||||||
videoFileName = videoFileName + fileExt
|
videoFileName = videoFileName + fileExt
|
||||||
@ -25,30 +25,37 @@ func (enc *DV8ImageEncoder) Init(videoFileName string) {
|
|||||||
"-f", "image2pipe",
|
"-f", "image2pipe",
|
||||||
"-vcodec", "ppm",
|
"-vcodec", "ppm",
|
||||||
//"-r", strconv.Itoa(framerate),
|
//"-r", strconv.Itoa(framerate),
|
||||||
|
"-vsync", "2",
|
||||||
"-r", "5",
|
"-r", "5",
|
||||||
|
"-probesize", "10000000",
|
||||||
//"-i", "pipe:0",
|
//"-i", "pipe:0",
|
||||||
"-i", "-",
|
"-i", "-",
|
||||||
|
|
||||||
|
//"-crf", "4",
|
||||||
"-vcodec", "libvpx", //"libvpx",//"libvpx-vp9"//"libx264"
|
"-vcodec", "libvpx", //"libvpx",//"libvpx-vp9"//"libx264"
|
||||||
"-b:v", "1M",
|
"-b:v", "0.5M",
|
||||||
|
//"-maxrate", "1.5M",
|
||||||
|
|
||||||
"-threads", "8",
|
"-threads", "8",
|
||||||
//"-speed", "0",
|
//"-speed", "0",
|
||||||
//"-lossless", "1", //for vpx
|
//"-lossless", "1", //for vpx
|
||||||
// "-tile-columns", "6",
|
// "-tile-columns", "6",
|
||||||
//"-frame-parallel", "1",
|
//"-frame-parallel", "1",
|
||||||
// "-an", "-f", "webm",
|
// "-an", "-f", "webm",
|
||||||
|
|
||||||
|
//"-preset", "ultrafast",
|
||||||
|
//"-deadline", "realtime",
|
||||||
|
"-quality", "good",
|
||||||
"-cpu-used", "-16",
|
"-cpu-used", "-16",
|
||||||
|
"-minrate", "0.2M",
|
||||||
"-preset", "ultrafast",
|
"-maxrate", "0.7M",
|
||||||
"-deadline", "realtime",
|
"-bufsize", "50M",
|
||||||
//"-cpu-used", "-5",
|
"-g", "180",
|
||||||
"-maxrate", "2.5M",
|
"-keyint_min", "180",
|
||||||
"-bufsize", "10M",
|
"-rc_lookahead", "20",
|
||||||
"-g", "6",
|
|
||||||
|
|
||||||
//"-rc_lookahead", "16",
|
|
||||||
//"-profile", "0",
|
//"-profile", "0",
|
||||||
"-qmax", "51",
|
"-qmax", "51",
|
||||||
"-qmin", "11",
|
"-qmin", "3",
|
||||||
//"-slices", "4",
|
//"-slices", "4",
|
||||||
//"-vb", "2M",
|
//"-vb", "2M",
|
||||||
|
|
||||||
@ -67,25 +74,26 @@ func (enc *DV8ImageEncoder) Init(videoFileName string) {
|
|||||||
}
|
}
|
||||||
enc.cmd = cmd
|
enc.cmd = cmd
|
||||||
}
|
}
|
||||||
func (enc *DV8ImageEncoder) Run(encoderFilePath string, videoFileName string) {
|
func (enc *VP8ImageEncoder) Run(encoderFilePath string, videoFileName string) {
|
||||||
if _, err := os.Stat(encoderFilePath); os.IsNotExist(err) {
|
if _, err := os.Stat(encoderFilePath); os.IsNotExist(err) {
|
||||||
logger.Error("encoder file doesn't exist in path:", encoderFilePath)
|
logger.Error("encoder file doesn't exist in path:", encoderFilePath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
enc.binaryPath = encoderFilePath
|
enc.binaryPath = encoderFilePath
|
||||||
enc.Init(videoFileName)
|
enc.Init(videoFileName)
|
||||||
logger.Infof("launching binary: %v", enc.cmd)
|
logger.Debugf("launching binary: %v", enc.cmd)
|
||||||
err := enc.cmd.Run()
|
err := enc.cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
|
logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (enc *DV8ImageEncoder) Encode(img image.Image) {
|
func (enc *VP8ImageEncoder) Encode(img image.Image) {
|
||||||
err := encodePPM(enc.input, img)
|
err := encodePPM(enc.input, img)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error while encoding image:", err)
|
logger.Error("error while encoding image:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (enc *DV8ImageEncoder) Close() {
|
|
||||||
|
func (enc *VP8ImageEncoder) Close() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ type DV9ImageEncoder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *DV9ImageEncoder) Init(videoFileName string) {
|
func (enc *DV9ImageEncoder) Init(videoFileName string) {
|
||||||
fileExt := ".webm"
|
fileExt := ".mp4"
|
||||||
if !strings.HasSuffix(videoFileName, fileExt) {
|
if !strings.HasSuffix(videoFileName, fileExt) {
|
||||||
videoFileName = videoFileName + fileExt
|
videoFileName = videoFileName + fileExt
|
||||||
}
|
}
|
||||||
@ -38,12 +38,12 @@ func (enc *DV9ImageEncoder) Init(videoFileName string) {
|
|||||||
// "-an", "-f", "webm",
|
// "-an", "-f", "webm",
|
||||||
"-cpu-used", "-8",
|
"-cpu-used", "-8",
|
||||||
|
|
||||||
"-preset", "ultrafast",
|
//"-preset", "ultrafast",
|
||||||
"-deadline", "realtime",
|
"-deadline", "realtime",
|
||||||
//"-cpu-used", "-5",
|
//"-cpu-used", "-5",
|
||||||
"-maxrate", "2.5M",
|
"-maxrate", "2.5M",
|
||||||
"-bufsize", "10M",
|
"-bufsize", "10M",
|
||||||
"-g", "6",
|
"-g", "120",
|
||||||
|
|
||||||
//"-rc_lookahead", "16",
|
//"-rc_lookahead", "16",
|
||||||
//"-profile", "0",
|
//"-profile", "0",
|
||||||
@ -74,7 +74,7 @@ func (enc *DV9ImageEncoder) Run(encoderFilePath string, videoFileName string) {
|
|||||||
}
|
}
|
||||||
enc.binaryPath = encoderFilePath
|
enc.binaryPath = encoderFilePath
|
||||||
enc.Init(videoFileName)
|
enc.Init(videoFileName)
|
||||||
logger.Infof("launching binary: %v", enc.cmd)
|
logger.Debugf("launching binary: %v", enc.cmd)
|
||||||
err := enc.cmd.Run()
|
err := enc.cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
|
logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
|
||||||
|
@ -5,9 +5,10 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"io"
|
"io"
|
||||||
|
"vnc2video"
|
||||||
)
|
)
|
||||||
|
|
||||||
func encodePPM(w io.Writer, img image.Image) error {
|
func encodePPMGeneric(w io.Writer, img image.Image) error {
|
||||||
maxvalue := 255
|
maxvalue := 255
|
||||||
size := img.Bounds()
|
size := img.Bounds()
|
||||||
// write ppm header
|
// write ppm header
|
||||||
@ -35,6 +36,110 @@ func encodePPM(w io.Writer, img image.Image) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var convImage []uint8
|
||||||
|
|
||||||
|
func encodePPMforRGBA(w io.Writer, img *image.RGBA) error {
|
||||||
|
maxvalue := 255
|
||||||
|
size := img.Bounds()
|
||||||
|
// write ppm header
|
||||||
|
_, err := fmt.Fprintf(w, "P6\n%d %d\n%d\n", size.Dx(), size.Dy(), maxvalue)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the bitmap
|
||||||
|
//colModel := color.RGBAModel
|
||||||
|
if convImage == nil {
|
||||||
|
convImage = make([]uint8, size.Dy()*size.Dx()*3)
|
||||||
|
}
|
||||||
|
|
||||||
|
//img1 := (img.(*vnc2video.VncCanvas).Image).(*image.RGBA)
|
||||||
|
rowCount := 0
|
||||||
|
for i := 0; i < len(img.Pix); i++ {
|
||||||
|
if (i % 4) != 3 {
|
||||||
|
//logger.Debug("pix: ", i)
|
||||||
|
convImage[rowCount] = img.Pix[i]
|
||||||
|
rowCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for y := size.Min.Y; y < size.Max.Y; y++ {
|
||||||
|
// i := 0
|
||||||
|
// for x := size.Min.X; x < size.Max.X; x++ {
|
||||||
|
|
||||||
|
// color := (img.At(x, y)).(color.RGBA)
|
||||||
|
// row[i] = color.R
|
||||||
|
// row[i+1] = color.G
|
||||||
|
// row[i+2] = color.B
|
||||||
|
// i += 3
|
||||||
|
// }
|
||||||
|
|
||||||
|
if _, err := w.Write(convImage); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// if _, err := w.Write(img.Pix); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func encodePPM(w io.Writer, img image.Image) error {
|
||||||
|
img1, isRGBImage := img.(*vnc2video.RGBImage)
|
||||||
|
img2, isRGBA := img.(*image.RGBA)
|
||||||
|
if isRGBImage {
|
||||||
|
return encodePPMforRGBImage(w, img1)
|
||||||
|
} else if isRGBA {
|
||||||
|
return encodePPMforRGBA(w, img2)
|
||||||
|
}
|
||||||
|
return encodePPMGeneric(w, img)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodePPMforRGBImage(w io.Writer, img *vnc2video.RGBImage) error {
|
||||||
|
maxvalue := 255
|
||||||
|
size := img.Bounds()
|
||||||
|
// write ppm header
|
||||||
|
_, err := fmt.Fprintf(w, "P6\n%d %d\n%d\n", size.Dx(), size.Dy(), maxvalue)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the bitmap
|
||||||
|
//colModel := color.RGBAModel
|
||||||
|
// // if convImage == nil {
|
||||||
|
// // convImage = make([]uint8, size.Dy()*size.Dx()*3)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // img1 := (img.(*vnc2video.VncCanvas).Image).(*image.RGBA)
|
||||||
|
// // rowCount := 0
|
||||||
|
// // for i := 0; i < len(img1.Pix); i++ {
|
||||||
|
// // if (i % 4) != 3 {
|
||||||
|
// // //logger.Debug("pix: ", i)
|
||||||
|
// // convImage[rowCount] = img1.Pix[i]
|
||||||
|
// // rowCount++
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// for y := size.Min.Y; y < size.Max.Y; y++ {
|
||||||
|
// i := 0
|
||||||
|
// for x := size.Min.X; x < size.Max.X; x++ {
|
||||||
|
|
||||||
|
// color := (img.At(x, y)).(color.RGBA)
|
||||||
|
// row[i] = color.R
|
||||||
|
// row[i+1] = color.G
|
||||||
|
// row[i+2] = color.B
|
||||||
|
// i += 3
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // if _, err := w.Write(convImage); err != nil {
|
||||||
|
// // return err
|
||||||
|
// // }
|
||||||
|
if _, err := w.Write(img.Pix); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type ImageEncoder interface {
|
type ImageEncoder interface {
|
||||||
Init(string)
|
Init(string)
|
||||||
Run()
|
Run()
|
||||||
|
@ -45,7 +45,7 @@ func (enc *MJPegImageEncoder) Encode(img image.Image) {
|
|||||||
logger.Error("Error while creating jpeg: ", err)
|
logger.Error("Error while creating jpeg: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//logger.Debugf("buff: %v\n", buf.Bytes())
|
//logger.Tracef("buff: %v\n", buf.Bytes())
|
||||||
|
|
||||||
err = enc.avWriter.AddFrame(buf.Bytes())
|
err = enc.avWriter.AddFrame(buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -29,28 +29,30 @@ func (enc *X264ImageEncoder) Init(videoFileName string) {
|
|||||||
"-r", "5",
|
"-r", "5",
|
||||||
//"-re",
|
//"-re",
|
||||||
//"-i", "pipe:0",
|
//"-i", "pipe:0",
|
||||||
|
|
||||||
|
"-vsync", "2",
|
||||||
|
///"-probesize", "10000000",
|
||||||
|
"-y",
|
||||||
"-i", "-",
|
"-i", "-",
|
||||||
"-vcodec", "libx264", //"libvpx",//"libvpx-vp9"//"libx264"
|
"-vcodec", "libx264", //"libvpx",//"libvpx-vp9"//"libx264"
|
||||||
"-b:v", "1M",
|
"-b:v", "0.5M",
|
||||||
"-threads", "8",
|
"-threads", "8",
|
||||||
//"-speed", "0",
|
//"-speed", "0",
|
||||||
//"-lossless", "1", //for vpx
|
//"-lossless", "1", //for vpx
|
||||||
// "-tile-columns", "6",
|
|
||||||
//"-frame-parallel", "1",
|
|
||||||
// "-an", "-f", "webm",
|
// "-an", "-f", "webm",
|
||||||
//"-cpu-used", "-16",
|
"-preset", "veryfast",
|
||||||
"-cpu-used", "-5",
|
"-tune", "animation",
|
||||||
"-preset", "ultrafast",
|
"-maxrate", "0.6M",
|
||||||
"-deadline", "realtime",
|
"-bufsize", "50M",
|
||||||
|
"-g", "120",
|
||||||
|
|
||||||
"-maxrate", "2.5M",
|
//"-crf", "0", //for lossless encoding!!!!
|
||||||
"-bufsize", "10M",
|
|
||||||
"-g", "6",
|
|
||||||
|
|
||||||
//"-rc_lookahead", "16",
|
//"-rc_lookahead", "16",
|
||||||
//"-profile", "0",
|
//"-profile", "0",
|
||||||
|
//"-crf", "18",
|
||||||
"-qmax", "51",
|
"-qmax", "51",
|
||||||
"-qmin", "11",
|
"-qmin", "7",
|
||||||
//"-slices", "4",
|
//"-slices", "4",
|
||||||
//"-vb", "2M",
|
//"-vb", "2M",
|
||||||
|
|
||||||
@ -77,7 +79,7 @@ func (enc *X264ImageEncoder) Run(encoderFilePath string, videoFileName string) e
|
|||||||
|
|
||||||
enc.binaryPath = encoderFilePath
|
enc.binaryPath = encoderFilePath
|
||||||
enc.Init(videoFileName)
|
enc.Init(videoFileName)
|
||||||
logger.Infof("launching binary: %v", enc.cmd)
|
logger.Debugf("launching binary: %v", enc.cmd)
|
||||||
err := enc.cmd.Run()
|
err := enc.cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
|
logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
|
||||||
|
@ -21,12 +21,12 @@ func (*CopyRectEncoding) Reset() error {
|
|||||||
func (*CopyRectEncoding) Type() EncodingType { return EncCopyRect }
|
func (*CopyRectEncoding) Type() EncodingType { return EncCopyRect }
|
||||||
|
|
||||||
func (enc *CopyRectEncoding) SetTargetImage(img draw.Image) {
|
func (enc *CopyRectEncoding) SetTargetImage(img draw.Image) {
|
||||||
//logger.Debugf("!!!!!!!!!!!!!setting image: %v", img.Bounds())
|
//logger.Tracef("!!!!!!!!!!!!!setting image: %v", img.Bounds())
|
||||||
enc.Image = img
|
enc.Image = img
|
||||||
}
|
}
|
||||||
|
|
||||||
func (enc *CopyRectEncoding) Read(c Conn, rect *Rectangle) error {
|
func (enc *CopyRectEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
logger.Debugf("Reading: CopyRect %v", rect)
|
logger.Tracef("Reading: CopyRect %v", rect)
|
||||||
if err := binary.Read(c, binary.BigEndian, &enc.SX); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &enc.SX); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ func (enc *CursorPseudoEncoding) Reset() error {
|
|||||||
func (*CursorPseudoEncoding) Type() EncodingType { return EncCursorPseudo }
|
func (*CursorPseudoEncoding) Type() EncodingType { return EncCursorPseudo }
|
||||||
|
|
||||||
func (enc *CursorPseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
func (enc *CursorPseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
logger.Debugf("CursorPseudoEncoding.Read: got rect: %v", rect)
|
logger.Tracef("CursorPseudoEncoding.Read: got rect: %v", rect)
|
||||||
//rgba := make([]byte, int(rect.Height)*int(rect.Width)*int(c.PixelFormat().BPP/8))
|
//rgba := make([]byte, int(rect.Height)*int(rect.Width)*int(c.PixelFormat().BPP/8))
|
||||||
numColors := int(rect.Height) * int(rect.Width)
|
numColors := int(rect.Height) * int(rect.Width)
|
||||||
colors := make([]color.Color, numColors)
|
colors := make([]color.Color, numColors)
|
||||||
@ -53,7 +53,11 @@ func (enc *CursorPseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
canvas := enc.Image.(*VncCanvas)
|
canvas := enc.Image.(*VncCanvas)
|
||||||
//canvas.Cursor =
|
//canvas.Cursor =
|
||||||
cursorImg := image.NewRGBA(MakeRect(0, 0, int(rect.Width), int(rect.Height)))
|
cursorImg := image.NewRGBA(MakeRect(0, 0, int(rect.Width), int(rect.Height)))
|
||||||
cursorMask := image.NewRGBA(cursorImg.Bounds())
|
//cursorMask := image.NewRGBA(cursorImg.Bounds())
|
||||||
|
cursorMask := [][]bool{}
|
||||||
|
for i := 0; i < int(rect.Width); i++ {
|
||||||
|
cursorMask = append(cursorMask, make([]bool, rect.Height))
|
||||||
|
}
|
||||||
|
|
||||||
//int[] cursorPixels = new int[rect.width * rect.height];
|
//int[] cursorPixels = new int[rect.width * rect.height];
|
||||||
for y := 0; y < int(rect.Height); y++ {
|
for y := 0; y < int(rect.Height); y++ {
|
||||||
@ -61,8 +65,9 @@ func (enc *CursorPseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
offset := y*int(rect.Width) + x
|
offset := y*int(rect.Width) + x
|
||||||
if bitmask[y*int(scanLine)+x/8]&(1<<uint(7-x%8)) > 0 {
|
if bitmask[y*int(scanLine)+x/8]&(1<<uint(7-x%8)) > 0 {
|
||||||
cursorImg.Set(x, y, colors[offset])
|
cursorImg.Set(x, y, colors[offset])
|
||||||
cursorMask.Set(x, y, color.RGBA{1, 1, 1, 1})
|
//cursorMask.Set(x, y, color.RGBA{1, 1, 1, 1})
|
||||||
//logger.Debugf("CursorPseudoEncoding.Read: setting pixel: (%d,%d) %v", x+int(rect.X), y+int(rect.Y), colors[offset])
|
cursorMask[x][y] = true
|
||||||
|
//logger.Tracef("CursorPseudoEncoding.Read: setting pixel: (%d,%d) %v", x+int(rect.X), y+int(rect.Y), colors[offset])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ func (z *HextileEncoding) Read(r Conn, rect *Rectangle) error {
|
|||||||
// defer func() {
|
// defer func() {
|
||||||
// z.bytes = r.EndByteCollection()
|
// z.bytes = r.EndByteCollection()
|
||||||
// }()
|
// }()
|
||||||
logger.Debugf("HextileEncoding.Read: got hextile rect: %v", rect)
|
logger.Tracef("HextileEncoding.Read: got hextile rect: %v", rect)
|
||||||
for ty := rect.Y; ty < rect.Y+rect.Height; ty += 16 {
|
for ty := rect.Y; ty < rect.Y+rect.Height; ty += 16 {
|
||||||
th := 16
|
th := 16
|
||||||
if rect.Y+rect.Height-ty < 16 {
|
if rect.Y+rect.Height-ty < 16 {
|
||||||
@ -98,10 +98,10 @@ func (z *HextileEncoding) Read(r Conn, rect *Rectangle) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//logger.Debugf("%v %v", rBounds, bgCol)
|
//logger.Tracef("%v %v", rBounds, bgCol)
|
||||||
}
|
}
|
||||||
rBounds := image.Rectangle{Min: image.Point{int(tx), int(ty)}, Max: image.Point{int(tx) + int(tw), int(ty) + int(th)}}
|
rBounds := image.Rectangle{Min: image.Point{int(tx), int(ty)}, Max: image.Point{int(tx) + int(tw), int(ty) + int(th)}}
|
||||||
//logger.Debugf("filling background rect: %v, col: %v", rBounds, bgCol)
|
//logger.Tracef("filling background rect: %v, col: %v", rBounds, bgCol)
|
||||||
FillRect(z.Image, &rBounds, bgCol)
|
FillRect(z.Image, &rBounds, bgCol)
|
||||||
|
|
||||||
if (subencoding & HextileForegroundSpecified) != 0 {
|
if (subencoding & HextileForegroundSpecified) != 0 {
|
||||||
@ -112,7 +112,7 @@ func (z *HextileEncoding) Read(r Conn, rect *Rectangle) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subencoding & HextileAnySubrects) == 0 {
|
if (subencoding & HextileAnySubrects) == 0 {
|
||||||
//logger.Debug("hextile reader: no Subrects")
|
//logger.Trace("hextile reader: no Subrects")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ func (z *HextileEncoding) Read(r Conn, rect *Rectangle) error {
|
|||||||
subtileHeight := 1 + (dimensions & 0x0f)
|
subtileHeight := 1 + (dimensions & 0x0f)
|
||||||
subrectBounds := image.Rectangle{Min: image.Point{int(tx) + int(subtileX), int(ty) + int(subtileY)}, Max: image.Point{int(tx) + int(subtileX) + int(subtileWidth), int(ty) + int(subtileY) + int(subtileHeight)}}
|
subrectBounds := image.Rectangle{Min: image.Point{int(tx) + int(subtileX), int(ty) + int(subtileY)}, Max: image.Point{int(tx) + int(subtileX) + int(subtileWidth), int(ty) + int(subtileY) + int(subtileHeight)}}
|
||||||
FillRect(z.Image, &subrectBounds, color)
|
FillRect(z.Image, &subrectBounds, color)
|
||||||
//logger.Debugf("%v", subrectBounds)
|
//logger.Tracef("%v", subrectBounds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func (enc *CursorPosPseudoEncoding) Reset() error {
|
|||||||
func (*CursorPosPseudoEncoding) Type() EncodingType { return EncPointerPosPseudo }
|
func (*CursorPosPseudoEncoding) Type() EncodingType { return EncPointerPosPseudo }
|
||||||
|
|
||||||
func (enc *CursorPosPseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
func (enc *CursorPosPseudoEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
logger.Debugf("CursorPosPseudoEncoding: got cursot pos update: %v", rect)
|
logger.Tracef("CursorPosPseudoEncoding: got cursot pos update: %v", rect)
|
||||||
canvas := enc.Image.(*VncCanvas)
|
canvas := enc.Image.(*VncCanvas)
|
||||||
canvas.CursorLocation = &image.Point{X: int(rect.X), Y: int(rect.Y)}
|
canvas.CursorLocation = &image.Point{X: int(rect.X), Y: int(rect.Y)}
|
||||||
return nil
|
return nil
|
||||||
|
@ -135,10 +135,10 @@ func (enc *TightEncoding) Reset() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *TightEncoding) resetDecoders(compControl uint8) {
|
func (enc *TightEncoding) resetDecoders(compControl uint8) {
|
||||||
logger.Debugf("###resetDecoders compctl :%d", 0x0F&compControl)
|
logger.Tracef("###resetDecoders compctl :%d", 0x0F&compControl)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
if (compControl&1) != 0 && enc.decoders[i] != nil {
|
if (compControl&1) != 0 && enc.decoders[i] != nil {
|
||||||
logger.Debugf("###resetDecoders - resetting decoder #%d", i)
|
logger.Tracef("###resetDecoders - resetting decoder #%d", i)
|
||||||
enc.decoders[i] = nil //.(zlib.Resetter).Reset(nil,nil);
|
enc.decoders[i] = nil //.(zlib.Resetter).Reset(nil,nil);
|
||||||
}
|
}
|
||||||
compControl >>= 1
|
compControl >>= 1
|
||||||
@ -146,7 +146,7 @@ func (enc *TightEncoding) resetDecoders(compControl uint8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *TightEncoding) SetTargetImage(img draw.Image) {
|
func (enc *TightEncoding) SetTargetImage(img draw.Image) {
|
||||||
enc.Image = img
|
enc.Image = img.(*VncCanvas).Image
|
||||||
}
|
}
|
||||||
|
|
||||||
var counter int = 0
|
var counter int = 0
|
||||||
@ -179,22 +179,22 @@ func (enc *TightEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
// defer func() { counter++ }()
|
// defer func() { counter++ }()
|
||||||
// defer jpeg.Encode(out, enc.Image, nil)
|
// defer jpeg.Encode(out, enc.Image, nil)
|
||||||
//////////////
|
//////////////
|
||||||
logger.Debugf("-----------READ-Tight-encoding compctl=%d -------------", compctl)
|
logger.Tracef("-----------READ-Tight-encoding compctl=%d -------------", compctl)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error in handling tight encoding: %v", err)
|
logger.Errorf("error in handling tight encoding: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//logger.Debugf("bytesPixel= %d, subencoding= %d", bytesPixel, compctl)
|
//logger.Tracef("bytesPixel= %d, subencoding= %d", bytesPixel, compctl)
|
||||||
enc.resetDecoders(compctl)
|
enc.resetDecoders(compctl)
|
||||||
|
|
||||||
//move it to position (remove zlib flush commands)
|
//move it to position (remove zlib flush commands)
|
||||||
compType := compctl >> 4 & 0x0F
|
compType := compctl >> 4 & 0x0F
|
||||||
|
|
||||||
//logger.Debugf("afterSHL:%d", compType)
|
//logger.Tracef("afterSHL:%d", compType)
|
||||||
switch compType {
|
switch compType {
|
||||||
case TightCompressionFill:
|
case TightCompressionFill:
|
||||||
logger.Debugf("--TIGHT_FILL: reading fill size=%d,counter=%d", bytesPixel, counter)
|
logger.Tracef("--TIGHT_FILL: reading fill size=%d,counter=%d", bytesPixel, counter)
|
||||||
//read color
|
//read color
|
||||||
|
|
||||||
rectColor, err := getTightColor(c, &pixelFmt)
|
rectColor, err := getTightColor(c, &pixelFmt)
|
||||||
@ -206,7 +206,7 @@ func (enc *TightEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
//c1 := color.RGBAModel.Convert(rectColor).(color.RGBA)
|
//c1 := color.RGBAModel.Convert(rectColor).(color.RGBA)
|
||||||
dst := (enc.Image).(draw.Image) // enc.Image.(*image.RGBA)
|
dst := (enc.Image).(draw.Image) // enc.Image.(*image.RGBA)
|
||||||
myRect := MakeRectFromVncRect(rect)
|
myRect := MakeRectFromVncRect(rect)
|
||||||
logger.Debugf("--TIGHT_FILL: fill rect=%v,color=%v", myRect, rectColor)
|
logger.Tracef("--TIGHT_FILL: fill rect=%v,color=%v", myRect, rectColor)
|
||||||
FillRect(dst, &myRect, rectColor)
|
FillRect(dst, &myRect, rectColor)
|
||||||
|
|
||||||
if bytesPixel != 3 {
|
if bytesPixel != 3 {
|
||||||
@ -214,7 +214,7 @@ func (enc *TightEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case TightCompressionJPEG:
|
case TightCompressionJPEG:
|
||||||
logger.Debugf("--TIGHT_JPEG,counter=%d", counter)
|
logger.Tracef("--TIGHT_JPEG,counter=%d", counter)
|
||||||
if pixelFmt.BPP == 8 {
|
if pixelFmt.BPP == 8 {
|
||||||
return errors.New("Tight encoding: JPEG is not supported in 8 bpp mode")
|
return errors.New("Tight encoding: JPEG is not supported in 8 bpp mode")
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ func (enc *TightEncoding) Read(c Conn, rect *Rectangle) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//logger.Debugf("reading jpeg, size=%d\n", len)
|
//logger.Tracef("reading jpeg, size=%d\n", len)
|
||||||
jpegBytes, err := ReadBytes(len, c)
|
jpegBytes, err := ReadBytes(len, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -271,12 +271,12 @@ func (enc *TightEncoding) handleTightFilters(compCtl uint8, pixelFmt *PixelForma
|
|||||||
logger.Errorf("error in handling tight encoding, reading filterid: %v", err)
|
logger.Errorf("error in handling tight encoding, reading filterid: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//logger.Debugf("handleTightFilters: read filter: %d", filterid)
|
//logger.Tracef("handleTightFilters: read filter: %d", filterid)
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesPixel := calcTightBytePerPixel(pixelFmt)
|
bytesPixel := calcTightBytePerPixel(pixelFmt)
|
||||||
|
|
||||||
//logger.Debugf("handleTightFilters: filter: %d", filterid)
|
//logger.Tracef("handleTightFilters: filter: %d", filterid)
|
||||||
|
|
||||||
lengthCurrentbpp := int(bytesPixel) * int(rect.Width) * int(rect.Height)
|
lengthCurrentbpp := int(bytesPixel) * int(rect.Width) * int(rect.Height)
|
||||||
|
|
||||||
@ -288,9 +288,9 @@ func (enc *TightEncoding) handleTightFilters(compCtl uint8, pixelFmt *PixelForma
|
|||||||
logger.Errorf("handleTightFilters: error in Reading Palette: %v", err)
|
logger.Errorf("handleTightFilters: error in Reading Palette: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Infof("----PALETTE_FILTER,palette len=%d counter=%d, rect= %v", len(palette), counter, rect)
|
logger.Debugf("----PALETTE_FILTER,palette len=%d counter=%d, rect= %v", len(palette), counter, rect)
|
||||||
|
|
||||||
//logger.Debugf("got palette: %v", palette)
|
//logger.Tracef("got palette: %v", palette)
|
||||||
var dataLength int
|
var dataLength int
|
||||||
if len(palette) == 2 {
|
if len(palette) == 2 {
|
||||||
dataLength = int(rect.Height) * ((int(rect.Width) + 7) / 8)
|
dataLength = int(rect.Height) * ((int(rect.Width) + 7) / 8)
|
||||||
@ -298,7 +298,7 @@ func (enc *TightEncoding) handleTightFilters(compCtl uint8, pixelFmt *PixelForma
|
|||||||
dataLength = int(rect.Width * rect.Height)
|
dataLength = int(rect.Width * rect.Height)
|
||||||
}
|
}
|
||||||
tightBytes, err := enc.ReadTightData(dataLength, r, int(decoderId))
|
tightBytes, err := enc.ReadTightData(dataLength, r, int(decoderId))
|
||||||
//logger.Debugf("got tightBytes: %v", tightBytes)
|
//logger.Tracef("got tightBytes: %v", tightBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("handleTightFilters: error in handling tight encoding, reading palette filter data: %v", err)
|
logger.Errorf("handleTightFilters: error in handling tight encoding, reading palette filter data: %v", err)
|
||||||
return
|
return
|
||||||
@ -308,8 +308,8 @@ func (enc *TightEncoding) handleTightFilters(compCtl uint8, pixelFmt *PixelForma
|
|||||||
enc.drawTightPalette(rect, palette, tightBytes)
|
enc.drawTightPalette(rect, palette, tightBytes)
|
||||||
//enc.Image = myImg
|
//enc.Image = myImg
|
||||||
case TightFilterGradient: //GRADIENT_FILTER
|
case TightFilterGradient: //GRADIENT_FILTER
|
||||||
logger.Infof("----GRADIENT_FILTER: bytesPixel=%d, counter=%d", bytesPixel, counter)
|
logger.Debugf("----GRADIENT_FILTER: bytesPixel=%d, counter=%d", bytesPixel, counter)
|
||||||
//logger.Debugf("usegrad: %d\n", filterid)
|
//logger.Tracef("usegrad: %d\n", filterid)
|
||||||
data, err := enc.ReadTightData(lengthCurrentbpp, r, int(decoderId))
|
data, err := enc.ReadTightData(lengthCurrentbpp, r, int(decoderId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("handleTightFilters: error in handling tight encoding, Reading GRADIENT_FILTER: %v", err)
|
logger.Errorf("handleTightFilters: error in handling tight encoding, Reading GRADIENT_FILTER: %v", err)
|
||||||
@ -319,14 +319,14 @@ func (enc *TightEncoding) handleTightFilters(compCtl uint8, pixelFmt *PixelForma
|
|||||||
|
|
||||||
case TightFilterCopy: //BASIC_FILTER
|
case TightFilterCopy: //BASIC_FILTER
|
||||||
//lengthCurrentbpp1 := int(pixelFmt.BPP/8) * int(rect.Width) * int(rect.Height)
|
//lengthCurrentbpp1 := int(pixelFmt.BPP/8) * int(rect.Width) * int(rect.Height)
|
||||||
logger.Infof("----BASIC_FILTER: bytesPixel=%d, counter=%d", bytesPixel, counter)
|
logger.Debugf("----BASIC_FILTER: bytesPixel=%d, counter=%d", bytesPixel, counter)
|
||||||
|
|
||||||
tightBytes, err := enc.ReadTightData(lengthCurrentbpp, r, int(decoderId))
|
tightBytes, err := enc.ReadTightData(lengthCurrentbpp, r, int(decoderId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("handleTightFilters: error in handling tight encoding, Reading BASIC_FILTER: %v", err)
|
logger.Errorf("handleTightFilters: error in handling tight encoding, Reading BASIC_FILTER: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Debugf("tightBytes len= %d", len(tightBytes))
|
logger.Tracef("tightBytes len= %d", len(tightBytes))
|
||||||
enc.drawTightBytes(tightBytes, rect)
|
enc.drawTightBytes(tightBytes, rect)
|
||||||
default:
|
default:
|
||||||
logger.Errorf("handleTightFilters: Bad tight filter id: %d", filterid)
|
logger.Errorf("handleTightFilters: Bad tight filter id: %d", filterid)
|
||||||
@ -340,7 +340,7 @@ func (enc *TightEncoding) drawTightPalette(rect *Rectangle, palette color.Palett
|
|||||||
bytePos := 0
|
bytePos := 0
|
||||||
bitPos := uint8(7)
|
bitPos := uint8(7)
|
||||||
var palettePos int
|
var palettePos int
|
||||||
logger.Debugf("drawTightPalette numbytes=%d", len(tightBytes))
|
logger.Tracef("drawTightPalette numbytes=%d", len(tightBytes))
|
||||||
|
|
||||||
for y := 0; y < int(rect.Height); y++ {
|
for y := 0; y < int(rect.Height); y++ {
|
||||||
for x := 0; x < int(rect.Width); x++ {
|
for x := 0; x < int(rect.Width); x++ {
|
||||||
@ -353,7 +353,7 @@ func (enc *TightEncoding) drawTightPalette(rect *Rectangle, palette color.Palett
|
|||||||
palettePos = 1
|
palettePos = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
//logger.Debugf("currByte=%d, bitpos=%d, bytepos=%d, palettepos=%d, mask=%d, totalBytes=%d", currByte, bitPos, bytePos, palettePos, mask, len(tightBytes))
|
//logger.Tracef("currByte=%d, bitpos=%d, bytepos=%d, palettepos=%d, mask=%d, totalBytes=%d", currByte, bitPos, bytePos, palettePos, mask, len(tightBytes))
|
||||||
|
|
||||||
if bitPos == 0 {
|
if bitPos == 0 {
|
||||||
bytePos++
|
bytePos++
|
||||||
@ -365,15 +365,18 @@ func (enc *TightEncoding) drawTightPalette(rect *Rectangle, palette color.Palett
|
|||||||
}
|
}
|
||||||
//palettePos = palettePos
|
//palettePos = palettePos
|
||||||
enc.Image.Set(int(rect.X)+x, int(rect.Y)+y, palette[palettePos])
|
enc.Image.Set(int(rect.X)+x, int(rect.Y)+y, palette[palettePos])
|
||||||
//logger.Debugf("(%d,%d): pos: %d col:%d", int(rect.X)+j, int(rect.Y)+i, palettePos, palette[palettePos])
|
//logger.Tracef("(%d,%d): pos: %d col:%d", int(rect.X)+j, int(rect.Y)+i, palettePos, palette[palettePos])
|
||||||
}
|
}
|
||||||
bitPos = 0
|
// if bitPos != 7 {
|
||||||
|
// bytePos++
|
||||||
|
// }
|
||||||
|
bitPos = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
func (enc *TightEncoding) decodeGradData(rect *Rectangle, buffer []byte) {
|
func (enc *TightEncoding) decodeGradData(rect *Rectangle, buffer []byte) {
|
||||||
|
|
||||||
logger.Debugf("putting gradient size: %v on image: %v", rect, enc.Image.Bounds())
|
logger.Tracef("putting gradient size: %v on image: %v", rect, enc.Image.Bounds())
|
||||||
|
|
||||||
prevRow := make([]byte, rect.Width*3+3) //new byte[w * 3];
|
prevRow := make([]byte, rect.Width*3+3) //new byte[w * 3];
|
||||||
thisRow := make([]byte, rect.Width*3+3) //new byte[w * 3];
|
thisRow := make([]byte, rect.Width*3+3) //new byte[w * 3];
|
||||||
@ -424,7 +427,7 @@ func (enc *TightEncoding) decodeGradData(rect *Rectangle, buffer []byte) {
|
|||||||
for idx := 3; idx < (len(thisRow) - 3); idx += 3 {
|
for idx := 3; idx < (len(thisRow) - 3); idx += 3 {
|
||||||
myColor := color.RGBA{R: (thisRow[idx]), G: (thisRow[idx+1]), B: (thisRow[idx+2]), A: 1}
|
myColor := color.RGBA{R: (thisRow[idx]), G: (thisRow[idx+1]), B: (thisRow[idx+2]), A: 1}
|
||||||
enc.Image.Set(idx/3+int(rect.X)-1, int(rect.Y)+i, myColor)
|
enc.Image.Set(idx/3+int(rect.X)-1, int(rect.Y)+i, myColor)
|
||||||
//logger.Debugf("putting pixel: idx=%d, pos=(%d,%d), col=%v", idx, idx/3+int(rect.X), int(rect.Y)+i, myColor)
|
//logger.Tracef("putting pixel: idx=%d, pos=(%d,%d), col=%v", idx, idx/3+int(rect.X), int(rect.Y)+i, myColor)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +439,7 @@ func (enc *TightEncoding) decodeGradData(rect *Rectangle, buffer []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *TightEncoding) decodeGradientData(rect *Rectangle, buf []byte) {
|
func (enc *TightEncoding) decodeGradientData(rect *Rectangle, buf []byte) {
|
||||||
logger.Debugf("putting gradient on image: %v", enc.Image.Bounds())
|
logger.Tracef("putting gradient on image: %v", enc.Image.Bounds())
|
||||||
var dx, dy, c int
|
var dx, dy, c int
|
||||||
prevRow := make([]byte, rect.Width*3) //new byte[w * 3];
|
prevRow := make([]byte, rect.Width*3) //new byte[w * 3];
|
||||||
thisRow := make([]byte, rect.Width*3) //new byte[w * 3];
|
thisRow := make([]byte, rect.Width*3) //new byte[w * 3];
|
||||||
@ -453,7 +456,7 @@ func (enc *TightEncoding) decodeGradientData(rect *Rectangle, buf []byte) {
|
|||||||
pix[c] = byte(prevRow[c] + buf[dy*int(rect.Width)*3+c])
|
pix[c] = byte(prevRow[c] + buf[dy*int(rect.Width)*3+c])
|
||||||
thisRow[c] = pix[c]
|
thisRow[c] = pix[c]
|
||||||
}
|
}
|
||||||
//logger.Debugf("putting pixel:%d,%d,%d at offset: %d, pixArrayLen= %v, rect=x:%d,y:%d,w:%d,h:%d, Yposition=%d", pix[0], pix[1], pix[2], offset, len(dst.Pix), rect.X, rect.Y, rect.Width, rect.Height, dy)
|
//logger.Tracef("putting pixel:%d,%d,%d at offset: %d, pixArrayLen= %v, rect=x:%d,y:%d,w:%d,h:%d, Yposition=%d", pix[0], pix[1], pix[2], offset, len(dst.Pix), rect.X, rect.Y, rect.Width, rect.Height, dy)
|
||||||
myColor := color.RGBA{R: (pix[0]), G: (pix[1]), B: (pix[2]), A: 1}
|
myColor := color.RGBA{R: (pix[0]), G: (pix[1]), B: (pix[2]), A: 1}
|
||||||
dst.SetRGBA(int(rect.X), dy+int(rect.Y), myColor)
|
dst.SetRGBA(int(rect.X), dy+int(rect.Y), myColor)
|
||||||
|
|
||||||
@ -469,7 +472,7 @@ func (enc *TightEncoding) decodeGradientData(rect *Rectangle, buf []byte) {
|
|||||||
pix[c] = (byte)(byte(est[c]) + buf[(dy*int(rect.Width)+dx)*3+c])
|
pix[c] = (byte)(byte(est[c]) + buf[(dy*int(rect.Width)+dx)*3+c])
|
||||||
thisRow[dx*3+c] = pix[c]
|
thisRow[dx*3+c] = pix[c]
|
||||||
}
|
}
|
||||||
//logger.Debugf("putting pixel:%d,%d,%d at offset: %d, pixArrayLen= %v, rect=x:%d,y:%d,w:%d,h:%d, Yposition=%d", pix[0], pix[1], pix[2], offset, len(dst.Pix), x, y, w, h, dy)
|
//logger.Tracef("putting pixel:%d,%d,%d at offset: %d, pixArrayLen= %v, rect=x:%d,y:%d,w:%d,h:%d, Yposition=%d", pix[0], pix[1], pix[2], offset, len(dst.Pix), x, y, w, h, dy)
|
||||||
myColor := color.RGBA{R: pix[0], G: (pix[1]), B: (pix[2]), A: 1}
|
myColor := color.RGBA{R: pix[0], G: (pix[1]), B: (pix[2]), A: 1}
|
||||||
dst.SetRGBA(dx+int(rect.X), dy+int(rect.Y), myColor)
|
dst.SetRGBA(dx+int(rect.X), dy+int(rect.Y), myColor)
|
||||||
|
|
||||||
@ -511,7 +514,7 @@ func (enc *TightEncoding) readTightPalette(connReader Conn, bytesPixel int) (col
|
|||||||
}
|
}
|
||||||
|
|
||||||
paletteSize := colorCount + 1 // add one more
|
paletteSize := colorCount + 1 // add one more
|
||||||
//logger.Debugf("----PALETTE_FILTER: paletteSize=%d bytesPixel=%d\n", paletteSize, bytesPixel)
|
//logger.Tracef("----PALETTE_FILTER: paletteSize=%d bytesPixel=%d\n", paletteSize, bytesPixel)
|
||||||
//complete palette
|
//complete palette
|
||||||
paletteColorBytes, err := ReadBytes(int(paletteSize)*bytesPixel, connReader)
|
paletteColorBytes, err := ReadBytes(int(paletteSize)*bytesPixel, connReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -528,12 +531,12 @@ func (enc *TightEncoding) readTightPalette(connReader Conn, bytesPixel int) (col
|
|||||||
|
|
||||||
func (enc *TightEncoding) ReadTightData(dataSize int, c Conn, decoderId int) ([]byte, error) {
|
func (enc *TightEncoding) ReadTightData(dataSize int, c Conn, decoderId int) ([]byte, error) {
|
||||||
|
|
||||||
logger.Debugf(">>> Reading zipped tight data from decoder: %d", decoderId)
|
logger.Tracef(">>> Reading zipped tight data from decoder: %d", decoderId)
|
||||||
if int(dataSize) < TightMinToCompress {
|
if int(dataSize) < TightMinToCompress {
|
||||||
return ReadBytes(int(dataSize), c)
|
return ReadBytes(int(dataSize), c)
|
||||||
}
|
}
|
||||||
zlibDataLen, err := readTightLength(c)
|
zlibDataLen, err := readTightLength(c)
|
||||||
//logger.Debugf("RfbReadHelper.ReadTightData: compactlen=%d", zlibDataLen)
|
//logger.Tracef("RfbReadHelper.ReadTightData: compactlen=%d", zlibDataLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -658,12 +661,12 @@ func readTightLength(c Conn) (int, error) {
|
|||||||
*/
|
*/
|
||||||
func (enc *TightEncoding) drawTightBytes(bytes []byte, rect *Rectangle) {
|
func (enc *TightEncoding) drawTightBytes(bytes []byte, rect *Rectangle) {
|
||||||
bytesPos := 0
|
bytesPos := 0
|
||||||
logger.Debugf("drawTightBytes: len(bytes)= %d, %v", len(bytes), rect)
|
logger.Tracef("drawTightBytes: len(bytes)= %d, %v", len(bytes), rect)
|
||||||
|
|
||||||
for ly := rect.Y; ly < rect.Y+rect.Height; ly++ {
|
for ly := rect.Y; ly < rect.Y+rect.Height; ly++ {
|
||||||
for lx := rect.X; lx < rect.X+rect.Width; lx++ {
|
for lx := rect.X; lx < rect.X+rect.Width; lx++ {
|
||||||
color := color.RGBA{R: bytes[bytesPos], G: bytes[bytesPos+1], B: bytes[bytesPos+2], A: 1}
|
color := color.RGBA{R: bytes[bytesPos], G: bytes[bytesPos+1], B: bytes[bytesPos+2], A: 1}
|
||||||
//logger.Debugf("drawTightBytes: setting pixel= (%d,%d): %v", int(lx), int(ly), color)
|
//logger.Tracef("drawTightBytes: setting pixel= (%d,%d): %v", int(lx), int(ly), color)
|
||||||
enc.Image.Set(int(lx), int(ly), color)
|
enc.Image.Set(int(lx), int(ly), color)
|
||||||
|
|
||||||
bytesPos += 3
|
bytesPos += 3
|
||||||
|
@ -65,7 +65,7 @@ func (*TightPngEncoding) Type() EncodingType { return EncTightPng }
|
|||||||
|
|
||||||
func (enc *TightPngEncoding) Read(c Conn, rect *Rectangle) error {
|
func (enc *TightPngEncoding) Read(c Conn, rect *Rectangle) error {
|
||||||
tcc, err := readTightCC(c)
|
tcc, err := readTightCC(c)
|
||||||
logger.Debug("starting to read a tight rect: %v", rect)
|
logger.Trace("starting to read a tight rect: %v", rect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
type VncCanvas struct {
|
type VncCanvas struct {
|
||||||
draw.Image
|
draw.Image
|
||||||
Cursor draw.Image
|
Cursor draw.Image
|
||||||
CursorMask draw.Image
|
CursorMask [][]bool
|
||||||
CursorBackup draw.Image
|
CursorBackup draw.Image
|
||||||
CursorOffset *image.Point
|
CursorOffset *image.Point
|
||||||
CursorLocation *image.Point
|
CursorLocation *image.Point
|
||||||
@ -20,7 +20,7 @@ type VncCanvas struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewVncCanvas(width, height int) *VncCanvas {
|
func NewVncCanvas(width, height int) *VncCanvas {
|
||||||
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
img := NewRGBImage(image.Rect(0, 0, width, height))
|
||||||
canvas := VncCanvas{
|
canvas := VncCanvas{
|
||||||
Image: img,
|
Image: img,
|
||||||
}
|
}
|
||||||
@ -41,14 +41,14 @@ func (c *VncCanvas) RemoveCursor() image.Image {
|
|||||||
// offset := y*int(rect.Width) + x
|
// offset := y*int(rect.Width) + x
|
||||||
// if bitmask[y*int(scanLine)+x/8]&(1<<uint(7-x%8)) > 0 {
|
// if bitmask[y*int(scanLine)+x/8]&(1<<uint(7-x%8)) > 0 {
|
||||||
col := c.CursorBackup.At(x, y)
|
col := c.CursorBackup.At(x, y)
|
||||||
mask := c.CursorMask.At(x, y).(color.RGBA)
|
//mask := c.CursorMask.At(x, y).(color.RGBA)
|
||||||
|
mask := c.CursorMask[x][y]
|
||||||
//logger.Info("Drawing Cursor: ", x, y, col, mask)
|
//logger.Info("Drawing Cursor: ", x, y, col, mask)
|
||||||
if mask.R == 1 {
|
if mask {
|
||||||
//logger.Info("Drawing Cursor for real: ", x, y, col)
|
//logger.Info("Drawing Cursor for real: ", x, y, col)
|
||||||
img.Set(x+loc.X-c.CursorOffset.X, y+loc.Y-c.CursorOffset.Y, col)
|
img.Set(x+loc.X-c.CursorOffset.X, y+loc.Y-c.CursorOffset.Y, col)
|
||||||
}
|
}
|
||||||
// //logger.Debugf("CursorPseudoEncoding.Read: setting pixel: (%d,%d) %v", x+int(rect.X), y+int(rect.Y), colors[offset])
|
// //logger.Tracef("CursorPseudoEncoding.Read: setting pixel: (%d,%d) %v", x+int(rect.X), y+int(rect.Y), colors[offset])
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,18 +74,20 @@ func (c *VncCanvas) PaintCursor() image.Image {
|
|||||||
// offset := y*int(rect.Width) + x
|
// offset := y*int(rect.Width) + x
|
||||||
// if bitmask[y*int(scanLine)+x/8]&(1<<uint(7-x%8)) > 0 {
|
// if bitmask[y*int(scanLine)+x/8]&(1<<uint(7-x%8)) > 0 {
|
||||||
col := c.Cursor.At(x, y)
|
col := c.Cursor.At(x, y)
|
||||||
mask := c.CursorMask.At(x, y).(color.RGBA)
|
//mask := c.CursorMask.At(x, y).(RGBColor)
|
||||||
|
mask := c.CursorMask[x][y]
|
||||||
|
backup := c.Image.At(x+loc.X-c.CursorOffset.X, y+loc.Y-c.CursorOffset.Y)
|
||||||
|
//c.CursorBackup.Set(x, y, backup)
|
||||||
//backup the previous data at this point
|
//backup the previous data at this point
|
||||||
|
|
||||||
//logger.Info("Drawing Cursor: ", x, y, col, mask)
|
//logger.Info("Drawing Cursor: ", x, y, col, mask)
|
||||||
if mask.R == 1 {
|
if mask {
|
||||||
backup := c.Image.At(x+loc.X-c.CursorOffset.X, y+loc.Y-c.CursorOffset.Y)
|
|
||||||
c.CursorBackup.Set(x, y, backup)
|
c.CursorBackup.Set(x, y, backup)
|
||||||
//logger.Info("Drawing Cursor for real: ", x, y, col)
|
//logger.Info("Drawing Cursor for real: ", x, y, col)
|
||||||
img.Set(x+loc.X-c.CursorOffset.X, y+loc.Y-c.CursorOffset.Y, col)
|
img.Set(x+loc.X-c.CursorOffset.X, y+loc.Y-c.CursorOffset.Y, col)
|
||||||
}
|
}
|
||||||
// //logger.Debugf("CursorPseudoEncoding.Read: setting pixel: (%d,%d) %v", x+int(rect.X), y+int(rect.Y), colors[offset])
|
// //logger.Tracef("CursorPseudoEncoding.Read: setting pixel: (%d,%d) %v", x+int(rect.X), y+int(rect.Y), colors[offset])
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func CalcBytesPerCPixel(pf *PixelFormat) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *ZRLEEncoding) Read(r Conn, rect *Rectangle) error {
|
func (enc *ZRLEEncoding) Read(r Conn, rect *Rectangle) error {
|
||||||
logger.Debugf("reading ZRLE:%v\n", rect)
|
logger.Tracef("reading ZRLE:%v\n", rect)
|
||||||
len, err := ReadUint32(r)
|
len, err := ReadUint32(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -101,7 +101,7 @@ func (enc *ZRLEEncoding) readZRLERaw(reader io.Reader, pf *PixelFormat, tx, ty,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *ZRLEEncoding) renderZRLE(rect *Rectangle, pf *PixelFormat) error {
|
func (enc *ZRLEEncoding) renderZRLE(rect *Rectangle, pf *PixelFormat) error {
|
||||||
logger.Debug("-----renderZRLE: rendering rect:", rect)
|
logger.Trace("-----renderZRLE: rendering rect:", rect)
|
||||||
for tileOffsetY := 0; tileOffsetY < int(rect.Height); tileOffsetY += 64 {
|
for tileOffsetY := 0; tileOffsetY < int(rect.Height); tileOffsetY += 64 {
|
||||||
|
|
||||||
tileHeight := Min(64, int(rect.Height)-tileOffsetY)
|
tileHeight := Min(64, int(rect.Height)-tileOffsetY)
|
||||||
@ -111,7 +111,7 @@ func (enc *ZRLEEncoding) renderZRLE(rect *Rectangle, pf *PixelFormat) error {
|
|||||||
tileWidth := Min(64, int(rect.Width)-tileOffsetX)
|
tileWidth := Min(64, int(rect.Width)-tileOffsetX)
|
||||||
// read subencoding
|
// read subencoding
|
||||||
subEnc, err := ReadUint8(enc.unzipper)
|
subEnc, err := ReadUint8(enc.unzipper)
|
||||||
logger.Debugf("-----renderZRLE: rendering got tile:(%d,%d) w:%d, h:%d subEnc:%d", tileOffsetX, tileOffsetY, tileWidth, tileHeight, subEnc)
|
logger.Tracef("-----renderZRLE: rendering got tile:(%d,%d) w:%d, h:%d subEnc:%d", tileOffsetX, tileOffsetY, tileWidth, tileHeight, subEnc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("renderZRLE: error while reading subencoding: %v", err)
|
logger.Errorf("renderZRLE: error while reading subencoding: %v", err)
|
||||||
return err
|
return err
|
||||||
@ -200,7 +200,7 @@ func (enc *ZRLEEncoding) handlePaletteRLETile(tileOffsetX, tileOffsetY, tileWidt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//logger.Debugf("renderZRLE: writing pixel: col=%v times=%d", palette[index], runLen)
|
//logger.Tracef("renderZRLE: writing pixel: col=%v times=%d", palette[index], runLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write pixel to image
|
// Write pixel to image
|
||||||
|
@ -2,10 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
vnc "vnc2video"
|
vnc "vnc2video"
|
||||||
@ -21,7 +23,7 @@ func main() {
|
|||||||
logger.Fatalf("Error connecting to VNC host. %v", err)
|
logger.Fatalf("Error connecting to VNC host. %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("starting up the client, connecting to: %s", os.Args[1])
|
logger.Tracef("starting up the client, connecting to: %s", os.Args[1])
|
||||||
// Negotiate connection with the server.
|
// Negotiate connection with the server.
|
||||||
cchServer := make(chan vnc.ServerMessage)
|
cchServer := make(chan vnc.ServerMessage)
|
||||||
cchClient := make(chan vnc.ClientMessage)
|
cchClient := make(chan vnc.ClientMessage)
|
||||||
@ -64,15 +66,17 @@ func main() {
|
|||||||
// }
|
// }
|
||||||
//vcodec := &encoders.MJPegImageEncoder{Quality: 60, Framerate: 4}
|
//vcodec := &encoders.MJPegImageEncoder{Quality: 60, Framerate: 4}
|
||||||
vcodec := &encoders.X264ImageEncoder{}
|
vcodec := &encoders.X264ImageEncoder{}
|
||||||
//vcodec := &encoders.DV8ImageEncoder{}
|
//vcodec := &encoders.VP8ImageEncoder{}
|
||||||
//vcodec := &encoders.DV9ImageEncoder{}
|
//vcodec := &encoders.DV9ImageEncoder{}
|
||||||
|
|
||||||
//counter := 0
|
//counter := 0
|
||||||
//vcodec.Init("./output" + strconv.Itoa(counter))
|
//vcodec.Init("./output" + strconv.Itoa(counter))
|
||||||
go vcodec.Run("./ffmpeg", "./output.mp4")
|
|
||||||
|
|
||||||
//go vcodec.Run("/Users/amitbet/Dropbox/go/src/vnc2webm/example/file-reader/ffmpeg", "./output.mp4")
|
go vcodec.Run("./ffmpeg", "./output.mp4")
|
||||||
//go vcodec.Run("C:\\Users\\betzalel\\Dropbox\\go\\src\\vnc2video\\example\\client\\ffmpeg.exe", "./output.mp4")
|
//windows
|
||||||
|
///go vcodec.Run("/Users/amitbet/Dropbox/go/src/vnc2webm/example/file-reader/ffmpeg", "./output.mp4")
|
||||||
|
|
||||||
|
//go vcodec.Run("C:\\Users\\betzalel\\Dropbox\\go\\src\\vnc2video\\example\\client\\ffmpeg.exe", "output.mp4")
|
||||||
//vcodec.Run("./output")
|
//vcodec.Run("./output")
|
||||||
|
|
||||||
//screenImage := vnc.NewVncCanvas(int(cc.Width()), int(cc.Height()))
|
//screenImage := vnc.NewVncCanvas(int(cc.Width()), int(cc.Height()))
|
||||||
@ -86,18 +90,18 @@ func main() {
|
|||||||
}
|
}
|
||||||
// var out *os.File
|
// var out *os.File
|
||||||
|
|
||||||
logger.Debugf("connected to: %s", os.Args[1])
|
logger.Tracef("connected to: %s", os.Args[1])
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
|
|
||||||
cc.SetEncodings([]vnc.EncodingType{
|
cc.SetEncodings([]vnc.EncodingType{
|
||||||
vnc.EncCursorPseudo,
|
vnc.EncCursorPseudo,
|
||||||
vnc.EncPointerPosPseudo,
|
vnc.EncPointerPosPseudo,
|
||||||
vnc.EncCopyRect,
|
vnc.EncCopyRect,
|
||||||
vnc.EncTight,
|
//vnc.EncTight,
|
||||||
vnc.EncZRLE,
|
//vnc.EncZRLE,
|
||||||
vnc.EncHextile,
|
//vnc.EncHextile,
|
||||||
vnc.EncZlib,
|
//vnc.EncZlib,
|
||||||
vnc.EncRRE,
|
//vnc.EncRRE,
|
||||||
})
|
})
|
||||||
//rect := image.Rect(0, 0, int(cc.Width()), int(cc.Height()))
|
//rect := image.Rect(0, 0, int(cc.Width()), int(cc.Height()))
|
||||||
//screenImage := image.NewRGBA64(rect)
|
//screenImage := image.NewRGBA64(rect)
|
||||||
@ -105,7 +109,7 @@ func main() {
|
|||||||
|
|
||||||
// go func() {
|
// go func() {
|
||||||
// for {
|
// for {
|
||||||
// //logger.Infof("encoding screen")
|
// //logger.Debugf("encoding screen")
|
||||||
// vcodec.Encode(screenImage)
|
// vcodec.Encode(screenImage)
|
||||||
// time.Sleep(100 * time.Millisecond)
|
// time.Sleep(100 * time.Millisecond)
|
||||||
// }
|
// }
|
||||||
@ -116,25 +120,44 @@ func main() {
|
|||||||
syscall.SIGINT,
|
syscall.SIGINT,
|
||||||
syscall.SIGTERM,
|
syscall.SIGTERM,
|
||||||
syscall.SIGQUIT)
|
syscall.SIGQUIT)
|
||||||
|
frameBufferReq := 0
|
||||||
|
timeStart := time.Now()
|
||||||
|
|
||||||
|
runWithProfiler := false
|
||||||
|
if runWithProfiler {
|
||||||
|
profFile := "prof.file"
|
||||||
|
f, err := os.Create(profFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
pprof.StartCPUProfile(f)
|
||||||
|
defer pprof.StopCPUProfile()
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case err := <-errorCh:
|
case err := <-errorCh:
|
||||||
panic(err)
|
panic(err)
|
||||||
case msg := <-cchClient:
|
case msg := <-cchClient:
|
||||||
logger.Debugf("Received client message type:%v msg:%v\n", msg.Type(), msg)
|
logger.Tracef("Received client message type:%v msg:%v\n", msg.Type(), msg)
|
||||||
case msg := <-cchServer:
|
case msg := <-cchServer:
|
||||||
//logger.Debugf("Received server message type:%v msg:%v\n", msg.Type(), msg)
|
//logger.Tracef("Received server message type:%v msg:%v\n", msg.Type(), msg)
|
||||||
|
|
||||||
// out, err := os.Create("./output" + strconv.Itoa(counter) + ".jpg")
|
// out, err := os.Create("./output" + strconv.Itoa(counter) + ".jpg")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// os.Exit(1)
|
// os.Exit(1)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if msg.Type() == vnc.FramebufferUpdateMsgType {
|
if msg.Type() == vnc.FramebufferUpdateMsgType {
|
||||||
|
secsPassed := time.Now().Sub(timeStart).Seconds()
|
||||||
|
frameBufferReq++
|
||||||
|
reqPerSec := float64(frameBufferReq) / secsPassed
|
||||||
//counter++
|
//counter++
|
||||||
//jpeg.Encode(out, screenImage, nil)
|
//jpeg.Encode(out, screenImage, nil)
|
||||||
vcodec.Encode(screenImage)
|
vcodec.Encode(screenImage.Image)
|
||||||
|
logger.Infof("reqs=%d, seconds=%f, Req Per second= %f", frameBufferReq, secsPassed, reqPerSec)
|
||||||
|
|
||||||
reqMsg := vnc.FramebufferUpdateRequest{Inc: 1, X: 0, Y: 0, Width: cc.Width(), Height: cc.Height()}
|
reqMsg := vnc.FramebufferUpdateRequest{Inc: 1, X: 0, Y: 0, Width: cc.Width(), Height: cc.Height()}
|
||||||
//cc.ResetAllEncodings()
|
//cc.ResetAllEncodings()
|
||||||
reqMsg.Write(cc)
|
reqMsg.Write(cc)
|
||||||
@ -142,6 +165,7 @@ func main() {
|
|||||||
case signal := <-sigc:
|
case signal := <-sigc:
|
||||||
if signal != nil {
|
if signal != nil {
|
||||||
vcodec.Close()
|
vcodec.Close()
|
||||||
|
pprof.StopCPUProfile()
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func main() {
|
|||||||
//vcodec := &encoders.DV8ImageEncoder{}
|
//vcodec := &encoders.DV8ImageEncoder{}
|
||||||
//vcodec := &encoders.DV9ImageEncoder{}
|
//vcodec := &encoders.DV9ImageEncoder{}
|
||||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
logger.Debugf("current dir: %s", dir)
|
logger.Tracef("current dir: %s", dir)
|
||||||
go vcodec.Run("./ffmpeg", "./output.mp4")
|
go vcodec.Run("./ffmpeg", "./output.mp4")
|
||||||
|
|
||||||
screenImage := image.NewRGBA(image.Rect(0, 0, int(fbs.Width()), int(fbs.Height())))
|
screenImage := image.NewRGBA(image.Rect(0, 0, int(fbs.Width()), int(fbs.Height())))
|
||||||
|
@ -189,7 +189,7 @@ func (auth *AuthVNCHTTP) Auth(c vnc.Conn) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get auth data: %s", err.Error())
|
return fmt.Errorf("failed to get auth data: %s", err.Error())
|
||||||
}
|
}
|
||||||
logger.Infof("http auth: %s\n", buf.Bytes())
|
logger.Debugf("http auth: %s\n", buf.Bytes())
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
data := strings.Split(buf.String(), " ")
|
data := strings.Split(buf.String(), " ")
|
||||||
if len(data) < 2 {
|
if len(data) < 2 {
|
||||||
|
@ -50,12 +50,12 @@ func main() {
|
|||||||
case msg := <-chClient:
|
case msg := <-chClient:
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
default:
|
default:
|
||||||
logger.Debugf("11 Received message type:%v msg:%v\n", msg.Type(), msg)
|
logger.Tracef("11 Received message type:%v msg:%v\n", msg.Type(), msg)
|
||||||
}
|
}
|
||||||
case msg := <-chServer:
|
case msg := <-chServer:
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
default:
|
default:
|
||||||
logger.Debugf("22 Received message type:%v msg:%v\n", msg.Type(), msg)
|
logger.Tracef("22 Received message type:%v msg:%v\n", msg.Type(), msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
handlers.go
10
handlers.go
@ -157,7 +157,7 @@ func (*DefaultClientSecurityHandler) Handle(c Conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("authenticating, secType: %d, auth code(0=success): %d", secType.Type(), authCode)
|
logger.Tracef("authenticating, secType: %d, auth code(0=success): %d", secType.Type(), authCode)
|
||||||
if authCode == 1 {
|
if authCode == 1 {
|
||||||
var reasonLength uint32
|
var reasonLength uint32
|
||||||
if err := binary.Read(c, binary.BigEndian, &reasonLength); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &reasonLength); err != nil {
|
||||||
@ -258,7 +258,7 @@ type DefaultClientServerInitHandler struct{}
|
|||||||
|
|
||||||
// Handle provide default server init handler
|
// Handle provide default server init handler
|
||||||
func (*DefaultClientServerInitHandler) Handle(c Conn) error {
|
func (*DefaultClientServerInitHandler) Handle(c Conn) error {
|
||||||
logger.Debug("starting DefaultClientServerInitHandler")
|
logger.Trace("starting DefaultClientServerInitHandler")
|
||||||
var err error
|
var err error
|
||||||
srvInit := ServerInit{}
|
srvInit := ServerInit{}
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ func (*DefaultClientServerInitHandler) Handle(c Conn) error {
|
|||||||
if err = binary.Read(c, binary.BigEndian, &srvInit.NameText); err != nil {
|
if err = binary.Read(c, binary.BigEndian, &srvInit.NameText); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logger.Debugf("DefaultClientServerInitHandler got serverInit: %v", srvInit)
|
logger.Tracef("DefaultClientServerInitHandler got serverInit: %v", srvInit)
|
||||||
c.SetDesktopName(srvInit.NameText)
|
c.SetDesktopName(srvInit.NameText)
|
||||||
if c.Protocol() == "aten1" {
|
if c.Protocol() == "aten1" {
|
||||||
c.SetWidth(800)
|
c.SetWidth(800)
|
||||||
@ -375,7 +375,7 @@ type DefaultClientClientInitHandler struct{}
|
|||||||
|
|
||||||
// Handle provide default client client init handler
|
// Handle provide default client client init handler
|
||||||
func (*DefaultClientClientInitHandler) Handle(c Conn) error {
|
func (*DefaultClientClientInitHandler) Handle(c Conn) error {
|
||||||
logger.Debug("starting DefaultClientClientInitHandler")
|
logger.Trace("starting DefaultClientClientInitHandler")
|
||||||
cfg := c.Config().(*ClientConfig)
|
cfg := c.Config().(*ClientConfig)
|
||||||
var shared uint8
|
var shared uint8
|
||||||
if cfg.Exclusive {
|
if cfg.Exclusive {
|
||||||
@ -386,7 +386,7 @@ func (*DefaultClientClientInitHandler) Handle(c Conn) error {
|
|||||||
if err := binary.Write(c, binary.BigEndian, shared); err != nil {
|
if err := binary.Write(c, binary.BigEndian, shared); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logger.Debugf("DefaultClientClientInitHandler sending: shared=%d", shared)
|
logger.Tracef("DefaultClientClientInitHandler sending: shared=%d", shared)
|
||||||
return c.Flush()
|
return c.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
image.go
3
image.go
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"vnc2video/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
//var _ draw.Drawer = (*ServerConn)(nil)
|
//var _ draw.Drawer = (*ServerConn)(nil)
|
||||||
@ -166,7 +167,7 @@ func (rect *Rectangle) Read(c Conn) error {
|
|||||||
if err = binary.Read(c, binary.BigEndian, &rect.EncType); err != nil {
|
if err = binary.Read(c, binary.BigEndian, &rect.EncType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
logger.Debug(rect)
|
||||||
switch rect.EncType {
|
switch rect.EncType {
|
||||||
// case EncCopyRect:
|
// case EncCopyRect:
|
||||||
// rect.Enc = &CopyRectEncoding{}
|
// rect.Enc = &CopyRectEncoding{}
|
||||||
|
@ -2,13 +2,16 @@ package logger
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
var simpleLogger = SimpleLogger{LogLevelInfo}
|
var simpleLogger = SimpleLogger{LogLevelWarn}
|
||||||
|
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
|
Trace(v ...interface{})
|
||||||
|
Tracef(format string, v ...interface{})
|
||||||
Debug(v ...interface{})
|
Debug(v ...interface{})
|
||||||
Debugf(format string, v ...interface{})
|
Debugf(format string, v ...interface{})
|
||||||
Info(v ...interface{})
|
Info(v ...interface{})
|
||||||
Infof(format string, v ...interface{})
|
Infof(format string, v ...interface{})
|
||||||
|
DebugfNoCR(format string, v ...interface{})
|
||||||
Warn(v ...interface{})
|
Warn(v ...interface{})
|
||||||
Warnf(format string, v ...interface{})
|
Warnf(format string, v ...interface{})
|
||||||
Error(v ...interface{})
|
Error(v ...interface{})
|
||||||
@ -71,6 +74,12 @@ func (sl *SimpleLogger) Info(v ...interface{}) {
|
|||||||
fmt.Println(arr...)
|
fmt.Println(arr...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (sl *SimpleLogger) DebugfNoCR(format string, v ...interface{}) {
|
||||||
|
if sl.level <= LogLevelDebug {
|
||||||
|
fmt.Printf("[Info ] "+format, v...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (sl *SimpleLogger) Infof(format string, v ...interface{}) {
|
func (sl *SimpleLogger) Infof(format string, v ...interface{}) {
|
||||||
if sl.level <= LogLevelInfo {
|
if sl.level <= LogLevelInfo {
|
||||||
fmt.Printf("[Info ] "+format+"\n", v...)
|
fmt.Printf("[Info ] "+format+"\n", v...)
|
||||||
@ -119,12 +128,18 @@ func (sl *SimpleLogger) Fatalf(format string, v ...interface{}) {
|
|||||||
fmt.Printf("[Fatal] "+format+"\n", v)
|
fmt.Printf("[Fatal] "+format+"\n", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func Trace(v ...interface{}) {
|
||||||
|
simpleLogger.Trace(v...)
|
||||||
|
}
|
||||||
|
func Tracef(format string, v ...interface{}) {
|
||||||
|
simpleLogger.Tracef(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
func Debug(v ...interface{}) {
|
func Debug(v ...interface{}) {
|
||||||
simpleLogger.Debug(v...)
|
simpleLogger.Debug(v...)
|
||||||
}
|
}
|
||||||
func Debugf(format string, v ...interface{}) {
|
func Debugf(format string, v ...interface{}) {
|
||||||
simpleLogger.Debugf(format, v...)
|
simpleLogger.Tracef(format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Info(v ...interface{}) {
|
func Info(v ...interface{}) {
|
||||||
@ -133,7 +148,9 @@ func Info(v ...interface{}) {
|
|||||||
func Infof(format string, v ...interface{}) {
|
func Infof(format string, v ...interface{}) {
|
||||||
simpleLogger.Infof(format, v...)
|
simpleLogger.Infof(format, v...)
|
||||||
}
|
}
|
||||||
|
func DebugfNoCR(format string, v ...interface{}) {
|
||||||
|
simpleLogger.DebugfNoCR(format, v...)
|
||||||
|
}
|
||||||
func Warn(v ...interface{}) {
|
func Warn(v ...interface{}) {
|
||||||
simpleLogger.Warn(v...)
|
simpleLogger.Warn(v...)
|
||||||
}
|
}
|
||||||
|
11
messages.go
11
messages.go
@ -115,9 +115,11 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
|
|||||||
if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
logger.Debugf("-------Reading FrameBuffer update with %d rects-------", msg.NumRect)
|
||||||
|
|
||||||
for i := uint16(0); i < msg.NumRect; i++ {
|
for i := uint16(0); i < msg.NumRect; i++ {
|
||||||
rect := NewRectangle()
|
rect := NewRectangle()
|
||||||
//logger.Debugf("----------RECT %d----------:", i)
|
logger.DebugfNoCR("----------RECT %d----------", i)
|
||||||
|
|
||||||
if err := rect.Read(c); err != nil {
|
if err := rect.Read(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -125,7 +127,7 @@ func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) {
|
|||||||
if rect.EncType == EncDesktopSizePseudo {
|
if rect.EncType == EncDesktopSizePseudo {
|
||||||
c.(*ClientConn).ResetAllEncodings()
|
c.(*ClientConn).ResetAllEncodings()
|
||||||
}
|
}
|
||||||
logger.Debugf("----End RECT #%d Info (%dx%d) encType:%s", i, rect.Width, rect.Height, rect.EncType)
|
logger.Tracef("----End RECT #%d Info (%dx%d) encType:%s", i, rect.Width, rect.Height, rect.EncType)
|
||||||
msg.Rects = append(msg.Rects, rect)
|
msg.Rects = append(msg.Rects, rect)
|
||||||
}
|
}
|
||||||
return &msg, nil
|
return &msg, nil
|
||||||
@ -269,6 +271,7 @@ func (*SetColorMapEntries) Type() ServerMessageType {
|
|||||||
|
|
||||||
// Read unmrashal message from conn
|
// Read unmrashal message from conn
|
||||||
func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
|
func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
|
||||||
|
logger.Info("Reading SetColorMapEntries message")
|
||||||
msg := SetColorMapEntries{}
|
msg := SetColorMapEntries{}
|
||||||
var pad [1]byte
|
var pad [1]byte
|
||||||
if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &pad); err != nil {
|
||||||
@ -288,7 +291,9 @@ func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) {
|
|||||||
|
|
||||||
for i := uint16(0); i < msg.ColorsNum; i++ {
|
for i := uint16(0); i < msg.ColorsNum; i++ {
|
||||||
color := &msg.Colors[i]
|
color := &msg.Colors[i]
|
||||||
if err := binary.Read(c, binary.BigEndian, &color); err != nil {
|
err := color.Read(c)
|
||||||
|
if err != nil {
|
||||||
|
//if err := binary.Read(c, binary.BigEndian, &color); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
colorMap[msg.FirstColor+i] = *color
|
colorMap[msg.FirstColor+i] = *color
|
||||||
|
112
rgb-image.go
Normal file
112
rgb-image.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package vnc2video
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RGBA is an in-memory image whose At method returns color.RGBA values.
|
||||||
|
type RGBImage struct {
|
||||||
|
// Pix holds the image's pixels, in R, G, B, A order. The pixel at
|
||||||
|
// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*3].
|
||||||
|
Pix []uint8
|
||||||
|
// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
|
||||||
|
Stride int
|
||||||
|
// Rect is the image's bounds.
|
||||||
|
Rect image.Rectangle
|
||||||
|
}
|
||||||
|
|
||||||
|
type RGBColor struct {
|
||||||
|
R, G, B uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c RGBColor) RGBA() (r, g, b, a uint32) {
|
||||||
|
return uint32(c.R), uint32(c.G), uint32(c.B), 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RGBImage) ColorModel() color.Model { return nil }
|
||||||
|
|
||||||
|
func (p *RGBImage) Bounds() image.Rectangle { return p.Rect }
|
||||||
|
|
||||||
|
func (p *RGBImage) At(x, y int) color.Color {
|
||||||
|
col := p.RGBAt(x, y)
|
||||||
|
return color.RGBA{col.R, col.G, col.B, 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RGBImage) RGBAt(x, y int) *RGBColor {
|
||||||
|
if !(image.Point{x, y}.In(p.Rect)) {
|
||||||
|
return &RGBColor{}
|
||||||
|
}
|
||||||
|
i := p.PixOffset(x, y)
|
||||||
|
return &RGBColor{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2]}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PixOffset returns the index of the first element of Pix that corresponds to
|
||||||
|
// the pixel at (x, y).
|
||||||
|
func (p *RGBImage) PixOffset(x, y int) int {
|
||||||
|
return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RGBImage) Set(x, y int, c color.Color) {
|
||||||
|
if !(image.Point{x, y}.In(p.Rect)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := p.PixOffset(x, y)
|
||||||
|
c1 := color.RGBAModel.Convert(c).(color.RGBA)
|
||||||
|
p.Pix[i+0] = c1.R
|
||||||
|
p.Pix[i+1] = c1.G
|
||||||
|
p.Pix[i+2] = c1.B
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RGBImage) SetRGB(x, y int, c color.RGBA) {
|
||||||
|
if !(image.Point{x, y}.In(p.Rect)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := p.PixOffset(x, y)
|
||||||
|
p.Pix[i+0] = c.R
|
||||||
|
p.Pix[i+1] = c.G
|
||||||
|
p.Pix[i+2] = c.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubImage returns an image representing the portion of the image p visible
|
||||||
|
// through r. The returned value shares pixels with the original image.
|
||||||
|
func (p *RGBImage) SubImage(r image.Rectangle) image.Image {
|
||||||
|
r = r.Intersect(p.Rect)
|
||||||
|
// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
|
||||||
|
// either r1 or r2 if the intersection is empty. Without explicitly checking for
|
||||||
|
// this, the Pix[i:] expression below can panic.
|
||||||
|
if r.Empty() {
|
||||||
|
return &RGBImage{}
|
||||||
|
}
|
||||||
|
i := p.PixOffset(r.Min.X, r.Min.Y)
|
||||||
|
return &RGBImage{
|
||||||
|
Pix: p.Pix[i:],
|
||||||
|
Stride: p.Stride,
|
||||||
|
Rect: r,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opaque scans the entire image and reports whether it is fully opaque.
|
||||||
|
func (p *RGBImage) Opaque() bool {
|
||||||
|
if p.Rect.Empty() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
i0, i1 := 3, p.Rect.Dx()*3
|
||||||
|
for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
|
||||||
|
for i := i0; i < i1; i += 3 {
|
||||||
|
if p.Pix[i] != 0xff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i0 += p.Stride
|
||||||
|
i1 += p.Stride
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRGBA returns a new RGBA image with the given bounds.
|
||||||
|
func NewRGBImage(r image.Rectangle) *RGBImage {
|
||||||
|
w, h := r.Dx(), r.Dy()
|
||||||
|
buf := make([]uint8, 3*w*h)
|
||||||
|
return &RGBImage{buf, 3 * w, r}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user