//关闭live555推流服务
system("killall testOnDemandRTSPServer");
//重启live555推流服务
sleep(3);
system("./testOnDemandRTSPServer &");
//------------------------------------------------------------------------------------------------------
cv::Mat BasePic = cv::imread("./test.jpg");
cv::Mat inputPic;
cv::resize(BasePic, BasePic, cv::Size(1920, 1080));
//使用YUV420编码
cv::cvtColor(BasePic, BasePic, cv::COLOR_BGR2YUV_I420);
//创建fifo
::unlink("demo.264");
::mkfifo("demo.264", O_CREAT | O_EXCL | 777);
//打开fifo
int fp_dst = ::open("demo.264", O_WRONLY);
if(fp_dst == NULL)
{
::close(fp_dst);
return;
}
//H264编码设置
int video_width = 1920;
int video_height = 1080;
int res = 0;
//压缩编码前的图像
x264_picture_t pic;
x264_picture_t pic_out;
//
x264_t *h;
int i_frame = 0;
int i_frame_size = 0;
//压缩编码后的码流数据
x264_nal_t *nal;
int i_nal;
x264_param_t param;
res = x264_param_default_preset(¶m, "veryfast", NULL);
param.i_bitdepth = 8;//编码位数
param.i_csp = X264_CSP_I420;//编码制式
param.rc.i_qp_min = 36;//编码质量:越小,视频质量损失越小
param.rc.i_qp_max = 40;
param.rc.i_qp_step = 2;
param.i_width = video_width;//分辨率
param.i_height = video_height;
param.i_fps_den = 1;//帧率
param.i_fps_num = 30;
param.i_keyint_max = 4;//设置IDR关键帧间隔
param.i_keyint_min = 1;
param.b_vfr_input = 0;//固定帧率
param.b_repeat_headers = 1;//在每个关键帧前放置SPS/PPS
param.b_annexb = 1;//在NAL单元前放置起始码
res = x264_param_apply_profile(¶m, "baseline");
res = x264_picture_alloc(&pic, param.i_csp, param.i_width, param.i_height);
//打开编码器
h = x264_encoder_open(¶m);
if(h == 0)
{
return;
}
//输出头信息
i_frame_size = x264_encoder_headers(h, &nal, &i_nal);
if(i_frame_size < 0)
{
return;
}
else if(i_frame_size)
{
if(!::write(fp_dst, nal->p_payload, i_frame_size))
{
return;
}
}
//对视频帧进行编码
unsigned int luma_size = video_width * video_height;
unsigned int chroma_size = luma_size / 4;
for(;;i_frame++)
{
//读取输入帧YUV420
inputPic = BasePic.clone();
//绘制帧号
int id = i_frame / 30;
cv::String strFrameId;
QString idStr = QString("%1").arg(id);
strFrameId = idStr.toStdString();
cv::putText(inputPic, strFrameId, cv::Point(960,500), cv::HersheyFonts::FONT_ITALIC, 10, cv::Scalar(255,0,0), 3);
//
memcpy(pic.img.plane[0], inputPic.data, luma_size);
memcpy(pic.img.plane[1], inputPic.data + luma_size, chroma_size);
memcpy(pic.img.plane[2], inputPic.data + luma_size + chroma_size, chroma_size);
//
pic.i_pts = i_frame;
i_frame_size = x264_encoder_encode(h, &nal, &i_nal, &pic, &pic_out);
if(i_frame_size < 0)
{
break;
}
else if(i_frame_size)
{
try{
::write(fp_dst, nal->p_payload, i_frame_size);
}
catch(std::exception exception)
{
std::cout << exception.what() << std::endl;
}
}
if(i_frame == (30 * 60000))
{
break;
}
}
//关闭编码器
x264_encoder_close(h);
x264_picture_clean(&pic);
::close(fp_dst);
使用X264库进行H264编码
于 2024-02-20 15:40:11 首次发布