Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defines.go文件中GetTimestamp()函数的问题 #27

Open
programmerZhou opened this issue Sep 2, 2016 · 3 comments
Open

defines.go文件中GetTimestamp()函数的问题 #27

programmerZhou opened this issue Sep 2, 2016 · 3 comments

Comments

@programmerZhou
Copy link

programmerZhou commented Sep 2, 2016

  1. 下面rtmp_specification_1.0.pdf文件中关于timestamp的描述。

Because timestamps are 32 bits long, they roll over every 49 days, 17 hours, 2 minutes and 47.296 seconds. Because streams are allowed to run continuously, potentially for years on end, an RTMP application SHOULD use serial number arithmetic [RFC1982] when processing timestamps, and SHOULD be capable of handling wraparound. For example, an application assumes that all adjacent timestamps are within 2^31 - 1 milliseconds of each other, so 10000 comes after 4000000000, and 3000000000 comes before 4000000000.

上面的描述说明了的timestamp是32的无符号整数所表示的毫秒,由于该值最大只能表示不到50天的时间戳,所以需要对时间戳做环绕式处理。
2. defines.go文件中GetTimestamp的实现

466 // Get timestamp
467 func GetTimestamp() uint32 {
468     //return uint32(0)
469     return uint32(time.Now().UnixNano()/int64(1000000)) % MAX_TIMESTAMP
470 }

该函数取系统当前时间(毫秒)作为时间戳,然后与 MAX_TIMESTAMP取模,这样也确实实现的环绕处理, 但是我看到MAX_TIMESTAMP的定义如下:

278     MAX_TIMESTAMP                       = uint32(2000000000)  

正确的定义该值应该是32位无符号整数的最大值+1, 即0x100000000,defines.go文件对该值的定义的显然不对。
3. defines.go文件的第469行有一种更简单的改写方式, 如下:

469     return uint32(time.Now().UnixNano()/int64(1000000))

超过32位无符号整数的部分会被自然溢出,我们强制转换得到溢出后剩下的部分,即实现了环绕,也相当于对0x100000000做取模操作。

@hy05190134
Copy link
Contributor

@programmerZhou 你的意思不取余反而是正确的?

@programmerZhou
Copy link
Author

@hy05190134 强转让其溢出即是取模。

return uint32(time.Now().UnixNano()/int64(1000000))
return uint32(time.Now().UnixNano()/int64(1000000) % 0x100000000)

上面这两行等价。

类似的写法还有

// 对一个数除2 
a := x / 2 
// 也可写成 
a = x >> 1

上面的问题主要是MAX_TIMESTAMP定义的不对,应该是0x100000000, 时间戳是环绕的,达到最大值之后,下一个值为0,即0xffffffff的下一个值为0。

注:位运算一般效率更高。

@zhangpeihao
Copy link
Owner

这个需要实测,spec里面写的有些不准确,所以设置了一个最大支持的时间范围。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants