Selaa lähdekoodia

bring ogg parsing context purely inside stream.c - release

philippe44 1 vuosi sitten
vanhempi
commit
8e3d91020f
2 muutettua tiedostoa jossa 57 lisäystä ja 56 poistoa
  1. 0 14
      components/squeezelite/squeezelite.h
  2. 57 42
      components/squeezelite/stream.c

+ 0 - 14
components/squeezelite/squeezelite.h

@@ -580,20 +580,6 @@ struct streamstate {
 	u32_t meta_next;
 	u32_t meta_left;
 	bool  meta_send;
-    struct {
-		enum { STREAM_OGG_OFF, STREAM_OGG_SYNC, STREAM_OGG_HEADER, STREAM_OGG_SEGMENTS, STREAM_OGG_PAGE } state;
-		u32_t want, miss, match;
-		u8_t* data, segments[255];
-#pragma pack(push, 1)
-		struct {
-			char pattern[4];
-			u8_t version, type;
-			u64_t granule;
-			u32_t serial, page, checksum;
-			u8_t count;
-		} header;
-    } ogg;
-#pragma pack(pop)
 };
 
 void stream_init(log_level level, unsigned stream_buf_size);

+ 57 - 42
components/squeezelite/stream.c

@@ -61,6 +61,21 @@ static sockfd fd;
 
 struct EXT_RAM_ATTR streamstate stream;
 
+static EXT_RAM_ATTR struct {
+	enum { OGG_OFF, OGG_SYNC, OGG_HEADER, OGG_SEGMENTS, OGG_PAGE } state;
+	u32_t want, miss, match;
+	u8_t* data, segments[255];
+#pragma pack(push, 1)    
+	struct {
+		char pattern[4];
+		u8_t version, type;
+		u64_t granule;
+		u32_t serial, page, checksum;
+		u8_t count;
+	} header;
+#pragma pack(pop)    
+} ogg;
+
 #if USE_SSL
 static SSL_CTX *SSLctx;
 SSL *ssl;
@@ -148,8 +163,8 @@ static bool running = true;
 static void _disconnect(stream_state state, disconnect_code disconnect) {
 	stream.state = state;
 	stream.disconnect = disconnect;
-    if (stream.ogg.state == STREAM_OGG_PAGE && stream.ogg.data) free(stream.ogg.data);
-    stream.ogg.data = NULL;
+    if (ogg.state == OGG_PAGE && ogg.data) free(ogg.data);
+    ogg.data = NULL;
 #if USE_SSL
 	if (ssl) {
 		SSL_shutdown(ssl);
@@ -169,74 +184,74 @@ static u32_t memfind(const u8_t* haystack, u32_t n, const char* needle, u32_t le
 }
 
 static void stream_ogg(size_t n) {
-	if (stream.ogg.state == STREAM_OGG_OFF) return;
+	if (ogg.state == OGG_OFF) return;
 	u8_t* p = streambuf->writep;
 
 	while (n) {
-		size_t consumed = min(stream.ogg.miss, n);
+		size_t consumed = min(ogg.miss, n);
 
 		// copy as many bytes as possible and come back later if we do'nt have enough
-		if (stream.ogg.data) {
-			memcpy(stream.ogg.data + stream.ogg.want - stream.ogg.miss, p, consumed);
-			stream.ogg.miss -= consumed;
-			if (stream.ogg.miss) return;
+		if (ogg.data) {
+			memcpy(ogg.data + ogg.want - ogg.miss, p, consumed);
+			ogg.miss -= consumed;
+			if (ogg.miss) return;
 		}
 
 		// we have what we want, let's parse
-		switch (stream.ogg.state) {
-		case STREAM_OGG_SYNC: {
-			stream.ogg.miss -= consumed;
+		switch (ogg.state) {
+		case OGG_SYNC: {
+			ogg.miss -= consumed;
 			if (consumed) break;
 
 			// we have to memorize position in case any of last 3 bytes match...
-			int pos = memfind(p, n, "OggS", 4, &stream.ogg.match);
-			if (stream.ogg.match == 4) {
-				consumed = pos - stream.ogg.match;
-				stream.ogg.state = STREAM_OGG_HEADER;
-				stream.ogg.miss = stream.ogg.want = sizeof(stream.ogg.header);
-				stream.ogg.data = (u8_t*) &stream.ogg.header;
-				stream.ogg.match = 0;
+			int pos = memfind(p, n, "OggS", 4, &ogg.match);
+			if (ogg.match == 4) {
+				consumed = pos - ogg.match;
+				ogg.state = OGG_HEADER;
+				ogg.miss = ogg.want = sizeof(ogg.header);
+				ogg.data = (u8_t*) &ogg.header;
+				ogg.match = 0;
 			} else {
 				LOG_INFO("OggS not at expected position");
 				return;
 			}
 			break;
 		}
-		case STREAM_OGG_HEADER:
-			if (!memcmp(stream.ogg.header.pattern, "OggS", 4)) {
-				stream.ogg.miss = stream.ogg.want = stream.ogg.header.count;
-				stream.ogg.data = stream.ogg.segments;
-				stream.ogg.state = STREAM_OGG_SEGMENTS;
+		case OGG_HEADER:
+			if (!memcmp(ogg.header.pattern, "OggS", 4)) {
+				ogg.miss = ogg.want = ogg.header.count;
+				ogg.data = ogg.segments;
+				ogg.state = OGG_SEGMENTS;
 			} else {
-				stream.ogg.state = STREAM_OGG_SYNC;
-				stream.ogg.data = NULL;
+				ogg.state = OGG_SYNC;
+				ogg.data = NULL;
 			}
 			break;
-		case STREAM_OGG_SEGMENTS:
+		case OGG_SEGMENTS:
 			// calculate size of page using lacing values
-			for (int i = 0; i < stream.ogg.want; i++) stream.ogg.miss += stream.ogg.data[i];
-			stream.ogg.want = stream.ogg.miss;
+			for (int i = 0; i < ogg.want; i++) ogg.miss += ogg.data[i];
+			ogg.want = ogg.miss;
 
-			if (stream.ogg.header.granule == 0) {
+			if (ogg.header.granule == 0) {
 				// granule 0 means a new stream, so let's look into it
-				stream.ogg.state = STREAM_OGG_PAGE;
-				stream.ogg.data = malloc(stream.ogg.want);
+				ogg.state = OGG_PAGE;
+				ogg.data = malloc(ogg.want);
 			} else {
 				// otherwise, jump over data
-				stream.ogg.state = STREAM_OGG_SYNC;
-				stream.ogg.data = NULL;
+				ogg.state = OGG_SYNC;
+				ogg.data = NULL;
 			}
 			break;
-		case STREAM_OGG_PAGE: {
+		case OGG_PAGE: {
 			u32_t offset = 0;
 
 			// try to find one of valid Ogg pattern (vorbis, opus)
 			for (char** tag = (char*[]) { "\x3vorbis", "OpusTags", NULL }; *tag; tag++, offset = 0) {
-				u32_t pos = memfind(stream.ogg.data, stream.ogg.want, *tag, strlen(*tag), &offset);
+				u32_t pos = memfind(ogg.data, ogg.want, *tag, strlen(*tag), &offset);
 				if (offset != strlen(*tag)) continue;
 				
 				// u32:len,char[]:vendorId, u32:N, N x (u32:len,char[]:comment)
-				char* p = (char*) stream.ogg.data + pos;
+				char* p = (char*) ogg.data + pos;
 				p += *p + 4;
 				u32_t count = *p;
 				p += 4;
@@ -264,8 +279,8 @@ static void stream_ogg(size_t n) {
 				LOG_INFO("Ogg metadata length: %u", stream.header_len - 3);
 				break;
 			}
-			free(stream.ogg.data);
-			stream.ogg.state = STREAM_OGG_SYNC;
+			free(ogg.data);
+			ogg.state = OGG_SYNC;
 			break;
 		}
         default: 
@@ -703,8 +718,8 @@ void stream_sock(u32_t ip, u16_t port, char codec, const char *header, size_t he
 	stream.bytes = 0;
 	stream.threshold = threshold;
     
-    stream.ogg.miss = stream.ogg.match = 0;
-	stream.ogg.state = (codec == 'o' || codec == 'p') ? STREAM_OGG_SYNC : STREAM_OGG_OFF;
+    ogg.miss = ogg.match = 0;
+	ogg.state = (codec == 'o' || codec == 'p') ? OGG_SYNC : OGG_OFF;
 
 	UNLOCK;
 }
@@ -725,8 +740,8 @@ bool stream_disconnect(void) {
 		disc = true;
 	}
 	stream.state = STOPPED;
-    if (stream.ogg.state == STREAM_OGG_PAGE && stream.ogg.data) free(stream.ogg.data);
-    stream.ogg.data = NULL;
+    if (ogg.state == OGG_PAGE && ogg.data) free(ogg.data);
+    ogg.data = NULL;
 	UNLOCK;
 	return disc;
 }