From 450d475b2bfc3e73d56580e0061a508fa67972b0 Mon Sep 17 00:00:00 2001
From: Gerhard Sittig <gerhard.sittig@gmx.net>
Date: Sat, 23 Apr 2022 15:29:09 +0200
Subject: runtc: cope with "late" samplerate announcement

The previous implementation expected a rather specific sequence of
SR_DF_HEADER with samplerate, then SR_DF_LOGIC. This worked with .sr
formatted session files. But does not work with other input formats.

Also process SR_DF_META packets. Pass any samplerate that we learn about
to decoders' .metadata() method. Defer decoders' .start() until the first
logic samples are seen. This improves robustness of the decoder tests.
---
 decoder/runtc.c | 49 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/decoder/runtc.c b/decoder/runtc.c
index f095933..f24a180 100644
--- a/decoder/runtc.c
+++ b/decoder/runtc.c
@@ -326,10 +326,16 @@ static void sr_cb(const struct sr_dev_inst *sdi,
 		const struct sr_datafeed_packet *packet, void *cb_data)
 {
 	static int samplecnt = 0;
+	static gboolean start_sent;
+
 	const struct sr_datafeed_logic *logic;
 	struct srd_session *sess;
+	const struct sr_datafeed_meta *meta;
+	struct sr_config *src;
+	GSList *l;
 	GVariant *gvar;
 	uint64_t samplerate;
+	int ret;
 	int num_samples;
 	struct sr_dev_driver *driver;
 
@@ -338,26 +344,49 @@ static void sr_cb(const struct sr_dev_inst *sdi,
 	driver = sr_dev_inst_driver_get(sdi);
 
 	switch (packet->type) {
+	case SR_DF_META:
+		DBG("Received SR_DF_META");
+		meta = packet->payload;
+		for (l = meta->config; l; l = l->next) {
+			src = l->data;
+			switch (src->key) {
+			case SR_CONF_SAMPLERATE:
+				samplerate = g_variant_get_uint64(src->data);
+				ret = srd_session_metadata_set(sess,
+					SRD_CONF_SAMPLERATE,
+					g_variant_new_uint64(samplerate));
+				if (ret != SRD_OK)
+					ERR("Setting samplerate failed (meta)");
+				break;
+			default:
+				/* EMPTY */
+				break;
+			}
+		}
+		break;
 	case SR_DF_HEADER:
 		DBG("Received SR_DF_HEADER");
 		if (sr_config_get(driver, sdi, NULL, SR_CONF_SAMPLERATE,
 				&gvar) != SR_OK) {
-			ERR("Getting samplerate failed");
+			DBG("Getting samplerate failed (SR_DF_HEADER)");
 			break;
 		}
 		samplerate = g_variant_get_uint64(gvar);
 		g_variant_unref(gvar);
-		if (srd_session_metadata_set(sess, SRD_CONF_SAMPLERATE,
-				g_variant_new_uint64(samplerate)) != SRD_OK) {
-			ERR("Setting samplerate failed");
-			break;
-		}
-		if (srd_session_start(sess) != SRD_OK) {
-			ERR("Session start failed");
-			break;
-		}
+		ret = srd_session_metadata_set(sess, SRD_CONF_SAMPLERATE,
+			g_variant_new_uint64(samplerate));
+		if (ret != SRD_OK)
+			ERR("Setting samplerate failed (header)");
 		break;
 	case SR_DF_LOGIC:
+		DBG("Received SR_DF_LOGIC");
+		if (!start_sent) {
+			if (srd_session_start(sess) != SRD_OK) {
+				ERR("Session start failed");
+				break;
+			}
+			start_sent = TRUE;
+		}
 		logic = packet->payload;
 		num_samples = logic->length / logic->unitsize;
 		DBG("Received SR_DF_LOGIC (%"PRIu64" bytes, unitsize = %d).",
-- 
cgit v1.2.3-70-g09d2