live555源代码详细分析解析,教你如何使用live555接收rtsp数据
发布日期:2021-07-20 21:46:54
浏览次数:12
分类:技术文章
本文共 2319 字,大约阅读时间需要 7 分钟。
最近继续看了看live555的代码,进行了一些具体的实验。
对live555的部分特性有了一定的了解。 稍微看了网上的一些关于live555的文章,千篇一律。 大部分都是转载自一个人的博客。 很少人进行一些实验或进行一些比较深入的代码阅读,然后写出一些其他的经验之谈。 我想应该是很多人都进行了代码阅读,理解了代码,但是就是懒的写一些东西吧。 这里自夸一下自己,哈,hanyionet真是大好人,大闲人。 这里我尽我自己一份小小的力,给大家写一些小小的经验之谈。如果有时间的话,我将写一些更多的文章关于live555。以前在网上看到一个论坛有人问:
使用live555的testMpeg1or2VideoReceiver在其FrameSink的afterGettingFrame1(unsigned frameSize, struct timeval presentationTime) 接受的buffer是否是代表一个帧。 大概是这个问题。当时看到没有太在意。
因为没有搞这部分。 刚刚做了一些实验。 根据实验的结果。我可以得出: live555如果采用 A test program that reads a MPEG-1 or 2 Video Elementary Stream file就是testMpeg1or2VideoStreamer.cpp发送rtp包,那么得到的rtp包包含的就不是一个完整的帧。如果不是完整的一帧那么我们该如何进行“正确”的解码呢。
例如我们使用的是FFmpeg的avcodec_decode_video()进行解码。 那么如果要正确解码,就必须将一个完整的帧的buffer放入这个解码API中去。 如果没有正确的一帧,我们直接将buffer放入avcodec_decode_video()进行解码,会有什么结果呢。 我们就会得到抖动的画面,带着马赛克,或者画面模糊等等。 这说明了,我们没有正确的解码。接下来的问题是,我们该如何得到完整的一帧呢。
因为我们现在得到的是一些buffer(它为unsigned char*)。 很多人会想到要使用avcodec_decode_video()进行解码然后得到的例如AVFrame *_decoded_frame这样的_decoded_frame的指针。 通过类似_decoded_frame->pict_type == FF_I_TYPE 或FF_P_TYPE,进行判断。 但是我进行的实验证明这是不可以的,也就是说无法正确地判断这些buffer是否为同一帧的buffer。 我使用的avcodec_find_decoder( CODEC_ID_MPEG2VIDEO ); 可能其他的codec可以通过_decoded_frame->pict_type == FF_I_TYPE 或FF_P_TYPE,进行判断。 但是在CODEC_ID_MPEG2VIDEO或CODEC_ID_MPEG1VIDEO的情况下不行。经过一点思考。
我发现使用live555中afterGettingFrame1(unsigned frameSize, struct timeval presentationTime) 的presentationTime进行判断就可以判断出是得到的buffer是否是同一帧的。 具体实现如下,我只是提供一点思路。 具体实现请自己搞定。 请不要问我如何编。 很简单,请想想吧,请不要写信要源代码。一点思路:
可以将每次进入afterGettingFrame1的presentationTime进行判断,如果是相同的
那么将相同的buffer存入一个buffer中去,也就是两个buffer连接在一起,不知道我是否表述的清晰。 其实就是使用memcpy这个函数。 当presntationTime不同时候,将以前存的buffer(已经是完整一帧)传给avcodec_decode_video()就可以正确地解一帧了。当然了,这里在提一下,我们最好设两个thread,一个thread进行live555的接受,另一个thread进行解码使用FFmpeg或其他。
两个thread如果读取同一变量,请设定mutex进行锁。在进行一些延伸的思考,为什么可以使用presentationTime判断是否为同一帧呢。
如果读过live555的 liveMedia/DeviceSource.cpp的朋友就知道了,非常非常不负责任的简单地说,如果我们想自己进行编码然后再播放那么就要使用DeviceSource这个类,自己进行一些拓展,DeviceSource是在服务器端,进行rtp包发送前的处理。 DeviceSource里的deliverFrame()函数的用途就是将编码后产生的buffer连同想对应的presentationTime一起“发送出去”,如果熟悉FFmpeg可以使用avcodec_encode_video()进行编码。 看到了吧,在这里就可以找到了presentationTime和一帧里的buffer之间的联系。 当然了,我的这个解释很不负责任,极度简单。 只是通过一个例子进行说明。 有兴趣的朋友可以通过进行更进一步的代码阅读了解presentationTime和一帧里的buffer之间的关系。好了,随手写一些东西,比较不见条理性。希望大家见谅。
希望大家在需要的时候,能搜索到这篇文章,并得到一点帮助。 注意,以上的解释和记录比较不负责任,极度简单,因为没有进行更系统的代码阅读和分析,不能保证以上所诉完全正确转载地址:https://blog.csdn.net/lifan_3a/article/details/41694867 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年09月15日 10时13分19秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
集成电路专业术语简介
2019-05-24
成长日记
2019-05-24
从3个科技公司里学到的57条经验
2019-05-24
程序员应该投资的10件事
2019-05-24
多媒体
2019-05-24
沟通技巧
2019-05-24
专业camera/isp术语中英文对照
2019-05-24
摄像头
2019-05-24
手机摄像头
2019-05-24
2015 清明 扬州行
2019-05-24
我的理想,我的奋斗目标
2019-05-24
从程序员到CTO所要培养的六种能力
2019-05-24
提高孩子速度的五招
2019-05-24
为什么每个程序员都应该学习使用命令行
2019-05-24
浅谈软件开发人员的职业发展规划
2019-05-24
编程中的难得糊涂
2019-05-24
有效的软件质量管理
2019-05-24
程序员保持快乐活跃的6个好习惯
2019-05-24
【转】如何做好软件的质量管理?
2019-05-24
linux
2019-05-24