mirror of
https://github.com/freemkv/libfreemkv.git
synced 2026-10-07 18:13:10 +00:00
source: an image or folder names its title by the meta title, else the playlist, as 1.7.7
ed02bc1 named every disc layout's output title by its meta title, else its volume id. A
folder's volume id is its directory name, so a DVD title ripped from an image and from its
extracted folder got different segment titles and the two MKVs stopped being byte-identical.
A drive still names by meta title, else volume id.
This commit is contained in:
+1
-1
@@ -38,7 +38,7 @@
|
||||
- **`json://`** audio `sample_rate` is a number in Hz (`null` when unknown), not a string such as `"48kHz"`; a `sample_rates` array lists every rate a stream carries.
|
||||
- **FMKV (`network://`, `stdio://`) header version 2** is used when a track carries decoder timing (Opus CodecDelay/SeekPreRoll) and adds per-frame DiscardPadding; streams without timing stay version 1. Headers now also carry display aspect, CICP, stream purpose/qualifier, chapters and content format, and PIDs actually written by M2TS. A header declaring more than 256 streams is refused with E9008. An older receiver omits the MKV Channels element for the new channel-layout strings; keep both ends on one version.
|
||||
- **`dir://` image bytes:** the PVD declares interchange level 3, Unique IDs start at 16 and the volume id round-trips through the d-string encoder; `dir://` sources are stamped as images in the `fvi://` provenance header.
|
||||
- **One output title name:** a title read from a disc layout (`disc://`, `iso://`, `dir://`, a staged image, a server live rip) is named by the disc's meta title (else its volume id) in every container's title field and in `fvi://` provenance; 1.7.7 named image and server-live rips by the MPLS playlist file. `fvi://` provenance of an `iso://`/`dir://` source now carries the volume id.
|
||||
- **Output title names:** a title read from a drive (`disc://`, a server live rip) is named by the disc's meta title (else its volume id) in every container's title field and in `fvi://` provenance; one read from an image or folder (`iso://`, `dir://`, a staged image) by the disc's meta title, else its own playlist name as in 1.7.7, so an image and its extracted folder name a title alike. 1.7.7 named server-live rips by the MPLS playlist file. `fvi://` provenance of an `iso://`/`dir://` source now carries the volume id.
|
||||
- **TrueHD 7.1 / Atmos labels on every path:** the playlist labels a 7.1 or Atmos TrueHD track 5.1 at 48 kHz; every mux (live disc, staged image, `iso://`/`dir://`, containers) now completes the track's channels, sample rate and label from its first major sync before the output opens, and `json://` / `chapters://` get the completed title too. 1.7.7 corrected only `iso://`/`dir://` URL rips, so live and staged-image rips now label such tracks 7.1 / Atmos.
|
||||
- **Track selection applies to container inputs:** `selection` keeps a subset of the tracks of an `mkv://`, `mp4://`, `m2ts://`, `network://` or `stdio://` input (renumbered in order, video always kept), as it already did for disc titles; an unknown PID is refused at open.
|
||||
- **A live DVD extracted to `dir://` is descrambled:** `Disc::extract_tree` finds and cracks each scrambled VTS from its content on every DVD-Video layout. A live drive scan records no disc-wide CSS key, so a live DVD's title VOBs were written still scrambled.
|
||||
|
||||
+65
-4
@@ -30,12 +30,13 @@ pub struct ScannedTitle {
|
||||
}
|
||||
|
||||
impl ScannedTitle {
|
||||
/// Title `idx` of `disc`, named by the disc. `None` when out of range.
|
||||
/// Title `idx` of an image's `disc`, named as [`Source`] names an image's title (its
|
||||
/// meta title, else the title's own playlist name). `None` when out of range.
|
||||
pub fn of(disc: &Disc, idx: usize) -> Option<Self> {
|
||||
Some(ScannedTitle {
|
||||
title: disc.titles.get(idx)?.clone(),
|
||||
format: disc.content_format,
|
||||
disc_name: Some(disc_name(disc)),
|
||||
disc_name: disc.meta_title.clone(),
|
||||
volume_id: disc.volume_id.clone(),
|
||||
})
|
||||
}
|
||||
@@ -294,14 +295,74 @@ impl<'a> Source<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// The output title's name (SO14): every disc layout names it by the disc (its meta
|
||||
// title, else its volume id); a container keeps its own.
|
||||
// The output title's name (SO14): a drive's is the disc's meta title, else its volume id;
|
||||
// an image's or folder's the meta title, else the playlist (a folder's volume id is its
|
||||
// directory name, and an image and its folder must name a title alike); a container's own.
|
||||
pub(crate) fn title_name(&self) -> Option<String> {
|
||||
match &self.origin {
|
||||
Origin::Prescanned { title, .. } | Origin::Live { title, .. } => {
|
||||
title.disc_name.clone()
|
||||
}
|
||||
Origin::Image { disc, .. } => disc.meta_title.clone(),
|
||||
_ => self.layout().map(disc_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn disc(volume_id: &str, meta_title: Option<&str>) -> Disc {
|
||||
let mut title = crate::disc::DiscTitle::empty();
|
||||
title.playlist = "VTS_11_26.VOB".into();
|
||||
Disc {
|
||||
volume_id: volume_id.into(),
|
||||
meta_title: meta_title.map(str::to_string),
|
||||
format: crate::disc::DiscFormat::Dvd,
|
||||
capacity_sectors: 1,
|
||||
capacity_bytes: 2048,
|
||||
layers: 1,
|
||||
titles: vec![title],
|
||||
region: crate::disc::DiscRegion::Free,
|
||||
aacs: None,
|
||||
css: None,
|
||||
encrypted: false,
|
||||
aacs_error: None,
|
||||
css_error: None,
|
||||
content_format: crate::disc::ContentFormat::MpegPs,
|
||||
}
|
||||
}
|
||||
|
||||
fn image(d: Disc, folder: bool) -> Source<'static> {
|
||||
Source {
|
||||
origin: Origin::Image {
|
||||
path: PathBuf::from("x"),
|
||||
folder,
|
||||
reader: Box::new(crate::test_util::MemSource::new(vec![0u8; 2048])),
|
||||
disc: d,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// An image and its extracted folder name a title alike: the folder's volume id is its
|
||||
// directory name, so with no meta title both keep the title's playlist name, and the
|
||||
// engine's pre-scanned image title agrees.
|
||||
#[test]
|
||||
fn an_image_and_its_folder_name_a_title_alike() {
|
||||
let iso = image(disc("GREENLAND", None), false);
|
||||
let dir = image(disc("fmt_dir", None), true);
|
||||
assert_eq!(iso.title_name(), None);
|
||||
assert_eq!(dir.title_name(), None);
|
||||
let scanned = ScannedTitle::of(&disc("GREENLAND", None), 0).unwrap();
|
||||
assert_eq!(scanned.disc_name, None);
|
||||
assert_eq!(scanned.title.playlist, "VTS_11_26.VOB");
|
||||
|
||||
let iso = image(disc("GREENLAND", Some("Greenland")), false);
|
||||
let dir = image(disc("fmt_dir", Some("Greenland")), true);
|
||||
assert_eq!(iso.title_name().as_deref(), Some("Greenland"));
|
||||
assert_eq!(dir.title_name().as_deref(), Some("Greenland"));
|
||||
let scanned = ScannedTitle::of(&disc("GREENLAND", Some("Greenland")), 0).unwrap();
|
||||
assert_eq!(scanned.disc_name.as_deref(), Some("Greenland"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user