mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
mkvmerge will copy the attachments from Matroska source files. Can be disabled with the --no-attachments option.
This commit is contained in:
parent
b7c1b707c7
commit
0b02af818d
@ -1,3 +1,8 @@
|
|||||||
|
2003-09-29 Moritz Bunkus <moritz@bunkus.org>
|
||||||
|
|
||||||
|
* mkvmerge: new feature: Attachments are kept when reading
|
||||||
|
Matroska files.
|
||||||
|
|
||||||
2003-09-28 Moritz Bunkus <moritz@bunkus.org>
|
2003-09-28 Moritz Bunkus <moritz@bunkus.org>
|
||||||
|
|
||||||
* mmg: new feature: Added a (nearly) full-featured chapter editor.
|
* mmg: new feature: Added a (nearly) full-featured chapter editor.
|
||||||
|
2
debian/rules
vendored
2
debian/rules
vendored
@ -76,7 +76,7 @@ binary-arch: build install
|
|||||||
dh_testdir
|
dh_testdir
|
||||||
dh_testroot
|
dh_testroot
|
||||||
# dh_installdebconf
|
# dh_installdebconf
|
||||||
# dh_installdocs doc/matroskatags.dtd doc/matroskachapters.dtd doc/example-tags-1.xml doc/example-chapters-1.xml doc/example-chapters-2.xml
|
dh_installdocs doc/mkvmerge-gui.html
|
||||||
dh_installexamples examples/*xml examples/*dtd
|
dh_installexamples examples/*xml examples/*dtd
|
||||||
# dh_installmenu
|
# dh_installmenu
|
||||||
# dh_installlogrotate
|
# dh_installlogrotate
|
||||||
|
@ -179,6 +179,9 @@ Don't copy any subtitle track from this file.
|
|||||||
\fB\-\-no\-chapters\fR
|
\fB\-\-no\-chapters\fR
|
||||||
If the source is a Matroska file then don't copy chapters from it.
|
If the source is a Matroska file then don't copy chapters from it.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-no\-attachments\fR
|
||||||
|
If the source is a Matroska file then don't copy attachments from it.
|
||||||
|
.TP
|
||||||
\fB\-y\fR, \fB\-\-sync\fR <\fITID\fR:\fId\fR[,\fIo\fR[/\fIp\fR]]>
|
\fB\-y\fR, \fB\-\-sync\fR <\fITID\fR:\fId\fR[,\fIo\fR[/\fIp\fR]]>
|
||||||
Synchronize manually, delay the audio track with the id \fITID\fR by \fId\fR
|
Synchronize manually, delay the audio track with the id \fITID\fR by \fId\fR
|
||||||
ms. The track IDs are the same as the ones given with \fB\-\-identify\fR (see
|
ms. The track IDs are the same as the ones given with \fB\-\-identify\fR (see
|
||||||
|
@ -300,6 +300,7 @@ static void usage() {
|
|||||||
" -D, --novideo Don't copy any video track from this file.\n"
|
" -D, --novideo Don't copy any video track from this file.\n"
|
||||||
" -S, --nosubs Don't copy any text track from this file.\n"
|
" -S, --nosubs Don't copy any text track from this file.\n"
|
||||||
" --no-chapters Don't keep chapters from a Matroska file.\n"
|
" --no-chapters Don't keep chapters from a Matroska file.\n"
|
||||||
|
" --no-attachments Don't keep attachments from a Matroska file.\n"
|
||||||
" -y, --sync <TID:d[,o[/p]]>\n"
|
" -y, --sync <TID:d[,o[/p]]>\n"
|
||||||
" Synchronize, delay the audio track with the\n"
|
" Synchronize, delay the audio track with the\n"
|
||||||
" id TID by d ms. \n"
|
" id TID by d ms. \n"
|
||||||
@ -885,6 +886,7 @@ static void render_headers(mm_io_c *out, bool last_file, bool first_file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void render_attachments(IOCallback *out) {
|
static void render_attachments(IOCallback *out) {
|
||||||
|
KaxAttachments *other_as;
|
||||||
KaxAttached *kax_a;
|
KaxAttached *kax_a;
|
||||||
KaxFileData *fdata;
|
KaxFileData *fdata;
|
||||||
attachment_t *attch;
|
attachment_t *attch;
|
||||||
@ -894,9 +896,21 @@ static void render_attachments(IOCallback *out) {
|
|||||||
int64_t size;
|
int64_t size;
|
||||||
mm_io_c *io;
|
mm_io_c *io;
|
||||||
|
|
||||||
if (!(((file_num == 1) && (attachment_sizes_first > 0)) ||
|
other_as = new KaxAttachments;
|
||||||
(attachment_sizes_others > 0)))
|
for (i = 0; i < files.size(); i++)
|
||||||
|
files[i]->reader->add_attachments(other_as);
|
||||||
|
for (i = 0, size = 0; i < other_as->ListSize(); i++) {
|
||||||
|
kax_a = static_cast<KaxAttached *>((*other_as)[i]);
|
||||||
|
fdata = FindChild<KaxFileData>(*kax_a);
|
||||||
|
if (fdata != NULL)
|
||||||
|
size += fdata->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(((file_num == 1) && ((attachment_sizes_first + size) > 0)) ||
|
||||||
|
((attachment_sizes_others + size) > 0))) {
|
||||||
|
delete other_as;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (kax_as != NULL)
|
if (kax_as != NULL)
|
||||||
delete kax_as;
|
delete kax_as;
|
||||||
@ -936,10 +950,7 @@ static void render_attachments(IOCallback *out) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
io = new mm_io_c(attch->name, MODE_READ);
|
io = new mm_io_c(attch->name, MODE_READ);
|
||||||
io->setFilePointer(0, seek_end);
|
size = io->get_size();
|
||||||
size = io->getFilePointer();
|
|
||||||
io->setFilePointer(0, seek_beginning);
|
|
||||||
|
|
||||||
buffer = new binary[size];
|
buffer = new binary[size];
|
||||||
io->read(buffer, size);
|
io->read(buffer, size);
|
||||||
delete io;
|
delete io;
|
||||||
@ -952,6 +963,12 @@ static void render_attachments(IOCallback *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (other_as->ListSize() > 0) {
|
||||||
|
kax_as->PushElement(*(*other_as)[0]);
|
||||||
|
other_as->Remove(0);
|
||||||
|
}
|
||||||
|
delete other_as;
|
||||||
|
|
||||||
kax_as->Render(*out);
|
kax_as->Render(*out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1417,6 +1434,9 @@ static void parse_args(int argc, char **argv) {
|
|||||||
} else if (!strcmp(this_arg, "--no-chapters")) {
|
} else if (!strcmp(this_arg, "--no-chapters")) {
|
||||||
ti.no_chapters = true;
|
ti.no_chapters = true;
|
||||||
|
|
||||||
|
} else if (!strcmp(this_arg, "--no-attachments")) {
|
||||||
|
ti.no_attachments = true;
|
||||||
|
|
||||||
} else if (!strcmp(this_arg, "--dump-packets")) {
|
} else if (!strcmp(this_arg, "--dump-packets")) {
|
||||||
if (next_arg == NULL)
|
if (next_arg == NULL)
|
||||||
mxerror("'--dump-packets' lacks the output path.\n");
|
mxerror("'--dump-packets' lacks the output path.\n");
|
||||||
|
@ -657,6 +657,10 @@ void mmg_dialog::update_command_line() {
|
|||||||
cmdline += "--no-chapters ";
|
cmdline += "--no-chapters ";
|
||||||
clargs.Add("--no-chapters");
|
clargs.Add("--no-chapters");
|
||||||
}
|
}
|
||||||
|
if (f->no_attachments) {
|
||||||
|
cmdline += "--no-attachments ";
|
||||||
|
clargs.Add("--no-attachments");
|
||||||
|
}
|
||||||
if (no_video) {
|
if (no_video) {
|
||||||
cmdline += "-D ";
|
cmdline += "-D ";
|
||||||
clargs.Add("-D");
|
clargs.Add("-D");
|
||||||
|
@ -116,6 +116,7 @@ using namespace libmatroska;
|
|||||||
#define ID_CB_CHAPTERSELECTLANGUAGECODE 10069
|
#define ID_CB_CHAPTERSELECTLANGUAGECODE 10069
|
||||||
#define ID_CB_CHAPTERSELECTCOUNTRYCODE 10070
|
#define ID_CB_CHAPTERSELECTCOUNTRYCODE 10070
|
||||||
#define ID_B_ADDSUBCHAPTER 10071
|
#define ID_B_ADDSUBCHAPTER 10071
|
||||||
|
#define ID_CB_NOATTACHMENTS 10072
|
||||||
|
|
||||||
#define ID_M_FILE_LOAD 20000
|
#define ID_M_FILE_LOAD 20000
|
||||||
#define ID_M_FILE_SAVE 20001
|
#define ID_M_FILE_SAVE 20001
|
||||||
@ -164,7 +165,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
wxString *file_name;
|
wxString *file_name;
|
||||||
vector<mmg_track_t> *tracks;
|
vector<mmg_track_t> *tracks;
|
||||||
bool no_chapters;
|
bool no_chapters, no_attachments;
|
||||||
} mmg_file_t;
|
} mmg_file_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -191,7 +192,7 @@ class tab_input: public wxPanel {
|
|||||||
protected:
|
protected:
|
||||||
wxListBox *lb_input_files;
|
wxListBox *lb_input_files;
|
||||||
wxButton *b_add_file, *b_remove_file, *b_browse_tags;
|
wxButton *b_add_file, *b_remove_file, *b_browse_tags;
|
||||||
wxCheckBox *cb_no_chapters, *cb_default, *cb_aac_is_sbr;
|
wxCheckBox *cb_no_chapters, *cb_no_attachments, *cb_default, *cb_aac_is_sbr;
|
||||||
wxCheckListBox *clb_tracks;
|
wxCheckListBox *clb_tracks;
|
||||||
wxComboBox *cob_language, *cob_cues, *cob_sub_charset;
|
wxComboBox *cob_language, *cob_cues, *cob_sub_charset;
|
||||||
wxComboBox *cob_aspect_ratio, *cob_fourcc;
|
wxComboBox *cob_aspect_ratio, *cob_fourcc;
|
||||||
@ -210,6 +211,7 @@ public:
|
|||||||
void on_track_selected(wxCommandEvent &evt);
|
void on_track_selected(wxCommandEvent &evt);
|
||||||
void on_track_enabled(wxCommandEvent &evt);
|
void on_track_enabled(wxCommandEvent &evt);
|
||||||
void on_nochapters_clicked(wxCommandEvent &evt);
|
void on_nochapters_clicked(wxCommandEvent &evt);
|
||||||
|
void on_noattachments_clicked(wxCommandEvent &evt);
|
||||||
void on_default_track_clicked(wxCommandEvent &evt);
|
void on_default_track_clicked(wxCommandEvent &evt);
|
||||||
void on_aac_is_sbr_clicked(wxCommandEvent &evt);
|
void on_aac_is_sbr_clicked(wxCommandEvent &evt);
|
||||||
void on_language_selected(wxCommandEvent &evt);
|
void on_language_selected(wxCommandEvent &evt);
|
||||||
|
@ -61,11 +61,18 @@ tab_input::tab_input(wxWindow *parent):
|
|||||||
wxDefaultSize, 0);
|
wxDefaultSize, 0);
|
||||||
cb_no_chapters =
|
cb_no_chapters =
|
||||||
new wxCheckBox(this, ID_CB_NOCHAPTERS, _("No chapters"), wxPoint(5, 110),
|
new wxCheckBox(this, ID_CB_NOCHAPTERS, _("No chapters"), wxPoint(5, 110),
|
||||||
wxSize(100, -1), 0);
|
wxDefaultSize, 0);
|
||||||
cb_no_chapters->SetValue(false);
|
cb_no_chapters->SetValue(false);
|
||||||
cb_no_chapters->SetToolTip(_("Do not copy chapters from this file. Only "
|
cb_no_chapters->SetToolTip(_("Do not copy chapters from this file. Only "
|
||||||
"applies to Matroska files."));
|
"applies to Matroska files."));
|
||||||
cb_no_chapters->Enable(false);
|
cb_no_chapters->Enable(false);
|
||||||
|
cb_no_attachments =
|
||||||
|
new wxCheckBox(this, ID_CB_NOATTACHMENTS, _("No attachments"),
|
||||||
|
wxPoint(110, 110), wxDefaultSize, 0);
|
||||||
|
cb_no_attachments->SetValue(false);
|
||||||
|
cb_no_attachments->SetToolTip(_("Do not copy attachments from this file. "
|
||||||
|
"Only applies to Matroska files."));
|
||||||
|
cb_no_attachments->Enable(false);
|
||||||
new wxStaticText(this, wxID_STATIC, _("Tracks:"), wxPoint(5, 140),
|
new wxStaticText(this, wxID_STATIC, _("Tracks:"), wxPoint(5, 140),
|
||||||
wxDefaultSize, 0);
|
wxDefaultSize, 0);
|
||||||
clb_tracks =
|
clb_tracks =
|
||||||
@ -424,6 +431,7 @@ void tab_input::on_remove_file(wxCommandEvent &evt) {
|
|||||||
lb_input_files->Delete(selected_file);
|
lb_input_files->Delete(selected_file);
|
||||||
selected_file = -1;
|
selected_file = -1;
|
||||||
cb_no_chapters->Enable(false);
|
cb_no_chapters->Enable(false);
|
||||||
|
cb_no_attachments->Enable(false);
|
||||||
b_remove_file->Enable(false);
|
b_remove_file->Enable(false);
|
||||||
clb_tracks->Enable(false);
|
clb_tracks->Enable(false);
|
||||||
no_track_mode();
|
no_track_mode();
|
||||||
@ -438,10 +446,12 @@ void tab_input::on_file_selected(wxCommandEvent &evt) {
|
|||||||
|
|
||||||
b_remove_file->Enable(true);
|
b_remove_file->Enable(true);
|
||||||
cb_no_chapters->Enable(true);
|
cb_no_chapters->Enable(true);
|
||||||
|
cb_no_attachments->Enable(true);
|
||||||
selected_file = -1;
|
selected_file = -1;
|
||||||
new_sel = lb_input_files->GetSelection();
|
new_sel = lb_input_files->GetSelection();
|
||||||
f = &files[new_sel];
|
f = &files[new_sel];
|
||||||
cb_no_chapters->SetValue(f->no_chapters);
|
cb_no_chapters->SetValue(f->no_chapters);
|
||||||
|
cb_no_attachments->SetValue(f->no_attachments);
|
||||||
|
|
||||||
clb_tracks->Clear();
|
clb_tracks->Clear();
|
||||||
for (i = 0; i < f->tracks->size(); i++) {
|
for (i = 0; i < f->tracks->size(); i++) {
|
||||||
@ -468,6 +478,11 @@ void tab_input::on_nochapters_clicked(wxCommandEvent &evt) {
|
|||||||
files[selected_file].no_chapters = cb_no_chapters->GetValue();
|
files[selected_file].no_chapters = cb_no_chapters->GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tab_input::on_noattachments_clicked(wxCommandEvent &evt) {
|
||||||
|
if (selected_file -1)
|
||||||
|
files[selected_file].no_attachments = cb_no_attachments->GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
void tab_input::on_track_selected(wxCommandEvent &evt) {
|
void tab_input::on_track_selected(wxCommandEvent &evt) {
|
||||||
mmg_file_t *f;
|
mmg_file_t *f;
|
||||||
mmg_track_t *t;
|
mmg_track_t *t;
|
||||||
@ -631,6 +646,7 @@ void tab_input::save(wxConfigBase *cfg) {
|
|||||||
cfg->SetPath(s);
|
cfg->SetPath(s);
|
||||||
cfg->Write("file_name", *f->file_name);
|
cfg->Write("file_name", *f->file_name);
|
||||||
cfg->Write("no_chapters", f->no_chapters);
|
cfg->Write("no_chapters", f->no_chapters);
|
||||||
|
cfg->Write("no_attachments", f->no_attachments);
|
||||||
|
|
||||||
cfg->Write("number_of_tracks", (int)f->tracks->size());
|
cfg->Write("number_of_tracks", (int)f->tracks->size());
|
||||||
for (tidx = 0; tidx < f->tracks->size(); tidx++) {
|
for (tidx = 0; tidx < f->tracks->size(); tidx++) {
|
||||||
@ -718,6 +734,7 @@ void tab_input::load(wxConfigBase *cfg) {
|
|||||||
}
|
}
|
||||||
fi.file_name = new wxString(s);
|
fi.file_name = new wxString(s);
|
||||||
cfg->Read("no_chapters", &fi.no_chapters);
|
cfg->Read("no_chapters", &fi.no_chapters);
|
||||||
|
cfg->Read("no_attachments", &fi.no_attachments);
|
||||||
fi.tracks = new vector<mmg_track_t>;
|
fi.tracks = new vector<mmg_track_t>;
|
||||||
|
|
||||||
for (tidx = 0; tidx < (uint32_t)num_tracks; tidx++) {
|
for (tidx = 0; tidx < (uint32_t)num_tracks; tidx++) {
|
||||||
@ -905,6 +922,7 @@ BEGIN_EVENT_TABLE(tab_input, wxPanel)
|
|||||||
EVT_CHECKLISTBOX(ID_CLB_TRACKS, tab_input::on_track_enabled)
|
EVT_CHECKLISTBOX(ID_CLB_TRACKS, tab_input::on_track_enabled)
|
||||||
|
|
||||||
EVT_CHECKBOX(ID_CB_NOCHAPTERS, tab_input::on_nochapters_clicked)
|
EVT_CHECKBOX(ID_CB_NOCHAPTERS, tab_input::on_nochapters_clicked)
|
||||||
|
EVT_CHECKBOX(ID_CB_NOATTACHMENTS, tab_input::on_noattachments_clicked)
|
||||||
EVT_CHECKBOX(ID_CB_MAKEDEFAULT, tab_input::on_default_track_clicked)
|
EVT_CHECKBOX(ID_CB_MAKEDEFAULT, tab_input::on_default_track_clicked)
|
||||||
EVT_CHECKBOX(ID_CB_AACISSBR, tab_input::on_aac_is_sbr_clicked)
|
EVT_CHECKBOX(ID_CB_AACISSBR, tab_input::on_aac_is_sbr_clicked)
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <matroska/KaxAttachments.h>
|
||||||
#include <matroska/KaxBlock.h>
|
#include <matroska/KaxBlock.h>
|
||||||
#include <matroska/KaxCluster.h>
|
#include <matroska/KaxCluster.h>
|
||||||
#include <matroska/KaxTracks.h>
|
#include <matroska/KaxTracks.h>
|
||||||
@ -118,7 +119,7 @@ typedef struct {
|
|||||||
vector<language_t> *track_names; // As given on the command line
|
vector<language_t> *track_names; // As given on the command line
|
||||||
char *track_name; // For this very track
|
char *track_name; // For this very track
|
||||||
|
|
||||||
bool no_chapters;
|
bool no_chapters, no_attachments, no_tags;
|
||||||
} track_info_t;
|
} track_info_t;
|
||||||
|
|
||||||
class generic_reader_c;
|
class generic_reader_c;
|
||||||
@ -234,6 +235,8 @@ public:
|
|||||||
virtual void set_headers() = 0;
|
virtual void set_headers() = 0;
|
||||||
virtual void identify() = 0;
|
virtual void identify() = 0;
|
||||||
|
|
||||||
|
virtual void add_attachments(KaxAttachments *a) {
|
||||||
|
};
|
||||||
// virtual void set_tag_track_uids() = 0;
|
// virtual void set_tag_track_uids() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -143,6 +143,9 @@ kax_reader_c::~kax_reader_c() {
|
|||||||
safefree(tracks[i]);
|
safefree(tracks[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < attachments.size(); i++)
|
||||||
|
safefree(attachments[i].data);
|
||||||
|
|
||||||
if (es != NULL)
|
if (es != NULL)
|
||||||
delete es;
|
delete es;
|
||||||
if (saved_l1 != NULL)
|
if (saved_l1 != NULL)
|
||||||
@ -464,10 +467,11 @@ void kax_reader_c::handle_attachments(mm_io_c *io, EbmlStream *es,
|
|||||||
KaxAttachments *atts;
|
KaxAttachments *atts;
|
||||||
KaxAttached *att;
|
KaxAttached *att;
|
||||||
EbmlElement *l1, *l2;
|
EbmlElement *l1, *l2;
|
||||||
|
UTFstring description, name;
|
||||||
int upper_lvl_el, i, k;
|
int upper_lvl_el, i, k;
|
||||||
string name, type;
|
string mime_type;
|
||||||
int64_t size, id;
|
int64_t size, id;
|
||||||
char *str;
|
unsigned char *data;
|
||||||
bool found;
|
bool found;
|
||||||
kax_attachment_t matt;
|
kax_attachment_t matt;
|
||||||
|
|
||||||
@ -484,8 +488,9 @@ void kax_reader_c::handle_attachments(mm_io_c *io, EbmlStream *es,
|
|||||||
for (i = 0; i < atts->ListSize(); i++) {
|
for (i = 0; i < atts->ListSize(); i++) {
|
||||||
att = (KaxAttached *)(*atts)[i];
|
att = (KaxAttached *)(*atts)[i];
|
||||||
if (EbmlId(*att) == KaxAttached::ClassInfos.GlobalId) {
|
if (EbmlId(*att) == KaxAttached::ClassInfos.GlobalId) {
|
||||||
name = "";
|
name = L"";
|
||||||
type = "";
|
mime_type = "";
|
||||||
|
description = L"";
|
||||||
size = -1;
|
size = -1;
|
||||||
id = -1;
|
id = -1;
|
||||||
|
|
||||||
@ -494,13 +499,15 @@ void kax_reader_c::handle_attachments(mm_io_c *io, EbmlStream *es,
|
|||||||
|
|
||||||
if (EbmlId(*l2) == KaxFileName::ClassInfos.GlobalId) {
|
if (EbmlId(*l2) == KaxFileName::ClassInfos.GlobalId) {
|
||||||
KaxFileName &fname = *static_cast<KaxFileName *>(l2);
|
KaxFileName &fname = *static_cast<KaxFileName *>(l2);
|
||||||
str = UTFstring_to_cstr(UTFstring(fname));
|
name = UTFstring(fname);
|
||||||
name = str;
|
|
||||||
safefree(str);
|
} else if (EbmlId(*l2) == KaxFileDescription::ClassInfos.GlobalId) {
|
||||||
|
KaxFileDescription &fdesc = *static_cast<KaxFileDescription *>(l2);
|
||||||
|
description = UTFstring(fdesc);
|
||||||
|
|
||||||
} else if (EbmlId(*l2) == KaxMimeType::ClassInfos.GlobalId) {
|
} else if (EbmlId(*l2) == KaxMimeType::ClassInfos.GlobalId) {
|
||||||
KaxMimeType &mtype = *static_cast<KaxMimeType *>(l2);
|
KaxMimeType &mtype = *static_cast<KaxMimeType *>(l2);
|
||||||
type = string(mtype);
|
mime_type = string(mtype);
|
||||||
|
|
||||||
} else if (EbmlId(*l2) == KaxFileUID::ClassInfos.GlobalId) {
|
} else if (EbmlId(*l2) == KaxFileUID::ClassInfos.GlobalId) {
|
||||||
KaxFileUID &fuid = *static_cast<KaxFileUID *>(l2);
|
KaxFileUID &fuid = *static_cast<KaxFileUID *>(l2);
|
||||||
@ -509,11 +516,12 @@ void kax_reader_c::handle_attachments(mm_io_c *io, EbmlStream *es,
|
|||||||
} else if (EbmlId(*l2) == KaxFileData::ClassInfos.GlobalId) {
|
} else if (EbmlId(*l2) == KaxFileData::ClassInfos.GlobalId) {
|
||||||
KaxFileData &fdata = *static_cast<KaxFileData *>(l2);
|
KaxFileData &fdata = *static_cast<KaxFileData *>(l2);
|
||||||
size = fdata.GetSize();
|
size = fdata.GetSize();
|
||||||
|
data = (unsigned char *)fdata.GetBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((id != -1) && (size != -1) && (type.length() != 0)) {
|
if ((id != -1) && (size != -1) && (mime_type.length() > 0) &&
|
||||||
|
(name.length() > 0)) {
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
for (k = 0; k < attachments.size(); k++)
|
for (k = 0; k < attachments.size(); k++)
|
||||||
@ -524,9 +532,11 @@ void kax_reader_c::handle_attachments(mm_io_c *io, EbmlStream *es,
|
|||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
matt.name = name;
|
matt.name = name;
|
||||||
matt.type = type;
|
matt.mime_type = mime_type;
|
||||||
|
matt.description = description;
|
||||||
matt.size = size;
|
matt.size = size;
|
||||||
matt.id = id;
|
matt.id = id;
|
||||||
|
matt.data = (unsigned char *)safememdup(data, size);
|
||||||
attachments.push_back(matt);
|
attachments.push_back(matt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1487,6 +1497,7 @@ void kax_reader_c::set_headers() {
|
|||||||
void kax_reader_c::identify() {
|
void kax_reader_c::identify() {
|
||||||
int i;
|
int i;
|
||||||
string info;
|
string info;
|
||||||
|
char *str;
|
||||||
|
|
||||||
mxinfo("File '%s': container: Matroska\n", ti->fname);
|
mxinfo("File '%s': container: Matroska\n", ti->fname);
|
||||||
for (i = 0; i < tracks.size(); i++)
|
for (i = 0; i < tracks.size(); i++)
|
||||||
@ -1511,12 +1522,20 @@ void kax_reader_c::identify() {
|
|||||||
|
|
||||||
for (i = 0; i < attachments.size(); i++) {
|
for (i = 0; i < attachments.size(); i++) {
|
||||||
mxinfo("Attachment ID %lld: type '%s', size %lld bytes, ",
|
mxinfo("Attachment ID %lld: type '%s', size %lld bytes, ",
|
||||||
attachments[i].id, attachments[i].type.c_str(),
|
attachments[i].id, attachments[i].mime_type.c_str(),
|
||||||
attachments[i].size);
|
attachments[i].size);
|
||||||
|
if (attachments[i].description.length() > 0) {
|
||||||
|
str = UTFstring_to_cstr(attachments[i].description.c_str());
|
||||||
|
mxinfo("description '%s', ", str);
|
||||||
|
safefree(str);
|
||||||
|
}
|
||||||
if (attachments[i].name.length() == 0)
|
if (attachments[i].name.length() == 0)
|
||||||
mxinfo("no file name given\n");
|
mxinfo("no file name given\n");
|
||||||
else
|
else {
|
||||||
mxinfo("file name '%s'\n", attachments[i].name.c_str());
|
str = UTFstring_to_cstr(attachments[i].name.c_str());
|
||||||
|
mxinfo("file name '%s'\n", str);
|
||||||
|
safefree(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1533,3 +1552,37 @@ int64_t kax_reader_c::get_queued_bytes() {
|
|||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kax_reader_c::add_attachments(KaxAttachments *a) {
|
||||||
|
uint32_t i;
|
||||||
|
KaxAttached *attached;
|
||||||
|
KaxFileData *fdata;
|
||||||
|
binary *buffer;
|
||||||
|
|
||||||
|
if (ti->no_attachments)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < attachments.size(); i++) {
|
||||||
|
attached = new KaxAttached;
|
||||||
|
if (attachments[i].description.length() > 0)
|
||||||
|
*static_cast<EbmlUnicodeString *>
|
||||||
|
(&GetChild<KaxFileDescription>(*attached)) =
|
||||||
|
attachments[i].description;
|
||||||
|
|
||||||
|
*static_cast<EbmlString *>(&GetChild<KaxMimeType>(*attached)) =
|
||||||
|
attachments[i].mime_type;
|
||||||
|
|
||||||
|
*static_cast<EbmlUnicodeString *>(&GetChild<KaxFileName>(*attached)) =
|
||||||
|
attachments[i].name;
|
||||||
|
|
||||||
|
*static_cast<EbmlUInteger *>(&GetChild<KaxFileUID>(*attached)) =
|
||||||
|
attachments[i].id;
|
||||||
|
|
||||||
|
fdata = &GetChild<KaxFileData>(*attached);
|
||||||
|
buffer = new binary[attachments[i].size];
|
||||||
|
memcpy(buffer, attachments[i].data, attachments[i].size);
|
||||||
|
fdata->SetBuffer(buffer, attachments[i].size);
|
||||||
|
|
||||||
|
a->PushElement(*attached);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -32,14 +32,19 @@
|
|||||||
#include "pr_generic.h"
|
#include "pr_generic.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
|
#include <ebml/EbmlUnicodeString.h>
|
||||||
|
|
||||||
#include <matroska/KaxBlock.h>
|
#include <matroska/KaxBlock.h>
|
||||||
#include <matroska/KaxCluster.h>
|
#include <matroska/KaxCluster.h>
|
||||||
|
|
||||||
|
using namespace libebml;
|
||||||
using namespace libmatroska;
|
using namespace libmatroska;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
string name, type;
|
string mime_type;
|
||||||
|
UTFstring name, description;
|
||||||
|
unsigned char *data;
|
||||||
int64 size, id;
|
int64 size, id;
|
||||||
} kax_attachment_t;
|
} kax_attachment_t;
|
||||||
|
|
||||||
@ -118,6 +123,7 @@ public:
|
|||||||
virtual void display_progress(bool final = false);
|
virtual void display_progress(bool final = false);
|
||||||
virtual void set_headers();
|
virtual void set_headers();
|
||||||
virtual void identify();
|
virtual void identify();
|
||||||
|
virtual void add_attachments(KaxAttachments *a);
|
||||||
|
|
||||||
static int probe_file(mm_io_c *mm_io, int64_t size);
|
static int probe_file(mm_io_c *mm_io, int64_t size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user