1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:27:45 +00:00

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.
This commit is contained in:
Zaggy1024 2022-11-13 19:19:44 -06:00 committed by Andreas Kling
parent 2a9fb8b439
commit 56d8b96c78

View file

@ -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;
}));