1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
| /** x265库编码要使用以下库 -lpthread -ldl
ffprobe信息: Input #0, hevc, from 'test.h265': Duration: N/A, bitrate: N/A Stream #0:0: Video: hevc (Main), yuv420p(tv), 176x144, 25 fps, 25 tbr, 1200k tbn, 25 tbc */
#include <stdio.h> #include <stdlib.h>
#include "x265.h"
int x265_encode(const char* infile, int width, int height, int type, const char* outfile) { FILE *fp_src = NULL; FILE *fp_dst = NULL; unsigned int luma_size = 0; unsigned int chroma_size = 0; //int buff_size = 0; char *buff = NULL; uint32_t i_nal=0; int i_frame=0; int ret = 0;
x265_param param; x265_nal *nal = NULL; x265_encoder *handle = NULL; x265_picture *pic_in = NULL;
int csp = type; // X265_CSP_I420;
fp_src = fopen(infile, "rb"); fp_dst = fopen(outfile, "wb"); if(fp_src==NULL || fp_dst==NULL) { perror("Error open yuv files:"); return -1; }
x265_param_default(?m); param.bRepeatHeaders = 1;//write sps,pps before keyframe param.internalCsp = csp; param.sourceWidth = width; param.sourceHeight = height; param.fpsNum = 25; // 帧率 param.fpsDenom = 1; // 帧率
handle = x265_encoder_open(?m); if(handle == NULL) { printf("x265_encoder_open err\n"); goto out; }
pic_in = x265_picture_alloc(); if (pic_in == NULL) { goto out; } x265_picture_init(?m, pic_in);
// Y分量大小 luma_size = param.sourceWidth * param.sourceHeight; // 分量一帧YUV的空间 switch (csp) { case X265_CSP_I444: buff = (char *)malloc(luma_size*3); pic_in->planes[0] = buff; pic_in->planes[1] = buff + luma_size; pic_in->planes[2] = buff + luma_size*2; pic_in->stride[0] = width; pic_in->stride[1] = width; pic_in->stride[2] = width; break; case X265_CSP_I420: buff = (char *)malloc(luma_size*3/2); pic_in->planes[0] = buff; pic_in->planes[1] = buff + luma_size; pic_in->planes[2] = buff + luma_size*5/4; pic_in->stride[0] = width; pic_in->stride[1] = width/2; pic_in->stride[2] = width/2; break; default: printf("Colorspace Not Support.\n"); goto out; }
// 计算总帧数 fseek(fp_src, 0, SEEK_END); switch(csp) { case X265_CSP_I444: i_frame = ftell(fp_src) / (luma_size*3); chroma_size = luma_size; break; case X265_CSP_I420: i_frame = ftell(fp_src) / (luma_size*3/2); chroma_size = luma_size / 4; break; default: printf("Colorspace Not Support.\n"); return -1; } fseek(fp_src,0,SEEK_SET); printf("framecnt: %d, y: %d u: %d\n", i_frame, luma_size, chroma_size);
for(int i=0; i < i_frame; i++) { switch(csp) { case X265_CSP_I444: case X265_CSP_I420: if (fread(pic_in->planes[0], 1, luma_size, fp_src) != luma_size) break; if (fread(pic_in->planes[1], 1, chroma_size, fp_src) != chroma_size) break; if (fread(pic_in->planes[2], 1, chroma_size, fp_src) != chroma_size) break; break; default: printf("Colorspace Not Support.\n"); goto out; }
ret = x265_encoder_encode(handle, &nal, &i_nal, pic_in, NULL); printf("encode frame: %5d framesize: %d nal: %d\n", i+1, ret, i_nal); if (ret < 0) { printf("Error encode frame: %d.\n", i+1); goto out; }
for(uint32_t j = 0; j < i_nal; j++) { fwrite(nal[j].payload, 1, nal[j].sizeBytes, fp_dst); } } // Flush Decoder while((ret = x265_encoder_encode(handle, &nal, &i_nal, NULL, NULL))) { static int cnt = 1; printf("flush frame: %d\n", cnt++); for(uint32_t j=0; j < i_nal; j++) { fwrite(nal[j].payload, 1, nal[j].sizeBytes, fp_dst); } }
out: x265_encoder_close(handle); x265_picture_free(pic_in); if (buff) free(buff);
fclose(fp_src); fclose(fp_dst); return 0; }
|