Repository: pion/rtp
Pull request #26 (2019-12-09 09:29:50)

Add PartitionHeadChecker interface
Add an interface to check whether the given packet is the beginning of a new frame partition.
`OpusPartitionHeadChecker` and `VP8PartitionHeadChecker` are implemented.

Intended to be used in https://github.com/pion/webrtc/pull/932.

If there is better interface naming for this, please comment.

codecov-io: # [Codecov](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=h1) Report
> Merging [#26](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=desc) into [master](https://codecov.io/gh/pion/rtp/commit/94055aff4ae00d46f218eab6949fa713d48306af?src=pr&el=desc) will **increase** coverage by `0.6%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pion/rtp/pull/26/graphs/tree.svg?width=650&token=4KrbiBsspj&height=150&src=pr)](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##           master      #26     +/-   ##
=========================================
+ Coverage   79.75%   80.35%   +0.6%     
=========================================
  Files           9        9             
  Lines         326      336     +10     
=========================================
+ Hits          260      270     +10     
  Misses         57       57             
  Partials        9        9
```


| [Impacted Files](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [codecs/vp8\_packet.go](https://codecov.io/gh/pion/rtp/pull/26/diff?src=pr&el=tree#diff-Y29kZWNzL3ZwOF9wYWNrZXQuZ28=) | `100% <100%> (ø)` | :arrow_up: |
| [codecs/opus\_packet.go](https://codecov.io/gh/pion/rtp/pull/26/diff?src=pr&el=tree#diff-Y29kZWNzL29wdXNfcGFja2V0Lmdv) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=footer). Last update [94055af...948be0b](https://codecov.io/gh/pion/rtp/pull/26?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

at-wat: @Sean-Der please take a look this when you have time!
Sean-Der: @at-wat 

Hey! Sorry reviews have been taking so long, I made you an Administrator of Pion. You can merge things without me now. You are a really great developer and I agree with all the development decisions you have made. If you ever have things you want to discuss please send them my way. You have equal control over the project (no pressure though!) I don't want things to slow down because of me.

I have just been focused on turn + dtls recently. I do plan on shifting back into WebRTC more, but for me the 'grand vision' of Pion needs all these parts :)
at-wat: @Sean-Der thank you!

Patch:
diff --git a/README.md b/README.md
index bb0264c..d839b2f 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,7 @@ Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contribu
 * [Antoine Baché](https://github.com/Antonito) *Fixed crashes*
 * [Hugo Arregui](https://github.com/hugoArregui)
 * [Raphael Derosso Pereira](https://github.com/raphaelpereira)
+* [Atsushi Watanabe](https://github.com/at-wat)
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
diff --git a/codecs/opus_packet.go b/codecs/opus_packet.go
index 2dc676a..915b7d7 100644
--- a/codecs/opus_packet.go
+++ b/codecs/opus_packet.go
@@ -34,3 +34,15 @@ func (p *OpusPacket) Unmarshal(packet []byte) ([]byte, error) {
 	p.Payload = packet
 	return packet, nil
 }
+
+// OpusPartitionHeadChecker checks Opus partition head
+type OpusPartitionHeadChecker struct{}
+
+// IsPartitionHead checks whether if this is a head of the Opus partition
+func (*OpusPartitionHeadChecker) IsPartitionHead(packet []byte) bool {
+	p := &OpusPacket{}
+	if _, err := p.Unmarshal(packet); err != nil {
+		return false
+	}
+	return true
+}
diff --git a/codecs/vp8_packet.go b/codecs/vp8_packet.go
index 5e71b64..46bb937 100644
--- a/codecs/vp8_packet.go
+++ b/codecs/vp8_packet.go
@@ -134,3 +134,15 @@ func (p *VP8Packet) Unmarshal(payload []byte) ([]byte, error) {
 	p.Payload = payload[payloadIndex:]
 	return p.Payload, nil
 }
+
+// VP8PartitionHeadChecker checks VP8 partition head
+type VP8PartitionHeadChecker struct{}
+
+// IsPartitionHead checks whether if this is a head of the VP8 partition
+func (*VP8PartitionHeadChecker) IsPartitionHead(packet []byte) bool {
+	p := &VP8Packet{}
+	if _, err := p.Unmarshal(packet); err != nil {
+		return false
+	}
+	return p.S == 1
+}
diff --git a/partitionheadchecker.go b/partitionheadchecker.go
new file mode 100644
index 0000000..6ec2a76
--- /dev/null
+++ b/partitionheadchecker.go
@@ -0,0 +1,6 @@
+package rtp
+
+// PartitionHeadChecker is the interface that checks whether the packet is keyframe or not
+type PartitionHeadChecker interface {
+	IsPartitionHead([]byte) bool
+}


Test patch:
diff --git a/codecs/opus_packet_test.go b/codecs/opus_packet_test.go
index 37f02e9..a7400c0 100644
--- a/codecs/opus_packet_test.go
+++ b/codecs/opus_packet_test.go
@@ -68,3 +68,17 @@ func TestOpusPayloader_Payload(t *testing.T) {
 	}
 
 }
+
+func TestOpusPartitionHeadChecker_IsPartitionHead(t *testing.T) {
+	checker := &OpusPartitionHeadChecker{}
+	t.Run("SmallPacket", func(t *testing.T) {
+		if checker.IsPartitionHead([]byte{}) {
+			t.Fatal("Small packet should not be the head of a new partition")
+		}
+	})
+	t.Run("NormalPacket", func(t *testing.T) {
+		if !checker.IsPartitionHead([]byte{0x00, 0x00}) {
+			t.Fatal("All OPUS RTP packet should be the head of a new partition")
+		}
+	})
+}
diff --git a/codecs/vp8_packet_test.go b/codecs/vp8_packet_test.go
index 9a8cf16..4cd01bc 100644
--- a/codecs/vp8_packet_test.go
+++ b/codecs/vp8_packet_test.go
@@ -141,3 +141,22 @@ func TestVP8Payloader_Payload(t *testing.T) {
 		t.Fatal("Generated payload should be the same size as original payload size")
 	}
 }
+
+func TestVP8PartitionHeadChecker_IsPartitionHead(t *testing.T) {
+	checker := &VP8PartitionHeadChecker{}
+	t.Run("SmallPacket", func(t *testing.T) {
+		if checker.IsPartitionHead([]byte{0x00}) {
+			t.Fatal("Small packet should not be the head of a new partition")
+		}
+	})
+	t.Run("SFlagON", func(t *testing.T) {
+		if !checker.IsPartitionHead([]byte{0x10, 0x00, 0x00, 0x00}) {
+			t.Fatal("Packet with S flag should be the head of a new partition")
+		}
+	})
+	t.Run("SFlagOFF", func(t *testing.T) {
+		if checker.IsPartitionHead([]byte{0x00, 0x00, 0x00, 0x00}) {
+			t.Fatal("Packet without S flag should not be the head of a new partition")
+		}
+	})
+}