Repository navigation
Releases
Releases · lsegal/zvidlib
zvidlib v0.5.0
- Breaking: spell everything in American English, including public names (issue #657). The repository mixed British and American spellings; it now uses American spellings throughout, and
AGENTS.mdgives the rule. This renames these public items, with no deprecated aliases for the old names:zvidlib-core:ErrorKind::Cancelledis nowErrorKind::Canceled,CancellationToken::is_cancelledis nowis_canceled, andVp9CodecConfig::colour_primariesis nowcolor_primaries. In JavaScript, the error code for a canceled operation is now"CANCELED"instead of"CANCELLED".zvidlib-hevc-syntax:vui::ColourDescriptionis nowColorDescription(itscolour_primariesfield is nowcolor_primaries),VideoSignalType::colour_descriptionis nowcolor_description,sei::MasteringDisplayColourVolume(the struct and theSeiPayloadvariant) is nowMasteringDisplayColorVolume,SeqParameterSet::separate_colour_plane_flagis nowseparate_color_plane_flag,PpsSccExtension::residual_adaptive_colour_transform_enabled_flagis nowresidual_adaptive_color_transform_enabled_flag, andSliceSegmentHeader::colour_plane_idis nowcolor_plane_id. These HEVC syntax elements keep their specification meaning; only the spelling changed.zvidlib-hevc:engine::Neighbouris nowNeighbor,engine::motion::NeighbourPuandSpatialMergeNeighboursare nowNeighborPuandSpatialMergeNeighbors,SaoBoundaries::ctb_neighbourhood_unconstrainedis nowctb_neighborhood_unconstrained, and theresidual_adaptive_colour_transform_enabled_flagfields ofSliceDataParamsandTransformUnitParamsare nowresidual_adaptive_color_transform_enabled_flag.
Error and log messages change spelling too (for example,codec operation canceled), and the wording of earlier entries in this changelog was updated to match.
- Fix VP9 WebM files that zvidlib writes failing to play in Chrome when the stream is full range, as the browser's
WebCodecsencoder produces from canvas frames (issue #655).WebmMuxerwrote noColorelement, and Chrome takes a WebM VP9 track's color space from it rather than from the bitstream, so a<video>showed the first frame and then stopped with a decode error. A VP9 track now carries the range, primaries, transfer characteristics and matrix coefficients itsvpcCdeclares, andWebmDemuxerreads them back into the track'svpcC. The project website's "Record a canvas" demo now plays its VP9 WebM recordings. - The website's scrub demo resumes playback and synchronized audio from the selected frame after a timeline drag when it was already playing (issue #661). Paused scrubs stay paused, keyboard seeks continue playback immediately, and the mute setting is preserved.
- The project website's frame-exact scrubbing demo has a mute button that turns the clip's soundtrack down and back up without stopping or restarting playback (issue #659). When a clip has no audio track, or the browser has no Web Audio or cannot decode the track, the video still plays and the button is disabled with the reason. The README and the website now name audio alongside video in their headlines: decoding, encoding and muxing AAC, Opus and Vorbis, and exact sample-range reads.
- Fix browser HEVC output failing with
INTERNAL: browser video track produced no decoder configurationin browsers that can encode HEVC, such as Chrome on Windows (issue #653). TheWebCodecsencoder bridge looked for thehvcCdescription in each chunk'sEncodedVideoChunkMetadatawith a checked cast, and a WebIDL dictionary has no constructor to check against, so the cast always failed and the description Chrome supplied was never read. AMediaOutputwithvideoCodec = "hevc"now finishes with thathvcCand reads back frame-exactly, and the project website's "Record a canvas" demo records HEVC to MP4. - Fix browser video reads stalling a dozen frames into a track when they decode through
WebCodecs(issue #651). The browser decoder kept up toLimits::max_cached_frames(32) decodedVideoFrames open, and Chrome'sVideoDecoderstops emitting frames once about ten to fourteen of its output buffers are held, sovideo.get(n)never resolved past frame 10 of an HEVC track or frame 14 of an AV1 one, whether read sequentially or by seeking. It now keeps at most four decoded frames open at or before the one asked for, never evicts the frame aget()is waiting for, and keeps the frames the decoder has already run ahead to (up toLimits::max_cached_frames) for the reads that follow, so sequential reads and seeks run through a whole track, and reads paced like playback continue one decode session instead of re-decoding from the key frame every other frame (issue #655). - A new project website at lsegal.github.io/zvidlib, with a live in-browser demo built on the WebAssembly package: frame-exact scrubbing of a sample clip with seek previews, and recording an animated canvas to MP4 or WebM and reading a frame back from the file (issue #651). The API documentation stays at
/zvidlib/, and/api/now leads there too. The README now opens with what zvidlib does, codec, container and platform support tables, Rust and JavaScript quick starts, and zvid as an application built on it; the per-backend detail it carried moved to an appendix ofARCHITECTURE.md. - A release no longer waits for its crates to reach crates.io before its GitHub release is created (issue #649). Finalize release uploaded the crates itself, before creating the GitHub release, so once crates.io's burst of five new crates was spent it waited ten minutes per new crate, and the release, its notes and its
.crateandzvidlib-web-vX.Y.Z.tgzassets did not appear for hours. Crates are now published by a new Publish crates workflow, which Finalize release starts on the tag oncecargo packagehas verified the crates and the GitHub release is created, and does not wait for. Dispatch Publish crates by hand with avX.Y.Ztag to finish a publish that failed or timed out: it skips crates already on crates.io at that version, a second dispatch for the same tag waits for the first to finish rather than uploading alongside it, and without aCARGO_REGISTRY_TOKENit logs that nothing was published and succeeds.
zvidlib v0.4.1
- Make each native codec and direction a Cargo feature, so an application builds only the codecs it uses (issue #635). The
zvidlibcrate depended on every codec crate unconditionally, so a consumer that needed VP9 decoding alone still compiled and linked every encoder and decoder.av1-decoder,av1-encoder,vp8-decoder,vp8-encoder,vp9-decoder,vp9-encoder,hevc-decoder,hevc-encoder,opus-decoder,opus-encoder,vorbis-decoder,vorbis-encoder,aac-decoderandaac-encodereach build one direction of one codec;av1,vp8,vp9,hevc,opus,vorbisandaacbuild both directions of a codec, andallbuilds every one. A newhardwarefeature builds the NVDEC, Media Foundation and VideoToolbox backends of whichever enabled codecs have one; without itHardwarePreference::RequirereportsHardwareUnavailable. The default features areallandhardware, so a plainzvidlibdependency builds exactly what it did and its public API is unchanged;default-features = falsewith, for example,features = ["vp9-decoder"]builds the VP9 decoder and nothing else. Three internal crates make that possible:zvidlib-opus-syntaxandzvidlib-vorbis-syntaxhold the Opus and Vorbis configuration records the containers read and write, which lived in the codec crates, andzvidlib-hevcholds the HEVC engine the encoder shares with the decoder, so the HEVC encoder no longer builds the decoder crate. The--no-default-features --features webthe browser build documented now turns every codec off; build with--features webinstead, as the README, the examples and the release workflow now do. - The README's "Using a release" section no longer names a specific version, so it can no longer fall behind a release (issue #641). Its crates.io dependency takes the latest version from crates.io, the Git-tag dependency and
.cratearchive use anX.Y.Zplaceholder, and the browser package points to the latest GitHub release'szvidlib-web-vX.Y.Z.tgzasset. The release version is written only inCargo.toml,Cargo.lockandCHANGELOG.md, andtests/ci_version_lives_in_cargo_toml.rsfails, naming each file and line, if it appears anywhere else. - Release from the Actions tab instead of by hand (issue #643). The new Release workflow takes a
major,minororpatchlevel, or an explicitX.Y.Zversion, sets the workspace version and every=X.Y.Zpin inCargo.toml, promotes## UnreleasedinCHANGELOG.mdto## X.Y.Z - <date>under a new empty## Unreleased, pushes that commit and thevX.Y.Ztag tomain, and starts Finalize release on the tag. Finalize release, which also runs when av*tag is pushed by hand or when it is dispatched with a tag, does what the tag-triggered release workflow did: it checks every package is at the tag's version, packages the crates and the browser package, and publishes the crates to crates.io. The GitHub release now takes its notes from the tag's changelog section rather than generated notes, and a re-run on a release that already exists uploads its assets again instead of failing. Re-running Release for a version already prepared and tagged only starts Finalize release again. - Publish the crates to crates.io one at a time, paced to crates.io's rate limits, so a release of many new crates no longer fails with
429 Too Many Requests(issue #637). The release workflow uploaded every crate in onecargo publish --workspacecall, and crates.io allows an account only five new crates at once and then one every ten minutes, so thev0.4.0release failed partway through on every attempt and never created its GitHub release..github/scripts/publish_crates.pynow publishes each crate withcargo publish --packagein dependency order, waits before an upload that crates.io's limits would refuse, and answers a 429 by waiting until the time crates.io names and retrying the same crate. New versions of crates already on crates.io are allowed thirty at once, so a release of the existing crates is not slowed down. Every upload, skipped crate and wait is logged, a wait with the crate it is for and when it ends, and the step may run for up to four hours. A crate already on crates.io at the tag's version is still skipped, so a re-run resumes where the last one stopped. - CI no longer hangs for hours when an apt mirror stalls (issue #647). Every workflow step that installs Ubuntu packages, such as the
Rust tests (<package>)jobs' libasound2 and ffmpeg install, now runs.github/scripts/apt_install.py, which has apt retry failed downloads and drop silent connections, kills anapt-get updateorapt-get installthat runs for more than four minutes, and retries the whole install up to three times, finishing any install it interrupted first and fetching from the runner's next mirror instead of its first. Packages are installed without their recommendations, and theRust tests (<package>)jobs install ffmpeg only for the nine packages whose tests run ffmpeg or ffprobe, rather than downloading its hundred packages for every package. Each of those steps also stops after 15 minutes, so an install that never succeeds fails its job instead of holding the run until the 6-hour job limit.
zvidlib v0.3.0
What's Changed
- Verify VideoToolbox HEVC MP4 output in AVFoundation by @lsegal in #497
- Record a measured VideoToolbox row in the hevc_hardware_encode table by @lsegal in #501
- Fall back to software HEVC/AV1 decoding in wasm when WebCodecs can't decode by @lsegal in #505
- Embed cover art (covr) in MP4 output by @lsegal in #503
- Decode HEVC Main 10 in the software decoder, including the wasm fallback by @lsegal in #513
- Reset the WebCodecs decode session on a request before its starting random-access point by @lsegal in #514
- Decode colour AV1 in the native software decoder by @lsegal in #516
- Fix software HEVC decode of open-GOP leading pictures past frame 28 by @lsegal in #515
- Verify AV1 decoder tools the bundled sample misses against libdav1d by @lsegal in #520
- Generate MP4 cover art from video frame 4 by default by @lsegal in #512
- Release zvidlib 0.3.0 with MP4 cover-art thumbnails by @lsegal in #517
Full Changelog: v0.2.0...v0.3.0
zvidlib v0.2.0
zvidlib now encodes HEVC Main in hardware on macOS and Windows and AAC-LC on Windows as well as macOS, so a native application can record 1080p30 HEVC with AAC audio in real time through zvidlib alone. Use the v0.2.0 Git tag for Cargo and zvidlib-web-v0.2.0.tgz for the browser package.
- Behaviour change:
native_hevc_video_encoder_factory()now honoursHardwarePreferencefor target-bitrate configurations.Preferselects the platform's hardware HEVC encoder where one exists and falls back to software otherwise.Requireselects hardware or reportsHardwareUnavailable.Avoid, lossless and fixed-QP requests stay on the pure-Rust encoder. In 0.1.1,Preferalways meant the pure-Rust encoder, at seconds per 1080p frame. The README lists every native encoder by operating system and whether it is hardware, a platform codec, or software. - Platform capability change:
native_aac_audio_encoder_factory()now reportsSupportedon Windows as well as macOS.
Encoders by operating system
| Encoder | Windows | macOS | Linux |
|---|---|---|---|
| HEVC Main | Hardware (Media Foundation: NVENC, Quick Sync, AMF), then Media Foundation software, then pure Rust | Hardware (VideoToolbox), then pure Rust | Pure Rust |
| AV1 Main, 8-bit monochrome | Pure Rust | Pure Rust | Pure Rust |
| AAC-LC | Platform (Media Foundation) | Platform (AudioToolbox) | None |
Avoid, lossless and fixed-QP HEVC requests use the pure-Rust encoder on every OS. The README's Platform expectations section has the full table, and CHANGELOG.md has every change in this release.
What's Changed
- Add Windows Media Foundation hardware HEVC encoder by @lsegal in #491
- Add Windows Media Foundation AAC-LC encoder and exact gapless padding by @lsegal in #492
- Add VideoToolbox hardware HEVC encoder on macOS by @lsegal in #490
- Release zvidlib 0.2.0 with hardware HEVC and Windows AAC encoders by @lsegal in #496
Full Changelog: v0.1.1...v0.2.0
zvidlib v0.1.1
What's Changed
Full Changelog: v0.1.0...v0.1.1