gpt4 book ai didi

video - 使用 libav/ffmpeg 在 UDP 流中找到更好的 VP8 参数以实现稳健性

转载 作者:行者123 更新时间:2023-11-28 21:42:34 29 4
gpt4 key购买 nike

我在使用 libav 库的视频聊天应用程序中遇到了一些问题。我通过 UDP 发送以 VP8 编码的 1080p 视频作为 WebM 容器,效果很好。大多数情况下,任一侧的解码器都会从传输造成的数据包丢失中恢复过来。

然而,在某个时间点它只是卡住并且再也不会恢复。这最终会发生在双方。当通过有损传输 channel 发送时,我正在搜索 VP8 编解码器参数以提高鲁棒性。我结合了一些我发现的,以增加稳健性。但是,视频聊天一段时间后仍然卡住。

这是我目前使用的参数。

  pVidCodecCtx->codec_id     = AV_CODEC_ID_VP8;
pVidCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pVidCodecCtx->width = frmQ->pCodecCtx->width; //1920
pVidCodecCtx->height = frmQ->pCodecCtx->height; //1080
pVidCodecCtx->time_base = frmQ->pCodecCtx->time_base;
pVidCodecCtx->pix_fmt = PIX_FMT_YUV420P;
pVidCodecCtx->qmin = 4;
pVidCodecCtx->qmax = 56;
pVidCodecCtx->bit_rate = pVidCodecCtx->width * pVidCodecCtx->height * 6;
pVidCodecCtx->slices = 8;
pVidCodecCtx->profile = 3;
pVidCodecCtx->thread_count = 3;
pVidCodecCtx->keyint_min = 5;
av_dict_set(&pDictCodecOpts, "rc_lookahead", "0", 0);
av_dict_set(&pDictCodecOpts, "quality", "realtime", 0);
av_dict_set(&pDictCodecOpts, "deadline", "realtime", 0);
av_dict_set(&pDictCodecOpts, "max-intra-rate", "0", 0);
av_dict_set(&pDictCodecOpts, "qcomp", "0", 0);
av_dict_set(&pDictCodecOpts, "default", "er", 0);
av_dict_set(&pDictCodecOpts, "error_resilient", "er", 0);
av_dict_set(&pDictCodecOpts, "partitions", "er", 0);

我从 ffmpeg code for the vpx encoder 中提取的大部分参数.

我是否还必须为解码器设置参数以提高错误恢复能力?还是我在编码器中遗漏了一些参数或设置不正确。非常感谢任何帮助或提示。

最佳答案

我会回答我自己的问题,因为我最终成功地让视频聊天运行而没有卡住。

事实证明,这些参数实际上有利于错误恢复。

问题是一些函数调用,例如

av_read_frame()
avformat_open_input()

当包损坏时,解码器线程被阻塞,导致视频卡住。

所以我最终做的是编写一个定时器类,让定时器测量所述函数的执行时间。我写了一个中断回调函数并将它传递给我的解码器的格式上下文,如下所示:

static int interrupt_cb (void *p)
{
unsigned int expTime = 1000;
Uint32 elapsedTime = pVidConfTimer.elapsedTimeInMs();
if (elapsedTime > expTime)
{
return 1;
}
return 0;
}

static const AVIOInterruptCB cb = {interrupt_cb, &dummy};
frmQ.pFormatCtx->interrupt_callback = cb;

如果执行时间比 expTime 长,这将从函数返回。您还可以通过 void *p 将自定义参数传递给回调函数

在我的解码/显示线程中,我只是调用类似的东西

timer.tic();
ret = av_read_frame(...);
timer.reset();

if (ret<0)
{
//received corrupted frame
//reinitialize format context
//open input
//find decoder and open codec
...
}

希望这对遇到类似问题的人有所帮助。

关于video - 使用 libav/ffmpeg 在 UDP 流中找到更好的 VP8 参数以实现稳健性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24411982/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com