Debugging

This commit is contained in:
Marat Fayzullin 2023-02-12 21:22:50 -05:00
parent f14256d60d
commit 88bbff42f1
4 changed files with 101 additions and 32 deletions

View File

@ -118,7 +118,6 @@ class SstvDemodulator(ServiceDemodulator):
def __init__(self):
self.sampleRate = 48000
workers = [
Shift(1500.0 / self.sampleRate),
Agc(Format.COMPLEX_FLOAT),
SstvDecoder(self.sampleRate),
SstvParser()

View File

@ -1205,7 +1205,11 @@ img.openwebrx-mirror-img
white-space: pre;
}
.aprs-symbol {
#openwebrx-panel-sstv-message .frame {
border: 2px dotted white;
}
.aprs-symbol {
display: inline-block;
width: 15px;
height: 15px;

View File

@ -281,7 +281,7 @@ SstvMessagePanel.prototype.render = function() {
$(this.el).append($(
'<table>' +
'<thead><tr>' +
'<th class="message">Message</th>' +
'<th class="message">TV</th>' +
'</tr></thead>' +
'<tbody></tbody>' +
'</table>'
@ -290,15 +290,30 @@ SstvMessagePanel.prototype.render = function() {
SstvMessagePanel.prototype.pushMessage = function(msg) {
var $b = $(this.el).find('tbody');
if(msg.hasOwnProperty('message'))
if(msg.hasOwnProperty('message')) {
$b.append($('<tr><td class="message">' + msg.message + '</td></tr>'));
if(msg.width>0 && msg.height>0 && !msg.hasOwnProperty('line')) {
var $h = 'SCREEN ' + msg.width + "x" + msg.height + '<br>';
var $c = '<canvas width="' + msg.width + '" height="' + msg.height +
'" style="border: 1px solid black;"></canvas>';
$b.append($('<tr><td class="message">' + $h + $c + '</td></tr>'));
}
$b.scrollTop($b[0].scrollHeight);
}
else if(msg.width>0 && msg.height>0 && !msg.hasOwnProperty('line')) {
var h = 'SCREEN ' + msg.width + "x" + msg.height + '<br>';
var c = '<canvas width="' + msg.width + '" height="' + msg.height +
'" class="frame"></canvas>';
$b.append($('<tr><td class="message">' + h + c + '</td></tr>'));
$b.scrollTop($b[0].scrollHeight);
}
else if(msg.width>0 && msg.height>0 && msg.line>=0 && msg.hasOwnProperty('pixels')) {
var pixels = atob(msg.pixels);
var canvas = $(this.el).find('canvas');
var ctx = canvas.getContext("2d");
var img = $ctx.createImageData(msg.width, 1);
for (var x = 0; x < msg.width; x++) {
img.data[x*4 + 0] = pixels.charCodeAt(x*3 + 2);
img.data[x*4 + 1] = pixels.charCodeAt(x*3 + 1);
img.data[x*4 + 2] = pixels.charCodeAt(x*3 + 0);
img.data[x*4 + 3] = 0xFF;
}
ctx.putImageData(img, 0, msg.line);
}
};
$.fn.sstvMessagePanel = function() {

View File

@ -1,6 +1,5 @@
from csdr.module import ThreadModule
from pycsdr.types import Format
from io import BytesIO
import base64
import pickle
@ -10,6 +9,7 @@ logger = logging.getLogger(__name__)
class SstvParser(ThreadModule):
def __init__(self):
self.data = bytearray(b'')
self.width = 0
self.height = 0
self.line = 0
@ -22,32 +22,83 @@ class SstvParser(ThreadModule):
return Format.CHAR
def run(self):
# Run while there is input data
while self.doRun:
data = self.reader.read()
if data is None:
# Read input data
inp = self.reader.read()
# Terminate if no input data
if inp is None:
self.doRun = False
break
out = self.process(data.tobytes())
# Add read data to the buffer
self.data = self.data + inp.tobytes()
# Process buffer contents
out = self.process()
# Keep processing while there is input to parse
while out is not None:
self.writer.write(pickle.dumps(out))
out = self.process()
def process(self, data):
def process(self):
try:
out = { "mode": "SSTV" }
if len(data)==54 and data[0]==ord(b'B') and data[1]==ord(b'M'):
self.width = data[18] + (data[19]<<8) + (data[20]<<16) + (data[21]<<24)
self.height = data[22] + (data[23]<<8) + (data[24]<<16) + (data[25]<<24)
# Parse bitmap (BMP) file header starting with 'BM'
if len(self.data)>=54 and self.data[0]==ord(b'B') and self.data[1]==ord(b'M'):
# BMP height value is negative
self.width = self.data[18] + (self.data[19]<<8) + (self.data[20]<<16) + (self.data[21]<<24)
self.height = -self.data[22] - (self.data[23]<<8) - (self.data[24]<<16) - (self.data[25]<<24)
self.line = 0
elif self.width>0 and len(data)==self.width*3:
out["pixels"] = base64.b64encode(data).decode('utf-8')
out["line"] = self.line
self.line = self.line + 1
elif data[0]==ord(b' ') and data[1]==ord(b'['):
out["message"] = data.decode()
logger.warning("@@@ IMAGE %d x %d" % (self.width, self.height))
# Remove parsed data
del self.data[0:54]
# Return parsed values
return {
"mode": "SSTV",
"width": self.width,
"height": self.height
}
out["width"] = self.width
out["height"] = self.height
# Parse debug messages enclosed in ' [...]'
elif len(self.data)>=2 and self.data[0]==ord(b' ') and self.data[1]==ord(b'['):
# Wait until we find the closing bracket
w = self.data.find(b']')
if w>=0:
logger.warning("@@@ MESSAGE = '%s'" % str(self.data[0:w+1]))
# Compose result
return {
"mode": "SSTV",
"message": self.data[0:w+1].decode()
}
# Remove parsed data
del self.data[0:w+1]
# Return parsed values
return out
# Parse bitmap file data (scanlines)
elif self.width>0 and len(self.data)>=self.width*3:
logger.warning("@@@ LINE %d/%d..." % (self.line, self.height))
w = self.width * 3
# Compose result
out = {
"mode": "SSTV",
"pixels": base64.b64encode(self.data[0:w]).decode()
"line": self.line
"width": self.width
"height": self.height
}
# Advance scanline
self.line = self.line + 1
# If we reached the end of frame, finish scan
if self.line>=self.height:
self.width = 0
self.height = 0
self.line = 0
# Remove parsed data
del self.data[0:w]
# Return parsed values
return out
# Could not parse input data (yet)
return None
except Exception:
logger.exception("Exception while parsing SSTV data")