mirror of
https://github.com/infrost/RaptorQR.git
synced 2026-09-04 08:57:49 +08:00
Fix parityCount to use Math.floor, neededPackets to use totalGenerations
parityCount: Math.ceil → Math.floor - Small files (G ≤ 33) now truly get 0 parity generations - Large files (G ≥ 34) still get proportional parity (≈3%) - Previously Math.ceil always gave ≥1 parity for any G ≥ 1 neededPackets: K * sourceGenerations → K * totalGenerations - Aligns with the round-robin scheduler: symbols are interleaved across ALL generations, so practical minimum is K × totalGens - Fixes the mismatch where 'needed' showed 32 but actual decode required ~48 frames (for 2 source + 1 parity case) Tests: Updated assembly test comments and totalGenerations params to match new parityCount behavior. Closes the long-standing 'needed frames count is off because of outer error correction' issue.
This commit is contained in:
@@ -67,7 +67,7 @@ export const OUTER_EC_OVERHEAD = 0.03;
|
||||
|
||||
/** Compute number of parity generations for G source generations. */
|
||||
export function parityCount(sourceGenerations: number): number {
|
||||
return Math.ceil(sourceGenerations * OUTER_EC_OVERHEAD);
|
||||
return Math.floor(sourceGenerations * OUTER_EC_OVERHEAD);
|
||||
}
|
||||
|
||||
/** Compute source generation count from total generations. */
|
||||
|
||||
@@ -355,10 +355,10 @@ describe('Payload Assembly', () => {
|
||||
solved.set(0, g0);
|
||||
solved.set(1, g1);
|
||||
|
||||
// 2 source gens + 1 parity = 3 total. Both source gens present.
|
||||
// 2 source gens + 0 parity = 2 total (small file, no outer RS). Both source gens present.
|
||||
// dataLength spans into second generation so we can verify cross-gen assembly
|
||||
const dataLength = K * MAX_PAYLOAD_SIZE + 4;
|
||||
const data = assemblePayload(solved, 3, dataLength);
|
||||
const data = assemblePayload(solved, 2, dataLength);
|
||||
expect(data.length).toBe(dataLength);
|
||||
expect(data[0]).toBe(1);
|
||||
expect(data[1]).toBe(2);
|
||||
@@ -385,8 +385,8 @@ describe('Payload Assembly', () => {
|
||||
const solved = new Map<number, Uint8Array[]>();
|
||||
solved.set(0, g0);
|
||||
|
||||
// 1 source gen + 1 parity = 2 total. Source gen present.
|
||||
const data = assemblePayload(solved, 2, 3);
|
||||
// 1 source gen + 0 parity = 1 total (small file, no outer RS). Source gen present.
|
||||
const data = assemblePayload(solved, 1, 3);
|
||||
expect(data.length).toBe(3);
|
||||
expect(data[0]).toBe(1);
|
||||
expect(data[1]).toBe(2);
|
||||
@@ -403,7 +403,7 @@ describe('Payload Assembly', () => {
|
||||
const solved = new Map<number, Uint8Array[]>();
|
||||
solved.set(0, g0);
|
||||
|
||||
// 3 source gens + 1 parity = 4 total, but only 1 solved
|
||||
// 4 source gens + 0 parity = 4 total, but only 1 solved
|
||||
expect(() => assemblePayload(solved, 4, 3)).toThrow('only 1 generations solved');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -251,7 +251,7 @@ function reconstructData(state: DecodeState): void {
|
||||
function reportProgress(state: DecodeState): void {
|
||||
const totalGens = state.totalGenerations;
|
||||
const solvedGens = state.solvedGenerations.size;
|
||||
const needed = state.sourceGenerations > 0 ? K * state.sourceGenerations : 0;
|
||||
const needed = state.totalGenerations > 0 ? K * state.totalGenerations : 0;
|
||||
|
||||
self.postMessage({
|
||||
type: 'progress',
|
||||
|
||||
Reference in New Issue
Block a user