From 56d8b96c78234577b7565815e56e43bfc5ea16a0 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Sun, 13 Nov 2022 19:19:44 -0600 Subject: [PATCH] Utilities/matroska: Add arguments to print specific details This adds two options: - An option to print a specific track number only, and omit all others. - An option to print each block for each track that is printed. --- Userland/Utilities/matroska.cpp | 49 +++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/Userland/Utilities/matroska.cpp b/Userland/Utilities/matroska.cpp index 245e71e37a..d23013fdf9 100644 --- a/Userland/Utilities/matroska.cpp +++ b/Userland/Utilities/matroska.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -19,9 +20,19 @@ _temporary_result.release_value(); \ }) -ErrorOr serenity_main(Main::Arguments) +ErrorOr serenity_main(Main::Arguments arguments) { - auto reader = TRY_PARSE(Video::Matroska::Reader::from_file("/home/anon/Videos/test-webm.webm"sv)); + StringView filename; + bool blocks = false; + u64 track_number = 0; + + Core::ArgsParser args_parser; + args_parser.add_option(blocks, "Print blocks for each track.", "blocks", 'b'); + args_parser.add_option(track_number, "Specify a track number to print info for, omit to print all of them.", "track", 't', "tracknumber"); + args_parser.add_positional_argument(filename, "The video file to display.", "filename", Core::ArgsParser::Required::Yes); + args_parser.parse(arguments); + + auto reader = TRY_PARSE(Video::Matroska::Reader::from_file(filename)); outln("DocType is {}", reader.header().doc_type.characters()); outln("DocTypeVersion is {}", reader.header().doc_type_version); @@ -32,6 +43,9 @@ ErrorOr serenity_main(Main::Arguments) outln("Document has {} tracks", TRY_PARSE(reader.track_count())); TRY_PARSE(reader.for_each_track([&](Video::Matroska::TrackEntry const& track_entry) -> Video::DecoderErrorOr { + if (track_number != 0 && track_entry.track_number() != track_number) + return IterationDecision::Continue; + outln("\tTrack #{} with TrackID {}", track_entry.track_number(), track_entry.track_uid()); outln("\tTrack has TrackType {}", static_cast(track_entry.track_type())); outln("\tTrack has Language \"{}\"", track_entry.language().characters()); @@ -47,22 +61,29 @@ ErrorOr serenity_main(Main::Arguments) outln("\t\tAudio has {} channels with a bit depth of {}", audio_track.channels, audio_track.bit_depth); } - outln("\tBlocks:"); - auto iterator = TRY(reader.create_sample_iterator(track_entry.track_number())); + if (blocks) { + outln("\tBlocks:"); + auto iterator = TRY(reader.create_sample_iterator(track_entry.track_number())); - while (true) { - auto block_result = iterator.next_block(); - if (block_result.is_error()) { - if (block_result.error().category() == Video::DecoderErrorCategory::EndOfStream) - break; - return block_result.release_error(); + while (true) { + auto block_result = iterator.next_block(); + if (block_result.is_error()) { + if (block_result.error().category() == Video::DecoderErrorCategory::EndOfStream) + break; + return block_result.release_error(); + } + auto block = block_result.release_value(); + outln("\t\tBlock at timestamp {}ms:", block.timestamp().to_milliseconds()); + if (block.only_keyframes()) + outln("\t\t\tThis block contains only keyframes"); + outln("\t\t\tContains {} frames", block.frame_count()); + outln("\t\t\tLacing is {}", static_cast(block.lacing())); } - auto block = block_result.release_value(); - outln("\t\tBlock at timestamp {}ms:", block.timestamp().to_milliseconds()); - outln("\t\t\tContains {} frames", block.frame_count()); - outln("\t\t\tLacing is {}", static_cast(block.lacing())); } + if (track_number != 0) + return IterationDecision::Break; + return IterationDecision::Continue; }));