ソースを参照

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.
Zaggy1024 2 年 前
コミット
56d8b96c78
1 ファイル変更35 行追加14 行削除
  1. 35 14
      Userland/Utilities/matroska.cpp

+ 35 - 14
Userland/Utilities/matroska.cpp

@@ -6,6 +6,7 @@
  */
 
 #include <AK/Function.h>
+#include <LibCore/ArgsParser.h>
 #include <LibMain/Main.h>
 #include <LibVideo/Containers/Matroska/Reader.h>
 
@@ -19,9 +20,19 @@
         _temporary_result.release_value();                                                        \
     })
 
-ErrorOr<int> serenity_main(Main::Arguments)
+ErrorOr<int> 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<u64>(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<int> 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<IterationDecision> {
+        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<u8>(track_entry.track_type()));
         outln("\tTrack has Language \"{}\"", track_entry.language().characters());
@@ -47,22 +61,29 @@ ErrorOr<int> 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<u8>(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<u8>(block.lacing()));
         }
 
+        if (track_number != 0)
+            return IterationDecision::Break;
+
         return IterationDecision::Continue;
     }));