x264 Overview

Tue 14 November 2017
By YF

Introduction


x264 version compilable by visual studio, generated by Shift Media Project I have forked my own version and put it in my github website: git@github.com:huyunf/x264.git

Code Overview


h = x264_encoder_open( );

for(loop by frame number){
    ...
    encode_frame( );
    ...
}

The x264_encoder_open() function does several initial task for the following encoding process. For more detail, please refer to x264 Encoder Open

x264_encoder_encode


The encode_frame() will lead to x264_encoder_encode, which is the true main encoding funcion. In x264_encoder_encode, it

  1. prepare thread for encoding task
  2. setup new frame from picture list

    • setting frame parameters like resolution, picture structure. etc
    • initial parameters for adaptive MB level quantization by calling function x264_adaptive_quant_frame. For detail algorithm please refer to x264 Adaptive Quant
    • prepare low resolution frame for zero pass x264_frame_init_lowres
    • put frame into process queue x264_lookahead_put_frame. If enable multiple thread, each thread will get frame from the list and start their own process

    The prepare process should fill the prepare frame list. And the number of frame need to input to the list is decided by

        if( h->frames.i_input <= h->frames.i_delay + 1 - h->i_thread_frames )
        {
            ...
            return 0;
        }
    
  3. analyze picture in lookahead x264_lookahead_get_frames, mainly for get slice type

    • decide slice type x264_slicetype_decide. For more detail about the x264 slice type decision algorithm. Please refer to x264 Slice Type Decision
  4. several top level syntax process, like reference list prepare x264_reference_build_list, nal structure prepare. etc

  5. bit stream structure bs prepare bs_init, write header if necessary:

    • aud
    • if key frame, write SPS and PPS
    • period sei, extra sei, pic timing sei, sei for blu-ray. etc
  6. perform rate control x264_ratecontrol_start and get the global qp x264_ratecontrol_qp. For more detail of x264 rate control, please refer to x264 rate control

  7. initial slice header x264_slice_init

  8. weighted prediction prepare x264_macroblock_bipred_init for B frame and x264_weighted_pred_init

    Brief summery of algorithm in x264_macroblock_bipred_init. poc0 and poc1 represent the poc number from forward reference list and backward reference list.

    td = x264_clip3( poc1 - poc0, -128, 127 );
    if( td == 0 /* || pic0 is a long-term ref */ )
        dist_scale_factor = 256;
    else
    {
        int tb = x264_clip3( cur_poc - poc0, -128, 127 );
        int tx = (16384 + (abs(td) >> 1)) / td;
        dist_scale_factor = x264_clip3( (tb * tx + 32) >> 6, -1024, 1023 );
    }
    

    |<--------tb---------->|

    |----------------------|-----|

    |<-------------td----------->|

    tx = 16k / td

    dist_scale_factor = tb/td (multiple 16k to extend dynamic range)

  9. slice encoding entry x264_slices_write or x264_threaded_slices_write when multiple thread pool enabled

x264_slice_write


The x264_slices_write contain a while loop which will deal with each slice of the frame. It will first gt i_first_mb and i_last_mb for slice header and then call slice encoding function x264_slice_write

    static void *x264_slices_write( x264_t *h )
    {
        while( h->sh.i_first_mb + SLICE_MBAFF*h->mb.i_mb_stride <= last_thread_mb )
        {
            //... h->sh.i_last_mb;
            if( x264_stack_align( x264_slice_write, h ) )
                goto fail;
            //... h->sh.i_first_mb
        }
    }

In function x264_slice_write, the real encoding process happened

  1. get slice level qp from rate control x264_ratecontrol_mb_qp

  2. write slice header x264_slice_header_write

  3. if cabac enabled, several cabac initial step x264_cabac_context_init and x264_cabac_encode_init, which initiate the cabac context according to slice type and qp value

Then there goes to the while loop for encoding each mb (i_first_mb to i_last_mb)

  1. do the hpel & deblocking for top row x264_fdec_filter_row

  2. load cache data for each MB, x264_macroblock_cache_load_xxx. In this function, decoder prepare the context of top and left MB data if necessary. Most data store in x264_t.mb.cache

  3. macroblock analyse x264_macroblock_analyse, which doing so-called Mode decision. The decision choose the best rdo mode from intra & inter separately and then select the better from intra & inter. For more detail of the analyse, please refer to x264 MB Analyse and Coding

  4. following is real encoding process x264_macroblock_encode. The function encode the MB's syntax into bitstream and generate reconstruct data, which will be used as reference for later frame. For more detail please refer to x264 MB Analyse and Coding

  5. several steps for entropy cabac or cavlc engine.

  6. save context into cache x264_macroblock_cache_save

  7. mb level rate control x264_ratecontrol_mb x264 rate control

  8. several steps for accumulating mb stats

  9. calculate deblock strength values x264_macroblock_deblock_strength. actual deblocking is done per-row along with hpel

After the while loop for each MB, several step for

  1. deblocking for last row

  2. end of entropy coding engine

Reference Doc


Doc of X264 Overview

Comments