ffmpeg H264一次对帧进行编码,用于网络流传输



我正在开发一个远程桌面应用程序,我想通过使用ffmpeg进行编码,通过TCP发送一个编码的H264数据包。然而,对于只编码一帧(已经在YUV444上了)并获取数据包的特殊情况,我找不到有用的信息。

我有几个问题,第一个是:

avcodec_encode_video2

不是阻塞,我发现大多数时候你都会在最后得到"延迟"的帧,然而,由于这是实时流媒体,解决方案是:

av_opt_set(mCodecContext->priv_data, "tune", "zerolatency", 0);

现在我得到了帧,但有几个问题,它需要一段时间,更糟糕的是,我得到了一个带有垃圾像素的灰色视频。我的编解码器上下文配置:

m_pCodecCtx->bit_rate=8000000;
m_pCodecCtx->codec_id=AV_CODEC_ID_H264;
m_pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
m_pCodecCtx->width=1920;
m_pCodecCtx->height=1080;
m_pCodecCtx->pix_fmt=AV_PIX_FMT_YUV444P;
m_pCodecCtx->time_base.num = 1;
m_pCodecCtx->time_base.den = 25;
m_pCodecCtx->gop_size = 1;
m_pCodecCtx->keyint_min = 1;
m_pCodecCtx->i_quant_factor = float(0.71);
m_pCodecCtx->b_frame_strategy = 20;
m_pCodecCtx->qcompress = (float)0.6;
m_pCodecCtx->qmax = 51;
m_pCodecCtx->qmin = 20;
m_pCodecCtx->max_qdiff = 4;
m_pCodecCtx->refs = 4;
m_pCodecCtx->max_b_frames = 1;
m_pCodecCtx->thread_count = 1;

我想知道如何做到这一点,我如何设置"I帧"?而且,对于"一次一个"的编码来说,这将是最佳的?此外,我现在不关心质量,只需要足够快(低于16毫秒)。

对于编码部分:

nres = avcodec_encode_video2(m_pCodecCtx,&packet,m_pFrame,&framefinished);
if(nres<0){
qDebug() << "error encoding: " << nres << endl;
}
if(framefinished){
m_pFrame->pts++;
ofstream vidout("video.h264",ios::app);
if(vidout.good()){
vidout.write((const char*)&packet.data[0],packet.size);
}
vidout.close();
av_packet_unref(&packet);
}

我不使用容器,只使用原始文件,如果数据包正确,则ffplay会复制原始文件,这是我的主要问题。我计划通过tcp发送数据包,并在客户端进行解码。如有任何帮助,我们将不胜感激。

您可以查看webrtc的源代码它使用openh264和ffmpeg来完成您的工作。

我在里面学习了一段时间。但我目前无法获得最新的源代码。

我发现:源代码

希望能有所帮助。

事实证明,我从一开始就开始工作了,我犯了一个非常简单但重要的错误,我把二进制文件写成了文本,所以…

感谢您的反馈和帮助

最新更新