Update to PS3 encoding using mencoder in MP4 format

Sunday, January 24, 2010 Posted by Psyk
Further to my old (and probably obsolete) entry here I thought it worthwhile to add an update in regards to encoding to MP4 format playable on Windows Media Centres and PS3's, although it should work on other platforms such as the Xbox but can't be sure as I don't have one for testing.

One of the biggest issues I had with the previous method was the reliability in muxing it into an MP4 via MP4Box and especially when trying to get the audio, video sync right which I think had to do with it not being able to detect the FPS correctly.  In any case, the procedure involves converting everthing to an AVI (mencoder's preferred format) and then ripping/converting them raw and muxing it back into an MP4 using MP4box, mencoder can do MP4's but it's broken.

First things first, and I can't take all the credit for this.  Credit goes to the h264enc project which uses mencoder heavily and has some great built-in profiles.  Excellent display of show-casing mencoder's power and versatility.

Lets, start...

Add a new profile entry in ~/.mplayer/mencoder.conf  
 [H264ENC]  
 profile-desc="taken from h264enc, PS3 compatible encode with high quality."  
 vf=pp=al:c,softskip,scale=720:-10,harddup   
 aspect=16:9  
 af=volnorm=2,lavcresample=48000:16:1   
 srate=48000  
 oac=faac=yes   
 faacopts=mpeg=4:br=160:tns=yes:object=2  
 ovc=x264=yes  
 x264encopts=crf=19:me=umh:me_range=24:nodct_decimate:nointerlaced:8x8dct:nofast_pskip:trellis=1:partitions=p8x8,b8x8,i8x8,i4x4:mixed_refs:keyint=240:keyint_min=24:psy_rd=0.8,0.2:frameref=3:bframes=3:b_adapt=2:b_pyramid:weight_b:direct_pred=auto:subq=7:chroma_me:cabac:aud:aq_mode=1:deblock:vbv_maxrate=20000:vbv_bufsize=20000:level_idc=41:threads=auto:ssim:psnr  
Obviously you can add your own parameters here especially in the "vf" section where you can adjust the scale, add some additional features (e.g. pullup,softskip, yadif etc.)

I won't go into all the details here, but basically this scales the image down to a 720p type format, normalizes the volume and resamples it to 48kHz, encodes it to AAC at 160kb and uses a constant rate factor for h264 of '19' for higher-end quality without much regard for final file size (i.e. it focuses on maximizing the video quality).

Once you have your profile you can run:
 mencoder -profile H264ENC "source_movie_file.ext" -o "source_movie_file.avi"  
This is the encoding process and the lengthiest bit...

If you want to hardsub an SRT file you can specify the -sub "name_of_srt_file.srt" and the -subfont-autoscale 1 parameters to the mencoder line above.

For example:
 mencoder -profile H264ENC "source_movie_file.ext" -o "source_movie_file.ext.avi" -sub "name_of_srt_file.srt" -subfont-autoscale 1  

Once this is finished, you'll have a h264 encoded video and aac encoded audio muxed into an AVI format, which is not very friendly format and container combo, only mencoder/mplayer/vlc player friendly :)

Next process requires us to split the video and audio into 'raw' input files that MP4Box can handle. We'll do the video first:
 mencoder "source_movie_file.avi" -nosound -ovc copy -of rawvideo -o h264_video.h264  
This will output a file called "h264_video.h264" in a raw stream that MP4Box can understand. As we've already done the encoding in the first step this will be quick as we're just ripping it from the AVI file.

Next, is the audio:
 MP4Box -aviraw audio "source_movie_file.avi" -out aac.raw  
Here we're using MP4Box to rip the audio from the AVI to a file called "aac_audio.raw" as MP4Box will rename the output.

Rename it so that MP4Box can manage it as an AAC input:
 mv aac_audio.raw aac_audio.aac  

The next step is to pick up the framerate (FPS) of the original movie source for correct interpretation into MP4.
 mplayer "source_movie_file.avi" -noconfig all -loop 1 -identify -nosound -vo null -nocache -frames 1 2>/dev/null | grep '^ID_VIDEO_FPS' | tail -n 1 | awk -F= '{print $2}' > mp4fps.fps  
This outputs the FPS of the original converted movie (AVI file) to a file called mp4fps.fps.

The final step muxes the video and audio into an MP4 container compatible with the many MP4 hardware devices and media centres. This may not work with an iPod as it uses some advanced parameters in the encoding. I'll try and post up the iPod parameters another time...
 MP4Box -fps $(cat "mp4fps.fps") -add "h264_video.h264" -add "aac_audio.aac"#audio:name="LC-AAC Stereo" -itags name="source_movie_file.avi":comment="Tagged by Psyk on $(date)" -mpeg4 -new "source_movie_file.avi".mp4  
The final output will be something like "Source_movie_file.avi.mp4". You can obviously change these output files and edit the tags.

Lastly, the cleanup:
 rm h264_video.h264  
 rm aac_audio.aac  
 rm mp4fps.fps  

To make things easier I put all of these into a very simple shell-script.
 mencoder -profile H264ENC "$1" -o "$1".avi  
 sleep 2  
 mencoder "$1".avi -nosound -ovc copy -of rawvideo -o h264_video.h264  
 sleep 2  
 MP4Box -aviraw audio "$1".avi -out aac.raw  
 sleep 2  
 mv aac_audio.raw aac_audio.aac  
 mplayer "$1".avi -noconfig all -loop 1 -identify -nosound -vo null -nocache -frames 1 2>/dev/null | grep '^ID_VIDEO_FPS' | tail -n 1 | awk -F= '{print $2}' > mp4fps  
 .fps  
 MP4Box -fps $(cat "mp4fps.fps") -add "h264_video.h264" -add "aac_audio.aac"#audio:name="LC-AAC Stereo" -itags name="$1":comment="Tagged by lazza on $(date)" -mpeg4  
  -new "$1".mp4  
 sleep 2  
 rm h264_video.h264  
 rm aac_audio.aac  
 rm mp4fps.fps  
Labels:
  1. Anonymous

    I was getting a failure encoding "FATAL: Cannot initialize video driver" until I removed b_pyramid from the x264encopts

  2. Newer versions of the x264 libraries have removed the b_pyramid parameter I believe.

  3. XTL

    I also removed the pyramid line. I also tweaked the script a bit to add some code to the top:


    #!/bin/sh

    if [ ! -f "$1" ]; then
    echo "no file $1"
    exit 1
    fi

    BN=`basename $1 .mov`
    echo "Starting $BN (mov -> avi + mp4)"
    sleep 3

    .. and I used $BN instead of $1 later so it doesn't make .mov.mp4 style filenames.

    It could of course be made smarter still.

Post a Comment