diff --git a/changes-and-fixes.txt b/changes-and-fixes.txt deleted file mode 100644 index 85dd656..0000000 --- a/changes-and-fixes.txt +++ /dev/null @@ -1,198 +0,0 @@ -================================================================================ - MEDIABUNNY HLS BRANCH - BUG FIXES AND BEHAVIOR CHANGES TO EXISTING CODE - For use in release notes. Only covers changes to pre-existing code. - New HLS/CMAF features are not listed here. -================================================================================ - - -============================================================ -BUG FIXES -============================================================ - -1. SourceRef race conditions (commit aa810fc) - - Source cache entry was added BEFORE the reference was fully created, - allowing premature garbage collection of cached sources - - Cache eviction variable pointed to wrong ref (local instead of entry) - - `count > MAX_SOURCE_CACHE_SIZE` off-by-one -> `count >= MAX_SOURCE_CACHE_SIZE` - - Input.source and Input.target getters could return unused/stale instances - when using async callbacks; now properly tracked via _getRootSourceRef() - -2. Track closing race conditions in all muxers (commit 94678dd) - - ISOBMFF, Matroska, MPEG-TS, and OGG muxers used `trackData.track.source._closed` - to check if tracks were closed. This was racy because the closed state could - change between check and use. Added explicit `closed: boolean` field to all - muxer track data structures, set synchronously in onTrackClose(). - -3. Target.slice() validation bug (commit 7b70756) - - Validation used `!Number.isInteger(offset) && offset < 0` (AND), meaning - negative non-integer offsets slipped through. Fixed to use OR (`||`). - -4. MPEG-TS demuxer: off-by-one errors in reorder buffer logic - - Rewind loop changed from `reorderSize` to `reorderSize + 1` iterations, - fixing packet duration calculation near seek points - - End-of-stream rewind loop changed from `reorderSize - 1` to `reorderSize` - - Flush condition changed from `>= reorderSize` to `> reorderSize`, keeping - one extra packet in the buffer before flushing for correct presentation - order computation - -5. MPEG-TS demuxer: first chunk assertion crash (line 1031-1035) - - Old code asserted that a key frame is always found in the first chunk, - crashing on files where that assumption doesn't hold (e.g., HLS segments - starting mid-GOP). Changed to gracefully return null. - -6. MPEG-TS demuxer: video parameters only searched in first packet - - Some muxers place SPS/PPS in later packets. The demuxer now loops through - multiple packets to find AVC/HEVC decoder configuration records instead of - only checking the first one. - -7. ISOBMFF: duration calculation didn't account for sample duration - - `lastPresentedSample()` found the sample with the highest timestamp but - didn't add its duration. Replaced with `presentationSpan()` that correctly - computes `maxEndTimestamp - minTimestamp`. - -8. ISOBMFF demuxer: assertion crash on unavailable data - - Demuxer asserted that read slices are non-null. Changed to gracefully - return null when data is outside available range (important for streaming/ - progressive scenarios). - -9. ISOBMFF demuxer: multiple trun boxes per fragment rejected - - Old code logged a warning and skipped the second trun box. Now correctly - accumulates samples across multiple trun boxes per track per fragment, - maintaining cumulative offset and timestamp state. - -10. Conversion API: track count validation before fan-out consideration - (commit 2f576aa) - - Tracks were validated against the max count before considering that some - track options had `discard: true`. Now validates inside the fan-out loop. - -11. MP3 muxer: frame positions recorded at wrong offset - - Frame byte positions were recorded AFTER writing packet data. Now recorded - BEFORE writing, which is correct for Xing TOC frame offset calculations. - -12. FLAC demuxer: missing STREAMINFO validation - - Added explicit error when STREAMINFO metadata block is missing, - producing a clear "Corrupted FLAC file" message instead of undefined - behavior downstream. - - -============================================================ -BEHAVIOR CHANGES -============================================================ - -1. Default keyFrameInterval changed from 5 seconds to 2 seconds - (commit c6e505a) - Aligns with default HLS segment duration. Affects all video encoding - that doesn't explicitly set keyFrameInterval. - -2. Conversion API copies input pairability graph by default (commit 6410ea9) - When track group is not explicitly specified, conversion now auto-creates - OutputTrackGroups that mirror the input track pairing relationships. This - means converted outputs preserve which tracks are meant to play together. - -3. Matroska demuxer: removed implicit track sorting by default disposition - Tracks are no longer sorted so that default=true tracks come first. - Now all tracks have `primary: false` by default. Callers should use the - getPrimaryVideoTrack()/getPrimaryAudioTrack() methods for selection. - -4. Removed superfluous end-position seeks in muxer finalize methods - (commit 7b70756) - MP3, FLAC, and Matroska muxers no longer seek to the end of file after - writing final metadata. The seek was unnecessary since the writer is - done at that point. - -5. clampCropRectangle now returns a new object instead of mutating input - (src/sample.ts:1123) - -6. Date.now() -> performance.now() in FinalizationRegistry callback - (src/sample.ts:48) - Uses monotonic time for timing measurements. - -7. Codec string parsing: mp4a.40.34 now correctly identified as MP3 - (src/codec.ts:677-686) - Previously would have matched the aac prefix check. MP3 check now - runs first and includes this codec string. - -8. UrlSource: servers without Content-Length now supported - Previously, if the server returned 200 without a Content-Length header, - UrlSource threw an error. Now it gracefully handles this by downloading - the entire resource with an unbounded worker (targetPos = Infinity, - strictTarget = false), determining file size once the stream ends. - -9. UrlSource: file size probing request removed - The old UrlSource always made a dedicated initial `Range: bytes=0-` - request solely to probe file size and range request support. File size - is now determined lazily from the response headers of the first actual - read, removing the extra round-trip. - -10. UrlSource: non-range-request server warnings deduplicated per origin - The "server did not respond with 206 Partial Content" warning is now - emitted at most once per origin instead of on every request. - -11. ReadableStreamSource: reader now canceled on dispose - ReadableStreamSource._dispose() now calls `this._reader?.cancel()`, - properly releasing the underlying stream resource. - -12. ReadOrchestrator: worker queue system - When the maximum worker count is reached, reads are now queued and - dispatched when a worker becomes free, instead of evicting running - workers which could abort in-flight fetches. - - -============================================================ -DEPRECATIONS -============================================================ - -1. InputTrack sync property getters (commit 051578c) - All sync getters on InputTrack/InputVideoTrack/InputAudioTrack are now - deprecated in favor of async methods: - .codec -> await .getCodec() - .languageCode -> await .getLanguageCode() - .name -> await .getName() - .timeResolution -> await .getTimeResolution() - .disposition -> await .getDisposition() - .displayWidth -> await .getDisplayWidth() - .displayHeight -> await .getDisplayHeight() - .rotation -> await .getRotation() - (etc.) - The sync getters still work for non-HLS inputs but throw when the - backing requires async resolution (e.g., HLS tracks before hydration). - -2. Source.onread callback -> source.on('read', handler) - The onread setter still works but is marked @deprecated. - -3. Target.onwrite callback -> target.on('write', handler) - Same as above. - - -============================================================ -REMOVALS -============================================================ - -1. Target.onfinalized callback (commit 6410ea9) - Removed entirely. Use the 'finalized' event: target.on('finalized', ...). - -2. InputTrackDescriptor concept (commit 051578c) - The entire InputTrackDescriptor API was removed. Its functionality - (pairable tracks, primary track selection) is now directly on InputTrack. - -3. InputTrack[] option for ConversionOptions.tracks (commit 606ee87) - ConversionOptions.tracks now only accepts 'all' | 'primary', no longer - accepts an array of InputTrack instances. - -4. Unnecessary sync getter wrappers (commit 8241820) - Removed deprecated sync getters for: hasOnlyKeyPackets, bitrate, - averageBitrate, isRelativeToUnixEpoch on InputTrack. - - -============================================================ -API ADDITIONS (for context, not release-note-worthy on their own) -============================================================ - -- PacketRetrievalOptions.skipLiveWait (fixes #342) -- DiscardedTrack.trackOptions field -- TargetRequest.mimeType -- TrackDisposition.primary -- Source/Target/Output extend EventEmitter -- CanvasSink methods now async generators (getCanvas, canvases, canvasesAtTimestamps) -- EncodedPacketSink.getFirstPacket/getPacket/getNextPacket now async -- Muxer writers deferred to start() instead of constructor