Wednesday, September 3, 2008

Experience with mencoder

mencoder encodes videos, I use it to encode my DVB recordings. When you run mencoder without any tunning, you will waste useful space. Here is my experience with mencoder:

Removes all black borders
Really !! You can use the filter cropdetect to find the values for the crop filter or use the filter rectangle:
$ mplayer -vf cropdetect video.avi
$ mplayer -vf rectangle=716:428:: video.avi

Avoid odd numbers
as a general advise.

Height and Width
must be a multiple of 16. The video codec encodes the video with 16x16 blocks and if the size isn't a multiple of 16, you will waste space. The filter cropdetect returns values that are a multiple of 16, but also crops the video sometimes to much.

Scale
can help to solve this problem. And sometimes it's better to have a smaller height and width. First just crop only the black borders, then scale the video height and width to a multiple of 16.

For example:
$ mplayer -vf crop=716:428::,scale=640:-10

The new width is 640 and height 352.
The parameter -10 tells the scale filter to calculate the height using the width and to round the height to the closest multiple of 16.

Use filter hqdn3d=2:1:2
Use filter harddup
See man page why

Two Pass Mode
The  first pass analyzing the whole video and writes a statistics file. The second pass reads the statistics file and bases ratecontrol decisions on it. The output file from the first pass can be deleted or send directly to /dev/null

File Size
Should the movie fit on a CD, then you have of calculate the bitrate of your movie:
Bitrate = (Target_Size_in_MB - Audio_Size_in_MB - AVI_overhead_MB) * 1024 * 1024 / Length_in_secs * 8 / 1000
Use the video codec xvid and it will do it for you, you just need to set the video file size in KB (See example).
How to calculate it ? When you use the Two Pass Mode, write down the audio size after the first pass has finished.
Video_Size_MB = Target_Size_in_MB - Audio_Size_in_MB - AVI_overhead_MB
Video_Size_KB = (Target_Size_in_MB - Audio_Size_in_MB - AVI_overhead_MB) * 1024

AVI Overhead
When you use AVI as your container, some MBs will be wasted for the AVI header and index.
For a 350MB file ~ 5MB
For 700MB ~ 8MB

Example

First Pass
$ mencoder -ovc xvid -xvidencopts pass=1:autoaspect:threads=2 -vf crop=715:428::,scale=640:-10,hqdn3d=2:1:2,harddup -oac mp3lame -lameopts aq=3:preset=standard video.mpg -o /dev/null

Second Pass
$ mencoder -ovc xvid -xvidencopts pass=2:bitrate=-595968:autoaspect:threads=2 -vf crop=715:428::,scale=640:-10,hqdn3d=2:1:2,harddup -oac mp3lame -lameopts aq=3:preset=standard video.mpg -o video.avi


Is the value for the bitrate option negativ, it sets the video size in kilobytes [700 (CD) - 110 (audio size) - 8 (AVI overhead) = 580 * 1024 = 595968kb].
The threads option is only useful if you have more than one CPU else remove it.

DVB Streams

If you record a DVB streams you will notice sooner or later, that they aren't small.
For two hours 5 GB space, isn't that small and won't fit on a CD.

To encode a video, first you have to demux with ProjectX (http://sourceforge.net/projects/project-x) and remux with mplex (package mjpegtools) the stream to fix possible transmission errors. If you don't to that, you will maybe get a video where the audio and video is out of synchronization. It is also possible to export the subtitles from the Teletext.

$ java -jar ProjectX.jar myVideo.mpg

After running the program, you will find for every video and audio track an own file. To see all available options from ProjectX, run it without any parameters.

Then remux the video and audio together with mplex:

$ mplex -f 8 -o newVideo.mpg myVideo.m2v myVideo.mp2

When mplex returns without any errors, all files are no longer needed except newVideo.mpg.

Now cut out the advertisement, for example with dvbcut or avidemux and encode the video the get a smaller file size.