x264直播(2) - x264录屏输入

从上编编译x264继续, 添加一个输入接口直接从屏幕

  1. 在这之前可以添加一个对帧截图功能, 了解格式, 在 encode_frame 中添加一行

on_encode_frame(h, param, opt, pic, &pic_out, i_frame_size);

然后

static int on_encode_frame(x264_t *h, x264_param_t *param, cli_opt_t * opt, x264_picture_t *pic, x264_picture_t *pic_out, int i_frame_size)
{
if(opt->frame_img && pic_out->b_keyframe)
{
save_frame_img(opt->frame_img_dir, pic->i_pts, &pic->img, param->i_width, param->i_height);
}
return 0;
}

从格式上看 img->i_csp 是 X264_CSP_I420, 也就是yuv420, 转换代码可以从网上搜, 我从github找到一个转换的yuv_rgb.c 作者应该是Adrien Descamps
自行稍微修改 yuv420_bgr24_std
使用如下

bool yuv420_to_rgb(int w, int h, byte *y, byte *u, byte *v, byte **dat, int size)
{
byte rgb_dat;
int rgb_size;
uint32_t y_stride, uv_stride, rgb_stride;
YCbCrType yuv_format;
rgb_size = w
3
h;
rgb_dat = (byte )malloc(rgb_size);
memset(rgb_dat, 0, rgb_size);
y_stride = w;
uv_stride = w/2;
rgb_stride = w
3;
yuv_format = YCBCR_709;
yuv420_bgr24_std(w, h, y, u, v, y_stride, uv_stride, rgb_dat, rgb_stride, yuv_format);
*dat = rgb_dat;
*size = rgb_size;
return true;
}
然后把rgb数据添加bmp头就成为bmp文件

  1. 录屏输入, x264输入方式添加, 定义一个 const cli_input_t screen_input = ..
    在 select_input 添加一个判断选择 screen_input
    screent_read_frame 时用 BitBlt, 然后 bgr24_yuv420_std 转换就可以了

  2. 这样录屏输入生成的flv文件速度不对, 因为在screent_read_frame 时录制的是当前的帧, 可以在这加延迟处理, 直接Sleep延迟只能得到大概的速度, 不是很精准, 可计算延迟如下
    if(i_frame == 0)
    {
    hnd->dwStart = GetTickCount();
    }
    else
    {
    dwNeed = hnd->dwStart + i_frame * 1000/hnd->fps;
    for(dwCur=::GetTickCount(); dwCur<dwNeed; Sleep(1))
    dwCur=::GetTickCount();
    }
    这样计算后的延迟生成的fps非常精准了

  3. CPU比较高的问题, CPU主要消耗在截屏, 转换, 编码上
    截屏 效率低主要是因为用BitBlt, 显存到内存的速度比较慢, 可以换用其它方法, 如镜像驱动(VNC), 或直接Hook程序(directX)等
    编码 已经是比较完善了, 没什么优化空间
    转换 中使用的代码就是一般的x86指令, 代码中其实已经有了sse优化的代码, VS2010已经支持这个代码,
    添加宏 #define __SSE2__
    添加头文件 #include <emmintrin.h>

  4. 最终效果已经是比较好了, 平均cpu在5%左右, Gtx750Ti, E3-3220, 每帧截图转换时间, 用sse指令优化转换cpu从11%降到5%(但是CPU的功耗温度基本没什么改变)
    rgb32 x86 15ms
    rgb24 x86 12ms
    rgb24 sse 4ms

posted @ 2020-10-29 13:59  Yofoo  阅读(215)  评论(0编辑  收藏  举报