x264直接编码

本文介绍x264开源H.264编码库在x86 Linux平台上的编译方法及编码使用实例,包括配置、编译过程和编码示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


http://blog.youkuaiyun.com/subfate/article/details/48437693


目录(?)[+]

x264是一个开源的H.264编码库。本文介绍其在x86 Linux的编译方法,并给出实例。

一、编译

x264编译需要使用到yasm,到http://www.tortall.net/projects/yasm/releases/下载,最新版本为1.3.1。编译命令如下:

# ./configure;make;make install

x264官方下载:http://www.videolan.org/developers/x264.html。下载压缩包名为:last_x264.tar.bz2。解压得到的文件名为x264-snapshot-xxxx。编译命令如下:

$ ./configure  --prefix=/home/latelee/bin/x264 --enable-static
$ make
$ make install

二、实例

下面给出使用的示例。

[cpp]  view plain  copy
  1. /** 
  2. x264库编码要使用以下库 
  3. -lpthread -ldl 
  4. 要求头文件:stdint.h 
  5. ffprobe信息: 
  6. Input #0, h264, from 'test.h264': 
  7.   Duration: N/A, bitrate: N/A 
  8.     Stream #0:0: Video: h264 (High), yuv420p, 176x144, 25 fps, 25 tbr, 1200k tbn 
  9. , 50 tbc 
  10.  
  11. */  
  12.   
  13. #include <stdio.h>  
  14. #include <stdlib.h>  
  15.   
  16. #include <stdint.h> // for uint8_t in x264.h  
  17.   
  18. #include "x264.h"  
  19.   
  20. int x264_encode(const char* infile, int width, int height, int type, const char* outfile)  
  21. {  
  22.     FILE *fp_src = NULL;  
  23.     FILE *fp_dst = NULL;  
  24.     unsigned int luma_size = 0;  
  25.     unsigned int chroma_size = 0;  
  26.     int i_nal = 0;  
  27.     int i_frame = 0;  
  28.     unsigned int i_frame_size = 0;  
  29.   
  30.     int csp = type;//X264_CSP_I420;  
  31.     x264_nal_t* nal = NULL;  
  32.     x264_t* handle = NULL;  
  33.     x264_picture_t* pic_in = NULL;  
  34.     x264_picture_t* pic_out = NULL;  
  35.     x264_param_t param;  
  36.   
  37.     fp_src = fopen(infile, "rb");  
  38.     fp_dst = fopen(outfile, "wb");  
  39.     if(fp_src==NULL || fp_dst==NULL)  
  40.     {  
  41.         perror("Error open yuv files:");  
  42.         return -1;  
  43.     }  
  44.   
  45.     x264_param_default(¶m);  
  46.   
  47.     param.i_width  = width;  
  48.     param.i_height = height;  
  49.     /* 
  50.     //Param 
  51.     param.i_log_level  = X264_LOG_DEBUG; 
  52.     param.i_threads  = X264_SYNC_LOOKAHEAD_AUTO; 
  53.     param.i_frame_total = 0; 
  54.     param.i_keyint_max = 10; 
  55.     param.i_bframe  = 5; 
  56.     param.b_open_gop  = 0; 
  57.     param.i_bframe_pyramid = 0; 
  58.     param.rc.i_qp_constant=0; 
  59.     param.rc.i_qp_max=0; 
  60.     param.rc.i_qp_min=0; 
  61.     param.i_bframe_adaptive = X264_B_ADAPT_TRELLIS; 
  62.     param.i_fps_den  = 1; 
  63.     param.i_fps_num  = 25; 
  64.     param.i_timebase_den = param.i_fps_num; 
  65.     param.i_timebase_num = param.i_fps_den; 
  66.     */  
  67.     param.i_csp = csp;  
  68.     param.b_repeat_headers = 1;  
  69.     param.b_annexb = 1;  
  70.   
  71.     // profile: high x264_profile_names定义见x264.h  
  72.     x264_param_apply_profile(¶m, x264_profile_names[2]);  
  73.   
  74.     pic_in = (x264_picture_t*)malloc(sizeof(x264_picture_t));  
  75.     if (pic_in == NULL)  
  76.     {  
  77.         goto out;  
  78.     }  
  79.     pic_out = (x264_picture_t*)malloc(sizeof(x264_picture_t));  
  80.     if (pic_out == NULL)  
  81.     {  
  82.         goto out;  
  83.     }  
  84.     x264_picture_init(pic_out);  
  85.     x264_picture_alloc(pic_in, csp, param.i_width, param.i_height);  
  86.   
  87.     handle = x264_encoder_open(¶m);  
  88.   
  89.     // 计算有多少帧  
  90.     luma_size = param.i_width * param.i_height;  
  91.     fseek(fp_src, 0, SEEK_END);  
  92.     switch (csp)  
  93.     {  
  94.         case X264_CSP_I444:  
  95.             i_frame = ftell(fp_src) / (luma_size*3);  
  96.             chroma_size = luma_size;  
  97.             break;  
  98.         case X264_CSP_I420:  
  99.             i_frame = ftell(fp_src) / (luma_size*3/2);  
  100.             chroma_size = luma_size / 4;  
  101.             break;  
  102.         default:  
  103.             printf("Colorspace Not Support.\n");  
  104.             goto out;  
  105.     }  
  106.     fseek(fp_src, 0, SEEK_SET);  
  107.   
  108.     printf("framecnt: %d, y: %d u: %d\n", i_frame, luma_size, chroma_size);  
  109.   
  110.     // 编码  
  111.     for (int i = 0; i < i_frame; i++)  
  112.     {  
  113.         switch(csp)  
  114.         {  
  115.         case X264_CSP_I444:  
  116.         case X264_CSP_I420:  
  117.             i_frame_size = fread(pic_in->img.plane[0], 1, luma_size, fp_src);  
  118.             if (i_frame_size != luma_size)  
  119.             {  
  120.                 printf("read luma failed %d.\n", i_frame_size);  
  121.                 break;  
  122.             }  
  123.             i_frame_size = fread(pic_in->img.plane[1], 1, chroma_size, fp_src);  
  124.             if (i_frame_size != chroma_size)  
  125.             {  
  126.                 printf("read chroma1 failed %d.\n", i_frame_size);  
  127.                 break;  
  128.             }  
  129.             i_frame_size = fread(pic_in->img.plane[2], 1, chroma_size, fp_src);  
  130.             if (i_frame_size != chroma_size)  
  131.             {  
  132.                 printf("read chrome2 failed %d.\n", i_frame_size);  
  133.                 break;  
  134.             }  
  135.             break;  
  136.         default:  
  137.             printf("Colorspace Not Support.\n");  
  138.             return -1;  
  139.         }  
  140.         pic_in->i_pts = i;  
  141.   
  142.         i_frame_size = x264_encoder_encode(handle, &nal, &i_nal, pic_in, pic_out);  
  143.         printf("encode frame: %5d framesize: %d nal: %d\n", i+1, i_frame_size, i_nal);  
  144.         if (i_frame_size < 0)  
  145.         {  
  146.             printf("Error encode frame: %d.\n", i+1);  
  147.             goto out;  
  148.         }  
  149.         #if 01  
  150.         else if (i_frame_size)  
  151.         {  
  152.             if(!fwrite(nal->p_payload, 1, i_frame_size, fp_dst))  
  153.                 goto out;  
  154.         }  
  155.         #endif  
  156.         // 另一种做法  
  157.         #if 0  
  158.         // i_nal有可能为0,有可能多于1  
  159.         for (int j = 0; j < i_nal; j++)  
  160.         {  
  161.             fwrite(nal[j].p_payload, 1, nal[j].i_payload, fp_dst);  
  162.         }  
  163.         #endif  
  164.     }  
  165.   
  166.     //flush encoder  
  167.     while(x264_encoder_delayed_frames(handle))  
  168.     //while(1)  
  169.     {  
  170.         static int cnt = 1;  
  171.         i_frame_size = x264_encoder_encode(handle, &nal, &i_nal, NULL, pic_out);  
  172.         printf("flush frame: %d framesize: %d nalsize: %d\n", cnt++, i_frame_size, i_nal);  
  173.         if(i_frame_size == 0)  
  174.         {  
  175.             break;  
  176.             //goto out;  
  177.         }  
  178.         #if 01  
  179.         else if(i_frame_size)  
  180.         {  
  181.             if(!fwrite(nal->p_payload, 1, i_frame_size, fp_dst))  
  182.                 goto out;  
  183.         }  
  184.         #endif  
  185.         // 另一种做法  
  186.         #if 0  
  187.         // i_nal有可能为0,有可能多于1  
  188.         for (int j = 0; j < i_nal; j++)  
  189.         {  
  190.             fwrite(nal[j].p_payload, 1, nal[j].i_payload, fp_dst);  
  191.         }  
  192.         #endif  
  193.     }  
  194.   
  195. out:  
  196.     x264_picture_clean(pic_in);  
  197.     if (handle)  
  198.     {  
  199.         x264_encoder_close(handle);  
  200.         handle = NULL;  
  201.     }  
  202.   
  203.     if (pic_in)  
  204.         free(pic_in);  
  205.     if (pic_out)  
  206.         free(pic_out);  
  207.   
  208.     fclose(fp_src);  
  209.     fclose(fp_dst);  
  210.   
  211.     return 0;  
  212. }  

使用方法:

[cpp]  view plain  copy
  1. x264_encode("../src/suzie_qcif_176x144_yuv420p.yuv", 176, 144, 1, "test.h264");  

Makefile如下:

[cpp]  view plain  copy
  1. #  
  2. # (C) Copyleft 2011~2015  
  3. # Late Lee from http://www.latelee.org  
  4.   
  5. # A simple Makefile for *ONE* project(c or/and cpp file) in *ONE*  directory  
  6. #  
  7. # note:   
  8. # you can put head file(s) in 'include' directory, so it looks   
  9. # a little neat.  
  10. #  
  11. # usage: $ make  
  12. #        $ make debug=y  
  13. #  
  14. # log  
  15. #       2013-05-14 sth about debug...  
  16. ###############################################################################  
  17.   
  18. # !!!=== cross compile...  
  19. CROSS_COMPILE =   
  20.   
  21. CC = $(CROSS_COMPILE)gcc  
  22. CXX = $(CROSS_COMPILE)g++  
  23. AR = $(CROSS_COMPILE)ar  
  24.   
  25. ARFLAGS = cr  
  26. RM = -rm -rf  
  27. MAKE = make  
  28.   
  29. CFLAGS := -Wall  
  30.   
  31. #****************************************************************************  
  32. # debug can be set to y to include debugging info, or n otherwise  
  33. debug          := n  
  34.   
  35. #****************************************************************************  
  36.   
  37. ifeq ($(debug), y)  
  38. CFLAGS += -ggdb -rdynamic  
  39. else  
  40. CFLAGS += -O2 -s  
  41. endif  
  42.   
  43. # !!!===  
  44. DEFS =   
  45.   
  46. CFLAGS += $(DEFS)  
  47.   
  48. LDFLAGS := $(LIBS)  
  49.   
  50. # !!!===  
  51. INCDIRS := -I./include  
  52.   
  53. # !!!===  
  54. CFLAGS += $(INCDIRS)  
  55.   
  56. # !!!===  
  57. LDFLAGS += ./lib/libx264.a ./lib/libx265.a -lpthread -ldl  
  58.   
  59. # !!!===  
  60. # source file(s), including c file(s) cpp file(s)  
  61. # you can also use $(wildcard *.c), etc.  
  62. SRC_C   := $(wildcard *.c)  
  63. SRC_CPP := $(wildcard *.cpp)  
  64.   
  65. # object file(s)  
  66. OBJ_C   := $(patsubst %.c,%.o,$(SRC_C))  
  67. OBJ_CPP := $(patsubst %.cpp,%.o,$(SRC_CPP))  
  68.   
  69. # !!!===  
  70. # executable file  
  71. target = a.out  
  72.   
  73. ###############################################################################  
  74.   
  75. all: $(target)  
  76.   
  77. $(target): $(OBJ_C) $(OBJ_CPP)  
  78.     @echo "Generating executable file..." $(notdir $(target))  
  79.     @$(CXX) $(CFLAGS) $^ -o $(target) $(LDFLAGS)  
  80.   
  81. # make all .c or .cpp  
  82. %.o: %.c  
  83.     @echo "Compiling: " $(addsuffix .c, $(basename $(notdir $@)))  
  84.     @$(CC) $(CFLAGS) -c $< -o $@  
  85.   
  86. %.o: %.cpp  
  87.     @echo "Compiling: " $(addsuffix .cpp, $(basename $(notdir $@)))  
  88.     @$(CXX) $(CFLAGS) -c $< -o $@  
  89.   
  90. clean:  
  91.     @echo "Cleaning..."  
  92.     @$(RM) $(target)  
  93.     @$(RM) *.o *.back *~  
  94.   
  95. .PHONY: all clean  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值