PDA

View Full Version : Remux H264 from TS to AVI


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!

Sharktooth
5th December 2007, 12:38
remuxing h.264 to avi?!? that's the worst thing you can do...

SeeMoreDigital
5th December 2007, 14:55
remuxing h.264 to avi?!? that's the worst thing you can do...Indeed...

Same goes for just about every other audio/video stream format....

Brother John
5th December 2007, 19:23
As an intermediate format for further processing, if you absolutely need frame accurate seeking and DGAVCDec doesn’t work, why not?

Provided, of course, this method really does give you realiable frame accurate seeking.

Isochroma
5th December 2007, 19:25
Today I'm working on the next issue. I found last night that >2GB AVIs don't work with this method, so I'm pre-splitting the .TS into 2.6 GB parts (final AVI is about 3/4 the size of a given .TS for my source).

Sharktooth
5th December 2007, 19:32
use DGAVCDec... it WORKS.

crypto
6th December 2007, 19:55
@Isochroma
Your method works around the 2GB Limit, if you use the split option (-s 2000) of avc2avi_mod. In your AVS script use SegmentedAVISource instead of AVISource.

Isochroma
6th December 2007, 20:00
Thanks!

I was splitting the .ts using TSSplitter, but your method sound better.

check
6th December 2007, 21:48
Directshow isn't frame-accurate, and so I was losing frames in my encode.
Which frames? I've never had a problem with linear frame access with directshowsource(), the only frames that are even really possible to miss are the first and last ones. Which is why I'm wondering what this is for :confused:

Isochroma
6th December 2007, 21:54
Well, stepping backward causes problems, just often enough to throw audio sync out. I've verified that this frame loss exists - it screwed up my last encode. This is why Donald is busy making his DGAVCDec filter, and why most use MPEG2Source() instead of directshowsource() to get their VOBs, etc.

Because I'm compressing using a directshow based compressor (nic's WMVenc), it does seek both backward and forward for delta frame calculations.

Also, avisynth filters that request previous frame(s) will cause problems using directshowsource() as the frame provider. Directshow is NOT frame accurate, and will often deliver incorrect frames if requested out-of-order (backwards seeking).

Right now I'm just decoding from start to finish and compressing to avizlib or ffdshow VCM's ljpeg in vdub. This works ok but takes up lots of space.

neuron2
6th December 2007, 23:02
The Avisynth frame cache should take care of getting the previous frame accurately.

Isochroma
7th December 2007, 01:44
Theoretically it should, but it doesn't always. I've discovered this by stepping thru frames in vdub. That is why DGAVCDec is so important; the process outlined here is extrememly labour intensive, disk intensive and has several caveats. It is not envisioned as something I'd want to do in the future.

neuron2
7th December 2007, 01:47
If you are only retrieving the last few frames, it should work reliably. It would be worth exploring if you can show that it does not. Can you?

Isochroma
7th December 2007, 01:49
The problem exists but it requires searching thru lots of frames for it to crop up. It mostly happens near keyframes I think. If I have some extra time I'll look for it, but my work load just increased so it might be a while...