1、源码下载
http://download.videolan.org/x264/snapshots/
2、编译
./configure --prefix=./_install --enable-shared --enable-static
make
make install
3、demo
在x264库里的x264_config.h中确定版本号,版本太混乱了,相差太远可能还不兼容
#define X264_POINTVER "0.157.x"
main.c
/**
* 最简单的基于X264的视频编码器
* Simplest X264 Encoder
* leixiaohua
*
* 本程序可以YUV格式的像素数据编码为H.264码流,是最简单的
* 基于libx264的视频编码器
*
* This software encode YUV data to H.264 bitstream.
* It's the simplest encoder example based on libx264.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
//#include <pthread.h>
#if defined ( __cplusplus)
extern "C"
{
#include "x264.h"
};
#else
#include "x264.h"
#endif
int csp=X264_CSP_I420;
int frame_num=0;
int width=640;
int height=360;
FILE* fp_src;
FILE* fp_dst;
x264_nal_t* pNals;
x264_t* pHandle;
x264_picture_t* pPic_in;
x264_picture_t* pPic_out;
x264_param_t* pParam;
int y_size;
int en_h264_init()
{
fp_src = fopen("./cuc_ieschool_640x360_yuv420p.yuv", "rb");
fp_dst = fopen("output.h264", "wb");
pNals = NULL;
pHandle = NULL;
pPic_in = (x264_picture_t*)malloc(sizeof(x264_picture_t));
pPic_out = (x264_picture_t*)malloc(sizeof(x264_picture_t));
pParam = (x264_param_t*)malloc(sizeof(x264_param_t));
//Check
if(fp_src==NULL||fp_dst==NULL){
printf("Error open files.
");
return -1;
}
x264_param_default(pParam);
x264_param_default_preset(pParam, "fast" , "zerolatency" );
pParam->i_csp=csp;
pParam->i_width = width;
pParam->i_height = height;
pParam->i_fps_num = 25;
pParam->i_fps_den = 1;
pParam->i_threads = X264_SYNC_LOOKAHEAD_AUTO;
pParam->i_keyint_max = 10;
pParam->rc.i_bitrate = 1200;
pParam->rc.i_rc_method = X264_RC_ABR;
//set profile
x264_param_apply_profile(pParam, "baseline");
//open encoder
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 number
if(frame_num==0){
fseek(fp_src,0,SEEK_END);
frame_num=ftell(fp_src)/(y_size*3/2);
fseek(fp_src,0,SEEK_SET);
}
}
int en_h264_run(char *y,char *u,char *v)
{
int i,j,ret;
int iNal = 0;
#if 1
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
#else
memcpy(pPic_in->img.plane[0],y,y_size);
memcpy(pPic_in->img.plane[1],u,y_size / 4);
memcpy(pPic_in->img.plane[2],v,y_size / 4);
#endif
pPic_in->i_pts += 1;
ret = x264_encoder_encode(pHandle, &pNals, &iNal, pPic_in, pPic_out);
if (ret< 0){
printf("Error.
");
return -1;
}
printf("Succeed encode frame: %5d
",pPic_in->i_pts-1);
for ( j = 0; j < iNal; ++j){
fwrite(pNals[j].p_payload, 1, pNals[j].i_payload, fp_dst);
}
/* Flush delayed frames */
while( x264_encoder_delayed_frames( pHandle ) )
{
ret = x264_encoder_encode( pHandle, &pNals, &iNal, NULL, pPic_out );
if( ret )
{
fwrite( pNals[j].p_payload, 1, pNals[j].i_payload, fp_dst );
}
}
}
int en_h264_release()
{
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;
}
int main(int argc, char** argv)
{
en_h264_init();
char y[640*360];
char u[640*360/4];
char v[640*360/4];
for(int i=0;i<frame_num;i++){
en_h264_run(y,u,v);
}
en_h264_release();
return 0;
}
其实x264源码包里自带的demo更好,x264-snapshot-20190512-2245/example.c
/*****************************************************************************
* example.c: libx264 API usage example
*****************************************************************************
* Copyright (C) 2014-2019 x264 project
*
* Authors: Anton Mitrofanov <BugMaster@narod.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*
* This program is also available under a commercial proprietary license.
* For more information, contact us at licensing@x264.com.
*****************************************************************************/
#ifdef _WIN32
#include <io.h> /* _setmode() */
#include <fcntl.h> /* _O_BINARY */
#endif
#include <stdint.h>
#include <stdio.h>
#include "x264.h"
#include <math.h>
#define FAIL_IF_ERROR( cond, ... )
do
{
if( cond )
{
fprintf( stderr, __VA_ARGS__ );
goto fail;
}
} while( 0 )
int main( int argc, char **argv )
{
x264_param_t param;
x264_picture_t pic;
x264_picture_t pic_out;
x264_t *h;
int i_frame = 0;
int i_frame_size;
x264_nal_t *nal;
int i_nal;
FILE* fp_src = fopen("./cuc_ieschool_640x360_yuv420p.yuv", "rb");
FILE* fp_dst = fopen("cuc_ieschool.h264", "wb");
int width=640,height=360;
/* Get default params for preset/tuning */
if( x264_param_default_preset( ¶m, "medium", NULL ) < 0 )
goto fail;
/* Configure non-default params */
param.i_bitdepth = 8;
param.i_csp = X264_CSP_I420;
param.i_width = width;
param.i_height = height;
param.b_vfr_input = 0;
param.b_repeat_headers = 1;
param.b_annexb = 1;
/* Apply profile restrictions. */
if( x264_param_apply_profile( ¶m, "high" ) < 0 )
goto fail;
if( x264_picture_alloc( &pic, param.i_csp, param.i_width, param.i_height ) < 0 )
goto fail;
#undef fail
#define fail fail2
h = x264_encoder_open( ¶m );
if( !h )
goto fail;
#undef fail
#define fail fail3
int luma_size = width * height;
int chroma_size = luma_size / 4;
/* Encode frames */
for( ;; i_frame++ )
{
/* Read input frame */
if( fread( pic.img.plane[0], 1, luma_size, fp_src ) != luma_size )
break;
if( fread( pic.img.plane[1], 1, chroma_size, fp_src ) != chroma_size )
break;
if( fread( pic.img.plane[2], 1, chroma_size, fp_src ) != chroma_size )
break;
pic.i_pts = i_frame;
i_frame_size = x264_encoder_encode( h, &nal, &i_nal, &pic, &pic_out );
if( i_frame_size < 0 )
goto fail;
else if( i_frame_size )
{
if( !fwrite( nal->p_payload, i_frame_size, 1, fp_dst ) )
goto fail;
}
}
/* Flush delayed frames */
while( x264_encoder_delayed_frames( h ) )
{
i_frame_size = x264_encoder_encode( h, &nal, &i_nal, NULL, &pic_out );
if( i_frame_size < 0 )
goto fail;
else if( i_frame_size )
{
if( !fwrite( nal->p_payload, i_frame_size, 1, fp_dst ) )
goto fail;
}
}
x264_encoder_close( h );
x264_picture_clean( &pic );
return 0;
#undef fail
fail3:
x264_encoder_close( h );
fail2:
x264_picture_clean( &pic );
fail:
return -1;
}
4、编译
1) 务必先设置好库文件环境变量
export LD_LIBRARY_PATH=~/gb28181/x264-snapshot-20190512-2245/_install/lib:$LD_LIBRARY_PATH
gcc -o main main.c -I ./_install/include -L ./_install/lib -lx264 -lpthread -std=c99
gcc -o example example.c -I ./_install/include -L ./_install/lib -lx264 -lpthread -std=c99
#gcc -o main main.c -I ./_install/include ./_install/lib/libx264.a -lpthread -std=c99
不知道什么原因,用静态库编译会出错
2) 也可以不配置环境变量,将x264安装到ubuntu默认路径,直接gcc -o main main.c -lx264
5、yuv/rgb <---> h264
ffmpeg-4.1.tar.bz2
./configure
--target-os=linux --cc=arm-linux-gnueabihf-gcc --arch=arm
--enable-shared --enable-cross-compile
--cross-prefix=arm-linux-gnueabihf- --enable-gpl --enable-ffplay
--enable-libx264 --enable-postproc --prefix=$(pwd)/_install
--extra-cflags=-I$(pwd)/_install/include
--extra-ldflags=-L$(pwd)/_install/lib
make
make install
A simple C program that convert the raw RGB stream to H264 stream and vice versa
https://github.com/lctseng/H264-RGB-Encode-Decode
版本不一致,编译不过,改成以上ffmpeg-4.1.tar.bz2和x264-snapshot-20190512-2245了
https://files.cnblogs.com/files/dong1/rgb_h264_demo.zip
6、交叉编译
./configure --prefix=${PWD}/_install --enable-shared --disable-asm --disable-cli --host=arm-linux-gnueabihf
更改config.mak
CC=arm-linux-gnueabihf-gcc
LD=arm-linux-gnueabihf-gcc -o
AR=arm-linux-gnueabihf-gcc-ar rc
RANLIB=arm-linux-gnueabihf-gcc-ranlib
make
make install
7、参考设计
libx264编码---YUV图像数据编码为h.264码流
https://blog.csdn.net/qq_41248872/article/details/83068869
各种音视频测试文件
http://www.live555.com/liveMedia/public/
使用libyuv对yuv数据进行缩放,旋转,镜像,裁剪等操作