Skip to content

Commit

Permalink
extract: Support Matroska input
Browse files Browse the repository at this point in the history
  • Loading branch information
quietvoid committed Feb 13, 2025
1 parent e6d966f commit 4ae191f
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 24 deletions.
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license = "MIT"
[dependencies]
bitvec_helpers = { version = "3.1.6", default-features = false, features = ["bitstream-io"] }
hdr10plus = { path = "./hdr10plus", features = ["hevc", "json"] }
hevc_parser = { version = "0.6.4", features = ["hevc_io"] }
hevc_parser = { version = "0.6.6", features = ["hevc_io"] }

clap = { version = "4.5.29", features = ["derive", "wrap_help", "deprecated"] }
serde_json = { version = "1.0.138", features = ["preserve_order"] }
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ Options that apply to the commands:

## Commands
* ### **extract**
Extracts the HDR10+ metadata from HEVC SEI messages to a JSON file.
Extracts the HDR10+ metadata from a HEVC file to a JSON file.
Also calculates the scene information for compatibility with Samsung tools.

If no output is specified, the file is only parsed partially to verify presence of metadata.

Input file:
- HEVC bitstream
- Matroska (experimental): MKV file containing a HEVC video track.


**Flags**:
* `--skip-reorder` Skip metadata reordering after extracting.
- [Explanation on when to use `--skip-reorder`](README.md#wrong-metadata-order-workaround).
Expand All @@ -34,6 +39,9 @@ Options that apply to the commands:
**Examples**:
```console
hdr10plus_tool extract video.hevc -o metadata.json

# Experimental
hdr10plus_tool extract video.mkv -o metadata.json
```
```console
ffmpeg -i input.mkv -map 0:v:0 -c copy -bsf:v hevc_mp4toannexb -f hevc - | hdr10plus_tool extract -o metadata.json -
Expand Down
Binary file added assets/hevc_tests/regular.mkv
Binary file not shown.
4 changes: 2 additions & 2 deletions src/commands/extract.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::{bail, Result};
use anyhow::Result;
use hevc_parser::io::IoFormat;

use super::{input_from_either, CliOptions, ExtractArgs};
Expand All @@ -21,7 +21,7 @@ impl Extractor {
let format = hevc_parser::io::format_from_path(&input)?;

if format == IoFormat::Matroska {
bail!("Extractor: Matroska format unsupported");
println!("Extractor: Matroska input is experimental!");
}

if !options.verify && output.is_none() {
Expand Down
16 changes: 7 additions & 9 deletions src/core/parser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::fs::File;
use std::io::{stdout, BufRead, BufReader, BufWriter, Write};
use std::io::{stdout, BufWriter, Write};
use std::path::PathBuf;

use anyhow::{bail, ensure, Result};
Expand Down Expand Up @@ -78,15 +78,13 @@ impl Parser {
};
let mut processor = HevcProcessor::new(format.clone(), processor_opts, chunk_size);

let stdin = std::io::stdin();
let mut reader = Box::new(stdin.lock()) as Box<dyn BufRead>;

if let IoFormat::Raw = format {
let file = File::open(&self.input)?;
reader = Box::new(BufReader::with_capacity(100_000, file));
}
let file_path = if let IoFormat::RawStdin = format {
None
} else {
Some(self.input.clone())
};

processor.process_io(&mut reader, self)
processor.process_file(self, file_path)
}

pub fn add_hdr10plus_sei(&mut self, nals: &[NALUnit], chunk: &[u8]) -> Result<()> {
Expand Down
32 changes: 32 additions & 0 deletions tests/hevc/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1989,3 +1989,35 @@ fn dts_injected() -> Result<()> {

Ok(())
}

#[test]
fn regular() -> Result<()> {
let input_file = Path::new("assets/hevc_tests/regular.hevc");
let temp = assert_fs::TempDir::new()?;

let output_json = temp.child("metadata.json");
let expected_json = Path::new("assets/hevc_tests/regular_metadata.json");

assert_cmd_output(input_file, output_json.as_ref(), true)?;
output_json
.assert(predicate::path::is_file())
.assert(predicate::path::eq_file(expected_json));

Ok(())
}

#[test]
fn regular_mkv() -> Result<()> {
let input_file = Path::new("assets/hevc_tests/regular.mkv");
let temp = assert_fs::TempDir::new()?;

let output_json = temp.child("metadata.json");
let expected_json = Path::new("assets/hevc_tests/regular_metadata.json");

assert_cmd_output(input_file, output_json.as_ref(), true)?;
output_json
.assert(predicate::path::is_file())
.assert(predicate::path::eq_file(expected_json));

Ok(())
}

0 comments on commit 4ae191f

Please sign in to comment.