mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 20:01:53 +00:00
The start of support for situations like this: the user appends an AVI to an AVI and VobSubs to VobSubs. In such a case simply using the previous file's max timecode won't work for the subtitle-only files. Therefore mkvmerge has to look for an "associated" file whose max timecode it has to use. This has not been finished yet.
This commit is contained in:
parent
aae24e6fef
commit
df7fcc62de
@ -138,7 +138,7 @@ cluster_helper_c::add_packet(packet_t *packet) {
|
||||
if (splitting && (file_num <= split_max_num_files) &&
|
||||
(packet->bref == -1) &&
|
||||
((packet->source->get_track_type() == track_video) ||
|
||||
!video_track_present)) {
|
||||
(video_packetizer == NULL))) {
|
||||
split = false;
|
||||
c = clusters[num_clusters - 1];
|
||||
if (first_timecode_in_file == -1)
|
||||
@ -536,7 +536,8 @@ cluster_helper_c::render_cluster(ch_contents_t *clstr) {
|
||||
// ... or if this is an audio track, there is no video track and the
|
||||
// last cue entry was created more than 2s ago.
|
||||
((source->get_cue_creation() == CUES_SPARSE) &&
|
||||
(source->get_track_type() == track_audio) && !video_track_present &&
|
||||
(source->get_track_type() == track_audio) &&
|
||||
(video_packetizer == NULL) &&
|
||||
((source->get_last_cue_timecode() < 0) ||
|
||||
((pack->assigned_timecode - source->get_last_cue_timecode()) >=
|
||||
2000000000)))) {
|
||||
|
@ -323,8 +323,6 @@ identify(const string &filename) {
|
||||
file.name);
|
||||
|
||||
file.appending = false;
|
||||
file.fp = NULL;
|
||||
file.status = EMOREDATA;
|
||||
file.pack = NULL;
|
||||
file.ti = new track_info_c(ti);
|
||||
|
||||
@ -1725,11 +1723,10 @@ parse_args(vector<string> &args) {
|
||||
"your file type is supported but not recognized "
|
||||
"properly.\n"), file.name);
|
||||
|
||||
file.fp = NULL;
|
||||
if (file.type != TYPECHAPTERS) {
|
||||
file.status = EMOREDATA;
|
||||
file.pack = NULL;
|
||||
file.ti = ti;
|
||||
file.done = false;
|
||||
|
||||
files.push_back(file);
|
||||
} else {
|
||||
|
@ -113,7 +113,7 @@ int64_t file_sizes = 0;
|
||||
int max_blocks_per_cluster = 65535;
|
||||
int64_t max_ns_per_cluster = 2000000000;
|
||||
bool write_cues = true, cue_writing_requested = false;
|
||||
bool video_track_present = false;
|
||||
generic_packetizer_c *video_packetizer = NULL;
|
||||
bool write_meta_seek_for_clusters = true;
|
||||
bool no_lacing = false, no_linking = true;
|
||||
int64_t split_after = -1;
|
||||
@ -464,7 +464,7 @@ render_headers(mm_io_c *rout) {
|
||||
|
||||
kax_infos = &GetChild<KaxInfo>(*kax_segment);
|
||||
|
||||
if (!video_track_present ||
|
||||
if ((video_packetizer == NULL) ||
|
||||
(timecode_scale_mode == timecode_scale_mode_auto))
|
||||
kax_duration = new KaxMyDuration(EbmlFloat::FLOAT_64);
|
||||
else
|
||||
@ -1511,9 +1511,36 @@ append_track(packetizer_t &ptzr,
|
||||
// If we're dealing with a subtitle track or if the appending file contains
|
||||
// chapters then we have to suck the previous file dry. See below for the
|
||||
// reason (short version: we need all max_timecode_seen values).
|
||||
if (((*gptzr)->get_track_type() == track_subtitle) ||
|
||||
(src_file.reader->chapters != NULL))
|
||||
if ((((*gptzr)->get_track_type() == track_subtitle) ||
|
||||
(src_file.reader->chapters != NULL)) &&
|
||||
!dst_file.done) {
|
||||
vector<deferred_connection_t>::const_iterator def_con;
|
||||
|
||||
dst_file.reader->read_all();
|
||||
dst_file.done = true;
|
||||
foreach(def_con, dst_file.deferred_connections)
|
||||
append_track(*def_con->ptzr, def_con->amap);
|
||||
dst_file.deferred_connections.clear();
|
||||
}
|
||||
|
||||
if (((*gptzr)->get_track_type() == track_subtitle) &&
|
||||
(dst_file.reader->num_video_tracks == 0) &&
|
||||
(video_packetizer != NULL) && !ptzr.deferred) {
|
||||
vector<filelist_t>::iterator file;
|
||||
|
||||
foreach(file, files) {
|
||||
if (mxfind(video_packetizer, file->reader->reader_packetizers) !=
|
||||
file->reader->reader_packetizers.end()) {
|
||||
deferred_connection_t new_def_con;
|
||||
|
||||
ptzr.deferred = true;
|
||||
new_def_con.amap = amap;
|
||||
new_def_con.ptzr = &ptzr;
|
||||
file->deferred_connections.push_back(new_def_con);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mxinfo("Appending track %lld from file no. %lld ('%s') to track %lld from "
|
||||
"file no. %lld ('%s').\n",
|
||||
@ -1550,8 +1577,9 @@ append_track(packetizer_t &ptzr,
|
||||
// But then again I don't expect that people will try to concatenate such
|
||||
// files if they've been split before.
|
||||
timecode_adjustment = dst_file.reader->max_timecode_seen;
|
||||
if ((ptzr.packetizer->get_track_type() == track_subtitle) ||
|
||||
(src_file.reader->chapters != NULL)) {
|
||||
if (((ptzr.packetizer->get_track_type() == track_subtitle) ||
|
||||
(src_file.reader->chapters != NULL)) &&
|
||||
!ptzr.deferred) {
|
||||
vector<append_spec_t>::const_iterator cmp_amap;
|
||||
|
||||
if (src_file.reader->ptzr_first_packet == NULL)
|
||||
@ -1587,6 +1615,8 @@ append_track(packetizer_t &ptzr,
|
||||
delete src_file.reader->chapters;
|
||||
src_file.reader->chapters = NULL;
|
||||
}
|
||||
|
||||
ptzr.deferred = false;
|
||||
}
|
||||
|
||||
/** \brief Decide if packetizers have to be appended
|
||||
@ -1605,6 +1635,8 @@ append_tracks_maybe() {
|
||||
|
||||
appended_a_track = false;
|
||||
foreach(ptzr, packetizers) {
|
||||
if (ptzr->deferred)
|
||||
continue;
|
||||
if (!files[ptzr->orig_file].appended_to)
|
||||
continue;
|
||||
if ((ptzr->status == EMOREDATA) || (ptzr->status == EHOLDING))
|
||||
|
@ -38,26 +38,40 @@ class generic_packetizer_c;
|
||||
class generic_reader_c;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
mm_io_c *fp;
|
||||
|
||||
int type, status;
|
||||
|
||||
packet_t *pack;
|
||||
|
||||
generic_reader_c *reader;
|
||||
|
||||
track_info_c *ti;
|
||||
bool appending, appended_to;
|
||||
} filelist_t;
|
||||
int64_t src_file_id;
|
||||
int64_t src_track_id;
|
||||
int64_t dst_file_id;
|
||||
int64_t dst_track_id;
|
||||
} append_spec_t;
|
||||
|
||||
typedef struct packetizer_t {
|
||||
int status;
|
||||
packet_t *pack;
|
||||
generic_packetizer_c *packetizer, *orig_packetizer;
|
||||
int64_t file, orig_file;
|
||||
bool deferred;
|
||||
} packetizer_t;
|
||||
|
||||
typedef struct {
|
||||
append_spec_t amap;
|
||||
packetizer_t *ptzr;
|
||||
} deferred_connection_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
int type;
|
||||
|
||||
packet_t *pack;
|
||||
|
||||
generic_reader_c *reader;
|
||||
|
||||
track_info_c *ti;
|
||||
bool appending, appended_to, done;
|
||||
|
||||
vector<deferred_connection_t> deferred_connections;
|
||||
} filelist_t;
|
||||
|
||||
typedef struct {
|
||||
char *name, *mime_type, *description;
|
||||
int64_t size;
|
||||
@ -69,13 +83,6 @@ typedef struct {
|
||||
int64_t track_id;
|
||||
} track_order_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t src_file_id;
|
||||
int64_t src_track_id;
|
||||
int64_t dst_file_id;
|
||||
int64_t dst_track_id;
|
||||
} append_spec_t;
|
||||
|
||||
enum timecode_scale_mode_t {
|
||||
timecode_scale_mode_normal = 0,
|
||||
timecode_scale_mode_fixed,
|
||||
@ -116,7 +123,8 @@ extern string default_language;
|
||||
|
||||
extern float video_fps;
|
||||
|
||||
extern bool write_cues, cue_writing_requested, video_track_present;
|
||||
extern generic_packetizer_c *video_packetizer;
|
||||
extern bool write_cues, cue_writing_requested;
|
||||
extern bool no_lacing, no_linking, use_durations;
|
||||
|
||||
extern bool identifying, identify_verbose;
|
||||
|
@ -324,6 +324,14 @@ generic_packetizer_c::set_track_type(int type) {
|
||||
|
||||
if ((type == track_audio) && (ti->cues == CUES_UNSPECIFIED))
|
||||
ti->cues = CUES_SPARSE;
|
||||
if (type == track_audio)
|
||||
reader->num_audio_tracks++;
|
||||
else if (type == track_video) {
|
||||
reader->num_video_tracks++;
|
||||
if (video_packetizer == NULL)
|
||||
video_packetizer = this;
|
||||
} else
|
||||
reader->num_subtitle_tracks++;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1023,6 +1031,9 @@ generic_reader_c::generic_reader_c(track_info_c *nti) {
|
||||
appending = false;
|
||||
chapters = NULL;
|
||||
ptzr_first_packet = NULL;
|
||||
num_video_tracks = 0;
|
||||
num_audio_tracks = 0;
|
||||
num_subtitle_tracks = 0;
|
||||
|
||||
add_all_requested_track_ids2(atracks);
|
||||
add_all_requested_track_ids2(vtracks);
|
||||
|
@ -253,6 +253,7 @@ public:
|
||||
int64_t max_timecode_seen;
|
||||
KaxChapters *chapters;
|
||||
bool appending;
|
||||
int num_video_tracks, num_audio_tracks, num_subtitle_tracks;
|
||||
|
||||
public:
|
||||
generic_reader_c(track_info_c *nti);
|
||||
|
@ -50,7 +50,6 @@ video_packetizer_c::video_packetizer_c(generic_reader_c *nreader,
|
||||
ref_timecode = -1;
|
||||
if (get_cue_creation() == CUES_UNSPECIFIED)
|
||||
set_cue_creation(CUES_IFRAMES);
|
||||
video_track_present = true;
|
||||
duration_shift = 0;
|
||||
bref_frame.type = '?';
|
||||
fref_frame.type = '?';
|
||||
|
Loading…
Reference in New Issue
Block a user