Log in

View Full Version : An MPEG4 encoder model with source code to play with


Strongling
16th February 2007, 05:09
Hello all,

I have been working on an MPEG4 encoder model (in plain C) for some time now. I just finished cleaning it up a bit and now it is in a state that I would like to share with all of you.


The file is attached and here’s how it works. Running without any parameters will give a small description of the parameters like shown below.


usage: mp4sp.exe src_file_name w h v n c t i p r d s j a u f g

where: src_file_name : YUV420 filename to encode e.g. input.yuv
: w : width of Y component, must be multiple of 16 e.g. 352
: h : height of Y component, must be multiple of 16 e.g. 288
: v : frame-rate e.g. 30
: n : number of frames to encode e.g. 150
: c : prefiltering, 0=off, 1=low, 2=high ... 5=max
: t : I frame interval, 0=adaptive or e.g. 30
: i : quantizer value for I frame e.g. 3
: p : quantizer value for P frames e.g. 5
: r : initial search range for motion estimation e.g. 16
: d : decimation factor for first stage motion search e.g. 2
: s : half pixel motion estimation, 0=no, 1=yes
: j : intra MB injection in P frames, 0=no, 1=yes
: a : AC coefficient prediction in intra MBs, 0=no, 1=yes
: u : unrestricted motion vectors, 0=no, 1=yes
: f : 4MV mode, 0=no, 1=yes
: g : adaptive search range , 0=no, 1=yes


As you can see there are a lot of parameters/options here so I will give a brief on all of them one by one.



Parameter 1: src_file_name

The name of the input source file name to compress. Has to be in YUV420 planar format.


Parameter 2: w

The width of Luma component in source file. Has to be a multiple of 16, i.e. the source must have integral MB width.


Parameter 3: h

The height of Luma component in source file. Has to be a multiple of 4. If the height is not in integral MBs, the bottom part will be chopped off to make it a multiple of 16. This was done to take care of the HD sequences that are usually available in 1080 height which is not a multiple of 16. It will be encoded as 1920x1072.


Parameter 4: v

The frame-rate. Just a number needed to calculate and put proper timestamps in the encoded file. Does not have any impact on the quality of encoding. Has to be an integer so for NTSC sequences use 30 instead of 29.97 or 60 instead of 59.94.


Parameter 5: n

The number of frames to encode. Give a really large number to make sure that the whole sequence gets encoded. If the sequence is smaller than “n” frames, it will make sure to encode all the frames otherwise just the number of frames you want e.g. 3 etc.


Parameter 6: c

The preprocessing filter strength. It uses a simple 3 tap filter to smooth-out the source files BEFORE encoding. 0 means off, i.e. no filtering. 1 means it will use 1/14/1 taps and 2 is a stronger filter with 2/12/2 taps and so on. The whole image is filtered horizontally then vertically with the same taps. With the stronger filter I saw a bit-rate reduction by around 50% with same quantizers at the cost of some (non-annoying) blurriness.


Parameter 7: t

The I frame interval. Can be a number greater than 0 for a fixed rate I frame, e.g. 30. A value of 1 here will produce an all-I-frame sequence. A value of 0 is for adaptive which means the first frame is always an I frame and then it will make another I frame during encoding when the scene change detector sees a big change in overall brightness.


Parameter 8: i

The QP value to use for all I frames. Keep between 1 and 31.


Parameter 9: p

The QP value to use for all P frames. Keep between 1 and 31.


Parameter 10: r

This MPEG4 encoder model uses a full search motion estimator. The search range to be used by the motion estimator is given by this parameter. The meaning changes if adaptive search range option (see parameter 17) is enabled. Please keep it a multiple of the decimation factor chosen (see next parameter).


Parameter 11: d

The decimation factor to use by the motion estimator. For example if 4 is chosen here then the ME will search every 4th block and then the search will be refined to every 2nd block around the best 4th candidate and finally the search will be refined to full pixel accuracy around the best decimated match. If adaptive search range is OFF (parameter 17) then this can be any power of 2 e.g. 1,2,4,8 ... but with adaptive search ON the only valid values are 1 or 2. It is very important to note that this should NOT be 0 in any case. Make it 1 for a true full search.


Parameter 12: s

Half pixel motion estimation refinement. Can be turned off but this has the biggest impact (BAD) on quality and bitrate in my opinion. Keep it at 1.


Parameter 13: j

Whether I MBs are allowed in P frames or not. Should be kept ON always.


Parameter 14: a

Whether or not to use AC coefficient prediction for all I MBs, in I or P frames. Some results: this is kind of a hit or miss feature. I have seen that it sometimes hurts more than it helps, depending on the content. It is one of those MPEG things that helps when things are already good i.e. low-action sequences e.g. “susie”, and does nothing much with high-action sequences e.g. “bus”, “foreman” etc. I would like to improve it and make it adaptive as well, i.e. decided on a block basis rather than always ON or always OFF.


Parameter 15: u

Unrestricted motion vectors. Keep it on always, probably after half pixel ME, this has the biggest impact on bitrate/quality.


Parameter 16: f

Four motion vectors per MB. Can be turned on or off to see the effects. It is useful depending on the thresholds set.


Parameter 17: g

Adaptive search range for motion estimation. I could write a whole paper here but briefly the idea is to restrict (or expand) the search range on a frame by frame basis. So in a sense, the motion estimation search range becomes “scene adaptive”. While experimenting I saw some really amazing gains (typically less than 20% ME effort) without loss of quality and even an improvement in bitrate. Keep this OFF to see results of a typical full search motion estimator and turn it ON to see the difference in the number of searches performed per frame. If this is ON then the number given as the search range (parameter 10) is used only as a starting point and the encoder adapts as it goes along.


Some general notes about the model encoder:

0. It works! :)

1. There is minimum error handling so please be gentle.

2. The output file generated has the input name appended by the parameters(6 to 17) as chosen.

3. The (0,0) 1MV has been given a SAD bias of 40 as a preferred vector over others. Not available as a command line option, can ofcourse be changed in the source code.

4. The 1MV mode has a SAD bias of 128 preference over the 4MV mode for each MB. Not available as a commandline option. Not available as a command line option, can ofcourse be changed in the source code.

5. The inter modes(1MV and 4MV) have a SAD bias preference of 384 over intra for each MB. Not available as a command line option, can ofcourse be changed in the source code.

6. The encoder generates a frame-wise report as a txt file along with the encoded m4v file that has some valuable information about the encoding session.

7. The model is written with flexibility of being able to test new ideas in mind. e.g. if anyone has a different/new DCT/IDCT implementation, it can be plugged in easily to see the effects of speed vs. precision for example.

8. The model currently uses the famous “Chen-Wang” integer fast IDCT implementation that is used by all the MPEG (1, 2 and 4) reference models.

9. The model currently uses Skal’s integer fast FDCT implementation that is used by most popular mpeg codecs.

10. Please give it a spin in your spare time and let me know if you find anything interesting. Also all querries about anything in source code are welcome. I am doing a "programmer's comments.txt" that I will add soon. That should help uderstand (the already simple coded) source.


Regards,

Strongling

Strongling
19th February 2007, 04:38
Hi all,

Here's a small update.


Bugfixes:
- a small bug fixed to calculate PSNR

Added:
- if compiled with DEBUG_ENABLE 1 (in main.h), the encoder will dump each reference frame
and each predicted frame along with the encoded mp4 file
- "programmers comments.txt" please read this before looking at the source code

bond
22nd February 2007, 20:28
nice to play around with, thx! :)