Repository: pion/rtp
Pull request #39 (2020-01-19 00:25:35)

Adding noop VP9
#### Description
This is my attempt to address[1] by first adding noop VP9 packetizer[2], This
code is copy from opus_packet.go, then attempt to fix[1] by actually loading a
VP9Payloader instead of nil.

#### Reference issue
[1] pion/example-webrtc-applications#37
[2] pion/webrtc#755

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

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

```diff
@@            Coverage Diff             @@
##           master      #39      +/-   ##
==========================================
+ Coverage   80.97%   81.91%   +0.93%     
==========================================
  Files          10       11       +1     
  Lines         347      365      +18     
==========================================
+ Hits          281      299      +18     
  Misses         57       57              
  Partials        9        9
```


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

------

[Continue to review full report at Codecov](https://codecov.io/gh/pion/rtp/pull/39?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/39?src=pr&el=footer). Last update [66d64e8...bf67aae](https://codecov.io/gh/pion/rtp/pull/39?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Sean-Der: This is fantastic @sysbot I am so excited to see you contributing :D 

Sorry for the delay was on vacation 
Sean-Der: Sorry for the delay was traveling. 

This is fantastic @sysbot I am so excited to see this. Are there any other bugs/issues blocking you from using Pion? Would love to knock them out/always available via Slack

I need to come down to SF again soon, weather in Seattle makes me jealous :)

Patch:
diff --git a/README.md b/README.md
index 87d75cb..365b636 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contribu
 * [Raphael Derosso Pereira](https://github.com/raphaelpereira)
 * [Atsushi Watanabe](https://github.com/at-wat)
 * [adwpc](https://github.com/adwpc) *add transport-cc extension*
+* [Bao Nguyen](https://github.com/sysbot) *add VP9 noop, bug fixes.
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
diff --git a/codecs/vp9_packet.go b/codecs/vp9_packet.go
new file mode 100644
index 0000000..7bd025f
--- /dev/null
+++ b/codecs/vp9_packet.go
@@ -0,0 +1,49 @@
+package codecs
+
+import (
+	"fmt"
+)
+
+// VP9Payloader payloads VP9 packets
+type VP9Payloader struct{}
+
+// Payload fragments an VP9 packet across one or more byte arrays
+func (p *VP9Payloader) Payload(mtu int, payload []byte) [][]byte {
+	if payload == nil {
+		return [][]byte{}
+	}
+
+	out := make([]byte, len(payload))
+	copy(out, payload)
+	return [][]byte{out}
+}
+
+// VP9Packet represents the VP9 header that is stored in the payload of an RTP Packet
+type VP9Packet struct {
+	Payload []byte
+}
+
+// Unmarshal parses the passed byte slice and stores the result in the VP9Packet this method is called upon
+func (p *VP9Packet) Unmarshal(packet []byte) ([]byte, error) {
+	if packet == nil {
+		return nil, fmt.Errorf("invalid nil packet")
+	}
+
+	if len(packet) == 0 {
+		return nil, fmt.Errorf("Payload is not large enough")
+	}
+	p.Payload = packet
+	return packet, nil
+}
+
+// VP9PartitionHeadChecker checks VP9 partition head
+type VP9PartitionHeadChecker struct{}
+
+// IsPartitionHead checks whether if this is a head of the VP9 partition
+func (*VP9PartitionHeadChecker) IsPartitionHead(packet []byte) bool {
+	p := &VP9Packet{}
+	if _, err := p.Unmarshal(packet); err != nil {
+		return false
+	}
+	return true
+}


Test patch:
diff --git a/codecs/vp9_packet_test.go b/codecs/vp9_packet_test.go
new file mode 100644
index 0000000..e01463f
--- /dev/null
+++ b/codecs/vp9_packet_test.go
@@ -0,0 +1,83 @@
+package codecs
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestVP9Packet_Unmarshal(t *testing.T) {
+	pck := VP9Packet{}
+
+	errNilPacket := fmt.Errorf("invalid nil packet")
+	errPayloadTooSmall := fmt.Errorf("Payload is not large enough")
+
+	// Nil packet
+	raw, err := pck.Unmarshal(nil)
+	if raw != nil {
+		t.Fatal("Result should be nil in case of error")
+	}
+	if err == nil || err.Error() != errNilPacket.Error() {
+		t.Fatal("Error should be:", errNilPacket)
+	}
+
+	// Empty packet
+	raw, err = pck.Unmarshal([]byte{})
+	if raw != nil {
+		t.Fatal("Result should be nil in case of error")
+	}
+	if err == nil || err.Error() != errPayloadTooSmall.Error() {
+		t.Fatal("Error should be:", errPayloadTooSmall)
+	}
+
+	// Normal packet
+	raw, err = pck.Unmarshal([]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x90})
+	if raw == nil {
+		t.Fatal("Result shouldn't be nil in case of success")
+	}
+	if err != nil {
+		t.Fatal("Error should be nil in case of success")
+	}
+}
+
+func TestVP9Payloader_Payload(t *testing.T) {
+	pck := VP9Payloader{}
+	payload := []byte{0x90, 0x90, 0x90}
+
+	// Positive MTU, nil payload
+	res := pck.Payload(1, nil)
+	if len(res) != 0 {
+		t.Fatal("Generated payload should be empty")
+	}
+
+	// Positive MTU, small payload
+	res = pck.Payload(1, payload)
+	if len(res) != 1 {
+		t.Fatal("Generated payload should be the 1")
+	}
+
+	// Negative MTU, small payload
+	res = pck.Payload(-1, payload)
+	if len(res) != 1 {
+		t.Fatal("Generated payload should be the 1")
+	}
+
+	// Positive MTU, small payload
+	res = pck.Payload(2, payload)
+	if len(res) != 1 {
+		t.Fatal("Generated payload should be the 1")
+	}
+}
+
+func TestVP9PartitionHeadChecker_IsPartitionHead(t *testing.T) {
+	checker := &VP9PartitionHeadChecker{}
+	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 VP9 RTP packet should be the head of a new partition")
+		}
+	})
+}