mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
mkvextract: look for track header with kax_analyzer_c before processing the clusters
That way the track headers will be found even if they're located at the end of the file.
This commit is contained in:
parent
1ab1e68c8a
commit
c43882dec5
@ -1,6 +1,11 @@
|
||||
2013-12-29 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mmgL bug fixL the »playlist items« list box in the »select
|
||||
* mkvextract: bug fix: if the track headers were located at the
|
||||
end of the file (e.g. after modification with mkvpropedit or mmg's
|
||||
header editor) then mkvextract was writing files with a length 0
|
||||
bytes.
|
||||
|
||||
* mmg: bug fix: the »playlist items« list box in the »select
|
||||
playlist file to add« dialog was showing the items in reversed
|
||||
order. Fixes #952.
|
||||
|
||||
|
@ -83,7 +83,7 @@ main(int argc,
|
||||
options_c options = extract_cli_parser_c(command_line_utf8(argc, argv)).run();
|
||||
|
||||
if (options_c::em_tracks == options.m_extraction_mode) {
|
||||
extract_tracks(options.m_file_name, options.m_tracks);
|
||||
extract_tracks(options.m_file_name, options.m_tracks, options.m_parse_mode);
|
||||
|
||||
if (0 == verbose)
|
||||
mxinfo(Y("Progress: 100%\n"));
|
||||
|
@ -53,7 +53,7 @@ show_error(const boost::format &format) {
|
||||
|
||||
void find_and_verify_track_uids(KaxTracks &tracks, std::vector<track_spec_t> &tspecs);
|
||||
|
||||
bool extract_tracks(const std::string &file_name, std::vector<track_spec_t> &tspecs);
|
||||
bool extract_tracks(const std::string &file_name, std::vector<track_spec_t> &tspecs, kax_analyzer_c::parse_mode_e parse_mode);
|
||||
void extract_tags(const std::string &file_name, kax_analyzer_c::parse_mode_e parse_mode);
|
||||
void extract_chapters(const std::string &file_name, bool chapter_format_simple, kax_analyzer_c::parse_mode_e parse_mode);
|
||||
void extract_attachments(const std::string &file_name, std::vector<track_spec_t> &tracks, kax_analyzer_c::parse_mode_e parse_mode);
|
||||
|
@ -330,9 +330,22 @@ find_and_verify_track_uids(KaxTracks &tracks,
|
||||
mxerror(boost::format(Y("No track with the ID %1% was found in the source file.\n")) % tspec.tid);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_segment_info(EbmlMaster *info,
|
||||
kax_file_c *file,
|
||||
uint64_t &tc_scale) {
|
||||
auto ktc_scale = FindChild<KaxTimecodeScale>(info);
|
||||
if (!ktc_scale)
|
||||
return;
|
||||
|
||||
tc_scale = ktc_scale->GetValue();
|
||||
file->set_timecode_scale(tc_scale);
|
||||
}
|
||||
|
||||
bool
|
||||
extract_tracks(const std::string &file_name,
|
||||
std::vector<track_spec_t> &tspecs) {
|
||||
std::vector<track_spec_t> &tspecs,
|
||||
kax_analyzer_c::parse_mode_e parse_mode) {
|
||||
if (tspecs.empty())
|
||||
mxerror(Y("Nothing to do.\n"));
|
||||
|
||||
@ -348,8 +361,30 @@ extract_tracks(const std::string &file_name,
|
||||
}
|
||||
|
||||
int64_t file_size = in->get_size();
|
||||
uint64_t tc_scale = TIMECODE_SCALE;
|
||||
bool segment_info_found = false, tracks_found = false;
|
||||
|
||||
// open input file
|
||||
auto analyzer = std::make_shared<kax_analyzer_c>(static_cast<mm_file_io_c *>(in.get()));
|
||||
if (analyzer->process(parse_mode, MODE_READ)) {
|
||||
auto af_master = ebml_master_cptr{ analyzer->read_all(EBML_INFO(KaxInfo)) };
|
||||
auto segment_info = dynamic_cast<KaxInfo *>(af_master.get());
|
||||
if (segment_info) {
|
||||
segment_info_found = true;
|
||||
handle_segment_info(segment_info, file.get(), tc_scale);
|
||||
}
|
||||
|
||||
af_master = ebml_master_cptr{ analyzer->read_all(EBML_INFO(KaxTracks)) };
|
||||
auto tracks = dynamic_cast<KaxTracks *>(af_master.get());
|
||||
if (tracks) {
|
||||
tracks_found = true;
|
||||
find_and_verify_track_uids(*tracks, tspecs);
|
||||
create_extractors(*tracks, tspecs);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
in->setFilePointer(0);
|
||||
EbmlStream *es = new EbmlStream(*in);
|
||||
|
||||
// Find the EbmlHead element. Must be the first one.
|
||||
@ -383,31 +418,17 @@ extract_tracks(const std::string &file_name,
|
||||
delete l0;
|
||||
}
|
||||
|
||||
bool tracks_found = false;
|
||||
EbmlElement *l1 = nullptr;
|
||||
uint64_t tc_scale = TIMECODE_SCALE;
|
||||
|
||||
KaxChapters all_chapters;
|
||||
KaxTags all_tags;
|
||||
|
||||
while ((l1 = file->read_next_level1_element())) {
|
||||
if (Is<KaxInfo>(l1)) {
|
||||
// General info about this Matroska file
|
||||
show_element(l1, 1, Y("Segment information"));
|
||||
|
||||
auto ktc_scale = FindChild<KaxTimecodeScale>(l1);
|
||||
if (ktc_scale) {
|
||||
tc_scale = ktc_scale->GetValue();
|
||||
file->set_timecode_scale(tc_scale);
|
||||
show_element(ktc_scale, 2, boost::format(Y("Timecode scale: %1%")) % tc_scale);
|
||||
}
|
||||
|
||||
} else if ((Is<KaxTracks>(l1)) && !tracks_found) {
|
||||
|
||||
// Yep, we've found our KaxTracks element. Now find all tracks
|
||||
// contained in this segment.
|
||||
show_element(l1, 1, Y("Segment tracks"));
|
||||
if (Is<KaxInfo>(l1) && !segment_info_found) {
|
||||
segment_info_found = true;
|
||||
handle_segment_info(static_cast<EbmlMaster *>(l1), file.get(), tc_scale);
|
||||
|
||||
} else if (Is<KaxTracks>(l1) && !tracks_found) {
|
||||
tracks_found = true;
|
||||
find_and_verify_track_uids(*dynamic_cast<KaxTracks *>(l1), tspecs);
|
||||
create_extractors(*dynamic_cast<KaxTracks *>(l1), tspecs);
|
||||
|
@ -262,3 +262,4 @@ T_413memory_resize_nonfree_smaller:c1085152b4b60a197bf93d598d066924:passed:20131
|
||||
T_414vc1_no_sequence_headers_before_key_frames:48a03189f55b303a98332e6594f7bd31:passed:20131115-164756:0.133015738
|
||||
T_415create_webm:c1447a8f67f47a0b2d8c21d4208a8f98-5e1abfc5e13a44989a6ff31e51e9eaa9-8ba1b32bd84baef269181ea74cf06f0d-415d91e89e995b02b695e127617d2d8a-AAC@ok-AC3@ok-ALAC@ok-DivX@ok-h.264/AVC@ok-Dirac@ok-DTS@ok-FLV@ok-MP3@ok-MPEG1@ok-MPEG2@ok-PCM@ok-RV4@ok-SSA@ok-PGS@ok-SRT@ok-USF@ok-VC1@ok-WavPack4@ok:passed:20131218-221942:0.832721732
|
||||
T_416dts_in_mp4:77e4a560d93a9c1a1030318c07ee48e5-60d52627905d83b1e605119152d7bf4e:passed:20131218-231435:1.398112245
|
||||
T_417mkvextract_tracks_at_end_of_file:b3bb67d316e20da12926d5c1d628f6e5:passed:20131229-122704:0.04690235
|
||||
|
8
tests/test-417mkvextract_tracks_at_end_of_file.rb
Executable file
8
tests/test-417mkvextract_tracks_at_end_of_file.rb
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/ruby -w
|
||||
|
||||
# T_417mkvextract_tracks_at_end_of_file
|
||||
describe "mkvextract / track headers located at the end of the file"
|
||||
test "extraction" do
|
||||
extract "data/mkv/tracks-at-end.mka", 0 => tmp
|
||||
hash_tmp
|
||||
end
|
Loading…
Reference in New Issue
Block a user