FFMPEG挂在缓冲区填充C 上
FFmpeg hangs on buffer fill c++
我正在使用FFMPEG从RTSP流中处理一堆帧。我最终在这些框架上进行了很多处理,这意味着我并不总是在实时实时拉动。如果缓冲区满足,则过程将悬挂。我想知道以下解决方案之一是否可行/解决了问题,如果是这样,我将如何使用FFMPEG库实施它:
1)如果我到达悬挂的点,是否有办法清除缓冲区?(我可以确定何时悬挂,我只是不知道该怎么做)。
2)有没有办法使缓冲区覆盖旧数据,并且始终读取最新数据?如果我失去框架对我来说没关系。
3)我已经发现我可以使用以下方式使缓冲区较大:av_dict_set(&avd, "buffer_size", "655360", 0);
。这可能是一个解决方案,但我不知道它需要多大/小,因为我不知道该流将发布视频的时间多长时间?
4)这只是我需要与ffmpeg人一起提出的错误吗?
5)我没有考虑过的其他东西?
while(av_read_frame(context, &(packet)) >= 0 && fcount < fps*SECONDS) {
clock_t start, end;
int ret = avcodec_send_packet(codec_context, packet);
if(!(packet->stream_index == video_stream_index)) {
continue;
}
if (ret == AVERROR(EAGAIN) || ret == AVERROR(EINVAL)) {
continue;
} else if (ret < 0) {
cerr << "Error while decoding frame " << fcount << endl;
exit(1);
}
ret = avcodec_receive_frame(codec_context, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR(EINVAL)) {
continue;
} else if (ret < 0) {
cerr << "Error while decoding frame " << fcount << endl;
exit(1);
}
sws_scale(img_convert_ctx, frame->data, frame->linesize, 0,
codec_context->height, picture_rgb->data, picture_rgb->linesize);
if(!frame) {
cerr << "Could not allocate video frame" << endl;
exit(1);
}
if(codec_context == NULL) {
cerr << "Cannot initialize the conversion context!" << endl;
exit(1);
}
// Do something with the frame here
fcount++;
av_packet_unref(&(packet));
}
我添加了导致程序悬挂的代码。
您可以尝试进行多线程。每个帧都通过单独的线程处理(使用线程池)。
如果您需要顺序完成顺序,则必须使用一些结构(队列?)来在无序的线程完成时间内订单。
缓冲区的大小是套接字选项,如果缓冲区已满,则在引擎盖下方的ffmpeg下方可能会阻止其套接字RECV调用。查看了FFMPEG代码后,似乎在纯UDP流上有圆形缓冲区的FIFO尺寸选项,但对于RTP流而言,这是禁用的。
为了确保缓冲区永不完整,我将在一个线程中运行所有PKT RECV和框架解码操作,然后将其馈送到我自己的线程安全的圆形缓冲区。RASPI应该能够跟上解码的步伐,但是如果没有,我会研究硬件辅助解码。关键是,确保您的委托和解码保持实时速度。您可以在其他线程中处理所有调整大小,处理和框架写作,并相应地设置圆形缓冲区大小以处理溢出。
看来您正在尝试实时编写原始框架,因此一个警告:显然,FPS和框架尺寸在所有速度的速度中都起着作用,但是我怀疑您会看到很多掉落的帧。
这应该是解决问题的直接解决方案。使用FFMPEG
将流转换为帧时进行缓冲您应该尝试的是记录流并将其缓存到存储中,然后将其转换。您还可以尝试的是将缓冲区缓存到磁盘上并重新填充FFMPEG过程。
一个黑客解决方案是将RTSP流转换为UDP,实际上很容易AF,然后使用ffmpeg内部缓冲区选项,可用于UDP,该选项可用于RTSP
- C++:使用缓冲区中的数据填充结构
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- 缓冲区填充了不同类型的数据和严格的混叠
- DirectX11只绘制填充索引和顶点缓冲区中的一半顶点
- 填充和保存线程之间的共享缓冲区
- strcpy_s将超过字符串长度的字符串复制到目标缓冲区(用 0xFE 填充)
- 缓冲区用不需要的数据填充 char 数组中的最后一个空格
- InternetReadFile 填充缓冲区,但返回零字节读取
- 无法使用两种不同的频率填充 *.wav 文件的缓冲区
- P/调用C++用于填充托管缓冲区的 DLL
- 是否存在以相反顺序填充缓冲区的MEMSET函数
- FFMPEG挂在缓冲区填充C 上
- 在 C++ 中填充重复的自定义协议缓冲区字段
- C - 分配一个未签名的炭缓冲区,然后用字符串填充
- C/C++ 从字符缓冲区读取以填充结构
- 如果缓冲区由数据流填充,则 C++ boost async_read_some被缓冲区阻止
- 用iostream操作符填充缓冲区
- OpenGL如何填充缓冲区并读取它们
- 用随机值填充缓冲区
- 'clEnqueueFillBuffer()' 仅随机正确填充缓冲区