shithub: rtmp

Download patch

ref: 0ce01d66fb72ea51b7dd0e885a01e2bba1eda7ff
parent: 3acc9f1c414b3032531e1db73e77bb4af0f8ed38
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jul 28 10:07:08 EDT 2021

parse control packets

--- a/rtmp.c
+++ b/rtmp.c
@@ -28,6 +28,14 @@
 	CbStatus,
 	NumCbA,
 
+	CtlStreamBegin = 0,
+	CtlStreamEnd,
+	CtlStreamDry,
+	CtlStreamRecorded,
+	CtlPing = 6,
+	CtlBufferEmpty = 31,
+	CtlBufferReady,
+
 	PktChunkSz = 1,
 	PktBytesReadReport = 3,
 	PktControl = 4,
@@ -105,7 +113,7 @@
 	putobj(); \
 }while(0)
 
-static szs[] = {
+static int szs[] = {
 	[SzTiny] = 1,
 	[SzSmall] = 4,
 	[SzMedium] = 8,
@@ -128,6 +136,16 @@
 	[PktFlashVideo] = "FlashVideo",
 };
 
+static char *ctl2s[] = {
+	[CtlStreamBegin] = "StreamBegin",
+	[CtlStreamEnd] = "StreamEnd",
+	[CtlStreamDry] = "StreamDry",
+	[CtlStreamRecorded] = "StreamRecorded",
+	[CtlPing] = "Ping",
+	[CtlBufferEmpty] = "BufferEmpty",
+	[CtlBufferReady] = "BufferReady",
+};
+
 extern int debug;
 
 #pragma varargck type "T" int
@@ -156,9 +174,13 @@
 	p = va_arg(f->args, Packet*);
 
 	fmtprint(f, "type=%T chan=%d ts=%ud sz=%d", p->type, p->chan, p->ts, p->sz);
+
+	s = p->data;
+	e = s + p->sz;
+
 	if(p->type == PktInvoke){
 		fmtprint(f, ":");
-		for(s = p->data, e = s + p->sz; s != nil && s != e;){
+		for(; s != nil && s != e;){
 			if((s = amfparse(&a, s, e)) != nil)
 				fmtprint(f, " %A", a);
 			else
@@ -414,6 +436,7 @@
 	int res, n, ok;
 	Amf *a[NumCbA];
 	u8int *s, *e;
+	s16int s16;
 	Packet *p;
 	Invoke *i;
 	RTMP *r;
@@ -435,12 +458,13 @@
 			break;
 		}
 
+		s = r->pk.data;
+		e = s + r->pk.sz;
+
 		switch(p->type){
 		case PktInvoke:
 			i = nil;
 			ok = 0;
-			s = r->pk.data;
-			e = s + r->pk.sz;
 			for(n = 0; n < NumCbA; n++){
 				if((s = amfparse(&a[n], s, e)) == nil)
 					goto err;
@@ -483,7 +507,7 @@
 			break;
 
 		case PktChunkSz:
-			if(amfi32get(r->pk.data, r->pk.data+r->pk.sz, &r->chunk) == nil)
+			if(amfi32get(s, e, &r->chunk) == nil)
 				goto err;
 			if(r->chunk < 2){
 				werrstr("invalid chunk size: %d", r->chunk);
@@ -492,8 +516,35 @@
 			if(debug)
 				fprint(2, "new chunk size: %d bytes\n", r->chunk);
 			break;
+
 		case PktBytesReadReport:
 		case PktControl:
+			if((s = amfi16get(s, e, &s16)) == nil)
+				goto err;
+			if((s = amfi32get(s, e, &n)) == nil)
+				n = -1;
+			switch(s16){
+			case CtlStreamBegin:
+			case CtlStreamEnd:
+			case CtlStreamDry:
+			case CtlStreamRecorded:
+			case CtlBufferEmpty:
+			case CtlBufferReady:
+				if(0){
+			case CtlPing:
+					/* FIXME pong */
+					USED(n);
+				}
+				if(debug)
+					fprint(2, "control packet: %s %d\n", ctl2s[s16], n);
+				break;
+			default:
+				if(debug)
+					fprint(2, "unknown control packet %d (value %d)\n", s16, n);
+				break;
+			}
+			break;
+
 		case PktServerBW:
 		case PktClientBW:
 		case PktAudio: