Isochroma
5th December 2007, 04:26
Today I figured out a way to reliably remux TS files containing H264 video streams to AVI. The reason why I wanted to do this is because I'm recompressing to a codec which seeks back/forward in the stream. Directshow isn't frame-accurate, and so I was losing frames in my encode.
Now, AVI is frame-accurate, with avisource(filename.avi). Also, recent versions of ffdshow VCM codec are capable of H264 decoding, so... why not remux the H264 into an AVI file and enjoy the retro magnificence of VFW's accurate seeks?
First, the AVI file produced at the end of this process will have two extra frames, one at the beginning and one at the end. In addition one frame at the beginning will be green. The last step in the instructions below contains a template .avs which will fix this.
Ok, now on to the instructions!
Software required:
0.1 TsRemux (http://forum.doom9.org/showthread.php?t=125447)
0.2 xport (http://www.w6rz.net/xport.zip)
0.3 avc2avi mod (http://superb-east.dl.sourceforge.net/sourceforge/avc2avi/avc2avi_mod-20061112.zip)
0.4 abcAVI Tag Editor (http://abcavi.kibi.ru/abcavi.exe)
0.5 AVISynth (assumed you have it installed already)
0.6 ffdshow (recent, any build with H264 decoding in VCM codec, make sure it's enabled!)
Procedure:
1.0 Open your .TS file with TsRemux. If in the main list box you see AVC Video Stream # (number), then check the checkbox next to it. You can also check any audio streams you want to use for later. If there is no AVC Video Stream, you are out of luck and shall proceed no further.
1.1 In the Source File Info box, if the File format is TS with 188 byte packets, then set the Output Format to M2TS (192 byte packets), and remux to a new .TS file.
2.0 Command line: xport -h file.ts 1 1 1 [do as you please with the audio stream(s)]
3.0 Change the extension of the .mpv file to .264
4.0 Command line: avc2avi -f 23.976024 -i test.264 -o test.avi
5.0 Often, 1920x1080 streams are coded to 1920x1088, with the last 8 lines not decoded. The container has this info but it is lost during this process. So we use abcAVI Tag Editor to change the AVI's file header to remove the 8 extra lines.
To do this, run abcAVI Tag Editor and import your AVI file. In the Hacks & Tweaks tab, check the height box. If it says 1088, then put a check in the Force Frame Size checkbox and enter a height of 1080. Then click the Save button. Alternately, you can use crop() in your .avs to accomplish the same effect.
Done!
You now have an AVI file which can be decoded using avisource() with 100% frame-accurate seeking. For some reason VDub won't open the AVI file directly, so I use .avs (which I would anyway).
Script
To load this AVI file, here is a sample script which will make it with exactly the same number of frames and frame alignment as the original via directshowsource(), except that the last frame will be replaced with a black frame:
avisource("test.avi")
a=trim(2,117)
b=killaudio(blankclip(width=1920, height=1080, length=1, fps=23.976, pixel_type="YV12"))
return(b+a+b)
Script notes: we use trim(2,117) for this clip whose directshow length is 116 frames. The 2 removes the first and second frames, one of which is padded and the other of which is green. Rememer this is my case, file and/or ffdshow version may change the padd/loss/green at front/back, so checking must be done.
Different versions of ffdshow may decode the first/last frames differently, so it is wise to check the output against a version obtained by directshowsource(). Remember not to do any seeking backward in DSS version or its use as a reference will be compromised!
Now, AVI is frame-accurate, with avisource(filename.avi). Also, recent versions of ffdshow VCM codec are capable of H264 decoding, so... why not remux the H264 into an AVI file and enjoy the retro magnificence of VFW's accurate seeks?
First, the AVI file produced at the end of this process will have two extra frames, one at the beginning and one at the end. In addition one frame at the beginning will be green. The last step in the instructions below contains a template .avs which will fix this.
Ok, now on to the instructions!
Software required:
0.1 TsRemux (http://forum.doom9.org/showthread.php?t=125447)
0.2 xport (http://www.w6rz.net/xport.zip)
0.3 avc2avi mod (http://superb-east.dl.sourceforge.net/sourceforge/avc2avi/avc2avi_mod-20061112.zip)
0.4 abcAVI Tag Editor (http://abcavi.kibi.ru/abcavi.exe)
0.5 AVISynth (assumed you have it installed already)
0.6 ffdshow (recent, any build with H264 decoding in VCM codec, make sure it's enabled!)
Procedure:
1.0 Open your .TS file with TsRemux. If in the main list box you see AVC Video Stream # (number), then check the checkbox next to it. You can also check any audio streams you want to use for later. If there is no AVC Video Stream, you are out of luck and shall proceed no further.
1.1 In the Source File Info box, if the File format is TS with 188 byte packets, then set the Output Format to M2TS (192 byte packets), and remux to a new .TS file.
2.0 Command line: xport -h file.ts 1 1 1 [do as you please with the audio stream(s)]
3.0 Change the extension of the .mpv file to .264
4.0 Command line: avc2avi -f 23.976024 -i test.264 -o test.avi
5.0 Often, 1920x1080 streams are coded to 1920x1088, with the last 8 lines not decoded. The container has this info but it is lost during this process. So we use abcAVI Tag Editor to change the AVI's file header to remove the 8 extra lines.
To do this, run abcAVI Tag Editor and import your AVI file. In the Hacks & Tweaks tab, check the height box. If it says 1088, then put a check in the Force Frame Size checkbox and enter a height of 1080. Then click the Save button. Alternately, you can use crop() in your .avs to accomplish the same effect.
Done!
You now have an AVI file which can be decoded using avisource() with 100% frame-accurate seeking. For some reason VDub won't open the AVI file directly, so I use .avs (which I would anyway).
Script
To load this AVI file, here is a sample script which will make it with exactly the same number of frames and frame alignment as the original via directshowsource(), except that the last frame will be replaced with a black frame:
avisource("test.avi")
a=trim(2,117)
b=killaudio(blankclip(width=1920, height=1080, length=1, fps=23.976, pixel_type="YV12"))
return(b+a+b)
Script notes: we use trim(2,117) for this clip whose directshow length is 116 frames. The 2 removes the first and second frames, one of which is padded and the other of which is green. Rememer this is my case, file and/or ffdshow version may change the padd/loss/green at front/back, so checking must be done.
Different versions of ffdshow may decode the first/last frames differently, so it is wise to check the output against a version obtained by directshowsource(). Remember not to do any seeking backward in DSS version or its use as a reference will be compromised!