requiring callers to keep track of it
- stop trying to cache content_deltas, I think it results in losing
deltas. Instead just recompute the deltas for each page as we need
it. This is fast enough in practice.
- track the average fill rate for the additional offsets we emit.
This should be close to 3 if we're succeeding in finding enough
collateral work
- overhaul how we pass in the target memory maps. The previous way
didn't make sense: we weren't actually encoding for the target video
frame, but were using an inconsistent mix of old and new frames. I
think this was causing image artifacting because we were aiming for
the wrong thing.
- Add some debugging assertions that were used to track this down.
requiring callers to keep track of it
- stop trying to cache content_deltas, I think it results in losing
deltas. Instead just recompute the deltas for each page as we need
it. This is fast enough in practice.
- track the average fill rate for the additional offsets we emit.
This should be close to 3 if we're succeeding in finding enough
collateral work
- overhaul how we pass in the target memory maps. The previous way
didn't make sense: we weren't actually encoding for the target video
frame, but were using an inconsistent mix of old and new frames. I
think this was causing image artifacting because we were aiming for
the wrong thing.
- Add some debugging assertions that were used to track this down.
make_edit_distance
- use MASKED_DOTS since it does not have a simple relationship to the
HEADER_BITS/BODY_BITS for HGR
- try disabling transposition distances for Damerau-Levenshtein, this
may give better quality
screen
- introduce separate notion of MASKED_DOTS which is the number of
(coloured) pixels we can extract from MASKED_BITS. For HGR this is
not the same.
- fix bug in _fix_array_neighbours that was not fixing headers for HGR
- don't cache everything in byte_pair_differences, it's effectively
unbounded. Using 1M for LRU size seems to work just as well in
practise, without leaking memory.
- fix bug in _diff_weights when comparing content, we want to evaluate
the effect of storing content byte in each offset separately, not
cumulatively.
- add a consistency check function (not currently wired up) to assert
that headers/footers are in sync across columns
- HGR should have 16 body bits, this was causing headers not to
propagate correctly to/from neighbouring column
- add test case for this bug
video
- Use 8 random bits consistently, using 16 in some places may have
introduced bias
- ignore palette bit when comparing 0x00 and 0x7f in sanity check
packed representation (diff, apply etc). This allows the (D)HGRBitmap
classes to focus on the bitmap packing and share common logic.
Numpy has unfortunate long-standing bugs to do with type coercion of
np.uint64, which leads to spurious "incompatible type" warnings when
e.g. operating on a np.uint64 and some other integer type. To work
around this we cast explicitly to np.uint64 everywhere.
Get tests working again - for now HGR tests in screen_test.py are
disabled until I finish implementing new packing.
HGRBitmap is still incomplete although closer.
- naive version of NTSC artifacting, it uses a sliding 4-bit window to
assign a nominal (D)HGR colour to each dot position. A more
sophisticated/correct implementation would model the YIQ signal
directly.
- Switch DHGRBitmap implementation to use a 34-bit representation of
the 4-byte tuple, comprised of a 3-bit header and footer, plus
4*7=28-bit body. The headers/footers account for the influence on
neighbouring tuples from the 4-bit NTSC window.
- With this model each screen byte influences 13 pixels, so we need to
precompute 2^26 edit distances for all possible (source, target)
13-bit sequences.
- Checkpointing not-yet-working HGR implementation.
- Add new unit tests but not yet all passing due to refactoring
IIGS palettes.
Move the palette diff_matrix generation into make_data_tables.py since
that is the only place it is used.
Demand-load the edit distance matrices when transcoding.
Add a test case that the bmp2dhr output of input filenames containing
'.' are handled correctly.
Break out video.Mode into video_mode.VideoMode to resolve circular
dependency.
- Extract out a (File)FrameSequencer class from Video to encapsulate
the generation of still frames. This also makes Video easier to test.
- Fix FileFrameSequencer.frames() to correctly handle filenames
containing '.'
- Temporarily switch to the BMP2DHR NTSC palette (#5) for evaluation.
Video:
- Temporarily hardcode DHGR decoding
- Optimize _heapify_priorities() by using numpy to vectorize the
construction of the list of tuples. This requires changing the
random nonce to an int so the intermediate array has a uniform type.
- Use the efficient 28-bit representation of DHGR (aux, main, aux,
main) tuples introduced in DHGRBitmap to evaluate diffs
- Switch to np.int type for accumulating diffs, and random.randint(0,
10000) instead of float for nonce values.
- Fix/improve some of the error evaluation in _index_changes:
- skip offsets whose diffs have already been cleared
- hoist some stuff out of _compute_error into the parent
- Add some validation that when we run out of work to do with a frame,
the source and target memory maps should be equal. This isn't
happening sometimes, i.e. there is a bug.
Switch from 14340Hz to 14700Hz, which is 44100/3 i.e. a divisor of the
most common audio input sample rate. This gives better quality
(and/or faster to encode) audio quality at the cost of producing <2%
faster playback.
IIGS palettes.
Move the palette diff_matrix generation into make_data_tables.py since
that is the only place it is used.
Demand-load the edit distance matrices when transcoding.
Add a test case that the bmp2dhr output of input filenames containing
'.' are handled correctly.
Break out video.Mode into video_mode.VideoMode to resolve circular
dependency.
- Extract out a (File)FrameSequencer class from Video to encapsulate
the generation of still frames. This also makes Video easier to test.
- Fix FileFrameSequencer.frames() to correctly handle filenames
containing '.'
- Temporarily switch to the BMP2DHR NTSC palette (#5) for evaluation.
Video:
- Temporarily hardcode DHGR decoding
- Optimize _heapify_priorities() by using numpy to vectorize the
construction of the list of tuples. This requires changing the
random nonce to an int so the intermediate array has a uniform type.
- Use the efficient 28-bit representation of DHGR (aux, main, aux,
main) tuples introduced in DHGRBitmap to evaluate diffs
- Switch to np.int type for accumulating diffs, and random.randint(0,
10000) instead of float for nonce values.
- Fix/improve some of the error evaluation in _index_changes:
- skip offsets whose diffs have already been cleared
- hoist some stuff out of _compute_error into the parent
- Add some validation that when we run out of work to do with a frame,
the source and target memory maps should be equal. This isn't
happening sometimes, i.e. there is a bug.
- 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.
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.