mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-02 18:07:45 +00:00
006b50d2ae
* craft-media: shared codec identifiers, one ByteSource, the testkit The types a codec crate needs to describe a file and configure a decoder, ahead of craft-audio: - `Container`, `CodecId`, `PcmFormat` and `CodecParams` (`id.rs`), always built, with optional serde. - `codec_params()` on `isobmff::Track` and `matroska::Track`, both returning `CodecParams` in the same form; `extradata` follows Matroska's `CodecPrivate`. - One `ByteSource` trait (`source.rs`), with `ReadSeekSource`; `isobmff::ByteSource` and `matroska::ByteSource` are that trait. - craft-media-testkit (`publish = false`): the ffmpeg oracle helpers from craft-media's tests, so the codec crates share one copy. The existing tests prove the refactor; the new types have their own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-media: APV extradata is the bare record; reseek after a poisoned lock An MP4 apvC track gave CodecParams.extradata with the 4-byte FullBox header in front, where Matroska's V_APV CodecPrivate is the bare APVDecoderConfigurationRecord. ApvConfig::record_bytes serializes the record alone and extradata uses it. ReadSeekSource kept its tracked position after recovering a poisoned lock or a failed seek, so a reader moved by a panic was read from the wrong offset with no error. Both now force a seek on the next read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-media: MP4 codec params per sample description Track::codec_params always described the first stsd entry, while each sample selects its own through description_index. It now describes the first sample's entry; codec_params_for gives the parameters of any entry, and has_mixed_descriptions says whether one set covers every sample. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-media: test file-backed ByteSources; a File read past i64::MAX is an EOF A File and a ReadSeekSource over a file now have the buffer's test: the same bytes at the same offsets, and UnexpectedEof past the end. The test found that a File read at an offset past i64::MAX failed with the OS's InvalidInput instead of the UnexpectedEof the trait promises; it now reports the end of the source like the other implementations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-media: Matroska codec params match MP4 for ALAC, DNx and Opus Matroska's codec_params gave Unknown for A_ALAC and for DNxHD/DNxHR stored as V_MS/VFW/FOURCC (AVdn, AVdh), where MP4 gives Alac and Dnxhd; ALAC's extradata is the CodecPrivate, the ALACSpecificConfig MP4's alac box holds. Opus now reports 48 kHz from Matroska as from MP4, whatever rate the muxer declared. ReadSeekSource clears the poison when it recovers the lock, so one panicked read costs one recovery instead of a seek on every later read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-media: MP4 reports the MPEG audio layer the first frame names An MP4 track with MPEG audio reported CodecId::Mp3 whatever the layer, since mp4a + 0x69/0x6B names none (ffmpeg stores MP2 that way), while Matroska reports Mp1/Mp2/Mp3 from its CodecID. open() now reads the frame header of each such entry's first sample and codec_params() reports the layer it names; without a valid header, QuickTime's .mp2 gives Mp2 and anything else Mp3 as before. CodecConfig::Mp3 is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>