The SID codec never finishes on its own, so test_codec would decode
forever and a directory test would stall on the first SID file. Count
the decoded samples and halt the codec after 120 seconds of audio. Also
set the track length to that limit so the benchmark results are correct
and show the elapsed time while decoding.
Fixes FS#13662
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I4e7e99bf41d00c5597aae9d48b837e28df5b75c0
The rows that calibrated the Clip+ model in utils/perfsim, timed on
AS3525v2 with the tick timer's count for a 2/3 microsecond clock:
- calls, returns and loads into pc, interlocks after a load and
after a multiply, multiplies by operand size
- a miss with work after it, on each word of its line, back to
back, and evicting a dirty line; a load or store to the line
still filling
- stores to lines not cached: one stream, a word a line, four
words at a time, two streams turn about
- copies between uncached buffers, within a memory and across
- fetch misses in code written where it runs
- loops of adds and of branches by how many lines they cover, and
a cached pointer chase likewise
- the TTA filter stage by stage and Tremor's window loop
On AS3525v2 the miss rows run in DRAM and again in the RAM inside
the SoC, where codecs are loaded.
Rows that turned out to say nothing, or that a later row replaced,
stay in the file under TEST_CYC_ARCHIVE, each with why.
TEST_CYC_QUICK runs only the newest rows.
With these rows the plugin is about 140 KB on ARMv5, so it is left
out where the plugin buffer is 128 KB or less: the Clip, the m200v4
and the c200v2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I4ec45da514d0abaa02e1e041fd1a0387490994ed
A test plugin that measures what ARM instructions cost on the running
device. Each row times sixteen copies of one instruction in a loop and
subtracts the empty loop, giving cycles per instruction. Where plugins
get IRAM, each row is run with code and data in each combination of
IRAM and DRAM.
It covers ALU, shifts, branches, the load and store forms (including
halfword and register-offset loads), load-use, and the multiplier at
narrow and full-width operands. ARMv5 adds the DSP multiplies, clz,
qadd, ldrd/strd and pld; ARMv6 adds the top-word and dual 16-bit
multiplies, umaal, ssat, rev, the extends, pkhbt, the SIMD adds and
multiply result latency. Cache misses are priced by a pointer chase
and by sequential streams over working sets either side of the cache.
Timing uses the SoC's microsecond counter on PP502x, PP5002, S5L870x,
S5L8720, TCC7801 and i.MX233, and the tick elsewhere. Results go to
the screen and to /test_cyc.txt.
Built only with test plugins enabled, on native ARM targets that run
ARM code (not Cortex-M).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I4a41f6daaa27fb817f411de89901a117c5c70f4d
When the text reached the bottom of the screen it started again at
the top, over what was there, so the old lines showed through the
new. Scroll up a line instead, as test_codec does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I024eda05bbcca6f1539893ea609c89f562436e2f
The tests always ran on HOME_DIR, so a card could not be tested, and
the internal storage could not be left alone.
Where there is more than one volume the plugin now asks which to
test when it starts: HOME_DIR as before, or any volume the root
directory lists. "Select disk" in its menu changes it. The test
directory, the test file and the log are all on the disk chosen,
where the log used to go to HOME_DIR, so that testing a card writes
nothing to the internal storage. The log names the disk.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ib243fdd32fa205e00bc2b39d776e0fc8a420a1f0
The DSP gets its output samplerate from the codec thread when a
track is played. test_codec did not set it, so its runs with the
DSP used the rate of the last track played, or the default if
there was none: after "Playback frequency" was changed, they
resampled to the old rate until something had been played.
Set it from the mixer for each file, as the codec thread does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Checksum with DSP" and "Checksum folder with DSP" give the CRC32
of the DSP's 16-bit output for a file or a folder, as "Checksum"
does for the codec's output. That lets the DSP of a device, with
its settings, be checked against a reference for several files in
one run; "Write WAV with DSP" writes one file, /test.wav.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both decoders rejected extended sequential JPEGs (SOF1), which are
baseline files in all but name when they have 8-bit samples, and
16-bit quantization tables, which libjpeg writes for very low
quality settings unless told to force baseline.
Accept SOF1 with 8-bit samples, and read 16-bit table entries. The
core loader keeps its tables in 16 bits and scales them for the IDCT,
so it rejects entries over 8191; libjpeg's largest at quality 1 is
4950. Files using more than two Huffman tables are still rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I705a61402b4a0ab252995f8559b7ff2f68b05d72
A file's length and first cluster are only written to its directory
entry when it is closed, and the log was closed at the end of
plugin_start() alone. Leaving by USB or by power off goes through
exit() instead, so a whole run's log could be left as an empty file
with its data in clusters nothing pointed to.
Close the log from an atexit handler, close it when a run over a
folder ends, and close and reopen it after each track so that at
most one result is lost if the player dies.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I613d0ad8c637d7f48a82eb09bc310c6fcc6d77f9
The results were drawn right after backlight_on(), which only queues
a request to the backlight thread. lcd_update() does nothing while the
LCD is off, and the plugin then blocked waiting for a key without
updating again, so the display could keep showing the last progress
line. Refresh the display periodically while waiting for a key.
Also scroll the log up when the screen is full instead of wrapping
around to the top and overwriting old lines, which made the output
hard to read when testing a whole folder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On colour targets the image viewer hands every file its own decoder
rejects to jpegp, including damaged ones, but jpegp barely checks its
input. Corrupt and truncated files crashed or hung it:
- At the end of the file GETC() kept returning stale bytes, so marker
searches and table reads never ended. Feed EOI markers (FF D9)
instead, which ends every loop, and stop calling read() there. This
state is reset in OPEN(): the overlay loader does not clear .bss.
- A file ending before any scan decoded as a blank image. Report it as
corrupt instead.
- Out of range header values were used as array indexes: Huffman and
conditioning table IDs, Huffman table sizes, sampling factors, scan
component counts and spectral selection. Reject them, and frames of
zero width or with no components.
- Invalid Huffman codes walked past the code length table, run lengths
wrote past coefficient 63, and huge coefficients indexed past the
IDCT clamp table. Bound all three.
- An odd DAC segment length never ended its loop.
- The coefficient buffer size could overflow an int.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I49465f38d283e159274d2f381029280cea42a8f1
jpegp converted every image from YCbCr, so RGB JPEGs showed scrambled
colours. That affects progressive RGB files, and now also baseline RGB
files the jpeg decoder rejects and hands on to jpegp, such as RGB with
the R component sampled 2x2.
Record the JFIF and Adobe APP14 markers, decide the colour space with
the same rule as the other decoders, and skip the YUV conversion for
RGB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: If023eeb612b7f8a891d21fbe0070ab43c5a08f17
Both decoders treated every 3-component image as YCbCr, so RGB JPEGs
(as written by cjpeg -rgb, and by some Adobe software) came out with
wrong colours.
Decide the colour space as libjpeg does: a JFIF marker means YCbCr;
otherwise the transform flag of an Adobe APP14 marker decides (0 is
RGB); otherwise component IDs 'R', 'G', 'B' mean RGB.
Core loader: on colour targets R, G and B are stored in place in the
row buffer and the YUV conversion is skipped. Greyscale builds now
also decode G and B for RGB and combine them into luma per block,
which needs every component to be one block per MCU; other RGB
layouts are rejected there.
Plugin: RGB needs one block per MCU for every component, otherwise it
is rejected (colour targets fall back to jpegp). Colour builds convert
the R, G and B planes to YCbCr in place after decoding, so display and
greyscale view modes are unchanged; greyscale builds combine R, G and
B into luma per block as the core does.
Code size on the e200: core loader +351 bytes, plugin decoder +603
bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ib24a0b7690ca4c00b3ac01b2f511309efeac5975
Seven plugins have no layout or bitmaps for a 400x240 landscape
screen - the Samsung YP-CP3's, which no target building plugins has had
in that orientation. Give each the 320x240 one: the same height, and
centred in the 80 pixels more width wherever a 320x240 background has
to line up with it.
- bubbles, invadrox, rockblox: the 320x240 layout and background,
centred; the margins are cleared
- sudoku, jewels: the 320x240 bitmaps; their layouts already centre
themselves or use the width
- superdom: the 320x240 box size and board items - boxes as wide as
the screen allows make the board taller than it
- wormlet: the sizes of 320x240
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I223154da5da2250ba0f6068106ba9bec242a29ee
Five layouts define SCORENUM_Y as SCORE_Y + (...) unbracketed, so the
playfield update after each frame, PLAYFIELD_Y + 1 - SCORENUM_Y -
FONT_HEIGHT high, added that part rather than subtracting it: on a
240-line screen it ran 25 lines past the bottom. Most LCD drivers clip
it; the rk27xx one did not, and nothing in the playfield moved.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Icecf7780d81595db9d6e42125fc421cc1cb40339
Damaged and truncated JPEGs could make the image viewer read or write
outside its buffers:
- process_markers() trusted segment lengths, and Huffman table symbol
counts, so a segment running past the end of the file was parsed
from whatever memory followed it. Check that each marker segment,
and each Huffman table in it, lies within the file.
- A file without a complete SOS header was decoded from a NULL entropy
data pointer, as load_image() checked only for DQT and SOF. Require
SOS as well.
- img_mem() computed the image size in an int, which overflows for a
large image (a 65535x65535 file came out as 0), so the decode wrote
far past the buffer. Compute it in 64 bits and saturate.
Found with the jpeg-conformance files of the imazen codec-corpus,
which include truncated files and files from fuzzing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I1e2a9a4346fd1c0e34b0813267c6317dbf704bc7
Both JPEG decoders accepted several baseline layouts they cannot decode
and produced garbage without an error:
- chroma with sampling factors other than 1x1 (the MCU layout is chosen
from luma alone, so any other chroma layout desynchronises)
- files written as more than one scan, where the first scan does not
hold every component (it was decoded as if it were interleaved)
- scans whose components are not in frame order
- a height of 0 in SOF, to be defined later by a DNL marker
Reject these in process_markers(). The imageviewer then falls back to
the jpegp decoder on colour targets, which handles all of them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ia3373f2b934eef6e3f354b4d064faf2d89868050
Both JPEG decoders ignored the Tq selector in the frame header and
always dequantized luma with table 0 and chroma with table 1. Files
with a single shared table multiplied chroma by an empty table, and
files with separate Cb and Cr tables used the wrong one for Cr.
imageviewer/jpeg: build one dequantization table per component (3
instead of 2, +256 bytes) from the table it selects. tab_membership is
no longer used and is removed.
Core loader: the raw tables are pre-scaled in place for the IDCT, and
luma and chroma can use different IDCT scales. fix_quant_tables() now
maps each component to a table slot, copying a table that luma and
chroma share at different scales to a slot no component uses (there are
4 slots and at most 3 components, so one is always free), and rewrites
quanttable_select to that slot. No extra memory.
Selectors above 3 are rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: If04c61fb0fef95da11d98d9918ea7225d8a440b0
Both JPEG decoders ignored the DC/AC table selectors in the SOS header
and always decoded luma with tables 0 and chroma with tables 1, the
layout libjpeg writes by default. Files where all components share
table 0, or where the slots are assigned differently, decoded to noise.
Look up each component's tables from its selectors instead. Baseline
JPEG only allows tables 0 and 1, which both decoders already hold, so
this needs no extra memory; selectors above 1 are rejected. In the core
loader tab_membership is no longer used and is removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ie1ec407ddecf1256fef410b1256b97af412fb194
The bit reader refilled from the input buffer without checking its end.
The end-of-data check in the decode loops only runs once per MCU row, so
a stream that desynchronises (or is truncated) read past the end of the
file buffer for the rest of the row. Return zero bytes past the end
instead; the pointer still advances so the per-row check stops the
decode.
Found with AddressSanitizer on a JPEG whose chroma is sampled more
densely than its luma.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Iaada1bc3cbf62b18f10fb2377c12d4d5cb9524de
A single-component (grayscale) scan is non-interleaved, so its MCU is
one 8x8 block regardless of the sampling factors in the frame header
(T.81 A.2.2). Some encoders write H=2,V=2 for the lone component, which
sent both the imageviewer plugin decoder and the core loader down the
4:2:0 path: 6 blocks per 16x16 MCU, the image treated as colour, and
the entropy data overrun.
Force 1x1 sampling for single-component frames when parsing SOF0 so
these images use the 4:4:4 layout with one block per MCU. Also add the
missing else in fix_headers() in the core loader, matching the plugin.
Tested on a Sansa e200 with both the plugin and the core loader, and
the plugin in the e200 simulator and built for PC and for ARM (qemu).
Fixes FS#13749.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Iac2f925aab8cd602930470dca5da7dfb44e15961
Move the iriver-specific functions for detecting flashed
Rockbox/OF images into system-iriver.c and remove the
HAVE_FLASHED_ROCKBOX define which is now redundant (all
targets using system-iriver.c enable it).
Copyright attribution on the new system-iriver.h header
is a best guess from Git history.
Change-Id: If1933f881a63fd517162ab9ca8f4a3007b997739
Some files were not using the standard header with the
Rockbox logo. Add this and move any technical notes into
a separate comment.
Change-Id: Idaac932cd56154c7b785ba0e6c0231a21878f786
Most of the churn here occurs because 'filesize' is one of
the redefined filesystem functions, but some of the structs
used by the native FS code also include a 'filesize' member
variable which gets renamed by the macro in some but not all
source files.
It's easier to rename 'filesize()' to 'ffilesize()' rather
than try to clean up the macro mess or renaming the struct
members.
There is weirdness with root_realpath() which now breaks on
native builds because it was assumed to be unprefixed there.
dir_get_info() was unprefixed everywhere but this just seems
inconsistent; make it follow the FS_PREFIX() convention too.
Change-Id: Ic3700c6234ea45f32679c1a8429d70fdb8f4088a
backlight_on_button_hold / remote_backlight_on_button_hold
were never added to the Plugin API nor backlight_use_settings() helper
Change-Id: I75999af76f98244a870ab86564e591c8a900e66c
Add S5L8702 VPU-B initialization, reset, bitstream input, frame output,
and cache maintenance to the iPod 6G target. Advertise it with
HAVE_HW_H264 and append a capability-gated decoder interface to the
plugin API.
Keep MP4 parsing, AAC decode and mixer output, A/V synchronization,
playback controls, resume state, and presentation in the multi-file
h264_player plugin. The target layer exposes decoder operations only.
Accept non-fragmented MP4/M4V containing Constrained Baseline H.264
through level 3.0, up to 640x480 at 30 fps, with optional AAC-LC audio.
Validate codec configuration and all sample-table relationships before
activating the hardware.
Read MP4 tables in bulk, boost the CPU while preparing them, and report
staged loading progress so long movies do not appear to hang during
startup.
Register the viewer and document its format limits and controls. The
libm4a compatibility fixes needed by video-first containers remain in
the preceding standalone change.
Tested on an iPod Classic 6G through an isolated Rolo nightly runtime:
H.264/AAC playback and M4V startup succeeded. Normal and
isolated-runtime iPod 6G builds also complete, and git diff --check is
clean.
Change-Id: I1e96c65c7d0b4231a94f602f8052f1b26d6e4a80
Listen to GUI_EVENT_NEED_UI_UPDATE events and redraw, so
screen doesn't disappear if a theme draws over the UI vp.
Occurs in situations when the SBS is redrawn after waking
the screen, or when the song changes.
Change-Id: I062e802959ab9d34d8c04b7f82da6b87efb5d739
importing discards duplicate entries based on context + action code
however you may want multiple entries to map to the same action
and you can't do it within the same context
instead only consider an entry as a duplicate if they have the same
context, actioncode, button, and prebutton
Change-Id: I5aba3459505987ba37e26758aec62f02fcf8165a
I intended to remove this in commit a8f8aa40b9 ("lastfm_scrobbler:
fetch rbversion from plugin API") but apparently forgot to do so,
so the scrobbler plugin was still rebuilding itself when RBVERSION
changes. Removing the header fixes that.
Change-Id: I6740d72ad35f5037a6a4a7580559a6c980b3225b
apps/plugins/lua/rockaux.c defines strerror() and strcoll() so the Lua
plugin has something to link against on native targets, which have no
libc providing them. Hosted targets do have a libc, and defining them
there is at best redundant.
On the Windows simulator it is worse than redundant. Both come from
mingw's libmsvcrt.a, and because that is a static archive the linker
pulls in an archive member for an unrelated symbol, then finds a second
definition of these two, so lua.rock fails to link:
libmsvcrt.a(...): multiple definition of `strcoll';
rockaux.o:rockaux.c:244: first defined here
libmsvcrt.a(...): multiple definition of `strerror';
rockaux.o:rockaux.c:47: first defined here
On hosted Linux there is no diagnostic, because glibc supplies these
from a shared library where a local definition simply wins. That means
the plugin has been quietly shadowing glibc's strerror() with a stub
that always returned NULL, which is presumably not intended either.
Guard both with CONFIG_PLATFORM & PLATFORM_NATIVE, matching the guard
used a few lines above for errno. Hosted targets now get the real
implementations from their own libc.
This also silences a "redeclared without dllimport attribute" warning
that GCC 16 emits for the same clash.
Verified by building xduoox3 as a Windows simulator, xduoox3 as a Linux
simulator, and sansaclip as a native ARM target: all three link cleanly
with no multiple-definition errors.
Provenance, per the AI disclosure requirement in docs/CONTRIBUTING: this
change was drafted with Claude Code (Anthropic Claude Opus 5) at my
direction. Patch set 2 adopts Aidan MacDonald's review suggestion to key
the guard off PLATFORM_NATIVE rather than _WIN32.
Change-Id: I8ffb6fd792147c9067afa708003b1285fb9d07a4
This commit does the following changes to the 3ds port:
- Rename the target from ctru to 3ds.
- Rename all files and functions with the ctru naming convention to 3ds.
- Created a new file and folder structure that will better integrate future console ports that share the same codebase.
- Fixed a buffer overflow bug in pcm code.
Change-Id: I17c6f86df64eb99dd2b653485d70832ff46b2ba8
This prevents needlessly rebuilding the plugin whenever
RBVERSION changes. (This was introduced by the removal
of CVS $Revision$ tags.)
Change-Id: Ic981c86319edb9c7eb7f0c1de71d4fbaba8989ac
HibyOS-based target: keymaps, LED, powermgmt, bootloader and sim support,
plus cabbiev2 for the new 360x640x16 screen. Opus 5 helped w/ debugging
and the initial scaffolding.
Updated name to FB_STRIDE_MISMATCH, added simulator bmp and specs.
Change-Id: If797ac6581cf75d9d1fcf36e615ee03cf6f905d6
use require "audio_status" to use the new AUDIO_STATUS_ defines
use require "file_attrs" to use the new FILE_ATTR_ defines
Change-Id: If0b3b612e92e9e5b361a9487ccca2d40f79a953e
when browsing the filename gets cut off due to the
length of the parent path
Instead strip the parent from the beginning for files
Change-Id: Ib9dadffabced89b5895420cb696227ca8cc444a2
get_files(path, recurse, finddir, findfile, sort_by, cancel_fn, f_t, d_t)
get_files returns a sorted tables of directories and (another) of files
path is the starting path; recurse == false.. only that path will be searched
findfile & finddir are definable search functions
if not defined all files/dirs are returned if false is passed.. none
or you can provide your own function
sort_by can be by "name" "size" "date" or "none" to perform no sorting
note: for "size" and "date" you may need to strip the attribute data to use
the returned filename
cancel_fn if not defined or not a function no user cancel otherwise supply
your own cancel function which returns true to cancel searching for files
f_t and d_t allow you to pass your own tables for re-use but isn't necessary
Change-Id: Ic4c2ad9c9b5abeeeeaf572880edbc8873d52066b