Added support for the "stereo mode" flag for video tracks.

This commit is contained in:
Moritz Bunkus 2006-11-07 15:11:49 +00:00
parent 787bd740d5
commit 8083266e1d
9 changed files with 157 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2006-11-07 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: new feature: Added support for the "stereo mode"
flag for video tracks.
2006-11-03 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: bug fix: For MP4 files with certain CTTS contents

View File

@ -452,6 +452,12 @@ exclusive.
.TP
\fB\-\-cropping\fR <\fITID\fR:\fIleft\fR,\fItop\fR,\fIright\fR,\fIbottom\fR>
Sets the pixel cropping parameters of a video track to the given values.
.TP
\fB\-\-stereo\-mode\fR <\fITID\fR:\fIn\fR|\fIkeyword\fR>
Sets the stereo mode for the video track with the track ID \fITID\fR.
The mode can either be a number \fIn\fR between 0 and 3 or one of the
keywords \fInone\fR (same as n=0), \fIright\fR (same as n=1), \fIleft\fR
(same as n=2) or \fIboth\fR (same as n=3).
.LP
Options that only apply to text subtitle tracks:
.TP

View File

@ -1045,6 +1045,7 @@ kax_reader_c::read_headers() {
KaxVideoPixelCropTop *kv_pctop;
KaxVideoPixelCropRight *kv_pcright;
KaxVideoPixelCropBottom *kv_pcbottom;
KaxVideoStereoMode *kv_stereo_mode;
kv_pwidth = FINDFIRST(ktvideo, KaxVideoPixelWidth);
if (kv_pwidth != NULL) {
@ -1118,6 +1119,13 @@ kax_reader_c::read_headers() {
track->v_pcbottom);
}
kv_stereo_mode = FINDFIRST(ktvideo, KaxVideoStereoMode);
if (NULL != kv_stereo_mode) {
track->v_stereo_mode = (stereo_mode_e)uint64(*kv_stereo_mode);
mxverb(2, PFX "| + Stereo mode: %d\n",
(int)track->v_stereo_mode);
}
}
kcodecid = FINDFIRST(ktentry, KaxCodecID);
@ -1353,6 +1361,8 @@ kax_reader_c::init_passthrough_packetizer(kax_track_t *t) {
(t->v_pcright > 0) || (t->v_pcbottom > 0)))
ptzr->set_video_pixel_cropping(t->v_pcleft, t->v_pctop,
t->v_pcright, t->v_pcbottom);
if (STEREO_MODE_UNSPECIFIED == ptzr->ti.stereo_mode)
ptzr->set_stereo_mode(t->v_stereo_mode);
if (ptzr->get_cue_creation() == CUE_STRATEGY_UNSPECIFIED)
ptzr->set_cue_creation( CUE_STRATEGY_IFRAMES);
@ -1505,6 +1515,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
PTZR(t->ptzr)->set_video_pixel_cropping(t->v_pcleft, t->v_pctop,
t->v_pcright,
t->v_pcbottom);
if (STEREO_MODE_UNSPECIFIED == PTZR(t->ptzr)->ti.stereo_mode)
PTZR(t->ptzr)->set_stereo_mode(t->v_stereo_mode);
} else
init_passthrough_packetizer(t);

View File

@ -55,6 +55,7 @@ struct kax_track_t {
// Parameters for video tracks
uint64_t v_width, v_height, v_dwidth, v_dheight;
uint64_t v_pcleft, v_pctop, v_pcright, v_pcbottom;
stereo_mode_e v_stereo_mode;
float v_frate;
char v_fourcc[5];
bool v_bframes;
@ -97,6 +98,7 @@ struct kax_track_t {
lacing_flag(false),
v_width(0), v_height(0), v_dwidth(0), v_dheight(0),
v_pcleft(0), v_pctop(0), v_pcright(0), v_pcbottom(0),
v_stereo_mode(STEREO_MODE_UNSPECIFIED),
v_frate(0.0),
v_bframes(false),
a_channels(0), a_bps(0), a_formattag(0),

View File

@ -231,6 +231,10 @@ set_usage() {
" Explicitely set the display dimensions.\n"
" --cropping <TID:left,top,right,bottom>\n"
" Sets the cropping parameters.\n"
" --stereo-mode <TID:n|none|left|right|both>\n"
" Sets the stereo mode parameter. It can\n"
" either be a numer 0 - 3 or one of the\n"
" keywords 'none', 'right', 'left' or 'both'.\n"
"\n Options that only apply to text subtitle tracks:\n"
" --sub-charset <TID:charset>\n"
" Sets the charset the text subtitles are\n"
@ -668,6 +672,45 @@ parse_cropping(const string &s,
ti.pixel_crop_list[id] = crop;
}
/** \brief Parse the \c --stereo-mode argument
The argument must either be a number between 0 and 3 or
one of the keywords \c 'none', \c 'left', \c 'right' or \c 'both'.
*/
static void
parse_stereo_mode(const string &s,
track_info_c &ti) {
static const char * const keywords[] = {
"none", "right", "left", "both", NULL
};
static const char *errmsg =
_("Stereo mode parameter: not given in the form "
"<TID>:<n|keyword> where n is a number between 0 and 3 "
"or one of the keywords 'none', 'right', 'left', 'both' "
"(argument was '%s').\n");
int64_t i, id;
vector<string> v;
v = split(s, ":");
if (v.size() != 2)
mxerror(errmsg, s.c_str());
id = 0;
if (!parse_int(v[0], id))
mxerror(errmsg, s.c_str());
for (i = 0; NULL != keywords[i]; ++i)
if (v[1] == keywords[i]) {
ti.stereo_mode_list[id] = (stereo_mode_e)i;
return;
}
if (!parse_int(v[1], i) || (i < 0) || (i > STEREO_MODE_BOTH))
mxerror(errmsg, s.c_str());
ti.stereo_mode_list[id] = (stereo_mode_e)i;
}
/** \brief Parse the duration formats to \c --split
This function is called by ::parse_split if the format specifies
@ -1806,6 +1849,13 @@ parse_args(vector<string> args) {
parse_cropping(next_arg, *ti);
sit++;
} else if (this_arg == "--stereo-mode") {
if (no_next_arg)
mxerror(_("'--stereo-mode' lacks the crop parameters.\n"));
parse_stereo_mode(next_arg, *ti);
sit++;
} else if ((this_arg == "-y") || (this_arg == "--sync")) {
if (no_next_arg)
mxerror(_("'%s' lacks the audio delay.\n"), this_arg.c_str());

View File

@ -182,6 +182,12 @@ generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader,
else
ti.pixel_cropping_specified = false;
// Let's see if the user has specified a stereo mode for this track.
if (map_has_key(ti.stereo_mode_list, ti.id))
ti.stereo_mode = ti.stereo_mode_list[ti.id];
else if (map_has_key(ti.stereo_mode_list, -1))
ti.stereo_mode = ti.stereo_mode_list[-1];
// Let's see if the user has specified a default duration for this track.
htrack_default_duration = -1;
default_duration_forced = true;
@ -527,6 +533,19 @@ generic_packetizer_c::set_video_pixel_cropping(int left,
}
}
void
generic_packetizer_c::set_stereo_mode(stereo_mode_e stereo_mode) {
ti.stereo_mode = stereo_mode;
if ((NULL != track_entry) &&
(STEREO_MODE_UNSPECIFIED != stereo_mode)) {
KaxTrackVideo &video = GetChild<KaxTrackVideo>(*track_entry);
*(static_cast<EbmlUInteger *>
(&GetChild<KaxVideoStereoMode>(video))) = ti.stereo_mode;
}
}
void
generic_packetizer_c::set_headers() {
int idx, disp_width, disp_height;
@ -689,6 +708,10 @@ generic_packetizer_c::set_headers() {
(&GetChild<KaxVideoPixelCropBottom>(video))) =
ti.pixel_cropping.bottom;
}
if (STEREO_MODE_UNSPECIFIED != ti.stereo_mode)
*(static_cast<EbmlUInteger *>
(&GetChild<KaxVideoStereoMode>(video))) = ti.stereo_mode;
}
} else if (htrack_type == track_audio) {
@ -1393,6 +1416,7 @@ track_info_c::track_info_c():
packet_delay(0),
compression(COMPRESSION_UNSPECIFIED),
pixel_cropping_specified(false),
stereo_mode(STEREO_MODE_UNSPECIFIED),
no_chapters(false),
no_attachments(false),
no_tags(false),
@ -1482,6 +1506,9 @@ track_info_c::operator =(const track_info_c &src) {
pixel_cropping = src.pixel_cropping;
pixel_cropping_specified = src.pixel_cropping_specified;
stereo_mode_list = src.stereo_mode_list;
stereo_mode = src.stereo_mode;
no_chapters = src.no_chapters;
no_attachments = src.no_attachments;
no_tags = src.no_tags;

View File

@ -103,6 +103,14 @@ struct pixel_crop_t {
pixel_crop_t(): left(0), top(0), right(0), bottom(0) {}
};
enum stereo_mode_e {
STEREO_MODE_UNSPECIFIED = -1,
STEREO_MODE_NONE = 0,
STEREO_MODE_RIGHT = 1,
STEREO_MODE_LEFT = 2,
STEREO_MODE_BOTH = 3,
};
class track_info_c {
protected:
bool initialized;
@ -163,6 +171,9 @@ public:
pixel_crop_t pixel_cropping; // For this very track
bool pixel_cropping_specified;
map<int64_t, stereo_mode_e> stereo_mode_list; // As given on the command line
stereo_mode_e stereo_mode; // For this very track
map<int64_t, int64_t> default_durations; // As given on the command line
map<int64_t, int> max_blockadd_ids; // As given on the command line
@ -448,6 +459,7 @@ public:
}
virtual void set_video_pixel_cropping(int left, int top, int right,
int bottom);
virtual void set_stereo_mode(stereo_mode_e stereo_mode);
virtual void set_as_default_track(int type, int priority);

View File

@ -68,3 +68,4 @@ T_218theora:35ea3cf1add9a6687627953e1645d4c9-fac4b041366588e3c8215b9fbb696db2:pa
T_219srt_short_timecodes:a7db07ee64751fcc24993dd4af73ccf1:passed:20060926-112658
T_220ass_with_comments_at_start:51ccd0cbe4e60b21817d7547310250bb:passed:20060926-120101
T_221aac_lc_misdetected_as_sbr:f980b6252a24a5f855ec90e3d9d3a1fe:passed:20061103-174221
T_222stereo_mode:22eebd6bda7d848379044be8d9d8f440-38a1988c087c40e6e52025bb974f2c56-38a1988c087c40e6e52025bb974f2c56:passed:20061107-092251

View File

@ -0,0 +1,42 @@
#!/usr/bin/ruby -w
class T_222stereo_mode < Test
def description
return "mkvmerge / Stereo mode flag for video tracks / in(AVI)"
end
def run
merge(tmp + "-1",
"-A --stereo-mode 0:none data/avi/v.avi " +
"-A --stereo-mode 0:right data/avi/v.avi " +
"-A --stereo-mode 0:left data/avi/v.avi " +
"-A --stereo-mode 0:both data/avi/v.avi ")
if (!FileTest.exist?(tmp + "-1"))
error("First merge failed")
end
hash = hash_file(tmp + "-1")
merge(tmp + "-2",
"--stereo-mode 4:none --stereo-mode 3:right " +
"--stereo-mode 2:left --stereo-mode 1:both #{tmp}-1")
File.unlink(tmp + "-1")
if (!FileTest.exist?(tmp + "-2"))
error("Second merge failed")
end
hash += "-" + hash_file(tmp + "-2")
merge(tmp + "-3", tmp + "-2")
File.unlink(tmp + "-2")
if (!FileTest.exist?(tmp + "-3"))
error("Third merge failed")
end
hash += "-" + hash_file(tmp + "-3")
File.unlink(tmp + "-3")
return hash
end
end