Video transcoding notes

I do video transcoding so rarely that I need to recall everything by trial and error each time, so this time I’m going to write my recipe down here. Note that a lot of the parts here (avconv, libvpx in particular) are moving, so parts of this’ll probably get stale pretty fast.

  1. Figure out the filters using Avidemux. 2.5.4 works okay apart from an annoying bug, where closing the preview window closes the filters window as well. Workaround: use the Qt interface (eww!).
  2. Preferable filter order:
    1. De-interlace
    2. Resize
    3. Crop

    Note 1: for 16:9 material stored in 720×576 without letterboxing (at least some old DVB recordings) seem to need an initial resize to 1024×576 prior to deinterlacing, for the deinterlacing to work better.

    Note 2: For deinterlacing, yadif seems to work generally well, although the Avidemux wiki does recommend Decomb Telecide for telecined DVDs. In any case, you should try different values for the parameters to see which ones are best with each source material. With yadif, preview using one of the bob modes for getting the field order right. “If you see the video jumping back and forth all the time, then the selected Field Order is wrong!”

    Note 3: Resizing prior to cropping means some tweaking back and forth between the parameters. My recipe for doing this for 720×576 (letterboxed 16:9 or true 4:3) material is:

    1. Resize to 640×480.
    2. Do precise cropping (cutting all and only excess parts from the frame).
    3. Go back and tweak the resize number bigger so that either X will be 640 or Y will be 480 after the crop, and the other bigger than it should be. (For example, if precisely cropped picture was 622 px wide, scale the resize up to X=640 + (640-622) and Y according to aspect ratio to closest even number.)
    4. Go back to cropping and cut the now longer-than-desired-target dimension. Also check that the precisely-targeted crop is still good (not excessive).
    5. (Optional 1) If the longer-than-desired dimension’s cut seems excessively intrusive, go back and resize the frame to a slightly smaller size than previously. (For example, X=650 instead of X=658, with Y again according to aspect ratio.)
    6. (Optional 2) Go back to cropping, adjust both dimensions aiming for the desired final resolution. Note that the new resize translates to some excess material possibly being left on the initially precisely-targeted dimension, but also to more expendable pixels to cut from the other (i.e. a less invasive crop).
  3. Translate filters into avconv parameters. Note particularly that for yadif, “order” is 0 for “bottom first” in Avidemux, but 0 for “top first” in avconv. Do test clips with -ss and -t.

    For example, a two-pass MPEG-to-VP8-WebM:

    avconv -y -i in.mpeg -c:v libvpx -crf 10 -pre libvpx-360p -filter:v yadif=0:0,scale=664:498,crop=640:336:18:76 -b:v 717k -pass 1 -an out.webm
    avconv -y -i in.mpeg -c:v libvpx -crf 10 -pre libvpx-360p -filter:v yadif=0:0,scale=664:498,crop=640:336:18:76 -b:v 717k -pass 2 -c:a libvorbis -q:a 3 out.webm

    For yadif’s mode 1 to actually result in double-the-framerate, fps needs to be specified with -r. So for example, from a 25 fps source to a 50 fps 1 frame/field:

    avconv -y -i in.mpeg -c:v libvpx -crf 10 -pre libvpx-360p -filter:v yadif=1:0,scale=664:498,crop=640:336:18:76 -r 50 -b:v 717k -pass 1 -an out.webm
    avconv -y -i in.mpeg -c:v libvpx -crf 10 -pre libvpx-360p -filter:v yadif=1:0,scale=664:498,crop=640:336:18:76 -r 50 -b:v 717k -pass 2 -c:a libvorbis -q:a 3 out.webm

    (This caused me some headscratching at first, when mode 1 didn’t seem to result in the jerky effect clearly observable in Avidemux.)

    Note that libvpx/avconv may fail with “Application provided invalid, non monotonically increasing dts to muxer in stream 0” when a preset file with auto-alt-ref=1 is used, or (e.g.) with “Option lag-in-frames not found” when using presets and doing the second pass with audio (as I did above).

    The workaround for is to provide the options from the preset file in /usr/share/avconv/ as command-line parameters, except for auto-alt-ref, which fails either way.

    avconv -y -i g.mpeg -ss 280 -t 1 -c:v libvpx -crf 10 -filter:v yadif=1:0,scale=654:490,crop=640:480:8:6 -r 50 -g 120 -lag-in-frames 15 -deadline good -cpu-used 0 -slices 4 -profile 0 -qmax 63 -qmin 0 -b:v 768k -maxrate 1.5M -minrate 40k -arnr-maxframes 7 -arnr-strength 5 -arnr-type centered -pass 1 -an g.webm
    avconv -y -i g.mpeg -ss 280 -t 1 -c:v libvpx -crf 10 -filter:v yadif=1:0,scale=654:490,crop=640:480:8:6 -r 50 -g 120 -lag-in-frames 15 -deadline good -cpu-used 0 -slices 4 -profile 0 -qmax 63 -qmin 0 -b:v 768k -maxrate 1.5M -minrate 40k -arnr-maxframes 7 -arnr-strength 5 -arnr-type centered -pass 2 -c:a libvorbis -q:a 3 g.webm