使用FFMPEG作编码操作时,会涉及到将yuv数据编码成h264数据,FFmpeg的libavcodec中的libx264.c会调用x264库的源码作编码:
1.x264库编译
 下载X264,地址为:http://www.videolan.org/developers/x264.html,并解压。
 mkdir my_build
 ./configure --enable-shared --prefix=./my_build/
 make -j4
 make install
2.编译后可以查看 my_build目录
.
|-- bin
|   `-- x264
|-- include
|   |-- x264.h
|   `-- x264_config.h
`-- lib|-- libx264.so -> libx264.so.164|-- libx264.so.164`-- pkgconfig`-- x264.pc
其中bin目录下x264为可执行文件,我们通过此可执行文件来分析x264库的相关功能
3.运行
 通过-h信令,我们大致可以了解x264的主要功能和使用方法
 ./x264 -h
$ ./x264 -h
x264 core:164
Syntax: x264 [options] -o outfile infileInfile can be raw (in which case resolution is required),or YUV4MPEG (*.y4m),or Avisynth if compiled with support (yes).or libav* formats if compiled with lavf support (no) or ffms support (no).
Outfile type is selected by filename:.264 -> Raw bytestream.mkv -> Matroska.flv -> Flash Video.mp4 -> MP4 if compiled with GPAC or L-SMASH support (no)
Output bit depth: 8/10Options:-h, --help                  List basic options--longhelp              List more options--fullhelp              List all optionsExample usage:Constant quality mode:x264 --crf 24 -o <output> <input>Two-pass with a bitrate of 1000kbps:x264 --pass 1 --bitrate 1000 -o <output> <input>x264 --pass 2 --bitrate 1000 -o <output> <input>Lossless:x264 --qp 0 -o <output> <input>Maximum PSNR at the cost of speed and visual quality:x264 --preset placebo --tune psnr -o <output> <input>Constant bitrate at 1000kbps with a 2 second-buffer:x264 --vbv-bufsize 2000 --bitrate 1000 -o <output> <input>Presets:--profile <string>      Force the limits of an H.264 profileOverrides all settings.- baseline, main, high, high10, high422, high444--preset <string>       Use a preset to select encoding settings [medium]Overridden by user settings.- ultrafast,superfast,veryfast,faster,fast- medium,slow,slower,veryslow,placebo--tune <string>         Tune the settings for a particular type of sourceor situationOverridden by user settings.Multiple tunings are separated by commas.Only one psy tuning can be used at a time.- psy tunings: film,animation,grain,stillimage,psnr,ssim- other tunings: fastdecode,zerolatencyFrame-type options:-I, --keyint <integer or "infinite"> Maximum GOP size [250]--tff                   Enable interlaced mode (top field first)--bff                   Enable interlaced mode (bottom field first)--pulldown <string>     Use soft pulldown to change frame rate- none, 22, 32, 64, double, triple, euro (requires cfr input)Ratecontrol:-B, --bitrate <integer>     Set bitrate (kbit/s)--crf <float>           Quality-based VBR (-12-51) [23.0]--vbv-maxrate <integer> Max local bitrate (kbit/s) [0]--vbv-bufsize <integer> Set size of the VBV buffer (kbit) [0]-p, --pass <integer>        Enable multipass ratecontrol- 1: First pass, creates stats file- 2: Last pass, does not overwrite stats fileInput/Output:-o, --output <string>       Specify output file--sar width:height      Specify Sample Aspect Ratio--fps <float|rational>  Specify framerate--seek <integer>        First frame to encode--frames <integer>      Maximum number of frames to encode--level <string>        Specify level (as defined by Annex A)--quiet                 Quiet ModeFiltering:--vf, --video-filter <filter0>/<filter1>/... Apply video filtering to the input fileFilter options may be specified in <filter>:<option>=<value> format.Available filters:crop:left,top,right,bottomselect_every:step,offset1[,...]
4.建立一个工程,用于将YUV转成H264
编写测试程序
 代码结构
.
|-- Makefile
|-- in420.yuv
|-- inc
|-- obj
|   `-- test.o
|-- out.h264
|-- src
|   `-- test.cpp
|-- third_lib
|   `-- x264
|       |-- include
|       |   |-- x264.h
|       |   `-- x264_config.h
|       `-- lib
|           `-- libx264.so
`-- video_prjtest.cpp内容:
#include <stdio.h>
#include <stdlib.h>#include "stdint.h"#if defined ( __cplusplus)
extern "C"
{
#include "x264.h"
};
#else
#include "x264.h"
#endifint main(int argc, char** argv)
{int ret;int y_size;int i,j;FILE* fp_src  = fopen("./in420.yuv", "rb");FILE* fp_dst = fopen("out.h264", "wb");int frame_num=50;int csp=X264_CSP_I420;int width=640,height=360;int 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));//Checkif(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;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);y_size = pParam->i_width * pParam->i_height;//detect frame numberif(frame_num==0){fseek(fp_src,0,SEEK_END);switch(csp){case X264_CSP_I444:frame_num=ftell(fp_src)/(y_size*3);break;case X264_CSP_I420:frame_num=ftell(fp_src)/(y_size*3/2);break;default:printf("Colorspace Not Support.\n");return -1;}fseek(fp_src,0,SEEK_SET);}//Loop to Encodefor( i=0;i<frame_num;i++){switch(csp){case X264_CSP_I444:{fread(pPic_in->img.plane[0],y_size,1,fp_src);         //Yfread(pPic_in->img.plane[1],y_size,1,fp_src);         //Ufread(pPic_in->img.plane[2],y_size,1,fp_src);         //Vbreak;}case X264_CSP_I420:{fread(pPic_in->img.plane[0],y_size,1,fp_src);         //Yfread(pPic_in->img.plane[1],y_size/4,1,fp_src);     //Ufread(pPic_in->img.plane[2],y_size/4,1,fp_src);     //Vbreak;}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 encoderwhile(1){ret = x264_encoder_encode(pHandle, &pNals, &iNal, NULL, pPic_out);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;
}