From 9a3250d82c0b6adef7c199e6bc0158151510608a Mon Sep 17 00:00:00 2001
From: Julian Rother <julianr@fsmpi.rwth-aachen.de>
Date: Wed, 1 Nov 2017 17:41:59 +0100
Subject: [PATCH] Added probe worker

---
 probe.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)
 create mode 100644 probe.c

diff --git a/probe.c b/probe.c
new file mode 100644
index 0000000..2b6b01e
--- /dev/null
+++ b/probe.c
@@ -0,0 +1,91 @@
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include "util.h"
+#include "config.h"
+
+static char *getxmlattr(xmlAttr *a, char *name, char *err)
+{
+	for (; a && strcmp(a->name, name); a = a->next);
+	if (!a)
+		return err;
+	return a->children->content;
+}
+
+char *get_xmpchapters(char *xmp)
+{
+	int i, len, maxlen;
+	char *out;
+	xmlDocPtr doc;
+	xmlXPathContextPtr xpath;
+	xmlXPathObjectPtr res;
+	xmlNodePtr node;
+	double framerate, start;
+	if (!(doc = xmlParseMemory(xmp, strlen(xmp))))
+		return "";
+	if (!(xpath = xmlXPathNewContext(doc)))
+		return "";
+	xmlXPathRegisterNs(xpath, "x", "adobe:ns:meta/");
+	xmlXPathRegisterNs(xpath, "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+	xmlXPathRegisterNs(xpath, "xmpDM", "http://ns.adobe.com/xmp/1.0/DynamicMedia/");
+	res = xmlXPathEvalExpression("/x:xmpmeta/rdf:RDF/rdf:Description/@xmpDM:videoFrameRate", xpath);
+	if (!res || !res->nodesetval->nodeNr)
+		return "";
+	framerate = strtod(res->nodesetval->nodeTab[0]->children->content, 0);
+	xmlXPathFreeObject(res);
+	res = xmlXPathEvalExpression("/x:xmpmeta/rdf:RDF/rdf:Description/xmpDM:Tracks/rdf:Bag/rdf:li/rdf:Description/xmpDM:markers/rdf:Seq/rdf:li/rdf:Description", xpath);
+	if (!res || !res->nodesetval)
+		return "";
+	len = 0; maxlen = res->nodesetval->nodeNr*200;
+	out = malloc(maxlen);
+	len += xsnprintf(out+len, maxlen-len-1, "[");
+	for (i = 0; i < res->nodesetval->nodeNr; i ++)
+	{
+		start = atoi(getxmlattr(res->nodesetval->nodeTab[i]->properties, "startTime", "0"))/framerate;
+		if (i)
+			len += xsnprintf(out+len, maxlen-len-1, ",");
+		len += xsnprintf(out+len, maxlen-len-1, "{\"time\": %f, \"text\": \"%s\"}",
+				start, jescape(getxmlattr(res->nodesetval->nodeTab[i]->properties, "name", "")));
+	}
+	len += xsnprintf(out+len, maxlen-len-1, "]");
+	return out;
+}
+
+int main(int argc, char *argv[])
+{
+	int jobid;
+	char path[100], *xmp;
+	AVFormatContext *demux, *mux;
+	AVDictionaryEntry *tag;
+	AVDictionary *opts;
+	if (argc != 5)
+		return 1;
+	av_register_all();
+	av_log_set_callback(avlogbuf_callback);
+
+	jobid = atoi(argv[1]);
+	xsnprintf(BL(path), "%s/%s", CONFIG_VIDEOS_RAW,
+			jstr(jlookup(argv[4], "path"), ""));
+	ping_job(jobid, "running", 0);
+
+	opts = 0;
+	av_dict_set_int(&opts, "export_xmp", 1, 0);
+	demux = 0;
+	if (avformat_open_input(&demux, path, 0, &opts))
+		goto fail;
+	avformat_find_stream_info(demux, 0);
+	if (tag = av_dict_get(demux->metadata, "xmp", 0, 0))
+		ping_job(jobid, "finished", "{\"xmp_chapters\": %s, \"duration\": %f, \"log\": \"%s\"}", get_xmpchapters(tag->value), demux->duration*av_q2d(AV_TIME_BASE_Q), get_avlogbuf());
+	else
+		ping_job(jobid, "finished", "{\"duration\": %f, \"log\": \"%s\"}", demux->duration*av_q2d(AV_TIME_BASE_Q), get_avlogbuf());
+	return 0;
+
+fail:
+	ping_job(jobid, "failed", "{\"log\": \"%s\"}", get_avlogbuf());
+	return 1;
+}
-- 
GitLab