📄 main.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "h264_enc.h"
#define u64 unsigned __int64
__inline u64 get_now_tick()
{
u64 t;
__asm rdtsc
__asm mov DWORD PTR t, eax
__asm mov DWORD PTR t + 4, edx
return t;
}
int main(int argc, char *argv[])
{
FILE * fp1 = NULL;
FILE * fp2 = NULL;
int width = 176;
int height = 144;
CodecContext ctx;
int ret = 0;
int frames = 0;
int sum_size = 0;
unsigned int t = 0, tt = 0;
unsigned int start_time = 0, sum_time = 0;
u64 tick_temp, tick1 = 0, tick2 = 0;
printf("**********************************************\n");
printf("发布此 lib 库的目的在于学习交流,该库已经限制每次只能\n");
printf("使用约 10 分钟,此后各种性能将会下降或出现异常,敬请\n");
printf("谅解!如果您需要商用,请与本人联系:763393647@qq.com\n");
printf("**********************************************\n");
memset(&ctx, 0, sizeof(ctx));
ctx.width = width;
ctx.height = height;
ctx.csp = X264_CSP_I420; //X264_CSP_BGR | X264_CSP_VFLIP; // 设置颜色空间
ctx.data_in_size = width*height*3/2; // 一帧原始数据的大小, YV12 = w*h*3/2, RGB24 = w*h*3
ctx.buffer_in_size = 128*1024; // 缓冲区大小
ctx.frame_rate = 25; // 设置帧率,若等于0则取默认值
ctx.key_frame_interval = 250; // 设置最大关键帧间距,若等于0则取默认值
ctx.rc_mode = 1; // 0:vbr, 1: cbr
ctx.bit_rate = 300; // 设置比特率,仅在 cbr 模式下有效
ctx.quality = 26; // 设置质量,仅在 vbr 模式下有效,若等于0则取默认值
ctx.data_in = (unsigned char *)malloc(ctx.data_in_size);
if (ctx.data_in == NULL)
{
printf("malloc error!\n");
goto loc_end;
}
ctx.buffer = (unsigned char *)malloc(ctx.buffer_in_size);
if (ctx.buffer == NULL)
{
printf("内存不够!\n");
goto loc_end;
}
// 请在此处修改文件路径
fp1 = fopen("test.yuv", "rb");
fp2 = fopen("test.264", "wb");
if (fp1 == NULL || fp2 == NULL)
{
printf("打开文件失败!\n");
goto loc_end;
}
ret = H264EncoderOpen(&ctx); // 打开编码器
if (ret < 0)
{
printf("打开编码器失败!\n");
goto loc_end;
}
start_time = clock();
tick_temp = get_now_tick();
while (1)
{
// if (frames/10 != 5)
if (fread(ctx.data_in, 1, ctx.data_in_size, fp1) < ctx.data_in_size)
{
break;
}
tick2 += get_now_tick() - tick_temp;
tick_temp = get_now_tick();
ret = H264EncoderEncode(&ctx); // 编码
if (ret < 0)
{
break;
}
tick1 += get_now_tick() - tick_temp;
tick_temp = get_now_tick();
frames++;
sum_size += ctx.buffer_out_size;
// 输出下面信息时时间计算可能不准确
// printf("frame = %4d ", frames);
// printf("size = %6d ", ctx.buffer_out_size); // 编码后码流的有效长度
// printf("frame type = %d ", ctx.key_frame); // 返回帧类型
// printf("\n");
fwrite(ctx.buffer, 1, ctx.buffer_out_size, fp2);
fflush(fp2);
}
tick2 += get_now_tick() - tick_temp;
sum_time += clock() - start_time;
if ( frames > 0 )
{
printf("编码帧数 : %10d frames\n", frames);
printf("编码前文件大小 : %10d byte\n", ctx.data_in_size * frames );
printf("编码后文件大小 : %10d byte\n", sum_size );
printf("压缩比 : %6d : 1\n", ctx.data_in_size * frames / sum_size );
printf("比特率 : %10.2f kbps\n", (double)sum_size*8*ctx.frame_rate / frames / 1024 );
printf("编码时间 : %10.2f ms\n", (double)(tick1/(tick1+tick2+1.0))*sum_time);
printf("额外时间 : %10.2f ms\n", (double)(tick2/(tick1+tick2+1.0))*sum_time);
printf("编码速度 : %10.2f fps\n", frames * 1000.0 / ((double)(tick1/(tick1+tick2+1.0))*sum_time));
}
H264EncoderClose(&ctx); // 关闭编码器
loc_end:
if (fp1 != NULL) fclose(fp1);
if (fp2 != NULL) fclose(fp2);
if (ctx.data_in != NULL) free(ctx.data_in);
if (ctx.buffer != NULL) free(ctx.buffer);
fp1 = NULL;
fp2 = NULL;
ctx.data_in = NULL;
ctx.buffer = NULL;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -