This document records one of the simplest video encoders based on the libx264. The previously recorded H. Encode encoder is encoded based on the FFmpeg call libx264, for example:
The simplest ffmpeg-based video encoder (YUV code is h. a)
Compared with the encoder above, the encoder recorded in this document belongs to the "lightweight" encoder. Because it no longer contains ffmpeg code, call libx264 to complete the encoding directly. So the size of the project is very small. The encoder can encode the input YUV data into a h. A stream file.
Flow chart
The flowchart that calls libx264 for video encoding is shown below.
The main functions in the flowchart are shown below.
X264_param_default (): Sets the default value of the parameter set structure body x264_param_t.
X264_picture_alloc (): Allocates memory for the image structure body x264_picture_t.
X264_encoder_open (): Open the encoder.
X264_encoder_encode (): Encodes a frame image.
X264_encoder_close (): Turn off the encoder.
X264_picture_clean (): Releases the resources requested by X264_picture_alloc ().
The structure in which the data is stored is shown below.
x264_picture_t: Stores the pixel data before compressing the encoding.
X264_NAL_T: Stores encoded stream data after compression.
Also included in the flowchart is a "Flush_encoder" module, which uses the same function as the encoding module. The only difference is that the video pixel data is no longer entered. It works by outputting the remaining stream data in the encoder.
Source
/** * Simplest X264 based video encoder * Simplest X264 Encoder * * Lei hua Lei Xiaohua * [email protected] * Communication University/Digital TV Technology * Communicatio n University of China/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This program can be in YUV format pixel data encoded into H. s stream, is the simplest * LIBX264 based Video Encoder * * This software encode YUV data to H. bitstream. * It ' s The simplest encoder example based on libx264. */#include <stdio.h> #include <stdlib.h> #include "stdint.h" #if defined (__cplusplus) extern "C" {#include " X264.h "}; #else # include" x264.h "#endif int main (int argc, char** argv) {int ret; int y_size; int i,j; file* fp_src = fopen (".. /cuc_ieschool_640x360_yuv444p.yuv "," RB "); file* fp_src = fopen (".. /cuc_ieschool_640x360_yuv420p.yuv "," RB "); file* FP_DST = fopen ("cuc_ieschool.h264", "WB"); Encode frame//if set 0, Encode all frame int frame_num=50; int csp=x264_csp_i420; int width=640,height=360; InchT iNal = 0; x264_nal_t* pnals = NULL; x264_t* phandle = NULL; x264_picture_t* ppic_in = (x264_picture_t*) malloc (sizeof (x264_picture_t)); x264_picture_t* ppic_out = (x264_picture_t*) malloc (sizeof (x264_picture_t)); x264_param_t* Pparam = (x264_param_t*) malloc (sizeof (x264_param_t)); Check if (fp_src==null| | Fp_dst==null) {printf ("Error open files.\n"); return-1; } x264_param_default (Pparam); Pparam->i_width = width; Pparam->i_height = height; /*//param pparam->i_log_level = x264_log_debug; Pparam->i_threads = X264_sync_lookahead_auto; pparam->i_frame_total = 0; Pparam->i_keyint_max = 10; Pparam->i_bframe = 5; PPARAM->B_OPEN_GOP = 0; Pparam->i_bframe_pyramid = 0; pparam->rc.i_qp_constant=0; pparam->rc.i_qp_max=0; Pparam->rc.i_qp_min=0; Pparam->i_bframe_adaptive = X264_b_adapt_trellis; Pparam->i_fps_den = 1; Pparam->i_fps_num = 25; Pparam->i_timebase_den = pparam->i_fps_num; Pparam->i_timebase_num = pparam->i_fps_den; */pparam->i_csp=csp; X264_param_apply_profile (Pparam, x264_profile_names[5]); Phandle = X264_encoder_open (Pparam); X264_picture_init (ppic_out); X264_picture_alloc (ppic_in, CSP, Pparam->i_width, pparam->i_height); ret = X264_encoder_headers (Phandle, &pnals, &inal); Y_size = Pparam->i_width * pparam->i_height; Detect frame number if (frame_num==0) {fseek (fp_src,0,seek_end); Switch (CSP) {case X264_csp_i444:frame_num=ftell (FP_SRC)/(Y_SIZE*3); Case X264_csp_i420:frame_num=ftell (FP_SRC)/(Y_SIZE*3/2); Default:printf ("ColorSpace not support.\n"); return-1; } fseek (Fp_src,0,seek_set); }//loop to Encode for (i=0;i<frame_num;i++) {switch (CSP) { Case x264_csp_i444:{Fread (PPIC_IN->IMG.PLANE[0],Y_SIZE,1,FP_SRC); Y fread (PPIC_IN->IMG.PLANE[1],Y_SIZE,1,FP_SRC); U fread (PPIC_IN->IMG.PLANE[2],Y_SIZE,1,FP_SRC); V break;} Case x264_csp_i420:{Fread (PPIC_IN->IMG.PLANE[0],Y_SIZE,1,FP_SRC); Y fread (PPIC_IN->IMG.PLANE[1],Y_SIZE/4,1,FP_SRC); U fread (PPIC_IN->IMG.PLANE[2],Y_SIZE/4,1,FP_SRC); V break;} default:{printf ("ColorSpace not support.\n"); return-1;} } ppic_in->i_pts = i; ret = X264_encoder_encode (Phandle, &pnals, &inal, ppic_in, ppic_out); if (ret< 0) {printf ("error.\n"); return-1; } printf ("Succeed Encode frame:%5d\n", i); for (j = 0; j < INal; ++j) {fwrite (pnals[j].p_payload, 1, pnals[j].i_payload, FP_DST); }} i=0; Flush encoder while (1) {ret = X264_encoder_encode (Phandle, &pnals, &inal, NULL, Ppic_o UT); if (ret==0) {break; } printf ("Flush 1 frame.\n"); for (j = 0; j < INal; ++j) {fwrite (pnals[j].p_payload, 1, pnals[j].i_payload, FP_DST); }i++; } x264_picture_clean (ppic_in); X264_encoder_close (Phandle); Phandle = NULL; Free (ppic_in); Free (ppic_out); Free (pparam); Fclose (FP_SRC); Fclose (FP_DST); return 0;}
Run results
The input to the program is a YUV file (two formats have been tested for yuv444p and yuv420p).
The output is a. h code stream file.
The information for the H. A stream file is as follows.
Download
Simplest Encoder
SourceForge Project home: https://sourceforge.net/projects/simplestencoder/
cdsn:http://download.csdn.net/detail/leixiaohua1020/8284105
The solution contains several common examples of using encoders:
Simplest_vpx_encoder: The simplest LIBVPX-based video encoder
Simplest_x264_encoder: The simplest libx264-based video encoder
Simplest_x265_encoder: The simplest libx265-based video encoder
The simplest video encoder: Based on libx264 (encoded YUV is H. a)