Log in

View Full Version : A script for timecode-based VFR mp4


zmi
9th June 2006, 13:34
I've made a script and executable to make a VFR mp4 from mkv timecode file.

It can download from rapidshare.
http://sidheog.org/Documents/tc2mp4_20070124.rar

password: doom9.org

zmi
9th June 2006, 13:35
Description

Merge timecode into mp4

requirement:
avisynth with TIVTC plug-in
x264
mp4box

usage:
tc2mp4 -i [source CFR-mp4] -t [timecode file] -o [destination VFR-mp4] [-k] [-n TrackNumber]

example:
1. Prepare CFR-mp4 and timecode format v1/v2 file.
- You can use AVISynth script like below.
:example.avs:
DGDecode_mpeg2source("example.d2v")
tfm(d2v="example.d2v").tdecimate(mode=3,hybrid=2,vfrDec=1,mkvOut="example_timecode.txt")

- Encode.
x264 --output example.mp4 example.avs

2. Merge timecode into mp4
tc2mp4 -i example.mp4 -t example_timecode.txt -o example_vfr.mp4

3. Merge audio into mp4
mp4box -add example.aac example_vfr.mp4


2006/06/09 First release
2007/01/24 Support directory which name contains space.
Add -n flag to specify track number to extract.
Add -k flag to keep modified nhml file.

zmi
9th June 2006, 13:38
Perl script


#!/usr/bin/perl
# author: zmi
# version: 01/24/2007
# info: http://d.hatena.ne.jp/zmi/ (japanese)
# info: http://forum.doom9.org/showthread.php?t=112199 (english)

use Getopt::Std;
use Math::BigInt;
use File::Basename;

$usage = <<USAGE
tc2mp4 (01/24/2007)
usage: tc2mp4 -i InputFile -o OutputFile -t TimecodeFile [-k] [-n TrackNumber]
USAGE
;

getopts('i:t:o:n:kh');

die $usage if $opt_h;
$srcMP4 = $opt_i or die $usage;
$dstMP4 = $opt_o or die $usage;
$srcTC = $opt_t or die $usage;
$number = ($opt_n or 1);
$keep = $opt_k;
@extlist = ('\.mp4','\.m4v');
($basename, $dir) = fileparse($opt_i, @extlist);
$srcNHML = "${dir}${basename}_track$number.nhml";
$tcNHML = "${dir}${basename}_track$number_tc.nhml";

doCmd("mp4box -nhml $number \"$srcMP4\"");

$tcfv = detectTCFVersion($srcTC);

print "[Timecode info]\n";
print " Timecode format(v$tcfv)\n";

if($tcfv == 1){
@timescales = parseTimecodeV1($srcTC);

$ntsc = detectNTSC($srcTC);

for($frame = 0; $frame < @timescales; $frame++){
$factors{$timescales[$frame]}++;
}

$lcmTimescale = Math::BigInt::blcm(keys %factors);

# generate CTS from timecode
@cts = toCTS(\@timescales, $lcmTimescale, $ntsc);

print " Total frames(".@cts."), LCM Timescale($lcmTimescale)\n";
print " " . ($ntsc ? 'NTSC, ' : '') ."Factors(" . join('/',sort keys %factors) . ")\n";
}elsif($tcfv == 2){
$lcmTimescale = 1000000;
@cts = parseTimecodeV2($srcTC);

print " Total frames(".@cts."), Timescale($lcmTimescale)\n";
}

# read Timebase from source nhml
$timebase = readTimebase($srcNHML);

print "[NHML info]\n";
print " Timebase($timebase)\n";

applyTimecode($srcNHML, $tcNHML, $timebase, \@cts);

doCmd("mp4box -add \"$tcNHML\" -new \"$dstMP4\"");

unlink("$srcNHML");
unlink("$tcNHML") unless $keep;
unlink("${basename}_track$number.info","${dir}${basename}_track$number.media");

doCmd("mp4box -info \"$dstMP4\"");

print "Completed.\n";
exit 0;

sub doCmd{
my $cmd = shift @_;
print "$cmd\n";
system($cmd) and die $!;
}

sub applyTimecode{
my $srcNHML = shift @_;
my $tcNHML = shift @_;
my $timebase = shift @_;
my @cts = @{shift @_};

my $dtsFrame = 0,$dts;
my $ctsFrame,$ctsOffset,$cts;
my $delayFrame,$delayTC;

open SRC_NHML, "<$srcNHML" or die $!;
open TC_NHML, ">$tcNHML" or die $!;

while(<SRC_NHML>){
s/timeScale="\d+"/timeScale="$lcmTimescale"/ if(/<NHNTStream.*?>/);

((print TC_NHML), next) unless /<NHNTSample.*\/>/;

next unless $dtsFrame < @cts;

/CTSOffset="(\d+)"/;
$ctsOffset = ($1 or 0);

$ctsFrame = $dtsFrame + int($ctsOffset / $timebase + 0.5);

if($dtsFrame == 0){
$delayFrame = $ctsFrame;
$delayTC = $cts[$delayFrame];
print "[Delay]\n";
print " Frames($delayFrame), Timecode($delayTC) Milliseconds(" . ($delayTC * 1000 / $lcmTimescale) . ")\n";
}

if($dtsFrame < $delayFrame){
$dts = $cts[$dtsFrame];
$cts = $cts[$ctsFrame];
}else{
$dts = $cts[$dtsFrame - $delayFrame] + $delayTC;
$cts = $cts[$ctsFrame - $delayFrame] + $delayTC;
}
$ctsOffset = $cts - $dts;

s/DTS="\d+"/DTS="$dts"/;
s/CTSOffset="\d+"/CTSOffset="$ctsOffset"/;
s/(dataLength="\d+")/$1 CTSOffset="$ctsOffset"/ if $ctsOffset == 0; # hack for mp4box's bug
print TC_NHML;

$dtsFrame++;
}

close SRC_NHML;
close TC_NHML;
}

sub toCTS{
my @timescales = @{shift @_};
my $lcmTimescale = shift @_;
my $ntsc = shift @_;
my @cts, $frame, $duration;
my $step = $ntsc ? 1001 : 1000;

$cts[0] = 0;
for($frame = 1; $frame < @timescales; $frame++){
$duration = ($lcmTimescale / $timescales[$frame -1]) * $step;
$cts[$frame] = $cts[$frame -1] + $duration;
}
return @cts;
}

sub readTimebase{
my $nhmlFile = shift @_;
my @dts;
my $timebase;
my $count = 0;

open NHML, "<$nhmlFile" or die $!;
while(<NHML>){
next unless /<NHNTSample.*DTS="(\d+)".*\/>/;
$dts[$count] = $1;
last if (++$count >= 10);
}
close NHML;

$timebase = $dts[1] - $dts[0];
$avgTimebase = ($dts[$count - 1] - $dts[0]) / ($count - 1);

die "Input file is not CFR." if ($timebase != $avgTimebase);
return $timebase;
}

sub toTimescale{
my $fps = shift @_;
my $timescale = int($fps * 1.001 + 0.5) * 1000;
return $timescale;
}

sub detectTCFVersion{
my $timecodeFile = shift @_;
my $tcfv;

open TC, "<$timecodeFile" or die $!;
while(<TC>){
next unless /^\#\s+timecode format v([1-2])/;
$tcfv = $1;
}
close TC;

defined $tcfv or die "Only timecode format v1/v2 is supported.";
return $tcfv;
}

sub detectNTSC{
my $timecodeFile = shift @_;
my $assume;

open TC, "<$timecodeFile" or die $!;
while(<TC>){
next if /^\#/;
next unless /^Assume ([0-9.]+)/;
$assume = $1;
}
close TC;

if(toTimescale($assume) == $assume * 1000){
return 0;
}else{
return 1;
}
}

sub parseTimecodeV1{
my $timecodeFile = shift @_;
my $ntsc = shift @_;

my @timescale;
my $assume;
my $begin,$end,$last,$fps;
my $frame = 0;

open TC, "<$timecodeFile" or die $!;

while(<TC>){
($last = $1, next)
if /^\# TDecimate Mode.*Last Frame = (\d+)/;

next if /^\#/;

($assume = $1, next)
if /^Assume ([0-9.]+)/;

next unless /(\d+),(\d+),([\d.]+)/;

($begin, $end, $fps) = ($1, $2, $3);

for($frame; $frame < $begin; $frame++){
$timescale[$frame] = toTimescale($assume);
}

for($frame = $begin; $frame <= $end; $frame++){
$timescale[$frame] = toTimescale($fps);
}
}
for(;$frame <= $last; $frame++){
$timescale[$frame] = toTimescale($assume);
}
close TC;

$ntsc = 1111;

return @timescale;
}

sub parseTimecodeV2{
my $timecodeFile = shift @_;

my @cts;
my $frame = 0;

open TC, "<$timecodeFile" or die $!;
while(<TC>){
next if /^\#/;
next unless /([\d.]+)/;

$cts[$frame++] = int($1 * 1000 + 0.5);
}
close TC;

return @cts;
}

bond
10th June 2006, 14:28
whats the password for the archive?

edit: and how does tc2mp4 work? does it overwrite the stts info in the mp4 file? is it reliable to use on all sorts of mp4 files (eg with 64bit times?)

zmi
10th June 2006, 15:34
Sorry, password for the archive is "doom9.org".

tc2mp4 overwrites the stts thru nhml (xml style nhnt format extracted by mp4box).

bond
10th June 2006, 15:49
Sorry, password for the archive is "doom9.org".thx

tc2mp4 overwrites the stts thru nhml (xml style nhnt format extracted by mp4box).so it creates a nhml file and feeds this mp4box with and mp4box uses it for creating the vfr stts? (so being basically a mkvtimecode file -> nhml converter?)

Zero1
10th June 2006, 16:12
Good work, I'm gonna try this right now :)

Thanks :D

bond
10th June 2006, 17:50
so it creates a nhml file and feeds this mp4box with and mp4box uses it for creating the vfr stts? (so being basically a mkvtimecode file -> nhml converter?)yep, seems so

damn, didnt realise that mp4box already supports vfr file creation that way, but it again prooves that mp4box is damn powerful :)

bond
10th June 2006, 18:39
zmi, shouldnt the vfr file have exactly the same length timewise as the source cfr file? the vfr file i get is shorter (20s vs. 16.616s)

also how do you drop the not needed, duplicate frames?
i wonder why x264 outputs a 500 frames output file when using the avs script you described above (tdecimate). shouldnt avisynth drop the frames?

also my timecode file looks like this
# timecode format v1
Assume 25.000000
# TDecimate v0.9.12.1 by tritical
# Mode 3 - Auto-generated mkv timecodes file
0,3,20.000000
369,404,20.000000the cfr file i have has 500 frames, the vfr has 405? how do i see that 95 frames will be dropped from the timecode file?

foxyshadis
10th June 2006, 22:20
They'll only have the same length (timewise) if the cfr output was set to the average framerate, as described on the vfr page (http://avisynth.org/mediawiki/wiki/VFR#3.3.3_framerate). Next version of TDec may do that automatically, as it keeps bitrate calculators happier as well.

Thanks for providing such a useful tool! Automated vfr in mp4 is nice. Since this is modifying the atoms, does that mean it could do v2 timecodes as well, once a parser is written? (At first I thought it was just splitting and joining the mp4 on each timecode entry!)

MeteorRain
11th June 2006, 04:07
Since this is modifying the atoms, does that mean it could do v2 timecodes as well, once a parser is written?
it should do. what we need is a timecode v2 -> timecode v1 converter.

bond
11th June 2006, 11:50
Thanks for providing such a useful tool! Automated vfr in mp4 is nice. Since this is modifying the atoms, does that mean it could do v2 timecodes as well, once a parser is written? (At first I thought it was just splitting and joining the mp4 on each timecode entry!)it should do. what we need is a timecode v2 -> timecode v1 converter.afaik the script doesnt edit the atoms or the mp4

afaik it does the following:
1) use mp4box to create a .nhml file containing the timestamps of the source mp4 file (dts)
2) edit the timestamps in the .nhml file according to the info in the timecode file
3) feed this new .nhml file to mp4box, which then creates a new mp4 with the new timestamps

so the script is basically using an option of mp4box already being here for long but noone realised it :D
i think the .nhml files can be seen as an equivalent to the mkv timecode files

so what we need (and have here) is a "mkv style timecode file" -> "mp4box style timecode file" converter
or tdecimate/dedup to offer the option to output .nhml files directly

Zero1
11th June 2006, 14:36
An MKV timecodes v2 > v1 converter/script would be very useful (or v2 input > nhml would be even better). In the file I was going to experiment with I can only extract it as a v2 file, and AFAIK there aren't any such tools to convert it (also I believe mkvextract will only extract to v2 anyway). Well maybe there is, but I couldn't find any.

Would/have you thought about submitting this for inclusion in mp4box?

bond
11th June 2006, 14:41
the script seems to be slightly inaccurate, because of the way it chooses the timescale
on a ~25fps stream it used a timescale of 2600000, leading to funky dts values for the frames and introducing rounding errors i think, giving the normal frames a length of 40.04 instead of 40ms
(i also noticed that an inaccuracy is also introduced by the structure of the v1 timecode files when dealing with things like 1/3 aso)

i also noticed that it seems to have problems sometimes with the dts value for the last frame (giving it a negative value, which is not allowed and surely a bug)

edit:
An MKV timecodes v2 > v1 converter/script would be very useful (or v2 input > nhml would be even better). In the file I was going to experiment with I can only extract it as a v2 file, and AFAIK there aren't any such tools to convert it (also I believe mkvextract will only extract to v2 anyway). Well maybe there is, but I couldn't find any.http://www.animereactor.dk/mkv/

Zero1
11th June 2006, 14:51
Thanks bond, I just this minute saw that posted in #darkhold, tried it out and both the conversion and tc2mp4 work perfectly

bond
11th June 2006, 14:56
Thanks bond, I just this minute saw that posted in #darkhold, tried it out and both the conversion and tc2mp4 work perfectlydid it choose the right timescale for you? does your vfr file have the 100% correct length?

Zero1
11th June 2006, 15:22
Seems not. I don't have the CFR source to hand, but the VFR MKV is 27:01, and this turns out to be 28:31. You can go to around the 26:50 mark and hear the ending of the audio, it finishes as it should at 27:01 (or around there) but the video continues.

I wonder if it's caused by converting V2 > V1. Can anyone try this with an original (not converted) V1 timecode?

There isn't anything too odd about this video, but the decimation was pretty agressive and it was a very static CG anime (a combination of wanting to see how small I could get a file, it was viewable at 33MB if anyone is interested ;)), much more agressive than I would use normally, so this might exaggerate the problem, rather than it being off by a few seconds with some light decimation.

Here is the output from tc2mp4 anyway

C:\Documents and Settings\Michael\Desktop\tc2mp4>tc2mp4.exe -i Track2.mp4 -t tim
ev1.txt -o Track2vfr.mp4
mp4box -nhml 1 Track2.mp4
[Timecode info]
Total frames(16178), LCM Timescale(120000), Factors(1000/12000/2000/24000/3000
/4000/5000/6000/8000)
[NHML info]
Timebase(1001)
[Delay]
Frames(2), Timecode(10010)
mp4box -add Track2_track1_tc.nhml -new Track2vfr.mp4
NHML import - Stream Type Visual - ObjectTypeIndication 0x21
Saving Track2vfr.mp4: 0.500 secs Interleaving
mp4box -info Track2vfr.mp4
* Movie Info *
Timescale 600 - Duration 00:28:31.968
Fragmented File no - 1 track(s)
File Brand isom - version 1
Created: GMT Sun Jun 11 13:49:58 2006

File has no MPEG4 IOD/OD

Track # 1 Info - TrackID 1 - TimeScale 120000 - Duration 00:28:31.968
Media Info: Language "Undetermined" - Type "vide" - Sub Type "avc1" - 16178 samp
les
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x21
AVC/H264 Video - Visual Size 480 x 352 - Profile High @ Level 5.1
Pixel Aspect Ratio 4:3 - Indicated track size 640 x 352
Self-synchronized

Completed.

Edit
I should drop in that the maximum possible framerate at any one time would have been 23.976 (the source was constant 23.976 and I decimated redundant frames to save a little space)

zmi
12th June 2006, 19:12
Updated tc2mp4.
http://rapidshare.de/files/22887498/tc2mp4_20060613.rar.html

- Added timecode format v2 support.
- Improved accuracy for non-NTSC movie.

Zero1
12th June 2006, 22:48
Great work zmi.

I just tested this and can report some interesting things.

I used the v2 timecode extracted from my original MKV and tc2mp4 created the vfr mp4 from it, and it was exactly the correct duration.

So what about the test that I did in the previous post? Well that was a v1 timecode created from a v2 timecode (using the tool bond linked too). I muxed using this v1 timecode and I got the wrong duration again.

So I conclude that tc2mp4 was right, but the program that converted the v2 > v1 was doing something weird.

Here is the output using the updated tc2mp4 for the v1 timecode file created by converting the v2 file using the program bond linked to:
C:\Documents and Settings\Michael\Desktop\tc2mp4>tc2mp4.exe -i Track2.mp4 -t Tim
ev1.txt -o 2.mp4
mp4box -nhml 1 Track2.mp4
[Timecode info]
Timecode format(v1)
Total frames(16178), LCM Timescale(120000)
Factors(1000/12000/2000/24000/3000/4000/5000/6000/8000)
[NHML info]
Timebase(1001)
[Delay]
Frames(2), Timecode(10000)
mp4box -add Track2_track1_tc.nhml -new 2.mp4
NHML import - Stream Type Visual - ObjectTypeIndication 0x21
Saving 2.mp4: 0.500 secs Interleaving
mp4box -info 2.mp4
* Movie Info *
Timescale 600 - Duration 00:28:30.258
Fragmented File no - 1 track(s)
File Brand isom - version 1
Created: GMT Mon Jun 12 21:40:55 2006

File has no MPEG4 IOD/OD

Track # 1 Info - TrackID 1 - TimeScale 120000 - Duration 00:28:30.258
Media Info: Language "Undetermined" - Type "vide" - Sub Type "avc1" - 16178 samp
les
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x21
AVC/H264 Video - Visual Size 480 x 352 - Profile High @ Level 5.1
Pixel Aspect Ratio 4:3 - Indicated track size 640 x 352
Self-synchronized

Completed.

And here is the output that I got when I used the original demuxed v2 timecode file.
C:\Documents and Settings\Michael\Desktop\tc2mp4>tc2mp4.exe -i Track2.mp4 -t Tim
e.txt -o 1.mp4
mp4box -nhml 1 Track2.mp4
[Timecode info]
Timecode format(v2)
Total frames(16178), Timescale(1000000)
[NHML info]
Timebase(1001)
[Delay]
Frames(2), Timecode(83000)
mp4box -add Track2_track1_tc.nhml -new 1.mp4
NHML import - Stream Type Visual - ObjectTypeIndication 0x21
Saving 1.mp4: 0.500 secs Interleaving
mp4box -info 1.mp4
* Movie Info *
Timescale 600 - Duration 00:27:01.831
Fragmented File no - 1 track(s)
File Brand isom - version 1
Created: GMT Mon Jun 12 21:39:43 2006

File has no MPEG4 IOD/OD

Track # 1 Info - TrackID 1 - TimeScale 1000000 - Duration 00:27:01.832
Media Info: Language "Undetermined" - Type "vide" - Sub Type "avc1" - 16178 samp
les
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x21
AVC/H264 Video - Visual Size 480 x 352 - Profile High @ Level 5.1
Pixel Aspect Ratio 4:3 - Indicated track size 640 x 352
Self-synchronized

Completed.

It may or may not be of interest, but I thought it was best to post it anyway.

bond
14th June 2006, 18:50
in my first test the v2 -> v1 converter did the right thing and tc2mp4 was wrong slightly. i assume this is now fixed with zmis latest version

there is another reason why things can be wrong and this is because of flaws in the mkv timecode files themselves

eg they store 1/3fps not as 1/3fps but as 0.333333fps which is obviously not 100% the same and will therefore lead to slightly different results
such problems can be avioded with the nhml format

Zero1
15th June 2006, 01:14
Hmm, what would be ideal then as suggested by a friend of mine (Coderjoe), would be direct nhml output from DeDup.

Or maybe a high accuracy (neutral) timecode format that isn't specific to MKV or MP4 but can be converted to either format without any inaccuracies.

bond
15th June 2006, 11:16
Hmm, what would be ideal then as suggested by a friend of mine (Coderjoe), would be direct nhml output from DeDup.i thought about that too, but the problem is that nhml needs some strange .info and .media (which is not a raw stream) as input set, and those can only be created by mp4box
so dedup on its own cant really create this i think

Or maybe a high accuracy (neutral) timecode format that isn't specific to MKV or MP4 but can be converted to either format without any inaccuracies. well if i get it right its possible to convert mkv -> nhml "losslessly", the only problem is that the mkv timecode files already contain inaccuracies because of their structure

Drachir
15th June 2006, 12:04
i thought about that too, but the problem is that nhml needs some strange .info and .media (which is not a raw stream) as input set, and those can only be created by mp4box
so dedup on its own cant really create this i think


*.info is the Decoder Specific Info Descriptor -> header of the RAW Stream, isn't it?

*.media elementary stream without header of the raw stream?

Zero1
21st July 2006, 22:26
Is there any reason why this might fail with ASP?

I have been getting a division by zero error. This is the first time I've tried with ASP (I've tried with one encode of the source and got the error, deleted all my files and started again).

I have muxed a few files containing H.264 and they are fine, but it seems it doesn't like ASP, unless anyone else does not got an error, then it's a problem on my part somewhere.

Here's the relevant info.

Batch for encoding/VFR/muxing
xvid_encraw.exe -i Video1.avs -type 2 -w 720 -h 576 -o "pass1.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset 100 -bitrate 631 -pass1 "xvidstats.log" -full1pass -max_key_interval 480 -quality 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin 2 -pmax 31 -progress 25
xvid_encraw.exe -i Video1.avs -type 2 -w 720 -h 576 -o "pass2.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset 100 -bitrate 631 -pass2 "xvidstats.log" -max_key_interval 480 -kboost 10 -kthresh 1 -kreduction 20 -ostrength 0 -oimprove 5 -odegrade 5 -chigh 0 -clow 0 -quality 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin 2 -pmax 31 -progress 25
mp4box.exe -add pass2.m4v:par=64:45 in.mp4
tc2mp4.exe -i in.mp4 -t times.txt -o out.mp4
mp4box.exe -add hackaud.mp3:lang=jpn:name="MPEG-1 Layer 3 2.0 (Stereo)" -chap Chapter.chp -name 1="MPEG-4 Advanced Simple Profile @ Level 5 - 16/9" -lang 1=jpn out.mp4
pause

Output in CMD
C:\Documents and Settings\Michael\Desktop\enc>xvid_encraw.exe -i Video1.avs -typ
e 2 -w 720 -h 576 -o "pass1.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset
100 -bitrate 631 -pass1 "xvidstats.log" -full1pass -max_key_interval 480 -quali
ty 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin
2 -pmax 31 -progress 25
xvid_encraw - raw mpeg4 bitstream encoder written by Christoph Lampert 2002-2003


Input colorspace is YV12
xvidcore build version: xvid-1.2.0-dev
Bitstream version: 1.2.-127
Detected CPU flags: ASM MMX MMXEXT SSE SSE2 3DNOW 3DNOWEXT TSC
Detected 1 cpus, using 1 threads.
21876 frames( 99%) encoded, 13.96 fps, Average Bitrate = 1323kbps
Tot: enctime(ms) =1567377.00, length(bytes) = 151071363
Avg: enctime(ms) = 71.62, fps = 13.96, length(bytes) = 6902
I frames: 322 frames, size = 36095/11622701, quants = 2 / 2.00 / 2
P frames: 8083 frames, size = 13573/109712744, quants = 2 / 2.00 / 2
B frames: 13479 frames, size = 2206/29735918, quants = 4 / 4.00 / 4

C:\Documents and Settings\Michael\Desktop\enc>xvid_encraw.exe -i Video1.avs -typ
e 2 -w 720 -h 576 -o "pass2.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset
100 -bitrate 631 -pass2 "xvidstats.log" -max_key_interval 480 -kboost 10 -kthre
sh 1 -kreduction 20 -ostrength 0 -oimprove 5 -odegrade 5 -chigh 0 -clow 0 -quali
ty 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin
2 -pmax 31 -progress 25
xvid_encraw - raw mpeg4 bitstream encoder written by Christoph Lampert 2002-2003


Input colorspace is YV12
xvidcore build version: xvid-1.2.0-dev
Bitstream version: 1.2.-127
Detected CPU flags: ASM MMX MMXEXT SSE SSE2 3DNOW 3DNOWEXT TSC
Detected 1 cpus, using 1 threads.
21876 frames( 99%) encoded, 15.95 fps, Average Bitrate = 665kbps
Tot: enctime(ms) =1372638.00, length(bytes) = 75895490
Avg: enctime(ms) = 62.72, fps = 15.94, length(bytes) = 3467
I frames: 322 frames, size = 24370/7847320, quants = 2 / 3.39 / 4
P frames: 8083 frames, size = 6458/52202983, quants = 3 / 4.23 / 5
B frames: 13479 frames, size = 1175/15845187, quants = 5 / 7.13 / 9

C:\Documents and Settings\Michael\Desktop\enc>mp4box.exe -add pass2.m4v:par=64:4
5 in.mp4
MPEG-4 Video import - 720 x 576 @ 25.0000 FPS
Indicated Profile: Advanced Simple Profile @ Level 5
Has B-Frames (2 max consecutive B-VOPs)
Import results: 21884 VOPs (322 Is - 8083 Ps - 13479 Bs)
Converting to ISMA Audio-Video MP4 file...
Saving to in.mp4: 0.500 secs Interleaving

C:\Documents and Settings\Michael\Desktop\enc>tc2mp4.exe -i in.mp4 -t times.txt
-o out.mp4
mp4box -nhml 1 in.mp4
[Timecode info]
Timecode format(v2)
Total frames(21884), Timescale(1000000)
[NHML info]
Timebase(0)
Illegal division by zero at script/tc2mp4.pl line 94, <SRC_NHML> line 3.

C:\Documents and Settings\Michael\Desktop\enc>mp4box.exe -add hackaud.mp3:lang=j
pn:name="MPEG-1 Layer 3 2.0 (Stereo)" -chap Chapter.chp -name 1="MPEG-4 Advanced
Simple Profile @ Level 5 - 16/9" -lang 1=jpn out.mp4
MP3 import - sample rate 48000 - MPEG-1 audio - 2 channels
Saving to out.mp4: 0.500 secs Interleaving


I can provide the timecode file if needed; in theory it should be the same as the one I used when muxing the H.264, but I can't remember if I changed any filtering settings (which would alter detection).

bond
24th July 2006, 20:51
a description for the nhnt and nhml format:
http://gpac.sourceforge.net/doc_nhnt.php

leiming2006
3rd August 2006, 07:12
A tool that quite useful :D
I search for this for a long time but finally I find none.

Great work.

Edit: It can't work here.

By the way, I think it's easier to converting timecodes v2 to v1 than converting timecodes v1 to v2 XD
The total frame number seems to be not offered in timecodes v1. :p

chros
1st November 2006, 12:42
Thanks for this tool, too !!!

giandrea
10th November 2006, 02:23
Is it possible to do something like this with OpenSource tool available on Linux or Mac OS X, like ffmpeg or mplayer/mencoder?

giandrea
13th November 2006, 00:20
Is there any reason why this might fail with ASP?

I have been getting a division by zero error. This is the first time I've tried with ASP (I've tried with one encode of the source and got the error, deleted all my files and started again).

I have muxed a few files containing H.264 and they are fine, but it seems it doesn't like ASP, unless anyone else does not got an error, then it's a problem on my part somewhere.

Here's the relevant info.

Batch for encoding/VFR/muxing
xvid_encraw.exe -i Video1.avs -type 2 -w 720 -h 576 -o "pass1.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset 100 -bitrate 631 -pass1 "xvidstats.log" -full1pass -max_key_interval 480 -quality 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin 2 -pmax 31 -progress 25
xvid_encraw.exe -i Video1.avs -type 2 -w 720 -h 576 -o "pass2.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset 100 -bitrate 631 -pass2 "xvidstats.log" -max_key_interval 480 -kboost 10 -kthresh 1 -kreduction 20 -ostrength 0 -oimprove 5 -odegrade 5 -chigh 0 -clow 0 -quality 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin 2 -pmax 31 -progress 25
mp4box.exe -add pass2.m4v:par=64:45 in.mp4
tc2mp4.exe -i in.mp4 -t times.txt -o out.mp4
mp4box.exe -add hackaud.mp3:lang=jpn:name="MPEG-1 Layer 3 2.0 (Stereo)" -chap Chapter.chp -name 1="MPEG-4 Advanced Simple Profile @ Level 5 - 16/9" -lang 1=jpn out.mp4
pause

Output in CMD
C:\Documents and Settings\Michael\Desktop\enc>xvid_encraw.exe -i Video1.avs -typ
e 2 -w 720 -h 576 -o "pass1.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset
100 -bitrate 631 -pass1 "xvidstats.log" -full1pass -max_key_interval 480 -quali
ty 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin
2 -pmax 31 -progress 25
xvid_encraw - raw mpeg4 bitstream encoder written by Christoph Lampert 2002-2003


Input colorspace is YV12
xvidcore build version: xvid-1.2.0-dev
Bitstream version: 1.2.-127
Detected CPU flags: ASM MMX MMXEXT SSE SSE2 3DNOW 3DNOWEXT TSC
Detected 1 cpus, using 1 threads.
21876 frames( 99%) encoded, 13.96 fps, Average Bitrate = 1323kbps
Tot: enctime(ms) =1567377.00, length(bytes) = 151071363
Avg: enctime(ms) = 71.62, fps = 13.96, length(bytes) = 6902
I frames: 322 frames, size = 36095/11622701, quants = 2 / 2.00 / 2
P frames: 8083 frames, size = 13573/109712744, quants = 2 / 2.00 / 2
B frames: 13479 frames, size = 2206/29735918, quants = 4 / 4.00 / 4

C:\Documents and Settings\Michael\Desktop\enc>xvid_encraw.exe -i Video1.avs -typ
e 2 -w 720 -h 576 -o "pass2.m4v" -max_bframes 2 -bquant_ratio 150 -bquant_offset
100 -bitrate 631 -pass2 "xvidstats.log" -max_key_interval 480 -kboost 10 -kthre
sh 1 -kreduction 20 -ostrength 0 -oimprove 5 -odegrade 5 -chigh 0 -clow 0 -quali
ty 6 -vhqmode 4 -bvhq -qtype 0 -nopacked -imin 2 -imax 31 -bmin 2 -bmax 31 -pmin
2 -pmax 31 -progress 25
xvid_encraw - raw mpeg4 bitstream encoder written by Christoph Lampert 2002-2003


Input colorspace is YV12
xvidcore build version: xvid-1.2.0-dev
Bitstream version: 1.2.-127
Detected CPU flags: ASM MMX MMXEXT SSE SSE2 3DNOW 3DNOWEXT TSC
Detected 1 cpus, using 1 threads.
21876 frames( 99%) encoded, 15.95 fps, Average Bitrate = 665kbps
Tot: enctime(ms) =1372638.00, length(bytes) = 75895490
Avg: enctime(ms) = 62.72, fps = 15.94, length(bytes) = 3467
I frames: 322 frames, size = 24370/7847320, quants = 2 / 3.39 / 4
P frames: 8083 frames, size = 6458/52202983, quants = 3 / 4.23 / 5
B frames: 13479 frames, size = 1175/15845187, quants = 5 / 7.13 / 9

C:\Documents and Settings\Michael\Desktop\enc>mp4box.exe -add pass2.m4v:par=64:4
5 in.mp4
MPEG-4 Video import - 720 x 576 @ 25.0000 FPS
Indicated Profile: Advanced Simple Profile @ Level 5
Has B-Frames (2 max consecutive B-VOPs)
Import results: 21884 VOPs (322 Is - 8083 Ps - 13479 Bs)
Converting to ISMA Audio-Video MP4 file...
Saving to in.mp4: 0.500 secs Interleaving

C:\Documents and Settings\Michael\Desktop\enc>tc2mp4.exe -i in.mp4 -t times.txt
-o out.mp4
mp4box -nhml 1 in.mp4
[Timecode info]
Timecode format(v2)
Total frames(21884), Timescale(1000000)
[NHML info]
Timebase(0)
Illegal division by zero at script/tc2mp4.pl line 94, <SRC_NHML> line 3.

C:\Documents and Settings\Michael\Desktop\enc>mp4box.exe -add hackaud.mp3:lang=j
pn:name="MPEG-1 Layer 3 2.0 (Stereo)" -chap Chapter.chp -name 1="MPEG-4 Advanced
Simple Profile @ Level 5 - 16/9" -lang 1=jpn out.mp4
MP3 import - sample rate 48000 - MPEG-1 audio - 2 channels
Saving to out.mp4: 0.500 secs Interleaving


I can provide the timecode file if needed; in theory it should be the same as the one I used when muxing the H.264, but I can't remember if I changed any filtering settings (which would alter detection).

The message is old, but I will answer anyway. It's giving that error because the script will imply that the video track ID is 1, while it's not always 1. For example if you have ASP muxed by MP4Box, it could be 201. I have modified the script so that I can specify the videeo track ID on the command line, if you want I can post it.
In any case you can make the script work by modifying the lines 15,16 and 18. Replace "1" with your video track ID.

Zero1
22nd November 2006, 22:38
Hey, thanks for that. It's much appreciated.

I shall try that out at some point :)

Wilbert
26th November 2006, 15:56
The message is old, but I will answer anyway. It's giving that error because the script will imply that the video track ID is 1, while it's not always 1. For example if you have ASP muxed by MP4Box, it could be 201. I have modified the script so that I can specify the videeo track ID on the command line, if you want I can post it.
In any case you can make the script work by modifying the lines 15,16 and 18. Replace "1" with your video track ID.
I got the same problem, but i get the same error message after changing 1 to 201 (in tc2mp4.pl):

$srcNHML = "${basename}_track201.nhml";
$tcNHML = "${basename}_track201_tc.nhml";

doCmd("mp4box -nhml 201 $srcMP4");


Accordingly to mp4box the video id is indeed 201:

Track # 1 Info - TrackID 201 - TimeScale 24000 - Duration 00:01:38.348
Media Info: Language "Undetermined" - Type "vide" - Sub Type "mp4v" - 2358 samples
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x20
MPEG-4 Visual Size 848 x 352 - Advanced Simple Profile @ Level 5
Pixel Aspect Ratio 1:1 - Indicated track size 848 x 352
Synchronized on stream 1

Wilbert
9th December 2006, 15:28
I got the same problem, but i get the same error message after changing 1 to 201 (in tc2mp4.pl):
(...)
bump :) Nobody?

Is it possible to change the video id of a mp4 file to 1?

giandrea
13th December 2006, 01:56
bump :) Nobody?

Is it possible to change the video id of a mp4 file to 1?

Sorry, don't know... try to double check your inputs and outputs. Anyway the only time I tried this script on a full length movie, it started to slow down after 40% of the process, and then slowed down to halt at around 50%. I had to force quit the process. I think it's a bug or a memory leak...

Wilbert
16th December 2006, 20:57
Ok. I hope you find out the problem one day.
The message is old, but I will answer anyway. It's giving that error because the script will imply that the video track ID is 1, while it's not always 1. For example if you have ASP muxed by MP4Box, it could be 201. I have modified the script so that I can specify the videeo track ID on the command line, if you want I can post it.
Could you post this modified script?

martino
16th January 2007, 22:21
I keep getting an error:


C:\Program Files\video creation\video tools\tc2mp4>tc2mp4 -i "y:\02_30fps.mp4" -
t "y:\2.txt" -o "y:\02_vfr_correct.mp4"
mp4box -nhml 1 "y:\02_30fps.mp4"
[Timecode info]
Timecode format(v1)
Total frames(8650), LCM Timescale(120000)
NTSC, Factors(120000/24000/30000)
y:\02_30fps_track1.nhml[NHML info]
Timebase(0)
Illegal division by zero at script/tc2mp4.pl line 96, <SRC_NHML> line 3.

UPDATE: After some reading it looks like I wasn't the first one with this error, therefore I second a request for that script please. :)

ballofsnow
19th February 2007, 07:50
Can someone upload tc2mp4 again? The rapidshare links have expired.

zmi
12th March 2007, 17:55
Sorry for the long absence.
I posted an updated script to http://forum.doom9.org/showthread.php?t=112199

thank you.

Aktan
6th November 2009, 14:53
Not sure if there is much interest in this anymore, but I've recently wanted to create a VFR MP4 with MKV V2 timecodes. I tried your script zmi, but as people here have noted, it seem inaccurate. So I created my own version which seems to be accurate. The outputed timecodes once I converted to VFR MP4 back to MKV were practically the same (minor rounding errors). I don't think it's ready to be posted yet as it isn't very modular code yet and I write crappy code :), but I was wondering if anyone has samples they could provide for me so that I can test to see if I got it down correct.

I need both video and audio nhml since VRF in the video will introduce a big CTS offset that also needs to be applied to the audio in order to be synced. I also need to know the original CFR.

Also, thanks a lot, zmi, for your script as that is what my version was based off of.

stitchix
15th August 2010, 02:02
Please re-upload archive tc2mp4_20070124.rar
Thanks.

Aktan
15th August 2010, 02:45
Please re-upload archive tc2mp4_20070124.rar
Thanks.

[shameless advertise]
you can try out my version of his script here:
http://forum.doom9.org/showthread.php?t=150890
[/shameless advertise]