一、
FFmpeg定时截取rtsp流,60s保存为一个MP4,
我写的ffmpeg的命令为: ffmpeg -n -rtsp_transport tcp -i rtsp://XXXXXX -vcodec copy -acodec copy -f segment -segment_time 60 -segment_format mp4 d:\\1\\out%03d.mp4
显示保存的时间都是59s或者60s
但是如果第一个视频是18:01:01--18:02:01
第二个就是18:02:02--18:03:01
第三个就是18:03:03--18:04:01
。。。
第40个就是18:40:40--18:41:01
。。。
第60个可能就是19:01:01--19:01:01
越到后面,视频显示60s但是打开就结束了正真可能一秒都不到,我也不知道啥情况
先丢掉音频试一试
先将整个时间长度的截取下来,自己分段看看
确认下命令是否有问题
用命令的话感觉先整个保存下来, 看看有没有问题
我都很少用ffmepg命令,你可以直接用代码写吗?
ffmpeg -i rtsp://xxxxxx -c copy -map 0 -f segment -segment_time 300 -segment_format mp4 "capture-%03d.mp4"
这个我试过,截取多个后也会出现那个问题
而且不用tcp的丢包多
-segment_atclocktime 1
文件大小正常
想这个.后面3秒就自动跳过去了
用ffplay播放,看看mp4文件有没有什么错误
我发现了问题,用 vlc播放是正常的,用windows media player 播放不正常,同一个视频播放的开始时间不一样
我截的图都是从第一秒播放的,但是第一秒就播放时间不一样,少了9s,就导致了后面的9s直接跳过去了
没找到第一个SPS PPS 关键帧,然后直接跳过这个GOP了?
二、
rtsp录mp4,现在我录264都是正常的,265录出来不能放
用啥写的mp4文件?你用的库支持265吗?
最新版本的ffmpeg,播放都可以,就是录出来的放不了
不知道h265写mp4头有什么地方不对
直接取的海康摄像头的rtsp
我是用协议接了数据自己处理,我只是用的解码库,存储我是自己写的格式
就是不知道写265有啥区别?
264的直接copy源,windows自带的播放器都能识别,265的啥播放器也放不了,也不算放不了,vlc播放能走秒。就是黑屏
通常是你的SPS,PPS信息没有给对。
三、
NVR即网络视频录像机,是网络视频监控系统的存储转发部分,其核心功能是视频流的存储与转发。与DVR相比,NVR的功能比较单一,本身不具有模数转换及编码功能,不能独立工作,通常与视频编码器DVS或网络摄像机IPC协同工作,完成视频的录像、存储及转发功能。
相关问题记录:
1、视频预览界面如何画分割线的?
yuv直接画
用vgs
或者用cpu直接操yuv
2、实际项目是如何画的,常规做法,不靠猜。因为上面还要覆盖qt层,我不清楚该画在哪层
两种呀,一种画视频流,一种framebufer
图形层:一般不但有视频,还有UI
UI都是图形层
框也是UI
海思手册推荐vgs画
vgs相当于用显卡加速
没啥麻烦的,播放器都是一帧一帧的画
和pc的播放器没啥区别
贴了图片,在画几条线而已
然后一起显示出来
3、你说的图片就是视频帧?
嗯,解码出来也是yuv
4、要自己贴?不是vpss绑定vo?
也可以不绑定
绑定了,就要用海思里面的discover
reg
等模块,专门画osd
绑定只是mpp在驱动层面帮你画好了,不绑定,就是你自己在应用层画
没啥区别
为什么我一个都没听过。reg?discover?
单词打错了
我也不知道怎么拼了
你看下osd那个,有两种叠加osd的方法
5、如果是把框画在视频上。那没视频的通道怎么画框?比如四路,一路有视频,剩下三路没视频。
可以画vo上面
实际项目一般都是在FB上
就是UI
哦
图形层
一般都QT搞个框,
在视频那留几个框
留几个框是什么意思?
留几个透明的框,
然后,视频层显示在下面就好了
一般解码可以直接绑定到视频层
nvr支持好多视频层,
可以显示好多路
按位置排好就可以了,
然后最上面QT就在显示视频的位置透明
机顶盒不需要多路,解码能力要芯片支持
有些芯片可以解码4K 但是不能解码很多路小分辨率的,
nvr一般都可以解码很多路小分辨率,
这个感觉解码库有啥限制,我也不懂
可能资源利用没海思好吧
四、内存问题
频繁调用memcpy会不会带来很大的cpu消耗
优化什么的总是要等到遇到问题再说吧
在设计io读写api时,是直接将数据写入到调用者的缓冲区好(如果数据长度未知会很不灵活),还是先写到api内部的缓冲区再复制到调用者的缓冲区好(中间隔了一层memcpy,担心增加性能负担)
现在遇到的问题是为了避免二次复制,搞得并不是很优雅,只是想把事情做得更优雅一些而已
肯定是一码归一码
怎么能够图这种方便
万一出了叉子怎么查错?
IO只管接受缓存数据就好,其余的事不要他管
我之前设计的api是直接将将调用者的指针来接收解包后的数据,如果它的缓冲区不够,我会将它释放,然后重新分配,感觉很暴力
你如果写入调用者缓冲区,万一调用者缓冲区有个什么加锁解锁的问题
要写的写不进去
整个流程都堵住
就是一个指针而已,不会有什么锁的
一不小心有个什么空指针
类似于ReadStream(uint8_t *buf, int length)
会检测它的指针是否为空
IO肯定有写的过程嘛
好吧,我这个是内存上的io
就是一块数据缓冲区
不管什么地方的IO
是不是要写完了再处理?
少拷贝肯定是好的
然后是不是要处理完了再写?
但还是要考虑整个结构。
这样一来
就是你等我我等你
到性能不够的时候再调整呗,就师出有名了
如果有点问题,很难搞清楚是IO的问题还是处理流程的问题
我现在就是直接拷贝到调用者的缓冲区,只是考虑到它的缓冲区不够大时怎么办,又不想简单粗暴地丢弃数据
如果是我api内部分配一块数据缓冲区,即使发现长度不够,我也可以在内部调整,待所有数据收完后再拷贝到调用者的缓冲区,这样一样就多了一层memcpy了,担心加大性能开销
你这是侥幸心理嘛
什么意思
怎么可能有够的时候
你如果不控制数据源
有协议的
可以界定数据的边界
我是说,你不能指望调整自己的缓冲区大小去解决风险
你应该去想办法控制数据源
目前没有按照协议来,没有这样的风险
你不是担心位置不够大吗?
怎么又没有风险了?
我是担心调用者的缓冲不够大
packet怎么能判断是否包含h264 header?
发现用h264_mp4toannexb处理后的mp4,I帧前是有pps sps的
如果是先缓冲到api本地再一次性拷贝调用者缓冲区,即使它的内存不够,我也能通过错误码来提醒所需的最大缓冲大小了,接下来就是调用者应该处理的事情了
如果是这种API
直接由API负责申请内存不就好了?
让他返回一个结构,缓冲区地址,大小等等信息
没有必要拷贝吧
有考虑过这样的设计方案
不过还是太危险了
哈哈
建议拷贝出去算数
感觉要把事情做得优雅,太难了
我看了live555的内部实现,它在录制rtp包时也是先将数据写入到它自己的缓冲,录完一帧后再将它拷贝到调用者的缓冲区的
这不是优不优雅的问题
这样流程清晰,界限明显
流程清晰,界限明显,已经很优雅了/呲牙
IO和后面的处理程序甚至可以分开开发测试
主要还是看 性能瓶颈在哪里吧。如果copy占比很低无所谓了。
但是如果程序本身就是负责 数据转发,那可能就要考虑考虑了
也就是copy本身是主要任务
我的原则也是性能优先,能不拷贝就不要拷贝,少一分拷贝肯定cpu的负担会低一些,哪怕是微不足道的
微不足道就算了吧
先拷贝到自己的缓存区吧,socket也是先拷贝到自己的缓冲区的
我看libevent好像是直接拷贝最终目的地
但是人家主要任务就是数据转发,那肯定不管好看不好看了
如果在编码中就无所谓了,一帧拷贝时间还没有编码的1%吧
1% 优化到0.5%,牺牲其他就不值得了吧
我一台机器上要并发10几20个客户端的,我就担心并发多了,memcpy会带来性能上的瓶颈
比如加大了cpu的开销导致并发数降低了
要看具体数量咯。如果是十几个同时观看视频的数据
那就的。。
如果只是一般业务性的,十多个还好吧
视频播放客户端来的
算算好像即使10M码率,数据量也不算太大?
现在主流的搞法,IO不宜掺和太多东西
网络不稳,数据异常,丢包,还有对端服务完球什么的
要处理的异常多了去了
能稳定正确的把数据准备好就已经很吃力了
而且因为是与远端协作,调试起来也比较麻烦
就不要操心别的事了
本地计算只要骚操作不太多,调试一下基本都能很快排除故意
把70路视频接到大屏,有开源的软件么?