YUV/RGB与H264之间的编解码


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.\n"); 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.\n"); return -1; } printf("Succeed encode frame: %5d\n",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( &param, "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( &param, "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( &param ); 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/

http://samples.mplayerhq.hu/

使用libyuv对yuv数据进行缩放,旋转,镜像,裁剪等操作

https://github.com/lemenkov/libyuv

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM