live555保存文件的问题

 各位大哥,小菜现在遇到问题了:
    用live555保存的文件不可以用vlc播放,在网上查找到了很多的这种问题,就是没有一个完整的答案。
    通过查找,说在每个包的前面加上00 00 00 01 但是我在liveMedia/H264VideoFileSink.cpp的 void afterGettingFrame1函数中发现了unsigned char start_code[4] = {0x00, 0x00, 0x00, 0x01}; addData(start_code, 4, presentationTime);这两句,我的理解是在包里面live555自己已经加上了,有的说在保存文件的时候把sps和pps通过Base64解码写到文件中,这种说法也都不一样,有些人说只在文件的开头写上就行,有的说在每个I帧前面加上,有的说只写sps,有的说全都写。
    虽然说的方法是很多,但是只有这样冷统的说法,对于初学者来说,根本就不会理解的,比如,sps和pps是怎么得到的?解答的人说在SDP中,SDP从RTSP流中提取,还要通过Base64进行解码,如果你是初学者,你会吗?我不会。在解出sps和pps后怎么和addData的写文件结合?牛X的人会说,自己看,代码写的很清楚。live555不是个小的东西把,它的结构很大,类继承的也很深,不是一朝一夕就可以看会的,也许真的很简单,初学者也会钻牛角尖,不是吗?
    希望有经验的人可以指点一下小菜,谢谢!我的问题有这么几个:
    1、我知道调用MediaSubsession类中的fmtp_spropparametersets方法可以得到SDP中的sps和pps,但是在什么地方得到才是最好的?就是说在什么地方得到sps和pps与文件结合最方便。
    2、在什么地方调用Base64去对sps和pps解码?
    3、是在文件的开头些sps和pps还是在每一个I帧前面写?如果在每个I帧前面写怎样判断是I帧?
    4、在代码的什么地方保存文件好?还是在addData中?
    5、在什么地方sps和pps与文件结合?
    6、或者有什么更好的方法呢?

    谢谢各位大哥的讲解,当问题解决后我会总结出一个详细的方案更大家一起学习,谢谢!(该贴会继续加分)
   

问题点数:100分

CSDN推荐

CSDN今日推荐

小菜_默

Bbs1

0 2010-01-05 16:10:05

引用 ・ 举报 ・ 管理 #1 得分:0

    大哥们好,有些问题小菜应该说明白一下,用live555接收的是RTSP的流,保存的是H264的文件,要可以通过VLC可以进行播放,问题就是这样,我找到了一个有用的网站,http://topic.csdn.net/u/20100104/16/0fd992e8-b0a6-4c2b-85a4-d9513d3b1491.html?35280,谢谢大家的关注!

扫描二维码关注公众号,回复: 3097941 查看本文章

macrojj

Bbs1

0 2010-01-05 17:31:45

引用 ・ 举报 ・ 管理 #2 得分:0

你把vlc设置成rstp的这样行不行呢

macrojj

Bbs1

0 2010-01-05 17:33:51

引用 ・ 举报 ・ 管理 #3 得分:15

是在文件的开头些sps和pps还是在每一个I帧前面写?如果在每个I帧前面写怎样判断是I帧?

sps是序列头 是在一段视频前的, pps是图像头 对于每帧的。
具体在哪写 我也不知道。

小菜_默

Bbs1

0 2010-01-05 17:55:52

引用 ・ 举报 ・ 管理 #4 得分:0

引用 2 楼 macrojj 的回复:

你把vlc设置成rstp的这样行不行呢


谢谢您的回答,用VLC直接读取RTSP是可以的,但要求不是用vlc去直接读取RTSP的,要求是要VLC去播放live555保存的文件!

lius1984

Bbs1

0 2010-01-05 19:48:43

引用 ・ 举报 ・ 管理 #5 得分:15

光加0001还不够, sps和pps在服务器返回的SDP description里 用base64编码,格式是“sprop-parameter-sets=Z0JADJWwUH7AQCA=,aM4NyA==”,只要basedecode出来放在第一帧之前  一起送入解码器就可以了。

请LZ认真研究示例程序playCommon.cpp。  

小菜_默

Bbs1

0 2010-01-05 20:35:32

引用 ・ 举报 ・ 管理 #6 得分:0

引用 5 楼 lius1984 的回复:

光加0001还不够, sps和pps在服务器返回的SDP description里 用base64编码,格式是“sprop-parameter-sets=Z0JADJWwUH7AQCA=,aM4NyA==”,只要basedecode出来放在第一帧之前  一起送入解码器就可以了。

 请LZ认真研究示例程序playCommon.cpp。


    小菜先谢谢您了,我会好好看的!

小菜_默

Bbs1

0 2010-01-06 11:16:23

引用 ・ 举报 ・ 管理 #7 得分:0

引用 5 楼 lius1984 的回复:

光加0001还不够, sps和pps在服务器返回的SDP description里 用base64编码,格式是“sprop-parameter-sets=Z0JADJWwUH7AQCA=,aM4NyA==”,只要basedecode出来放在第一帧之前  一起送入解码器就可以了。

 请LZ认真研究示例程序playCommon.cpp。


    您好,对于您说说的,我看过了,通过getSDPDescriptionFromURL函数得到sdp信息因为我的用户名和密码是空的,所以进入了RTSPClient类的describeURL方法,通过在该方法中的实现,和在getSDPDescriptionFromURL函数调用成功后的env输出来看,并没有对上号,输出的东西远比在describeURL方法中实现的要多。
describeURL方法内容如下:

C/C++ code?

1

2

3

4

5

6

7

8

9

10

 char const* sdpFmt =

         "v=0\r\n"

         "o=NoSpacesAllowed 1 1 IN IP4 %u.%u.%u.%u\r\n"

         "s=%s\r\n"

         "c=IN IP4 %u.%u.%u.%u\r\n"

         "t=0 0\r\n"

         "a=control:*\r\n"

         "a=range:npt=0-%llu\r\n"

         "m=video 1554 RAW/RAW/UDP 33\r\n"

         "a=control:trackID=%d\r\n";



实际输出内容如下:

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Opened URL "rtsp://192.168.0.4/stream1", returning a SDP description:

v=0

o=- 95776820 1 IN IP4 192.168.0.4

s=Session streamed by "Streaming Server"

i=stream1

t=0 0

a=tool:LIVE555 Streaming Media v2007.07.09

a=type:broadcast

a=control:*

a=range:npt=0-

a=x-qt-text-nam:Session streamed by "Streaming Server"

a=x-qt-text-inf:stream1

m=video 0 RTP/AVP 96

c=IN IP4 0.0.0.0

a=rtpmap:96 H264/90000

a=fmtp:96 packetization-mode=1;profile-level-id=4366376;sprop-parameter-sets=Z0KgKOcoDwBE/LgIgAAHCAABX5AwAAANWfgAAas/EXvxgAAAas/AAA1Z+IvfjQ==,aN48gA==

a=control:track1


谢谢各位能够解答小菜的疑惑!

lazyter1

Bbs1

0 2010-01-06 11:28:35

引用 ・ 举报 ・ 管理 #8 得分:15

在脱去rtp标签后,那部分数据你直接写入文件,那么这个数据应该就是你服务器发的原始流媒体文件数据。

记住要找对位置,不要将RTCP的数据写入文件。rtp 的。

小菜_默

Bbs1

0 2010-01-06 13:10:02

引用 ・ 举报 ・ 管理 #9 得分:0

引用 8 楼 lazyter1 的回复:

在脱去rtp标签后,那部分数据你直接写入文件,那么这个数据应该就是你服务器发的原始流媒体文件数据。

 记住要找对位置,不要将RTCP的数据写入文件。rtp 的。


  首先谢谢您的帮助,您可以说的明白点吗》?我没有看懂、、、、

小菜_默

Bbs1

0 2010-01-06 17:28:09

引用 ・ 举报 ・ 管理 #10 得分:0

掉下去了,给自己顶一下、、、、

小菜_默

Bbs1

0 2010-01-07 09:57:47

引用 ・ 举报 ・ 管理 #11 得分:0

怎么还没有人呢?

lazyter1

Bbs1

0 2010-01-07 10:08:09

引用 ・ 举报 ・ 管理 #12 得分:15

udp:乱序,丢包,速度较快。
tcp:反之。

live555默认是rtp over UDP,符合实时性要求,所以你要下载再播放,的确叫做录播。而不是live 直播。这样就需要你在内存中进行缓存,将RTP包进行排序,并且有丢包发生的话,还需要处理容错。

不过,根据rfc标准,可以考虑rtp over TCP。这样就没问题了。

小菜_默

Bbs1

0 2010-01-07 11:34:35

引用 ・ 举报 ・ 管理 #13 得分:0

引用 12 楼 lazyter1 的回复:

udp:乱序,丢包,速度较快。
 tcp:反之。

 live555默认是rtp over UDP,符合实时性要求,所以你要下载再播放,的确叫做录播。而不是live 直播。这样就需要你在内存中进行缓存,将RTP包进行排序,并且有丢包发生的话,还需要处理容错。

 不过,根据rfc标准,可以考虑rtp over TCP。这样就没问题了。


您好,您的意思是说我在保存时还要在内存中进行缓存以及排序?我不太明白您的意思。
    我现在了解到的是live555保存的是es流,而vlc可以播放的是ts流,这样的话要对es进行封包,这是一种方法,但是现在不会封ts包!还有个疑问就是在es流中加入sps和ppsvlc就可以播放吧!

小菜_默

Bbs1

0 2010-01-07 15:27:24

引用 ・ 举报 ・ 管理 #14 得分:0

又掉下去了、、、、

rightorwrong

Bbs1 版主

Blank Blank

0 2010-01-07 15:46:55

引用 ・ 举报 ・ 管理 #15 得分:15

没有看回复,注意Live555在写入pps和sps时分别都加入了00 00 00 01,就成了00 00 00 01 pps 00 00 00 01 psp 00 00 00 01图像数据。live555是这样的格式,所以VLC不能播放
应该的格式是00 00 00 01 pps psp 图像数据,这样vlc就能够播放,你可以这样修改下.

jinlking

Bbs1

0 2010-01-07 15:53:43

引用 ・ 举报 ・ 管理 #16 得分:0

mark

小菜_默

Bbs1

0 2010-01-07 16:03:06

引用 ・ 举报 ・ 管理 #17 得分:0

引用 15 楼 rightorwrong 的回复:

没有看回复,注意Live555在写入pps和sps时分别都加入了00 00 00 01,就成了00 00 00 01 pps 00 00 00 01 psp 00 00 00 01图像数据。live555是这样的格式,所以VLC不能播放
 应该的格式是00 00 00 01 pps psp 图像数据,这样vlc就能够播放,你可以这样修改下.



    我写了一下文件,输出是 00 00 00 01 06 05 2d 15 05 ffffffa8 ffffffa8 ffffffaf 4b ffffffb4、、、这是用live555写的文件。不是说00 00 00 001 67 和00 00 00 01 68才是sps和pps吗?那我写的那个文件是什么东西阿!

rightorwrong

Bbs1 版主

Blank Blank

0 2010-01-07 21:56:44

引用 ・ 举报 ・ 管理 #18 得分:0

H264正确的应该是00 00 00 001 67 。。。68。。。。65,这样的数据。你的文件肯定有问题了。可能是还没有pps信息

小菜_默

Bbs1

0 2010-01-08 08:45:37

引用 ・ 举报 ・ 管理 #19 得分:0

引用 18 楼 rightorwrong 的回复:

H264正确的应该是00 00 00 001 67 。。。68。。。。65,这样的数据。你的文件肯定有问题了。可能是还没有pps信息


恩,这就是要点,我不知道怎么把sps和pps写您去,如在哪提取,在哪写入等、、、应该怎么做呢?

lius1984

Bbs1

0 2010-01-08 10:56:05

引用 ・ 举报 ・ 管理 #20 得分:5

从sdp description提取出sprop-parameter-sets之后的内容然后再做base64解码。 已经足够具体了,难道还要“手把手教你流媒体开发”? 多看文档,多GOOGLE吧。

a=fmtp:96 packetization-mode=1;profile-level-id=4366376;sprop-parameter-sets=Z0KgKOcoDwBE/LgIgAAHCAABX5AwAAANWfgAAas/EXvxgAAAas/AAA1Z+IvfjQ==,aN48gA==
a=control:track1
 

rightorwrong

Bbs1 版主

Blank Blank

0 2010-01-08 11:28:01

引用 ・ 举报 ・ 管理 #21 得分:15

你可以用抓包工具,看DESCRIBE返回的sdp description字段有没有lius1984说的sprop-parameter-sets信息,如果有就按照lius1984方法,
我们的设备sps和pps信息是发RTP时发过来的,你的应该不是

numen115

Bbs1

0 2010-01-08 11:56:55

引用 ・ 举报 ・ 管理 #22 得分:5

NALU中不是可以判断该单元是什么类型吗?如果是sps,pps,你就开始保存

小菜_默

Bbs1

0 2010-01-08 13:46:38

引用 ・ 举报 ・ 管理 #23 得分:0

谢谢lius1984 rightorwrong numen115的回答,我先试试大家提供的方法,有问题在贴出来,还有一个问题,如果我10分钟就重新保存一个文件,那么,所有的sps和pps都用那一个吗?

小菜_默

Bbs1

1 2010-01-09 09:46:51

引用 ・ 举报 ・ 管理 #24 得分:0

通过大家和 kevin@liu 的指导,先把我理解到的总结一下,有任何不对的地方还请大家指出:
    现在我只是在playCommon.cpp的主函数中调用的,在if (!subsession->initiate(simpleRTPoffsetArg))的else下面,fmtp_spropparametersets()返回的是sps和pps 我调用了 parseSPropParameterSets 函数,它的返回值是一个 SPropRecord 类型,参数就是fmtp_spropparametersets(),假如我定义的SPropRecord的指针是Info,那么Info[0]就是sps,长度是46,Info[1]就是pps,长度是四。
    不知道我的理解是否正确。
    还有一个问题,如果我10分钟就重新保存一个文件,那么,所有的sps和pps都用那一个吗?

小菜_默

Bbs1

1 2010-01-12 08:33:57

引用 ・ 举报 ・ 管理 #25 得分:0

不知道是怎么回事!从我保存的文件上来看,他是带有pps和sps的,问题正在解决!

kensp1

Bbs1

0 2010-02-03 23:26:55

引用 ・ 举报 ・ 管理 #26 得分:0

请问有没有答案啊

小菜_默

Bbs1

0 2010-02-04 08:26:55

引用 ・ 举报 ・ 管理 #27 得分:0

引用 26 楼 kensp1 的回复:

请问有没有答案啊


呵呵,没有阿,有的话我早就总结了阿~~

lyg1761983

Bbs1

0 2010-03-09 11:28:53

引用 ・ 举报 ・ 管理 #28 得分:0

遇到了同样的问题,你最后生成的本地264文件能用vlc 播放了吗?

小菜_默

Bbs1

0 2010-03-24 11:24:24

引用 ・ 举报 ・ 管理 #29 得分:0

~~现在已经解决了~~解决方式就是在保存文件时从第一个sps处开始保存,保存的文件就可以被VLC播放!

破破天荒

Bbs1

0 2010-04-17 10:07:19

引用 ・ 举报 ・ 管理 #30 得分:0

学习.......

ExperiencesOf...

Bbs1

0 2010-06-09 14:40:25

引用 ・ 举报 ・ 管理 #31 得分:0

asdfsadfsdafsafsdf

ExperiencesOf...

Bbs1

0 2010-06-09 14:41:12

引用 ・ 举报 ・ 管理 #32 得分:0

就是没有pps 和sps 头

fixdot

Bbs1

0 2010-12-20 17:01:50

引用 ・ 举报 ・ 管理 #33 得分:0

偶实现了live555+ffmpeg+sdl显示,需要的q我:一一五六九九四二八一

tairikun01

Bbs1

0 2011-09-19 13:27:40

引用 ・ 举报 ・ 管理 #34 得分:0

引用 29 楼 ct200901 的回复:

~~现在已经解决了~~解决方式就是在保存文件时从第一个sps处开始保存,保存的文件就可以被VLC播放!



直接保存的文件播放时帧率正常么?怎么控制帧率啊?

小菜_默

Bbs1

0 2011-10-25 17:03:14

引用 ・ 举报 ・ 管理 #35 得分:0

引用 34 楼 tairikun01 的回复:

引用 29 楼 ct200901 的回复:
~~现在已经解决了~~解决方式就是在保存文件时从第一个sps处开始保存,保存的文件就可以被VLC播放!


直接保存的文件播放时帧率正常么?怎么控制帧率啊?



  额,,,这个我没有控制,,只是保存起来而已~~~

猜你喜欢

转载自blog.csdn.net/special00/article/details/82533743