Commit Graph

209 Commits

Author SHA1 Message Date
kris de8747ff37 Emit the video header and add an assertion to help make sure we don't
break the stream framing.
2019-04-25 16:28:06 +01:00
kris 2a76e3d48f Add a HEADER opcode that emits the 7-byte video header, used to
select the playback mode (HGR/DHGR).
2019-04-25 16:26:38 +01:00
kris 6bde085d5e Introduce a 7-byte video header and use it to select between HGR and
DHGR playback modes.  Actually the only difference is whether to
initialize (D)HGR display since everything else is steered by the video
stream.  6 of these bytes are currently unused, but it is convenient
to pad to the same length as the TICK opcode so that it does not
complicate the ACK stream framing.

Move towards the convention of using upper-case labels for system use
(soft switches etc) and lower-case for program use.
2019-04-25 16:25:36 +01:00
kris aaf56e6ec5 Merge remote-tracking branch 'origin/dhgr' into dhgr 2019-03-28 23:48:40 +00:00
kris 33ac880d29 Improve comment about stream padding 2019-03-28 23:47:38 +00:00
KrisKennaway e80e10924c
Update main.s
Fix last-minute typo
2019-03-28 23:29:10 +00:00
kris fa6c2bb25d Minor cleanups:
- Use a safe ZP address instead of $00
- Use dec instead of hex for IP address bytes
- Remove some unused Uthernet/W5100 defines

Optimize the socket buffer management
- Since we're guaranteeing 2K frame padding, the low byte is always 0
- Remove some vestiges of the Uthernet TCP demo code - AFAICT there
  isn't a need to compare high and low bytes of the S0RXRSR, this
  was just being used as a (slightly risky) check that they were both
  not equal (presumably to 0)
- (h/t Oliver Schmidt <ol.sc@web.de>) it turns out that the W5100
  automatically wraps the address pointer at the end of the 8k RX/TX
  buffer space, so since we're using 8k buffers we don't need any of the
  pointer/mask arithmetic to make sure we don't stray outside this range
- Instead, we can just save the W5100 address pointer before we start
  doing the stream buffer management and restore it when we're ready
  to read from the stream again.
- Moreover, since we know the low-byte is 0 we don't even need to
  save it.

This gives us enough free cycles to implement a keypress check.  For
now any key will pause the video and any other key resume it.

We still have a whole 16 cycles left over while maintaining the 36/37
cycle tick cadence.

We've saved 73 cycles of "dead time" though, i.e. the
op_ack + CHECKRECV + op_nop "slow path" now takes 2*73 rather than 3*73
cycles.  This should result in better audio quality.
2019-03-28 23:08:52 +00:00
kris 10fa4bc72d Proof of concept DHGR encoding/playback
- Every time we process an ACK opcode, toggle page 1/page 2 soft
  switches to steer subsequent writes between MAIN and AUX memory
- while I'm here, squeeze out some unnecessary operations from the
  buffer management

On the player side, this is implemented by maintaining two screen
memory maps, and alternating between opcode streams for each of them.
This is using entirely the wrong colour model for errors, but
surprisingly it already works pretty well in practise (and the frame
rate is acceptable on test videos)

DHGR/HGR could be made runtime selectable by adding a header byte that
determines whether to set the DHGR soft switches before initiating
the decode loop.

While I'm in here, fix op_terminate to clear keyboard strobe before
waiting.
2019-03-27 21:37:06 +00:00
kris d4a27444c6 Merge remote-tracking branch 'origin/master' 2019-03-24 00:15:16 +00:00
kris 21a4ac0186 Fix video termination logic 2019-03-24 00:14:41 +00:00
KrisKennaway bb3f2e4a4c
Add some more details 2019-03-24 00:03:04 +00:00
KrisKennaway 403915d783
Create README.md 2019-03-23 23:48:55 +00:00
kris dd422d1156 Fix tests 2019-03-23 22:05:36 +00:00
kris 13fb9c3125 Clean up module and abort import if we are unable to find the address
of an opcode.
2019-03-23 22:01:49 +00:00
kris 531a6ae345 Allow player to exit cleanly
- can't emit Terminate opcode in the middle of the bytestream
- pad the TCP stream to next 2k boundary when emitting terminate opcode,
  since the player will block until receiving this much data.
2019-03-23 21:46:35 +00:00
kris 8ffc8efaac Install RESET handler that exits to ProDOS
Implement op_terminate which waits for a keypress and then exits.
2019-03-23 21:45:13 +00:00
kris 8174d853f9 Downsize image using LANCZOS resampler. 2019-03-22 00:06:29 +00:00
kris f37d07914d Print input frame rate, and default to every_n_video_frames=2 which
gives better quality without compromising frame rate too much.
2019-03-21 23:25:51 +00:00
kris eebbccf711 Add some docstrings
Clean up naming in edit_distance

In video encoder, when we emit additional offsets as part of an opcode,
reinsert back into the priority heapq if the new edit distance is
nonzero, in case we get the chance to fix it up later in the frame.

Also make sure to zero out the diff_weights and content_deltas
so we don't consider the offset again as a side-effect of some other
opcode.

Instead of prioritizing side-effect offsets by their previous update
priority, prioritize by those with the lowest (error - edit) delta i.e.
not introducing too much error relative to their edit distance.
2019-03-21 22:56:45 +00:00
kris fe10f98128 Support skipping frames from the input video to increase output
image quality at the expense of frame rate.
2019-03-21 22:43:02 +00:00
kris 8bdad22162 Stop ticking cycles as part of emitting the opcodes, we are counting
them externally in audio.py now.

Add some docstrings
2019-03-21 22:42:09 +00:00
kris ce078f493f Start to flesh out function docstrings, add some more type annotations. 2019-03-21 22:41:05 +00:00
kris da2e2476e7 Rename tests and clean up a bit. Still don't pass. 2019-03-21 17:21:43 +00:00
kris 5a5c761183 Remove _END from opcode.
Don't set cls in outer module scope
2019-03-21 17:15:44 +00:00
kris 84e14efc57 Fix 2019-03-21 16:51:33 +00:00
kris 5411793ea4 factor out State and CycleCounter to a new machine module and rename 2019-03-21 16:48:02 +00:00
kris cf493e782c Add module docstrings 2019-03-21 16:42:47 +00:00
kris 5d4148daaf No need to store opcode _END any more 2019-03-21 16:35:42 +00:00
kris 7164f20eab Oops fix byte ordering for port 2019-03-21 16:35:12 +00:00
kris fb47e48e4a Fix imports and point to player debug symbols 2019-03-21 16:24:40 +00:00
kris d55ee0e170 Rename binary 2019-03-21 16:23:56 +00:00
kris bbfcacd674 Move transcoder to new location 2019-03-21 16:10:16 +00:00
kris 4ae5e7a153 Move player to new location 2019-03-21 16:09:23 +00:00
kris 2f88408c23 Style 2019-03-21 16:04:26 +00:00
kris 0d54f182f5 Whitespace 2019-03-21 16:02:18 +00:00
kris 44c1216542 Rename byte_to_colour_string -> byte_to_nominal_colour_string and
introduce an attempt at post-processing the colour artefacting that
results in coalescing adjacent '1' bits into white pixels.  This is
an incomplete modeling even of this artefact, let alone the other
various fringing weirdness that happens for e.g. NTSC rendering (which
is not faithfully reproduced by Apple //GS RGB display, so hard for me
to test further)
2019-03-21 15:59:56 +00:00
kris 4c168721bb - Don't hardcode clock speed
- Commented-out experimentation with using hitherdither library to
use yliluoma dithering (see
https://bisqwit.iki.fi/story/howto/dither/jy/) instead of the
(error-diffusion) based BMP2DHR which introduces a lot of noise between
frames since it is easily perturbed.

Unfortunately apart from being extremely slow, it also doesn't give
good results, even for (simulated) DHGR palette.  There's a lot of
banding and for HGR the available colours are just too far apart in
colour space.

This is even without (somehow) applying the HGR colour constraints.

- Also return the priority from _compute_error as preparation for
reinserting the offset back into the priority heap, in case we can do
a better job later.  In order to do this properly we need to compute
both the error edit distance and the "true" edit distance and only
insert the priority of the latter.
2019-03-21 15:57:09 +00:00
kris 8f6aa019b6 Remove old player 2019-03-21 15:43:09 +00:00
kris 065d9dddf8 Move server file into subdir 2019-03-21 15:37:51 +00:00
kris 0732e2c067 Remove unneeded assert 2019-03-21 15:36:29 +00:00
kris c4ed5f3d0a Remove files no longer in use. 2019-03-21 15:35:55 +00:00
kris c8942ba138 Add cc65's LOADER.SYSTEM to the base disk image so we can use it to
bootstrap the player.
2019-03-21 15:28:41 +00:00
kris 341c645c12 Reorder a bit to put the configurable bits at the top. 2019-03-21 15:27:24 +00:00
kris c53cf76df0 Switch to argparse and parametrize some flags 2019-03-21 15:26:00 +00:00
kris 0a9e83fa22 Listen on all interfaces, switch to port 1977 and use argparse instead
of sys.argv.
2019-03-21 15:25:06 +00:00
kris 92e1247c63 Add more comments and clean up timings for op_ack. Magically,
this all fits in exact multiples of 36/37 ticks!
2019-03-15 22:42:33 +00:00
kris b3ba069b2d - Improve comments and clean up a bit
- un-orphan the code that sets up 5 connection retries

- Pad CHECKRECV loop to 36,37,36,37 tick cycles
2019-03-15 22:18:03 +00:00
kris fffd05f4d1 Don't schedule a NOP for TCP frame padding; instead just have the ACK
include the 2 dummy reads.
2019-03-15 21:09:45 +00:00
kris 7343aa39ed Fix 2019-03-15 21:08:31 +00:00
kris 2092ef0926 - Add some comments
- Change ACK code to perform two dummy stream reads rather than relying
  on a preceding NOP to pad the TCP frame to 2K.  This fixes the timing
  issue that was causing most of the low-frequency ticks.

- Ticks still aren't perfectly aligned during the ACK slow path but
  it's almost good enough, i.e. probably no need to actually bother
  optimizing the slow path more.
2019-03-15 21:08:06 +00:00