Transcoding 50 fps Interlaced AVCHD to 50 fps Progressive x264 with MEncoder - Getting Every Last Drop of Quality out of your Interlaced AVCHD Recordings

Have you ever wondered how much quality your HD camera can deliver? This script helps you to find it out if you have a camera that encodes interlaced video. It uses special filters to calculate 50 whole frames out of the half frames, which makes motions seem extremely fluent. You could play the file at half speed slow motion and still have a full 25 frames per second.

You need a more or less recent version of mplayer. It should be a version of mplayer after the release of ffmpeg 0.5. Current repositories of current distributions should be able to deliver this. But be aware that not all of them provide an mencoder compiled to work properly with x264. If that's the case you may have to compile it yourself.

After that it's as "easy" as this command, once you've put it all together. I'll explain further below and post a sample script for the entire conversion. The result is extremely smoothly playing video files that look great.

This is the main part:

mencoder -demuxer lavf -sws 9 -fps 100 -vf yadif=1,mcdeint,softskip -ofps 50

The demuxer parameter works around mplayer's transport stream implementation, which does not work well with AVCHD files. It tells mplayer to trust ffmpeg's libavformat instead. This makes a huge difference for me. With this command I can play AVCHD files and transcode them in sync without problems and serious glitches.

The fps and yadif part was tricky. It creates 50 full progressive frames out of the 25 interlaced frames it gets from the camera. I had sync problems at first, but I found the solution somewhere in the mplayer mailing list I think. I'm not sure why you have to take twice the framerate of the AVCHD file, but only this way it works. Of course, if you camera is not PAL, you may have to change this to double your framerate. Otherwise I had the sound playing half as fast as the video with the consequence of constant frame skips and no sync at all.

Now let's put it all together into a little please-do-it-all-for-me script:


#!/bin/sh
# High Quality Mencoder AVCHD Transcoding Script, (c) 2010 linux-tipps.blogspot.com, published under the GNU GPL v. 3.0

# Settings
CRF=26 # 18-26, the higher the smaller the resulting file, HD files can stand a higher than SD
FPS=50 # input fps of your file, "mplayer -demuxer lavf -identify" helps you with finding this
X264OPTS=""  # add subq=6 frameref=6 for higher quality per bit but lower encoding rate.

# Preparation
INPUT="$1"; shift
OUT=$(basename "$INPUT"|sed 's/.m2ts//')"-x264.avi"
echo Mencoder Interlaced AVCHD to Progressive x264 Script, published under the GPL v. 3.0 \(http://www.gnu.org/licenses/gpl-3.0.txt\), check for the newest version of this script at http://linux-tipps.blogspot.com/2010/01/transcoding-50-fps-interlaced-avchd-to.html.
echo $0 Encoding $INPUT to $OUT using the following command line:
[ -f "$OUT" ] && echo File exists - aborting && exit 1;

# Encoding
mencoder="time nice mencoder -cache 8096 -demuxer lavf -sws 9 -fps $((FPS*2)) -vf yadif=1,mcdeint,softskip -ofps $FPS"
enc="$mencoder -ovc x264 -oac copy -x264encopts crf=$CRF:trellis=1:threads=0:ratetol=inf:frameref=2:bframes=2:8x8dct:ssim:psnr:$X264OPTS"

echo $enc -o "$OUT" "$INPUT" $*
$enc -o "$OUT" "$INPUT" $*

Just run the script and give a .m2ts file as parameter. E.g.
sh avchd-mencode 000001.m2ts # or for all m2ts file in the current directory:
for i in ./*.m2ts; do sh avchd-mencode "$i"; done;

Let me know how it worked for you! Or if you have an idea how to improve the script. Try skipping frame for frame with the "." button in mplayer. Be aware that the file size of the resulting video may easily be bigger than the input. That's because you're creating full frames out of half ones, and storing them takes more space.

Check out a Squirrel in HD slow motion produced with this script and then "mencoder -speed 0.5 -af scaletempo -oac lavc -lavcopts acodec=ac3 -ovc copy" and uploaded in FullHD (but available only in 720p currently):

23 comments:

  1. Hi there! I tried your script with Ubuntu 9.10, but I get the following error:
    MEncoder SVN-r29237-4.4.1 (C) 2000-2009 MPlayer Team
    Option vf: mcdeint doesn't exist.
    Error parsing option on the command line: -vf

    Does this mean my mencoder is too old?

    ReplyDelete
  2. Easy: Your mplayer/mencoder was compiled without support for the mcdeint filter. Did you compile it yourself? Did you install all dependencies with apt-get build-dep mplayer first? Try installing a packaged version via apt and replacing mencoder= with
    mencoder="time nice /usr/bin/mencoder -cache 8096 -demuxer lavf -sws 9 -fps $((FPS*2)) -vf yadif=1,mcdeint,softskip -ofps $FPS"
    Let me know if it works for you! ;)

    ReplyDelete
  3. ähm, no I did not compile it myself, I like software that can be installed with sudo apt-get install ;) Can you point me a finger how to do it? Everything I did until now is "sudo apt-get install mencoder"

    ReplyDelete
  4. Oh ok. Try using this repository, it includes the filter:
    deb http://ppa.launchpad.net/rvm/mplayer/ubuntu karmic main
    Don't know why the filter is not included in Ubuntu's regular packages...

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Thanks for the help, now it works quite well, but a lot of programs seem to think that the resulting avi file is nearly 5 hours long, instead of only 11 seconds.. Do you know what that could be about?

    Here you can see the output of your script, it says something about missing pictures -->
    http://pastebin.com/ffce5d8d

    ReplyDelete
  7. The only other idea I have is to compile it yourself: sudo apt-get build-dep mplayer && wget http://www.mplayerhq.hu/MPlayer/releases/mplayer-checkout-snapshot.tar.bz2 && tar jxfs mplayer-checkout-snapshot.tar.bz2 && cd mplayer* && ./configure && make
    Then start the script with ./mencoder

    ReplyDelete
  8. Wow, I did not think that compiling mplayer yourself would be that easy! ;) Okey so I did as you told me and now using the self-compiled mencoder I get the following Output:

    MEncoder SVN-r30230-4.4.1 (C) 2000-2009 MPlayer Team
    -x264encopts is not an MEncoder option

    ReplyDelete
  9. cd mplayer* && CFLAGS= CXXFLAGS= ./configure --enable-x264 && make
    I forgot the --enable-x264

    ReplyDelete
  10. I get errors when compiling with the new configuration:

    libx264.c: In function 'X264_init':
    libx264.c:184: error: 'x264_param_t' has no member named 'i_bframe_pyramid'
    ...

    ReplyDelete
  11. Oh dear. The only idea I have is to get a fresh x264 from git as well... But I tried that and it has compilation problems, there seems to be a bug in the mplayer sources at the moment. I then fixed that my manually adding libx264 to the linking (-lx264 at the end of the c++ .... line). Maybe that would also help you. Worth a try. Otherwise it looks like you're out of luck. It's only the time problem left, right? Maybe that's a bug in the other programs as well. Don't know.

    ReplyDelete
  12. Maybe you want to try again later.

    ReplyDelete
  13. I used this guide to reinstall x264:
    http://ubuntuforums.org/showthread.php?t=786095
    Now I can use the self-compiled mplayer (without the --enable-x264) for your script

    ReplyDelete
  14. Hi, I still have to try your script but I wanted to ask you if it is possible to modify the script to just deinterlace to 25p. I'm looking for a good deinterlacing method under linux for my Canon HV10 m2t 50i files without compressing them and outputting the same m2t 25 Mb/s quality.
    Thanks so much,
    Ignazio

    ReplyDelete
  15. Sorry Thomas, compilation of mplayer and x264 etc seems to change about daily. But x264 is the best codec out there and it's all free, so that's great.

    Hi gigi, it's certainly possible and much easier. are you trying to pipe the output somewhere, edit it or do you simply like large files? ;)
    I've had excellent experience with openshot, which can directly open all my video files and cut them together. Maybe that would be easier for you? I think good deinterlacing is possible with a combination of mcdeint and yadif. I'm sure you understand I won't write a new script for your purposes now... ;)

    ReplyDelete
  16. Thank you! Thank you!!

    I have been looking for this for about a week now.

    I have been using Kdenlive to encode my AVCHD footage. It works well but it is slow (10+hours for 35mins of film) and uses 3-4 GB of virtual memory to do that same encode.

    Just a tip, you can replace this:

    OUT=$(basename "$INPUT"|sed 's/.m2ts//')"-x264.avi"

    With:

    OUT="${INPUT%.*}-x264.avi"

    That way you don't have to guess the extension and also it is less expensive as not calling extra binaries.

    Thanks again!!

    ReplyDelete
  17. Hi David,
    you're very welcome! I'm always glad to hear I saved someone the trouble I went through to find the solution. And glad to learn new bash tricks.

    ReplyDelete
  18. Hello,

    I followed your HOWTO and it worked fine except for the fact that the sound and video in the resulting file is out of sync.

    Do you have any idea what the problem is?

    ReplyDelete
  19. I guess it probably isn't 25i material then, or your version of mencoder is pretty old or incompatible with the camera.
    Where did you buy the camera? US? then you need to adjust the frame rates accordingly - these are for EU norm cameras.

    ReplyDelete
  20. Hi,
    thank you for your script. The only issue I see is with the subtitles (the recording time is embeded in the mts/m2ts file as a subtitle, PGS type) and your script just discards it. Using ffmpeg you can save it, do you know if it is possible to do the same with menconder?

    Thanks,
    BL

    ReplyDelete
  21. I think it's dumpsub or something. You can probably just reintegrate it in a second step after the encode.
    Haha, I was so glad to finally get mencoder working with 50 fps progressive, for me that was enough. Plus I don't use subtitle in my camera. ;)
    Good luck!

    ReplyDelete
  22. Thank you for this script!! But I have an annoying issue, the audio is copied from the video source and with this script, the output video is delayed a few seconds. I want to deinterlace a FullHD 50i video from a Sony HandyCam.

    ReplyDelete

I appreciate comments. And I do read them.