va_encode: libVA encoding tool Content: 1. Introduction 2. Quick start 3. Bitrate control setting 4. Performance testing 5. Special feature testing 6. Dynamic encoding testing 1. Introduction va_encode is a command line encoding tool through VAAPI. It encodes a video file from a YUV source. The YUV source can be from a storage file, or the tool itself can auto-generate a white-black checkerboard sequence. The tools supports some advanced testing features which is useful for driver development and tunning. 2. Quick start Simply type "va_encode" on command line, it will encode a clip with bellow configuration: (a) codec is H264, resolution 176x144, frame number 60, VBR (b) input YUV is the auto-generated white-black checkerboard (c) coded file is saved into /tmp/test.out (Linux) or /sdcard/test.out (Android) To encode VP8, the command line is "va_encoder -t VP8" To encode JPEG, the command line is "va_encoder -t JPEG" To specify a resolution, use "va_encode -w 1280 -h 720" To encode more than 60 frames, use "va_encode -n 100" To encode from a YUV file, use "va_encode -srcyuv yuv_file_name" To save to another file, use "va_encode -o file_path_and_name" For encoding from a YUV file, the tool supports various fourcc, use "-fourcc" parameter to specify it, e.g. "-fourcc IYUV", "-fourcc YV12". The default format is NV12 3. Rate control settings (1) RC mode RC mode can be specified by "-rcMode", e.g. -rcMode CBR -rcMode VBR -rcMode VCM -rcMode CQP (2) Bitrate Bitrate is set by "-bitrate", e.g. -bitrate 500000 It sets the bitrate to 500000bps (3) QP The tool can set the min and max value of QP,e.g. -minqp 15 -maxqp 30 -initalqp 20 It limites qp range to [15, 30], and set the first IDR frame qp to 20 This option may not take effect because of the underline HW/driver bit rate control constrains minqp/maxqp is not applicable to CQP mode. Use "-initialqp" to set the qp (4) I/P/B setting Parameters that are used to set I/P/B sequence -intra_period -idr_period -ip_period The number for "-idr_period" is special. It means after number of "intra_period", there will be an IDR frame. Bellow is detailed explanation about these parameters (intra_id_period is the result of "idr_peroid number" * "intra_perid number" from command line): ================================================================ Assume frame sequence is: Frame#0,#1,#2,...,#M,...,#X,... (encoding order) 1) period between Frame #X and Frame #N = #X - #N 2) 0 means infinite for intra_period/intra_idr_period, and 0 is invalid for ip_period 3) intra_idr_period % intra_period (intra_period > 0) and intra_period % ip_period must be 0 4) intra_period and intra_idr_period take precedence over ip_period 5) if ip_period > 1, intra_period and intra_idr_period are not the strict periods of I/IDR frames, see bellow examples ------------------------------------------------------------------- intra_period intra_idr_period ip_period frame sequence (intra_period/intra_idr_period/ip_period) 0 ignored 1 IDRPPPPPPP ... (No IDR/I any more) 0 ignored >=2 IDR(PBB)(PBB)... (No IDR/I any more) 1 0 ignored IDRIIIIIII... (No IDR any more) 1 1 ignored IDR IDR IDR IDR... 1 >=2 ignored IDRII IDRII IDR... (1/3/ignore) >=2 0 1 IDRPPP IPPP I... (3/0/1) >=2 0 >=2 IDR(PBB)(PBB)(IBB) (6/0/3) (PBB)(IBB)(PBB)(IBB)... >=2 >=2 1 IDRPPPPP IPPPPP IPPPPP (6/18/1) IDRPPPPP IPPPPP IPPPPP... >=2 >=2 >=2 {IDR(PBB)(PBB)(IBB)(PBB)(IBB)(PBB)} (6/18/3) {IDR(PBB)(PBB)(IBB)(PBB)(IBB)(PBB)}... {IDR(PBB)(PBB)(IBB)(PBB)} (6/12/3) {IDR(PBB)(PBB)(IBB)(PBB)}... {IDR(PBB)(PBB)} (6/6/3) {IDR(PBB)(PBB)}. ================================================================ (4) VP8 parameters -raw output is vp8 element stream -riff will add RIFF file header to VP8 element stream Note: default output data for VP8 is IVF file Correctness test: -correctness_test Key frame control: -auto_kf -kf_min_dist -kf_max_dist Error concealment: -error_resilient: default value = 0 0 = off(reset context tables for key frame only), 1 = on(reset context tables for both key frames and golden frames) 4. Performance testing (1) Minimize source YUV loading cost The end-to-end encoding testing includes source YUV loading. It is usually very slow for large resolutions. Two options here: (a) don't set "-srcyuv", it will use auto-generated source, and only load once (b) use "-srcyuv XXX -perf", it always encoding the first 16 frames of the YUV file (2) Single thread vs Multiple thread Parameter "-syncmode" runs encoding with single thread, while without this parameter, the tool create two threads: one is continously sending encoding frames, and another continously read from source YUV and save coded file into storage Multiple thread or single thread should only have impact to end-to-end fps, the core encoding fps is a little different: (1) single thread: core encoding fps counts the time of bellow VAAPIs: vaBeginPicture/vaRenderPicture/vaEndPicture/vaSyncSurface (2) multiple thread: core encoding fps counts the time of bellow VAAPIs: vaBeginPicture/vaRenderPicture/vaEndPicture vaSyncSurface is not counted because it runs in another thread which may be in parallel with vaBeginPicture/vaRenderPicture/vaEndPicture 5. Special feature testing (1) ROI testing -roi_enable: enable ROI feature (default 0) -roi_value: the priority of the ROI region (defautl -2) -roi_minqp: the min allowed delta QP (defaut -4) -roi_maxqp: the max allowed delta QP (default 4) -roi_rect_x/y/w/h: ROI rectangle (default the 1/3 center area of the frame) 6. Dynamic encoding testing Option "-configfile", which could read dynamic RC settings from configure file. The RC settings include: frame_start frame_end frame_width frame_height bits_per_second target_percentage window_size initial_qp min_qp max_qp force_kf no_ref_last no_ref_gf no_ref_arf frame_rate intra_period intra_idr_period ip_period quality refresh_entropy_probs copy_buffer_to_golden copy_buffer_to_alternate refresh_last refresh_golden_frame refresh_alternate_frame Write dynamic change settings into a configuration file, e.g. [beginrc] frame_width=1280 frame_height=720 frame_start=0 frame_end=999 bits_per_second=1000000 [endrc] [beginrc] bits_per_second=2000000 frame_start=1000 frame_end=1999 [endrc] [beginrc] frame_start=2000 frame_end=2999 bits_per_second=3000000 [endrc] [beginrc] frame_start=3000 frame_end=3999 bits_per_second=5000000 [endrc] Another example for VP8 dynmaic bitrate testing [beginrc] frame_width=176 frame_height=144 frame_start=0 frame_end=4 force_kf=1 [endrc] [beginrc] frame_start=5 frame_end=9 force_kf=0 [endrc] [beginrc] frame_start=10 frame_end=19 no_ref_last=1 no_ref_arf=1 no_ref_gf=0 [endrc] [beginrc] frame_start=20 frame_end=29 no_ref_last=1 no_ref_arf=0 no_ref_gf=1 [endrc] [beginrc] frame_start=30 frame_end=39 no_ref_last=1 no_ref_arf=0 no_ref_gf=0 [endrc] [beginrc] frame_start=40 frame_end=49 no_ref_last=0 no_ref_arf=1 no_ref_gf=1 [endrc] [beginrc] frame_start=50 frame_end=59 no_ref_last=0 no_ref_arf=1 no_ref_gf=0 [endrc] [beginrc] frame_start=60 frame_end=69 no_ref_last=0 no_ref_arf=0 no_ref_gf=1 [endrc] [beginrc] frame_start=70 frame_end=79 refresh_last=0 [endrc] [beginrc] frame_start=80 frame_end=139 refresh_golden_frame=0 [endrc] [beginrc] frame_start=140 frame_end=199 refresh_alternate_frame=0 [endrc] Parameter "-dynamic_resolution" is used to singal application to allocate surface at 1080P resolutioin, then it can test dynamic resolution change feature