shithub: treason

Download patch

ref: 98ff0d3b979916a86e675557021c485ee07ba04b
parent: b4ab00e016ba0b1b30bc8a58698287f9e2b0afdb
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Sep 16 11:13:47 EDT 2020

add VP8/VP9 decoding

--- a/README.md
+++ b/README.md
@@ -14,6 +14,10 @@
 supported atm.  AAC audio is supported (inside and outside of a
 container).  OPUS audio is supported outside of a container.
 
+It can play VP8 and VP9, but no support for webm/matroska has been
+added yet to mcfs, so treason can only play a VP8/VP9 video stream
+muxed as IVF as of now.
+
 *It's only supposed to build and run on AMD64 for now.*
 
 More is coming. Patches are very welcome, too.
@@ -24,11 +28,13 @@
 
 	cd /tmp
 	git/clone https://git.sr.ht/~ft/dav1d
+	git/clone https://git.sr.ht/~ft/faad2
 	git/clone https://git.sr.ht/~ft/h264bsd
-	git/clone https://git.sr.ht/~ft/treason
+	git/clone https://git.sr.ht/~ft/libvpx
 	git/clone https://git.sr.ht/~ft/mcfs
-	git/clone https://git.sr.ht/~ft/faad2
-	cd dav1d/src && mk
+	git/clone https://git.sr.ht/~ft/treason
+	cd libvpx && mk
+	cd ../dav1d/src && mk
 	cd ../../h264bsd/src && mk install
 	cd ../../treason && mk install
 	cd ../mcfs && mk install
--- a/decoder.c
+++ b/decoder.c
@@ -5,7 +5,7 @@
 #include "decoder.h"
 #include "frame.h"
 
-extern Decoderops av1ops, h264ops;
+extern Decoderops av1ops, h264ops, vpxops;
 
 static struct {
 	char *name;
@@ -14,6 +14,8 @@
 }ops[] = {
 	{"AV1", &av1ops, FmtAV1},
 	{"H264", &h264ops, FmtH264},
+	{"VP8", &vpxops, FmtVP8},
+	{"VP9", &vpxops, FmtVP9},
 };
 
 Decoder *
--- a/decoder_h264.c
+++ b/decoder_h264.c
@@ -31,7 +31,6 @@
 	d = x;
 	a = d->aux;
 	lasttimestamp = 0;
-	memset(&pic, 0, sizeof(pic));
 	realh = 0;
 	for(res = 0; res >= 0 && (res = Sread(d->s, &sf)) == 0 && sf.sz > 0;){
 		off = 0;
--- /dev/null
+++ b/decoder_vpx.c
@@ -1,0 +1,104 @@
+#include <vpx_codec.h>
+#include <vpx_decoder.h>
+#include <vpx_image.h>
+#include <vp8dx.h>
+#include "frame.h"
+#include "stream.h"
+#include "decoder.h"
+#include "misc.h"
+
+#pragma lib "../libvpx/libvpx.a"
+
+typedef struct Aux Aux;
+
+struct Aux {
+	vpx_codec_ctx_t ctx;
+};
+
+static void
+decode(void *x)
+{
+	uvlong lasttimestamp;
+	Decoder *d;
+	Channel *c;
+	Frame *f;
+	Streamframe sf;
+	Aux *a;
+	int res;
+	u8int *pic;
+    vpx_codec_iter_t iter;
+    vpx_image_t *im;
+
+	threadsetname("decoder/vpx");
+	d = x;
+	a = d->aux;
+	lasttimestamp = 0;
+	memset(&pic, 0, sizeof(pic));
+	for(res = 0; res >= 0 && (res = Sread(d->s, &sf)) == 0 && sf.sz > 0;){
+		if((res = vpx_codec_decode(&a->ctx, sf.buf, sf.sz, NULL, 0)) != 0){
+			werrstr("vpx_codec_decode failed");
+			break;
+		}
+
+		for(iter = nil;;){
+			if((im = vpx_codec_get_frame(&a->ctx, &iter)) == nil)
+				break;
+
+			if((f = malloc(sizeof(*f) + im->w*im->h*3)) != nil){
+				f->w = im->w;
+				f->h = im->h;
+				yuv420_rgb24(im->w, im->h, im->planes[0], im->planes[1], im->planes[2], im->stride[0], im->stride[1], f->rgb, f->w*3);
+				f->dt = (sf.timestamp - lasttimestamp) * d->timebase * 1000000000ULL;
+				lasttimestamp = sf.timestamp;
+
+				if(sendp(d->frames, f) < 0){
+					free(f);
+					goto done;
+				}
+			}
+		}
+	}
+	if(res != 0)
+		fprint(2, "vpx: %r\n");
+
+done:
+	vpx_codec_destroy(&a->ctx);
+	free(a);
+	c = d->finished;
+	sendp(c, res == 0 ? nil : "error");
+	chanclose(c);
+
+	threadexits(nil);
+}
+
+static int
+vpxopen(Decoder *d)
+{
+	Aux *a;
+	vpx_codec_iface_t *iface;
+
+	a = calloc(1, sizeof(*a));
+	iface = d->s->fmt == FmtVP9 ? vpx_codec_vp9_dx() : vpx_codec_vp8_dx();
+
+	if(vpx_codec_dec_init(&a->ctx, iface, nil, 0) != 0){
+		werrstr("vpx_codec_dec_init failed");
+		free(a);
+		return -1;
+	}
+
+	d->aux = a;
+	proccreate(decode, d, 65536);
+
+	return 0;
+}
+
+static void
+vpxclose(Decoder *d)
+{
+	USED(d);
+}
+
+Decoderops vpxops = {
+	.open = vpxopen,
+	.close = vpxclose,
+};
--- a/mkfile
+++ b/mkfile
@@ -1,7 +1,7 @@
 </$objtype/mkfile
 
 TARG=treason
-CFLAGS=$CFLAGS -D__plan9__ -p -I../dav1d/include/dav1d -I../dav1d/src/plan9 -I../h264bsd/src
+CFLAGS=$CFLAGS -D__plan9__ -p -I../dav1d/include/dav1d -I../libvpx/vpx -I../dav1d/src/plan9 -I../h264bsd/src
 BIN=/$objtype/bin
 
 HFILES=\
@@ -14,6 +14,7 @@
 	decoder.$O\
 	decoder_av1.$O\
 	decoder_h264.$O\
+	decoder_vpx.$O\
 	main.$O\
 	misc.$O\
 	stream.$O\
--- a/stream.c
+++ b/stream.c
@@ -8,8 +8,8 @@
 	char *name;
 	Streamops *o;
 }ops[] = {
-	{"mc", &mcops},
 	{"ivf", &ivfops},
+	{"mc", &mcops},
 	{"audio", &audops},
 };