Sample two short windows before re-encoding a cached video and skip the full encode when HEVC will not save 15 percent
This commit is contained in:
@@ -38,6 +38,13 @@ beforeAll(async () => {
|
||||
'-c:v', 'libx265', '-preset', 'ultrafast', '-pix_fmt', 'yuv420p', '-tag:v', 'hvc1', '-x265-params', 'log-level=error',
|
||||
'-c:a', 'aac', '-shortest', fx('hevc.mp4'));
|
||||
ff('-i', fx('hevc.mp4'), '-c', 'copy', '-tag:v', 'hev1', fx('hevc-hev1.mp4'));
|
||||
// 64 s sources for the sample-first path (videos ≥ 60 s get sampled):
|
||||
// "fat" = far more bits than needed (HEVC will win), "lean" = already
|
||||
// starved (HEVC at CRF 28 can't beat it — like most YouTube encodes).
|
||||
ff('-f', 'lavfi', '-i', 'testsrc2=size=640x360:rate=24:duration=64', '-f', 'lavfi', '-i', 'sine=frequency=330:duration=64',
|
||||
'-c:v', 'libx264', '-preset', 'ultrafast', '-qp', '8', '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-shortest', fx('fat64.mp4'));
|
||||
ff('-f', 'lavfi', '-i', 'testsrc2=size=640x360:rate=24:duration=64', '-f', 'lavfi', '-i', 'sine=frequency=330:duration=64',
|
||||
'-c:v', 'libx264', '-preset', 'medium', '-crf', '44', '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-shortest', fx('lean64.mp4'));
|
||||
const buf = readFileSync(fx('good.mp4'));
|
||||
writeFileSync(fx('truncated.mp4'), buf.subarray(0, Math.floor(buf.length * 0.6)));
|
||||
// The nasty case: moov up front (index says 10 s) but the media data is cut.
|
||||
@@ -241,6 +248,34 @@ describe('media cache jobs', () => {
|
||||
expect(await cache.verify('optAAAAAAA1')).toBe(true);
|
||||
});
|
||||
|
||||
test('sample-first: a source HEVC cannot beat is skipped without a full encode', async () => {
|
||||
await clearDb();
|
||||
const lines = [];
|
||||
const { cache } = makeCache({ fixture: 'lean64.mp4', duration: 64, log: { info: (m) => lines.push(m), warn: (m) => lines.push(m) },
|
||||
transcode: { enabled: true, codec: 'hevc', crf: 28, preset: 'ultrafast', threads: 2 } });
|
||||
await cache.init();
|
||||
const first = await cache.ensureCached('sampAAAAAA1', { priority: HIGH });
|
||||
expect(await until(async () => (await dbmod.getMedia('sampAAAAAA1')).optimized === OPT_REV, 60000)).toBe(true);
|
||||
const after = await dbmod.getMedia('sampAAAAAA1');
|
||||
expect(after.gen).toBe(first.gen);
|
||||
expect(after.vcodec).toBe('h264');
|
||||
expect(lines.some((l) => /sample predicts/.test(l))).toBe(true);
|
||||
}, 90000);
|
||||
|
||||
test('sample-first: a source HEVC can beat gets the full encode and swaps', async () => {
|
||||
await clearDb();
|
||||
const lines = [];
|
||||
const { cache } = makeCache({ fixture: 'fat64.mp4', duration: 64, log: { info: (m) => lines.push(m), warn: (m) => lines.push(m) },
|
||||
transcode: { enabled: true, codec: 'hevc', crf: 28, preset: 'ultrafast', threads: 2 } });
|
||||
await cache.init();
|
||||
const first = await cache.ensureCached('sampAAAAAA2', { priority: HIGH });
|
||||
expect(await until(async () => (await dbmod.getMedia('sampAAAAAA2')).optimized === OPT_REV, 60000)).toBe(true);
|
||||
const after = await dbmod.getMedia('sampAAAAAA2');
|
||||
expect(after.vcodec).toBe('hevc');
|
||||
expect(after.gen).toBeGreaterThan(first.gen);
|
||||
expect(lines.some((l) => /sample predicts/.test(l))).toBe(false);
|
||||
}, 90000);
|
||||
|
||||
test('copies evaluated by an older lane revision are re-queued at boot', async () => {
|
||||
await clearDb();
|
||||
const seed = makeCache();
|
||||
|
||||
Reference in New Issue
Block a user