shithub: dav1d

Download patch

ref: 0c9a16c6708ef4ba53f753ec322e3404c5754ac7
parent: 5fe20ec7dd89c88453a61cd47d5d01e49d6cc6c2
author: Sigrid Haflínudóttir <[email protected]>
date: Fri Aug 28 10:24:31 EDT 2020

port to Plan 9

diff: cannot open b/src/plan9//null: file does not exist: 'b/src/plan9//null'
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@
 .DS_Store
 /tests/dav1d-test-data
 *.snap
+*.6
+6.*
--- a/include/common/dump.h
+++ b/include/common/dump.h
@@ -30,7 +30,9 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#ifndef __plan9__
 #include <stdio.h>
+#endif
 
 #include "common/bitdepth.h"
 
--- a/include/common/validate.h
+++ b/include/common/validate.h
@@ -28,8 +28,10 @@
 #ifndef DAV1D_COMMON_VALIDATE_H
 #define DAV1D_COMMON_VALIDATE_H
 
+#ifndef __plan9__
 #include <stdio.h>
 #include <stdlib.h>
+#endif
 
 #if defined(NDEBUG)
 #define debug_abort()
--- a/include/dav1d/data.h
+++ b/include/dav1d/data.h
@@ -39,6 +39,7 @@
     struct Dav1dRef *ref; ///< allocation origin
     Dav1dDataProps m; ///< user provided metadata passed to the output picture
 } Dav1dData;
+#pragma incomplete Dav1dData
 
 /**
  * Allocate data.
@@ -89,11 +90,12 @@
  *
  * @return 0 on success. A negative DAV1D_ERR value on error.
  */
-DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,
-                                        const uint8_t *user_data,
-                                        void (*free_callback)(const uint8_t *user_data,
-                                                              void *cookie),
-                                        void *cookie);
+DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *buf,
+                              const uint8_t *const user_data,
+                              void (*const free_callback)(const uint8_t *user_data,
+                                                          void *cookie),
+                              void *const cookie);
+
 
 /**
  * Free the data reference.
--- a/include/dav1d/dav1d.h
+++ b/include/dav1d/dav1d.h
@@ -41,12 +41,14 @@
 #include "version.h"
 
 typedef struct Dav1dContext Dav1dContext;
+#pragma incomplete Dav1dContext
 typedef struct Dav1dRef Dav1dRef;
+#pragma incomplete Dav1dRef
 
 #define DAV1D_MAX_FRAME_THREADS 256
 #define DAV1D_MAX_TILE_THREADS 64
 
-typedef struct Dav1dLogger {
+typedef struct {
     void *cookie; ///< Custom data to pass to the callback.
     /**
      * Logger callback. May be NULL to disable logging.
@@ -57,8 +59,9 @@
      */
     void (*callback)(void *cookie, const char *format, va_list ap);
 } Dav1dLogger;
+#pragma incomplete Dav1dLogger
 
-typedef struct Dav1dSettings {
+typedef struct {
     int n_frame_threads;
     int n_tile_threads;
     int apply_grain;
@@ -69,6 +72,7 @@
     Dav1dPicAllocator allocator; ///< Picture allocator callback.
     Dav1dLogger logger; ///< Logger callback.
 } Dav1dSettings;
+#pragma incomplete Dav1dSettings
 
 /**
  * Get library version.
--- a/include/dav1d/picture.h
+++ b/include/dav1d/picture.h
@@ -39,7 +39,7 @@
  * instructions. */
 #define DAV1D_PICTURE_ALIGNMENT 64
 
-typedef struct Dav1dPictureParameters {
+typedef struct {
     int w; ///< width (in pixels)
     int h; ///< height (in pixels)
     enum Dav1dPixelLayout layout; ///< format of the picture
@@ -46,7 +46,7 @@
     int bpc; ///< bits per pixel component (8 or 10)
 } Dav1dPictureParameters;
 
-typedef struct Dav1dPicture {
+typedef struct {
     Dav1dSequenceHeader *seq_hdr;
     Dav1dFrameHeader *frame_hdr;
 
@@ -94,8 +94,9 @@
 
     void *allocator_data; ///< pointer managed by the allocator
 } Dav1dPicture;
+#pragma incomplete Dav1dPicture
 
-typedef struct Dav1dPicAllocator {
+typedef struct {
     void *cookie; ///< custom data to pass to the allocator callbacks.
     /**
      * Allocate the picture buffer based on the Dav1dPictureParameters.
@@ -135,6 +136,7 @@
      */
     void (*release_picture_callback)(Dav1dPicture *pic, void *cookie);
 } Dav1dPicAllocator;
+#pragma incomplete Dav1dPicAllocator
 
 /**
  * Release reference to a picture.
--- /dev/null
+++ b/src/av19.c
@@ -1,0 +1,56 @@
+#include "dav1d.h"
+#include "tools/input/input.h"
+
+int mainstacksize = 65536*8;
+
+void
+threadmain(int argc, char **argv)
+{
+	Dav1dSettings av1s;
+	Dav1dContext *c;
+	Dav1dPicture *p;
+	Dav1dData data;
+	DemuxerContext *dc;
+	unsigned fps[2], timebase[2], total;
+	int res;
+
+	if(argc != 2)
+		sysfatal("usage");
+
+	dav1d_default_settings(&av1s);
+	c = nil;
+	if(input_open(&dc, "ivf", argv[1], fps, &total, timebase) < 0)
+		sysfatal("input_open");
+	av1s.n_frame_threads = 1;
+	av1s.n_tile_threads = 1;
+	if(dav1d_open(&c, &av1s) != 0)
+		sysfatal("dav1d_open");
+
+	//print("%d %d %d %d %d\n", fps[0], fps[1], timebase[0], timebase[1], total);
+
+	if(input_read(dc, &data) < 0)
+		sysfatal("input_read");
+
+	do{
+		fprint(2, "sending\n");
+		res = dav1d_send_data(c, &data);
+		fprint(2, "sent, res is %d\n", res);
+		if(res < 0 && res != DAV1D_ERR(EAGAIN))
+			sysfatal("dav1d_send_data: %d", res);
+		fprint(2, "getting a picture\n");
+		p = calloc(1, sizeof(*p));
+		if((res = dav1d_get_picture(c, p)) < 0){
+			if(res != DAV1D_ERR(EAGAIN))
+				sysfatal("dav1d_get_picture");
+		}
+		free(p);
+		
+	}while(data.sz > 0 || input_read(dc, &data) == 0);
+
+	if(data.sz > 0)
+		dav1d_data_unref(&data);
+
+	/* get more pics here? */
+
+	threadexitsall(nil);
+}
--- a/src/cdef_apply_tmpl.c
+++ b/src/cdef_apply_tmpl.c
@@ -182,7 +182,7 @@
                     backup2x8(lr_bak[!bit], bptrs, f->cur.stride, 8, layout, flag);
                 }
 
-                int dir;
+                int dir = 0;
                 unsigned variance;
                 if (y_pri_lvl || uv_pri_lvl)
                     dir = dsp->cdef.dir(bptrs[0], f->cur.stride[0],
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -4091,8 +4091,10 @@
         dst->coef = av1_default_coef_cdf[src->data.qcat];
         memcpy(dst->mv.joint, default_mv_joint_cdf, sizeof(default_mv_joint_cdf));
         memcpy(dst->dmv.joint, default_mv_joint_cdf, sizeof(default_mv_joint_cdf));
-        dst->mv.comp[0] = dst->mv.comp[1] = dst->dmv.comp[0] = dst->dmv.comp[1] =
-            default_mv_component_cdf;
+        dst->mv.comp[0] = default_mv_component_cdf;
+        dst->mv.comp[1] = default_mv_component_cdf;
+        dst->dmv.comp[0] = default_mv_component_cdf;
+        dst->dmv.comp[1] = default_mv_component_cdf;
     }
 }
 
--- a/src/data.c
+++ b/src/data.c
@@ -71,7 +71,7 @@
     return 0;
 }
 
-int dav1d_data_wrap_user_data_internal(Dav1dData *const buf,
+int dav1d_data_wrap_user_data_internal(Dav1dData *buf,
                                        const uint8_t *const user_data,
                                        void (*const free_callback)(const uint8_t *user_data,
                                                                    void *cookie),
@@ -134,7 +134,7 @@
     props->user_data.ref = NULL;
 }
 
-void dav1d_data_unref_internal(Dav1dData *const buf) {
+void dav1d_data_unref_internal(Dav1dData *buf) {
     validate_input(buf != NULL);
 
     struct Dav1dRef *user_data_ref = buf->m.user_data.ref;
--- a/src/data.h
+++ b/src/data.h
@@ -31,6 +31,7 @@
 #include "dav1d/data.h"
 
 void dav1d_data_ref(Dav1dData *dst, const Dav1dData *src);
+void dav1d_data_unref(Dav1dData *buf);
 
 /**
  * Move a data reference.
--- a/src/decode.c
+++ b/src/decode.c
@@ -30,7 +30,9 @@
 #include <errno.h>
 #include <limits.h>
 #include <string.h>
+#ifndef __plan9__
 #include <stdio.h>
+#endif
 #include <inttypes.h>
 
 #include "dav1d/data.h"
@@ -698,6 +700,7 @@
                     const enum BlockPartition bp,
                     const enum EdgeFlags intra_edge_flags)
 {
+	static int decode_b_index = 0;
     Dav1dTileState *const ts = t->ts;
     const Dav1dFrameContext *const f = t->f;
     Av1Block b_mem, *const b = f->frame_thread.pass ?
@@ -716,6 +719,7 @@
                            (bw4 > ss_hor || t->bx & 1) &&
                            (bh4 > ss_ver || t->by & 1);
 
+	fprintf(stderr, "decode_b %d\n", decode_b_index++);
     if (f->frame_thread.pass == 2) {
         if (b->intra) {
             f->bd_fn.recon_b_intra(t, bs, intra_edge_flags, b);
@@ -884,10 +888,14 @@
     }
 
     // skip_mode
+    if(seg)
+		fprintf(stderr, "%d %d %d\n", seg->globalmv, seg->ref, seg->skip);
+	fprintf(stderr, "%d %d\n", f->frame_hdr->skip_mode_enabled, imin(bw4, bh4));
     if ((!seg || (!seg->globalmv && seg->ref == -1 && !seg->skip)) &&
         f->frame_hdr->skip_mode_enabled && imin(bw4, bh4) > 1)
     {
         const int smctx = t->a->skip_mode[bx4] + t->l.skip_mode[by4];
+		fprintf(stderr, "smctx=%d\n", smctx);
         b->skip_mode = dav1d_msac_decode_bool_adapt(&ts->msac,
                            ts->cdf.m.skip_mode[smctx]);
         if (DEBUG_BLOCK_INFO)
@@ -1032,7 +1040,7 @@
             init_quant_tables(f->seq_hdr, f->frame_hdr, ts->last_qidx, ts->dqmem);
             ts->dq = ts->dqmem;
         }
-        if (!memcmp(ts->last_delta_lf, (int8_t[4]) { 0, 0, 0, 0 }, 4)) {
+        if (!memcmp(ts->last_delta_lf, "\0\0\0\0", 4)) {
             // assign frame-wide lf values to this sb
             ts->lflvl = f->lf.lvl;
         } else if (memcmp(ts->last_delta_lf, prev_delta_lf, 4)) {
@@ -1042,14 +1050,17 @@
         }
     }
 
+	fprintf(stderr, "skip=%d frame_type=%d\n", b->skip_mode, f->frame_hdr->frame_type);
     if (b->skip_mode) {
         b->intra = 0;
     } else if (f->frame_hdr->frame_type & 1) {
+    	fprintf(stderr, "seg: %d\n", seg && (seg->ref >= 0 || seg->globalmv));
         if (seg && (seg->ref >= 0 || seg->globalmv)) {
             b->intra = !seg->ref;
         } else {
             const int ictx = get_intra_ctx(t->a, &t->l, by4, bx4,
                                            have_top, have_left);
+			fprintf(stderr, "ictx=%d\n", ictx);
             b->intra = !dav1d_msac_decode_bool_adapt(&ts->msac,
                             ts->cdf.m.intra[ictx]);
             if (DEBUG_BLOCK_INFO)
@@ -1209,6 +1220,7 @@
             if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE && t_dim->max > TX_4X4) {
                 const int tctx = get_tx_ctx(t->a, &t->l, t_dim, by4, bx4);
                 uint16_t *const tx_cdf = ts->cdf.m.txsz[t_dim->max - 1][tctx];
+                fprintf(stderr, "==> %d %d\n", t_dim->max - 1, tctx);
                 int depth = dav1d_msac_decode_symbol_adapt4(&ts->msac, tx_cdf,
                                 imin(t_dim->max, 2));
 
@@ -1301,8 +1313,9 @@
         // intra block copy
         refmvs_candidate mvstack[8];
         int n_mvs, ctx;
+        union refmvs_refpair ref0 = { .ref = { 0, -1 }};
         dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
-                          (union refmvs_refpair) { .ref = { 0, -1 }},
+                          ref0,
                           bs, intra_edge_flags, t->by, t->bx);
 
         if (mvstack[0].mv.mv[0].n)
@@ -1425,6 +1438,7 @@
         {
             const int ctx = get_comp_ctx(t->a, &t->l, by4, bx4,
                                          have_top, have_left);
+			fprintf(stderr, "comp_ctx=%d\n", ctx);
             is_comp = dav1d_msac_decode_bool_adapt(&ts->msac,
                           ts->cdf.m.comp[ctx]);
             if (DEBUG_BLOCK_INFO)
@@ -1443,9 +1457,10 @@
 
             refmvs_candidate mvstack[8];
             int n_mvs, ctx;
+            union refmvs_refpair ref = { .ref = {
+                                    b->ref[0] + 1, b->ref[1] + 1 }};
             dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
-                              (union refmvs_refpair) { .ref = {
-                                    b->ref[0] + 1, b->ref[1] + 1 }},
+                              ref,
                               bs, intra_edge_flags, t->by, t->bx);
 
             b->mv[0] = mvstack[0].mv.mv[0];
@@ -1459,6 +1474,7 @@
         } else if (is_comp) {
             const int dir_ctx = get_comp_dir_ctx(t->a, &t->l, by4, bx4,
                                                  have_top, have_left);
+		fprintf(stderr, "dir_ctx=%d\n", dir_ctx);
             if (dav1d_msac_decode_bool_adapt(&ts->msac,
                     ts->cdf.m.comp_dir[dir_ctx]))
             {
@@ -1521,9 +1537,9 @@
 
             refmvs_candidate mvstack[8];
             int n_mvs, ctx;
+            union refmvs_refpair ref = { .ref = { b->ref[0] + 1, b->ref[1] + 1 }};
             dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
-                              (union refmvs_refpair) { .ref = {
-                                    b->ref[0] + 1, b->ref[1] + 1 }},
+                              ref,
                               bs, intra_edge_flags, t->by, t->bx);
 
             b->inter_mode = dav1d_msac_decode_symbol_adapt8(&ts->msac,
@@ -1600,6 +1616,7 @@
             int is_segwedge = 0;
             if (f->seq_hdr->masked_compound) {
                 const int mask_ctx = get_mask_comp_ctx(t->a, &t->l, by4, bx4);
+                fprintf(stderr, "mask_ctx=%d\n", mask_ctx);
 
                 is_segwedge = dav1d_msac_decode_bool_adapt(&ts->msac,
                                   ts->cdf.m.mask_comp[mask_ctx]);
@@ -1616,6 +1633,7 @@
                                          f->refp[b->ref[0]].p.frame_hdr->frame_offset,
                                          f->refp[b->ref[1]].p.frame_hdr->frame_offset,
                                          t->a, &t->l, by4, bx4);
+		fprintf(stderr, "jnt_ctx=%d %d %d %d\n", jnt_ctx, f->cur.frame_hdr->frame_offset, f->refp[b->ref[0]].p.frame_hdr->frame_offset, f->refp[b->ref[1]].p.frame_hdr->frame_offset);
                     b->comp_type = COMP_INTER_WEIGHTED_AVG +
                                    dav1d_msac_decode_bool_adapt(&ts->msac,
                                        ts->cdf.m.jnt_comp[jnt_ctx]);
@@ -1696,8 +1714,9 @@
 
             refmvs_candidate mvstack[8];
             int n_mvs, ctx;
+            union refmvs_refpair ref = { .ref = { b->ref[0] + 1, -1 }};
             dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
-                              (union refmvs_refpair) { .ref = { b->ref[0] + 1, -1 }},
+                              ref,
                               bs, intra_edge_flags, t->by, t->bx);
 
             // mode parsing and mv derivation from ref_mvs
@@ -1877,6 +1896,7 @@
                 const int comp = b->comp_type != COMP_INTER_NONE;
                 const int ctx1 = get_filter_ctx(t->a, &t->l, comp, 0, b->ref[0],
                                                 by4, bx4);
+				fprintf(stderr, "ctx1=%d\n", ctx1);
                 filter[0] = dav1d_msac_decode_symbol_adapt4(&ts->msac,
                                ts->cdf.m.filter[0][ctx1],
                                DAV1D_N_SWITCHABLE_FILTERS - 1);
@@ -1935,9 +1955,9 @@
 
         // context updates
         if (is_comp) {
-            splat_tworef_mv(&t->rt, t->by, t->bx, bs, b->inter_mode,
-                            (refmvs_refpair) { .ref = { b->ref[0], b->ref[1] }},
-                            (refmvs_mvpair) { .mv = { [0] = b->mv[0], [1] = b->mv[1] }});
+            refmvs_refpair ref = { .ref = { b->ref[0], b->ref[1] }};
+            refmvs_mvpair mv = { .mv = { [0] = b->mv[0], [1] = b->mv[1] }};
+            splat_tworef_mv(&t->rt, t->by, t->bx, bs, b->inter_mode, ref, mv);
         } else {
             splat_oneref_mv(&t->rt, t->by, t->bx, bs, b->inter_mode,
                             b->ref[0], b->mv[0], b->interintra_type);
@@ -1957,7 +1977,7 @@
         rep_macro(type, t->dir filter[1], off, mul * filter[1]); \
         rep_macro(type, t->dir mode, off, mul * b->inter_mode); \
         rep_macro(type, t->dir ref[0], off, mul * b->ref[0]); \
-        rep_macro(type, t->dir ref[1], off, mul * ((uint8_t) b->ref[1]))
+        rep_macro(type, t->dir ref[1], off, mul * b->ref[1])
         case_set(bh4, l., 1, by4);
         case_set(bw4, a->, 0, bx4);
 #undef set_ctx
@@ -2373,10 +2393,10 @@
         &f->frame_thread.pal_idx[(size_t)tile_start_off * size_mul[1] / 4] :
         NULL;
 
-    ts->frame_thread.cf = f->frame_thread.cf ?
+    ts->frame_thread.cf = (void*)(f->frame_thread.cf ?
         (uint8_t*)f->frame_thread.cf +
             (((size_t)tile_start_off * size_mul[0]) >> !f->seq_hdr->hbd) :
-        NULL;
+        NULL);
 
     dav1d_cdf_thread_copy(&ts->cdf, &f->in_cdf);
     ts->last_qidx = f->frame_hdr->quant.yac;
@@ -2514,6 +2534,7 @@
     const int col_sb_start = f->frame_hdr->tiling.col_start_sb[tile_col];
     const int col_sb128_start = col_sb_start >> !f->seq_hdr->sb128;
 
+	fprintf(stderr, "%d %d %d %d %d\n", root_bl, sb_step, tile_row, col_sb_start, col_sb128_start);
     if ((f->frame_hdr->frame_type & 1) || f->frame_hdr->allow_intrabc) {
         dav1d_refmvs_tile_sbrow_init(&t->rt, &f->rf, ts->tiling.col_start,
                                      ts->tiling.col_end, ts->tiling.row_start,
@@ -2520,7 +2541,6 @@
                                      ts->tiling.row_end, t->by >> f->sb_shift,
                                      ts->tiling.row);
     }
-
     reset_context(&t->l, !(f->frame_hdr->frame_type & 1), f->frame_thread.pass);
     if (f->frame_thread.pass == 2) {
         for (t->bx = ts->tiling.col_start,
@@ -2537,7 +2557,7 @@
         f->bd_fn.backup_ipred_edge(t);
         return 0;
     }
-
+	fprintf(stderr, "%d\n", ts->msac.cnt);
     // error out on symbol decoder overread
     if (ts->msac.cnt < -15) return 1;
 
@@ -2833,24 +2853,24 @@
 
         ptr += 32;
         if (y_stride < 0) {
-            f->lf.cdef_line[0][0] = ptr - y_stride * 1;
-            f->lf.cdef_line[1][0] = ptr - y_stride * 3;
+            f->lf.cdef_line[0][0] = (void*)(ptr - y_stride * 1);
+            f->lf.cdef_line[1][0] = (void*)(ptr - y_stride * 3);
             ptr -= y_stride * 4;
         } else {
-            f->lf.cdef_line[0][0] = ptr + y_stride * 0;
-            f->lf.cdef_line[1][0] = ptr + y_stride * 2;
+            f->lf.cdef_line[0][0] = (void*)(ptr + y_stride * 0);
+            f->lf.cdef_line[1][0] = (void*)(ptr + y_stride * 2);
             ptr += y_stride * 4;
         }
         if (uv_stride < 0) {
-            f->lf.cdef_line[0][1] = ptr - uv_stride * 1;
-            f->lf.cdef_line[0][2] = ptr - uv_stride * 3;
-            f->lf.cdef_line[1][1] = ptr - uv_stride * 5;
-            f->lf.cdef_line[1][2] = ptr - uv_stride * 7;
+            f->lf.cdef_line[0][1] = (void*)(ptr - uv_stride * 1);
+            f->lf.cdef_line[0][2] = (void*)(ptr - uv_stride * 3);
+            f->lf.cdef_line[1][1] = (void*)(ptr - uv_stride * 5);
+            f->lf.cdef_line[1][2] = (void*)(ptr - uv_stride * 7);
         } else {
-            f->lf.cdef_line[0][1] = ptr + uv_stride * 0;
-            f->lf.cdef_line[0][2] = ptr + uv_stride * 2;
-            f->lf.cdef_line[1][1] = ptr + uv_stride * 4;
-            f->lf.cdef_line[1][2] = ptr + uv_stride * 6;
+            f->lf.cdef_line[0][1] = (void*)(ptr + uv_stride * 0);
+            f->lf.cdef_line[0][2] = (void*)(ptr + uv_stride * 2);
+            f->lf.cdef_line[1][1] = (void*)(ptr + uv_stride * 4);
+            f->lf.cdef_line[1][2] = (void*)(ptr + uv_stride * 6);
         }
 
         f->lf.cdef_line_sz[0] = (int) y_stride;
@@ -2867,7 +2887,7 @@
         }
 
         for (int pl = 0; pl <= 2; pl++) {
-            f->lf.lr_lpf_line[pl] = lr_ptr;
+            f->lf.lr_lpf_line[pl] = (void*)lr_ptr;
             lr_ptr += lr_line_sz * 12;
         }
 
@@ -2920,20 +2940,20 @@
         dav1d_calc_eih(&f->lf.lim_lut, f->frame_hdr->loopfilter.sharpness);
         f->lf.last_sharpness = f->frame_hdr->loopfilter.sharpness;
     }
-    dav1d_calc_lf_values(f->lf.lvl, f->frame_hdr, (int8_t[4]) { 0, 0, 0, 0 });
+    dav1d_calc_lf_values(f->lf.lvl, f->frame_hdr, "\0\0\0\0");
     memset(f->lf.mask, 0, sizeof(*f->lf.mask) * num_sb128);
 
     const int ipred_edge_sz = f->sbh * f->sb128w << hbd;
     if (ipred_edge_sz != f->ipred_edge_sz) {
         dav1d_freep_aligned(&f->ipred_edge[0]);
-        uint8_t *ptr = f->ipred_edge[0] =
-            dav1d_alloc_aligned(ipred_edge_sz * 128 * 3, 32);
+        uint8_t *ptr = dav1d_alloc_aligned(ipred_edge_sz * 128 * 3, 32);
         if (!ptr) {
             f->ipred_edge_sz = 0;
             goto error;
         }
-        f->ipred_edge[1] = ptr + ipred_edge_sz * 128 * 1;
-        f->ipred_edge[2] = ptr + ipred_edge_sz * 128 * 2;
+        f->ipred_edge[0] = (void*)ptr;
+        f->ipred_edge[1] = (void*)(ptr + ipred_edge_sz * 128 * 1);
+        f->ipred_edge[2] = (void*)(ptr + ipred_edge_sz * 128 * 2);
         f->ipred_edge_sz = ipred_edge_sz;
     }
 
@@ -2975,9 +2995,11 @@
     if (f->frame_hdr->switchable_comp_refs) {
         for (int i = 0; i < 7; i++) {
             const unsigned ref0poc = f->refp[i].p.frame_hdr->frame_offset;
+            fprintf(stderr, "ref0poc=%u\n", ref0poc);
 
             for (int j = i + 1; j < 7; j++) {
                 const unsigned ref1poc = f->refp[j].p.frame_hdr->frame_offset;
+            fprintf(stderr, "ref1poc=%u\n", ref1poc);
 
                 const unsigned d1 =
                     imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref0poc,
@@ -2986,6 +3008,7 @@
                     imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref1poc,
                                           f->cur.frame_hdr->frame_offset)), 31);
                 const int order = d0 <= d1;
+            fprintf(stderr, "d0=%u d1=%u\n", d0, d1);
 
                 static const uint8_t quant_dist_weight[3][2] = {
                     { 2, 3 }, { 2, 5 }, { 2, 7 }
@@ -3110,7 +3133,7 @@
                     for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
                         t->ts = &f->ts[tile_row * f->frame_hdr->tiling.cols + tile_col];
 
-                        if (dav1d_decode_tile_sbrow(t)) goto error;
+                        if (dav1d_decode_tile_sbrow(t)) { fprintf(stderr, "dav1d_decode_tile_sbrow failed\n"); goto error; }
                     }
                     if (f->frame_thread.pass <= 1 && f->frame_hdr->frame_type & 1) {
                         dav1d_refmvs_save_tmvs(&t->rt, 0, f->bw >> 1, t->by >> 1, by_end);
@@ -3208,10 +3231,10 @@
                 ts->frame_thread.pal_idx = f->frame_thread.pal_idx ?
                     &f->frame_thread.pal_idx[tile_start_off * size_mul[1] / 4] :
                     NULL;
-                ts->frame_thread.cf = f->frame_thread.cf ?
+                ts->frame_thread.cf = (void*)(f->frame_thread.cf ?
                     (uint8_t*)f->frame_thread.cf +
                         ((tile_start_off * size_mul[0]) >> !f->seq_hdr->hbd) :
-                    NULL;
+                    NULL);
                 if (f->n_tc > 0) {
                     const unsigned row_sb_start =
                         f->frame_hdr->tiling.row_start_sb[ts->tiling.row];
@@ -3597,7 +3620,7 @@
                     dav1d_ref_dec(&c->refs[i].refmvs);
                 }
             }
-            return res;
+           return res;
         }
     } else {
         pthread_cond_signal(&f->frame_thread.td.cond);
--- a/src/env.h
+++ b/src/env.h
@@ -72,12 +72,18 @@
     }
 }
 
+static inline int RET(int x) {
+	fprintf(stderr, "XX~~> %d\n", x);
+	return x;
+}
+
 static inline int get_tx_ctx(const BlockContext *const a,
                              const BlockContext *const l,
                              const TxfmInfo *const max_tx,
                              const int yb4, const int xb4)
 {
-    return (l->tx_intra[yb4] >= max_tx->lh) + (a->tx_intra[xb4] >= max_tx->lw);
+	fprintf(stderr, "~~> %d %d %d %d %d %d\n", (int)l->tx_intra[yb4], max_tx->lh, a->tx_intra[xb4], max_tx->lw, yb4, xb4);
+    return ((int)l->tx_intra[yb4] >= (int)max_tx->lh) + ((int)a->tx_intra[xb4] >= (int)max_tx->lw);
 }
 
 static inline int get_partition_ctx(const BlockContext *const a,
@@ -165,19 +171,19 @@
                     return 4;
                 } else {
                     // 4U means intra (-1) or bwd (>= 4)
-                    return 2 + ((unsigned)l->ref[0][yb4] >= 4U);
+                    return RET(2 + ((unsigned)l->ref[0][yb4] >= 4U));
                 }
             } else if (l->comp_type[yb4]) {
                 // 4U means intra (-1) or bwd (>= 4)
-                return 2 + ((unsigned)a->ref[0][xb4] >= 4U);
+                return RET(2 + ((unsigned)a->ref[0][xb4] >= 4U));
             } else {
-                return (l->ref[0][yb4] >= 4) ^ (a->ref[0][xb4] >= 4);
+                return RET((l->ref[0][yb4] >= 4) ^ (a->ref[0][xb4] >= 4));
             }
         } else {
-            return a->comp_type[xb4] ? 3 : a->ref[0][xb4] >= 4;
+            return RET(a->comp_type[xb4] ? 3 : a->ref[0][xb4] >= 4);
         }
     } else if (have_left) {
-        return l->comp_type[yb4] ? 3 : l->ref[0][yb4] >= 4;
+        return RET(l->comp_type[yb4] ? 3 : l->ref[0][yb4] >= 4);
     } else {
         return 1;
     }
@@ -200,7 +206,7 @@
             const int off = a_intra ? yb4 : xb4;
 
             if (edge->comp_type[off] == COMP_INTER_NONE) return 2;
-            return 1 + 2 * has_uni_comp(edge, off);
+            return RET(1 + 2 * has_uni_comp(edge, off));
         }
 
         const int a_comp = a->comp_type[xb4] != COMP_INTER_NONE;
@@ -208,19 +214,19 @@
         const int a_ref0 = a->ref[0][xb4], l_ref0 = l->ref[0][yb4];
 
         if (!a_comp && !l_comp) {
-            return 1 + 2 * ((a_ref0 >= 4) == (l_ref0 >= 4));
+            return RET(1 + 2 * ((a_ref0 >= 4) == (l_ref0 >= 4)));
         } else if (!a_comp || !l_comp) {
             const BlockContext *const edge = a_comp ? a : l;
             const int off = a_comp ? xb4 : yb4;
 
             if (!has_uni_comp(edge, off)) return 1;
-            return 3 + ((a_ref0 >= 4) == (l_ref0 >= 4));
+            return RET(3 + ((a_ref0 >= 4) == (l_ref0 >= 4)));
         } else {
             const int a_uni = has_uni_comp(a, xb4), l_uni = has_uni_comp(l, yb4);
 
             if (!a_uni && !l_uni) return 0;
             if (!a_uni || !l_uni) return 2;
-            return 3 + ((a_ref0 == 4) == (l_ref0 == 4));
+            return RET(3 + ((a_ref0 == 4) == (l_ref0 == 4)));
         }
     } else if (have_top || have_left) {
         const BlockContext *const edge = have_left ? l : a;
@@ -228,7 +234,7 @@
 
         if (edge->intra[off]) return 2;
         if (edge->comp_type[off] == COMP_INTER_NONE) return 2;
-        return 4 * has_uni_comp(edge, off);
+        return RET(4 * has_uni_comp(edge, off));
     } else {
         return 2;
     }
@@ -257,6 +263,8 @@
                       a->ref[0][xb4] == 6;
     const int l_ctx = l->comp_type[yb4] >= COMP_INTER_AVG ||
                       l->ref[0][yb4] == 6;
+	fprintf(stderr, "40~~> %d\n", a_ctx);
+	fprintf(stderr, "41~~> %d\n", l_ctx);
 
     return 3 * offset + a_ctx + l_ctx;
 }
@@ -269,6 +277,8 @@
                       a->ref[0][xb4] == 6 ? 3 : 0;
     const int l_ctx = l->comp_type[yb4] >= COMP_INTER_SEG ? 1 :
                       l->ref[0][yb4] == 6 ? 3 : 0;
+	fprintf(stderr, "30~~> %d\n", a_ctx);
+	fprintf(stderr, "31~~> %d\n", l_ctx);
 
     return imin(a_ctx + l_ctx, 5);
 }
@@ -289,12 +299,16 @@
     int cnt[2] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "20~~> %d\n", a->ref[0][xb4] >= 4);
         cnt[a->ref[0][xb4] >= 4]++;
+		fprintf(stderr, "21~~> %d\n", a->ref[1][xb4] >= 4);
         if (a->comp_type[xb4]) cnt[a->ref[1][xb4] >= 4]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "22~~> %d\n", l->ref[0][yb4] >= 4);
         cnt[l->ref[0][yb4] >= 4]++;
+		fprintf(stderr, "23~~> %d\n", l->ref[1][yb4] >= 4);
         if (l->comp_type[yb4]) cnt[l->ref[1][yb4] >= 4]++;
     }
 
@@ -309,12 +323,16 @@
     int cnt[4] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "10~~> %d\n", a->ref[0][xb4] < 4);
         if (a->ref[0][xb4] < 4) cnt[a->ref[0][xb4]]++;
+		fprintf(stderr, "11~~> %d\n", a->comp_type[xb4] && a->ref[1][xb4] < 4);
         if (a->comp_type[xb4] && a->ref[1][xb4] < 4) cnt[a->ref[1][xb4]]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "12~~> %d\n", l->ref[0][yb4] < 4);
         if (l->ref[0][yb4] < 4) cnt[l->ref[0][yb4]]++;
+		fprintf(stderr, "13~~> %d\n", l->comp_type[yb4] && l->ref[1][yb4] < 4);
         if (l->comp_type[yb4] && l->ref[1][yb4] < 4) cnt[l->ref[1][yb4]]++;
     }
 
@@ -332,12 +350,16 @@
     int cnt[2] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "00~~> %d\n", a->ref[0][xb4] < 2);
         if (a->ref[0][xb4] < 2) cnt[a->ref[0][xb4]]++;
+		fprintf(stderr, "01~~> %d\n", a->comp_type[xb4] && a->ref[1][xb4] < 2);
         if (a->comp_type[xb4] && a->ref[1][xb4] < 2) cnt[a->ref[1][xb4]]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "02~~> %d\n", l->ref[0][yb4] < 2);
         if (l->ref[0][yb4] < 2) cnt[l->ref[0][yb4]]++;
+		fprintf(stderr, "03~~> %d\n", l->comp_type[yb4] && l->ref[1][yb4] < 2);
         if (l->comp_type[yb4] && l->ref[1][yb4] < 2) cnt[l->ref[1][yb4]]++;
     }
 
@@ -352,11 +374,15 @@
     int cnt[2] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "A0~~> %d\n", (a->ref[0][xb4] ^ 2U) < 2);
+		fprintf(stderr, "A1~~> %d\n", a->comp_type[xb4] && (a->ref[1][xb4] ^ 2U) < 2);
         if ((a->ref[0][xb4] ^ 2U) < 2) cnt[a->ref[0][xb4] - 2]++;
         if (a->comp_type[xb4] && (a->ref[1][xb4] ^ 2U) < 2) cnt[a->ref[1][xb4] - 2]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "A2~~> %d\n", (l->ref[0][yb4] ^ 2U) < 2);
+		fprintf(stderr, "A3~~> %d\n", l->comp_type[yb4] && (l->ref[1][yb4] ^ 2U) < 2);
         if ((l->ref[0][yb4] ^ 2U) < 2) cnt[l->ref[0][yb4] - 2]++;
         if (l->comp_type[yb4] && (l->ref[1][yb4] ^ 2U) < 2) cnt[l->ref[1][yb4] - 2]++;
     }
@@ -372,12 +398,16 @@
     int cnt[3] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "B0~~> %d\n", a->ref[0][xb4] >= 4);
         if (a->ref[0][xb4] >= 4) cnt[a->ref[0][xb4] - 4]++;
+		fprintf(stderr, "B1~~> %d\n", a->comp_type[xb4] && (int)a->ref[1][xb4] >= 4);
         if (a->comp_type[xb4] && a->ref[1][xb4] >= 4) cnt[a->ref[1][xb4] - 4]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "B2~~> %d\n", l->ref[0][yb4] >= 4);
         if (l->ref[0][yb4] >= 4) cnt[l->ref[0][yb4] - 4]++;
+		fprintf(stderr, "B3~~> %d\n", l->comp_type[yb4] && l->ref[1][yb4] >= 44);
         if (l->comp_type[yb4] && l->ref[1][yb4] >= 4) cnt[l->ref[1][yb4] - 4]++;
     }
 
@@ -394,12 +424,16 @@
     int cnt[3] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "C0~~> %d\n", a->ref[0][xb4] >= 4);
         if (a->ref[0][xb4] >= 4) cnt[a->ref[0][xb4] - 4]++;
+		fprintf(stderr, "C1~~> %d\n", a->comp_type[xb4] && a->ref[1][xb4] >= 4);
         if (a->comp_type[xb4] && a->ref[1][xb4] >= 4) cnt[a->ref[1][xb4] - 4]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "C2~~> %d\n", a->ref[0][xb4] >= 4);
         if (l->ref[0][yb4] >= 4) cnt[l->ref[0][yb4] - 4]++;
+		fprintf(stderr, "C3~~> %d\n", l->comp_type[yb4] && l->ref[1][yb4] >= 4);
         if (l->comp_type[yb4] && l->ref[1][yb4] >= 4) cnt[l->ref[1][yb4] - 4]++;
     }
 
@@ -414,12 +448,16 @@
     int cnt[3] = { 0 };
 
     if (have_top && !a->intra[xb4]) {
+		fprintf(stderr, "D0~~> %d\n", a->ref[0][xb4] - 1U < 3);
         if (a->ref[0][xb4] - 1U < 3) cnt[a->ref[0][xb4] - 1]++;
+		fprintf(stderr, "D1~~> %d\n", a->comp_type[xb4] && a->ref[1][xb4] - 1U < 3);
         if (a->comp_type[xb4] && a->ref[1][xb4] - 1U < 3) cnt[a->ref[1][xb4] - 1]++;
     }
 
     if (have_left && !l->intra[yb4]) {
+		fprintf(stderr, "D2~~> %d\n", l->ref[0][yb4] - 1U < 3);
         if (l->ref[0][yb4] - 1U < 3) cnt[l->ref[0][yb4] - 1]++;
+		fprintf(stderr, "D3~~> %d\n", l->comp_type[yb4] && l->ref[1][yb4] - 1U < 3);
         if (l->comp_type[yb4] && l->ref[1][yb4] - 1U < 3) cnt[l->ref[1][yb4] - 1]++;
     }
 
@@ -496,25 +534,27 @@
                        gmv->matrix[4] * x + gmv->matrix[1];
         const int shift = 16 - (3 - !hdr->hp);
         const int round = (1 << shift) >> 1;
-        mv res = (mv) {
-            .y = apply_sign(((abs(yc) + round) >> shift) << !hdr->hp, yc),
-            .x = apply_sign(((abs(xc) + round) >> shift) << !hdr->hp, xc),
-        };
+        mv res;
+        res.y = apply_sign(((abs(yc) + round) >> shift) << !hdr->hp, yc);
+        res.x = apply_sign(((abs(xc) + round) >> shift) << !hdr->hp, xc);
         if (hdr->force_integer_mv)
             fix_int_mv_precision(&res);
         return res;
     }
     case DAV1D_WM_TYPE_TRANSLATION: {
-        mv res = (mv) {
-            .y = gmv->matrix[0] >> 13,
-            .x = gmv->matrix[1] >> 13,
-        };
+        mv res;
+        res.y = gmv->matrix[0] >> 13;
+        res.x = gmv->matrix[1] >> 13;
         if (hdr->force_integer_mv)
             fix_int_mv_precision(&res);
         return res;
     }
-    case DAV1D_WM_TYPE_IDENTITY:
-        return (mv) { .x = 0, .y = 0 };
+    case DAV1D_WM_TYPE_IDENTITY: {
+        mv res;
+        res.x = 0;
+        res.y = 0;
+        return res;
+    }
     }
 }
 
--- a/src/ipred_prepare_tmpl.c
+++ b/src/ipred_prepare_tmpl.c
@@ -47,31 +47,31 @@
     90, 180, 45, 135, 113, 157, 203, 67
 };
 
-static const struct {
-    uint8_t needs_left:1;
-    uint8_t needs_top:1;
-    uint8_t needs_topleft:1;
-    uint8_t needs_topright:1;
-    uint8_t needs_bottomleft:1;
-} av1_intra_prediction_edges[N_IMPL_INTRA_PRED_MODES] = {
-    [DC_PRED]       = { .needs_top  = 1, .needs_left = 1 },
-    [VERT_PRED]     = { .needs_top  = 1 },
-    [HOR_PRED]      = { .needs_left = 1 },
-    [LEFT_DC_PRED]  = { .needs_left = 1 },
-    [TOP_DC_PRED]   = { .needs_top  = 1 },
-    [DC_128_PRED]   = { 0 },
-    [Z1_PRED]       = { .needs_top = 1, .needs_topright = 1,
-                        .needs_topleft = 1 },
-    [Z2_PRED]       = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
-    [Z3_PRED]       = { .needs_left = 1, .needs_bottomleft = 1,
-                        .needs_topleft = 1 },
-    [SMOOTH_PRED]   = { .needs_left = 1, .needs_top = 1 },
-    [SMOOTH_V_PRED] = { .needs_left = 1, .needs_top = 1 },
-    [SMOOTH_H_PRED] = { .needs_left = 1, .needs_top = 1 },
-    [PAETH_PRED]    = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
-    [FILTER_PRED]   = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
+enum {
+    needs_left = 1<<0,
+    needs_top = 1<<1,
+    needs_topleft = 1<<2,
+    needs_topright = 1<<3,
+    needs_bottomleft = 1<<4,
 };
 
+static const uint8_t av1_intra_prediction_edges[N_IMPL_INTRA_PRED_MODES] = {
+    [DC_PRED]       = needs_top | needs_left,
+    [VERT_PRED]     = needs_top,
+    [HOR_PRED]      = needs_left,
+    [LEFT_DC_PRED]  = needs_left,
+    [TOP_DC_PRED]   = needs_top,
+    [DC_128_PRED]   = 0,
+    [Z1_PRED]       = needs_top | needs_topright | needs_topleft,
+    [Z2_PRED]       = needs_left | needs_top | needs_topleft,
+    [Z3_PRED]       = needs_left | needs_bottomleft | needs_topleft,
+    [SMOOTH_PRED]   = needs_left | needs_top,
+    [SMOOTH_V_PRED] = needs_left | needs_top,
+    [SMOOTH_H_PRED] = needs_left | needs_top,
+    [PAETH_PRED]    = needs_left | needs_top | needs_topleft,
+    [FILTER_PRED]   = needs_left | needs_top | needs_topleft,
+};
+
 enum IntraPredMode
 bytefn(dav1d_prepare_intra_edges)(const int x, const int have_left,
                                   const int y, const int have_top,
@@ -116,9 +116,9 @@
 
     const pixel *dst_top;
     if (have_top &&
-        (av1_intra_prediction_edges[mode].needs_top ||
-         av1_intra_prediction_edges[mode].needs_topleft ||
-         (av1_intra_prediction_edges[mode].needs_left && !have_left)))
+        ((av1_intra_prediction_edges[mode] & needs_top) ||
+         (av1_intra_prediction_edges[mode] & needs_topleft) ||
+         ((av1_intra_prediction_edges[mode] & needs_left) && !have_left)))
     {
         if (prefilter_toplevel_sb_edge) {
             dst_top = &prefilter_toplevel_sb_edge[x * 4];
@@ -127,7 +127,7 @@
         }
     }
 
-    if (av1_intra_prediction_edges[mode].needs_left) {
+    if (av1_intra_prediction_edges[mode] & needs_left) {
         const int sz = th << 2;
         pixel *const left = &topleft_out[-sz];
 
@@ -142,7 +142,7 @@
             pixel_set(left, have_top ? *dst_top : ((1 << bitdepth) >> 1) + 1, sz);
         }
 
-        if (av1_intra_prediction_edges[mode].needs_bottomleft) {
+        if (av1_intra_prediction_edges[mode] & needs_bottomleft) {
             const int have_bottomleft = (!have_left || y + th >= h) ? 0 :
                                         (edge_flags & EDGE_I444_LEFT_HAS_BOTTOM);
 
@@ -159,7 +159,7 @@
         }
     }
 
-    if (av1_intra_prediction_edges[mode].needs_top) {
+    if (av1_intra_prediction_edges[mode] & needs_top) {
         const int sz = tw << 2;
         pixel *const top = &topleft_out[1];
 
@@ -172,7 +172,7 @@
             pixel_set(top, have_left ? dst[-1] : ((1 << bitdepth) >> 1) - 1, sz);
         }
 
-        if (av1_intra_prediction_edges[mode].needs_topright) {
+        if (av1_intra_prediction_edges[mode] & needs_topright) {
             const int have_topright = (!have_top || x + tw >= w) ? 0 :
                                       (edge_flags & EDGE_I444_TOP_HAS_RIGHT);
 
@@ -189,7 +189,7 @@
         }
     }
 
-    if (av1_intra_prediction_edges[mode].needs_topleft) {
+    if (av1_intra_prediction_edges[mode] & needs_topleft) {
         if (have_left)
             *topleft_out = have_top ? dst_top[-1] : dst[-1];
         else
--- a/src/lib.c
+++ b/src/lib.c
@@ -35,9 +35,6 @@
 #include <dlfcn.h>
 #endif
 
-#include "dav1d/dav1d.h"
-#include "dav1d/data.h"
-
 #include "common/mem.h"
 #include "common/validate.h"
 
@@ -63,7 +60,7 @@
     return DAV1D_VERSION;
 }
 
-COLD void dav1d_default_settings(Dav1dSettings *const s) {
+COLD void dav1d_default_settings(Dav1dSettings *s) {
     s->n_frame_threads = 1;
     s->n_tile_threads = 1;
     s->apply_grain = 1;
@@ -95,7 +92,7 @@
     return 0;
 }
 
-COLD int dav1d_open(Dav1dContext **const c_out, const Dav1dSettings *const s) {
+COLD int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s) {
     static pthread_once_t initted = PTHREAD_ONCE_INIT;
     pthread_once(&initted, init_internal);
 
@@ -250,6 +247,7 @@
 
     while (buf.sz > 0) {
         res = dav1d_parse_obus(c, &buf, 1);
+        fprintf(stderr, "res=%d\n", res);
         if (res < 0) goto error;
 
         assert((size_t)res <= buf.sz);
@@ -368,6 +366,7 @@
 
     while (in->sz > 0) {
         res = dav1d_parse_obus(c, in, 0);
+        fprintf(stderr, "res=%d\n", res);
         if (res < 0) {
             dav1d_data_unref_internal(in);
         } else {
@@ -492,7 +491,7 @@
             f->frame_thread.die = 1;
             pthread_cond_signal(&f->frame_thread.td.cond);
             pthread_mutex_unlock(&f->frame_thread.td.lock);
-            pthread_join(f->frame_thread.td.thread, NULL);
+            pthread_join(&f->frame_thread.td.thread, NULL);
             freep(&f->frame_thread.b);
             dav1d_freep_aligned(&f->frame_thread.pal_idx);
             dav1d_freep_aligned(&f->frame_thread.cf);
@@ -519,7 +518,7 @@
             for (int m = 0; m < f->n_tc; m++) {
                 Dav1dTileContext *const t = &f->tc[m];
                 if (f->n_tc > 1 && t->tile_thread.td.inited) {
-                    pthread_join(t->tile_thread.td.thread, NULL);
+                    pthread_join(&t->tile_thread.td.thread, NULL);
                     pthread_mutex_destroy(&t->tile_thread.td.lock);
                     pthread_cond_destroy(&t->tile_thread.td.cond);
                 }
@@ -592,7 +591,7 @@
     return dav1d_data_wrap_internal(buf, ptr, sz, free_callback, user_data);
 }
 
-int dav1d_data_wrap_user_data(Dav1dData *const buf,
+int dav1d_data_wrap_user_data(Dav1dData *buf,
                               const uint8_t *const user_data,
                               void (*const free_callback)(const uint8_t *user_data,
                                                           void *cookie),
@@ -604,6 +603,6 @@
                                               cookie);
 }
 
-void dav1d_data_unref(Dav1dData *const buf) {
+void dav1d_data_unref(Dav1dData *buf) {
     dav1d_data_unref_internal(buf);
 }
--- a/src/log.c
+++ b/src/log.c
@@ -27,7 +27,9 @@
 #include "config.h"
 
 #include <stdarg.h>
+#ifndef __plan9__
 #include <stdio.h>
+#endif
 
 #include "dav1d/dav1d.h"
 
--- a/src/lr_apply_tmpl.c
+++ b/src/lr_apply_tmpl.c
@@ -27,7 +27,9 @@
 
 #include "config.h"
 
+#ifndef __plan9__
 #include <stdio.h>
+#endif
 
 #include "common/intops.h"
 
--- a/src/mc_tmpl.c
+++ b/src/mc_tmpl.c
@@ -105,7 +105,7 @@
     GET_V_FILTER(my)
 
 static NOINLINE void
-put_8tap_c(pixel *dst, ptrdiff_t dst_stride,
+put_etap_c(pixel *dst, ptrdiff_t dst_stride,
            const pixel *src, ptrdiff_t src_stride,
            const int w, int h, const int mx, const int my,
            const int filter_type HIGHBD_DECL_SUFFIX)
@@ -166,7 +166,7 @@
 }
 
 static NOINLINE void
-put_8tap_scaled_c(pixel *dst, const ptrdiff_t dst_stride,
+put_etap_scaled_c(pixel *dst, const ptrdiff_t dst_stride,
                   const pixel *src, ptrdiff_t src_stride,
                   const int w, int h, const int mx, int my,
                   const int dx, const int dy, const int filter_type
@@ -216,7 +216,7 @@
 }
 
 static NOINLINE void
-prep_8tap_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride,
+prep_etap_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride,
             const int w, int h, const int mx, const int my,
             const int filter_type HIGHBD_DECL_SUFFIX)
 {
@@ -277,7 +277,7 @@
 }
 
 static NOINLINE void
-prep_8tap_scaled_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride,
+prep_etap_scaled_c(int16_t *tmp, const pixel *src, ptrdiff_t src_stride,
                    const int w, int h, const int mx, int my,
                    const int dx, const int dy, const int filter_type
                    HIGHBD_DECL_SUFFIX)
@@ -323,7 +323,7 @@
 }
 
 #define filter_fns(type, type_h, type_v) \
-static void put_8tap_##type##_c(pixel *const dst, \
+static void put_etap_##type##_c(pixel *const dst, \
                                 const ptrdiff_t dst_stride, \
                                 const pixel *const src, \
                                 const ptrdiff_t src_stride, \
@@ -331,10 +331,10 @@
                                 const int mx, const int my \
                                 HIGHBD_DECL_SUFFIX) \
 { \
-    put_8tap_c(dst, dst_stride, src, src_stride, w, h, mx, my, \
+    put_etap_c(dst, dst_stride, src, src_stride, w, h, mx, my, \
                type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \
 } \
-static void put_8tap_##type##_scaled_c(pixel *const dst, \
+static void put_etap_##type##_scaled_c(pixel *const dst, \
                                        const ptrdiff_t dst_stride, \
                                        const pixel *const src, \
                                        const ptrdiff_t src_stride, \
@@ -343,10 +343,10 @@
                                        const int dx, const int dy \
                                        HIGHBD_DECL_SUFFIX) \
 { \
-    put_8tap_scaled_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, \
+    put_etap_scaled_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, \
                       type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \
 } \
-static void prep_8tap_##type##_c(int16_t *const tmp, \
+static void prep_etap_##type##_c(int16_t *const tmp, \
                                  const pixel *const src, \
                                  const ptrdiff_t src_stride, \
                                  const int w, const int h, \
@@ -353,10 +353,10 @@
                                  const int mx, const int my \
                                  HIGHBD_DECL_SUFFIX) \
 { \
-    prep_8tap_c(tmp, src, src_stride, w, h, mx, my, \
+    prep_etap_c(tmp, src, src_stride, w, h, mx, my, \
                 type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \
 } \
-static void prep_8tap_##type##_scaled_c(int16_t *const tmp, \
+static void prep_etap_##type##_scaled_c(int16_t *const tmp, \
                                         const pixel *const src, \
                                         const ptrdiff_t src_stride, \
                                         const int w, const int h, \
@@ -364,7 +364,7 @@
                                         const int dx, const int dy \
                                         HIGHBD_DECL_SUFFIX) \
 { \
-    prep_8tap_scaled_c(tmp, src, src_stride, w, h, mx, my, dx, dy, \
+    prep_etap_scaled_c(tmp, src, src_stride, w, h, mx, my, dx, dy, \
                        type_h | (type_v << 2) HIGHBD_TAIL_SUFFIX); \
 }
 
@@ -919,15 +919,15 @@
     c->mct_scaled[type] = prep_##name##_scaled_c; \
 } while (0)
 
-    init_mc_fns(FILTER_2D_8TAP_REGULAR,        8tap_regular);
-    init_mc_fns(FILTER_2D_8TAP_REGULAR_SMOOTH, 8tap_regular_smooth);
-    init_mc_fns(FILTER_2D_8TAP_REGULAR_SHARP,  8tap_regular_sharp);
-    init_mc_fns(FILTER_2D_8TAP_SHARP_REGULAR,  8tap_sharp_regular);
-    init_mc_fns(FILTER_2D_8TAP_SHARP_SMOOTH,   8tap_sharp_smooth);
-    init_mc_fns(FILTER_2D_8TAP_SHARP,          8tap_sharp);
-    init_mc_fns(FILTER_2D_8TAP_SMOOTH_REGULAR, 8tap_smooth_regular);
-    init_mc_fns(FILTER_2D_8TAP_SMOOTH,         8tap_smooth);
-    init_mc_fns(FILTER_2D_8TAP_SMOOTH_SHARP,   8tap_smooth_sharp);
+    init_mc_fns(FILTER_2D_8TAP_REGULAR,        etap_regular);
+    init_mc_fns(FILTER_2D_8TAP_REGULAR_SMOOTH, etap_regular_smooth);
+    init_mc_fns(FILTER_2D_8TAP_REGULAR_SHARP,  etap_regular_sharp);
+    init_mc_fns(FILTER_2D_8TAP_SHARP_REGULAR,  etap_sharp_regular);
+    init_mc_fns(FILTER_2D_8TAP_SHARP_SMOOTH,   etap_sharp_smooth);
+    init_mc_fns(FILTER_2D_8TAP_SHARP,          etap_sharp);
+    init_mc_fns(FILTER_2D_8TAP_SMOOTH_REGULAR, etap_smooth_regular);
+    init_mc_fns(FILTER_2D_8TAP_SMOOTH,         etap_smooth);
+    init_mc_fns(FILTER_2D_8TAP_SMOOTH_SHARP,   etap_smooth_sharp);
     init_mc_fns(FILTER_2D_BILINEAR,            bilin);
 
     c->avg      = avg_c;
--- /dev/null
+++ b/src/mkfile
@@ -1,0 +1,64 @@
+</$objtype/mkfile
+
+CFLAGS=$CFLAGS -I../include/dav1d -I.. -I../include -Iplan9 -p -D__plan9__
+
+HFILES=\
+
+OFILES=\
+	cdef_apply_tmpl.$O\
+	cdef_tmpl.$O\
+	cdf.$O\
+	cpu.$O\
+	data.$O\
+	decode.$O\
+	dequant_tables.$O\
+	fg_apply_tmpl.$O\
+	film_grain_tmpl.$O\
+	getbits.$O\
+	intra_edge.$O\
+	ipred_prepare_tmpl.$O\
+	ipred_tmpl.$O\
+	itx_1d.$O\
+	itx_tmpl.$O\
+	lf_apply_tmpl.$O\
+	lf_mask.$O\
+	lib.$O\
+	log.$O\
+	loopfilter_tmpl.$O\
+	looprestoration_tmpl.$O\
+	lr_apply_tmpl.$O\
+	mc_tmpl.$O\
+	msac.$O\
+	obu.$O\
+	picture.$O\
+	qm.$O\
+	recon_tmpl.$O\
+	ref.$O\
+	refmvs.$O\
+	scan.$O\
+	tables.$O\
+	thread_task.$O\
+	warpmv.$O\
+	wedge.$O\
+	plan9_builtins.$O\
+	plan9_thread.$O\
+	\
+	av19.$O\
+	ivf.$O\
+	annexb.$O\
+	input.$O\
+	section5.$O\
+
+</sys/src/cmd/mkone
+
+ivf.$O: ../tools/input/ivf.c
+	$CC $CFLAGS -I../tools $prereq
+
+input.$O: ../tools/input/input.c
+	$CC $CFLAGS -I../tools $prereq
+
+annexb.$O: ../tools/input/annexb.c
+	$CC $CFLAGS -I../tools $prereq
+
+section5.$O: ../tools/input/section5.c
+	$CC $CFLAGS -I../tools $prereq
--- /dev/null
+++ b/src/mkfile.lib
@@ -1,0 +1,49 @@
+</$objtype/mkfile
+
+LIB=/$objtype/lib/libdav1d.a
+CFLAGS=$CFLAGS -I.. -I../include -I../include/dav1d -Iplan9 -p -D__plan9__
+
+HFILES=\
+
+OFILES=\
+	cdef_apply_tmpl.$O\
+	cdef_tmpl.$O\
+	cdf.$O\
+	cpu.$O\
+	data.$O\
+	decode.$O\
+	dequant_tables.$O\
+	fg_apply_tmpl.$O\
+	film_grain_tmpl.$O\
+	getbits.$O\
+	intra_edge.$O\
+	ipred_prepare_tmpl.$O\
+	ipred_tmpl.$O\
+	itx_1d.$O\
+	itx_tmpl.$O\
+	lf_apply_tmpl.$O\
+	lf_mask.$O\
+	lib.$O\
+	log.$O\
+	loopfilter_tmpl.$O\
+	looprestoration_tmpl.$O\
+	lr_apply_tmpl.$O\
+	mc_tmpl.$O\
+	msac.$O\
+	obu.$O\
+	picture.$O\
+	qm.$O\
+	recon_tmpl.$O\
+	ref.$O\
+	refmvs.$O\
+	scan.$O\
+	tables.$O\
+	thread_task.$O\
+	warpmv.$O\
+	wedge.$O\
+	plan9_thread.$O\
+
+/sys/include/%.h:
+	cp ../include/$stem.h /sys/include/$stem.h
+
+</sys/src/cmd/mksyslib
--- a/src/msac.c
+++ b/src/msac.c
@@ -41,7 +41,7 @@
 static inline void ctx_refill(MsacContext *const s) {
     const uint8_t *buf_pos = s->buf_pos;
     const uint8_t *buf_end = s->buf_end;
-    int c = EC_WIN_SIZE - s->cnt - 24;
+    int c = (int)EC_WIN_SIZE - s->cnt - 24;
     ec_win dif = s->dif;
     while (c >= 0 && buf_pos < buf_end) {
         dif ^= ((ec_win)*buf_pos++) << c;
@@ -48,7 +48,8 @@
         c -= 8;
     }
     s->dif = dif;
-    s->cnt = EC_WIN_SIZE - c - 24;
+    //fprint(2, "cnt: %d -> %d\n", s->cnt, EC_WIN_SIZE - c - 24);
+    s->cnt = (int)EC_WIN_SIZE - c - 24;
     s->buf_pos = buf_pos;
 }
 
@@ -134,10 +135,14 @@
         v = r * (cdf[val] >> EC_PROB_SHIFT);
         v >>= 7 - EC_PROB_SHIFT;
         v += EC_MIN_PROB * ((unsigned)n_symbols - val);
+        fprint(2, ". %ud %ud %ud %ud %ud\n", val, cdf[val], r, c, v);
     } while (c < v);
 
     assert(u <= s->rng);
 
+    fprintf(stderr, "!3 %zd %ud -> %ud\n", n_symbols, s->rng, v);
+    //if(s->rng == 33215)
+    //  *(uint8_t*)0 = 0;
     ctx_norm(s, s->dif - ((ec_win)v << (EC_WIN_SIZE - 16)), u - v);
 
     if (s->allow_update_cdf) {
--- a/src/obu.c
+++ b/src/obu.c
@@ -29,7 +29,9 @@
 
 #include <errno.h>
 #include <limits.h>
+#ifndef __plan9__
 #include <stdio.h>
+#endif
 
 #include "dav1d/data.h"
 
@@ -46,7 +48,7 @@
 static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
                          Dav1dSequenceHeader *const hdr)
 {
-#define DEBUG_SEQ_HDR 0
+#define DEBUG_SEQ_HDR 1
 
 #if DEBUG_SEQ_HDR
     const unsigned init_bit_pos = dav1d_get_bits_pos(gb);
@@ -55,7 +57,7 @@
     hdr->profile = dav1d_get_bits(gb, 3);
     if (hdr->profile > 2) goto error;
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-profile: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-profile: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
@@ -63,7 +65,7 @@
     hdr->reduced_still_picture_header = dav1d_get_bits(gb, 1);
     if (hdr->reduced_still_picture_header && !hdr->still_picture) goto error;
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-stillpicture_flags: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-stillpicture_flags: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
@@ -102,7 +104,7 @@
             hdr->decoder_model_info_present = 0;
         }
 #if DEBUG_SEQ_HDR
-        printf("SEQHDR: post-timinginfo: off=%ld\n",
+        fprintf(stderr, "SEQHDR: post-timinginfo: off=%ld\n",
                dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
@@ -136,7 +138,7 @@
             c->operating_point < hdr->num_operating_points ? c->operating_point : 0;
         c->operating_point_idc = hdr->operating_points[op_idx].idc;
 #if DEBUG_SEQ_HDR
-        printf("SEQHDR: post-operating-points: off=%ld\n",
+        fprintf(stderr, "SEQHDR: post-operating-points: off=%ld\n",
                dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
     }
@@ -146,7 +148,7 @@
     hdr->max_width = dav1d_get_bits(gb, hdr->width_n_bits) + 1;
     hdr->max_height = dav1d_get_bits(gb, hdr->height_n_bits) + 1;
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-size: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-size: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
     hdr->frame_id_numbers_present =
@@ -156,7 +158,7 @@
         hdr->frame_id_n_bits = dav1d_get_bits(gb, 3) + hdr->delta_frame_id_n_bits + 1;
     }
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-frame-id-numbers-present: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-frame-id-numbers-present: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
@@ -190,7 +192,7 @@
         }
         hdr->screen_content_tools = dav1d_get_bits(gb, 1) ? DAV1D_ADAPTIVE : dav1d_get_bits(gb, 1);
     #if DEBUG_SEQ_HDR
-        printf("SEQHDR: post-screentools: off=%ld\n",
+        fprintf(stderr, "SEQHDR: post-screentools: off=%ld\n",
                dav1d_get_bits_pos(gb) - init_bit_pos);
     #endif
         hdr->force_integer_mv = hdr->screen_content_tools ?
@@ -202,7 +204,7 @@
     hdr->cdef = dav1d_get_bits(gb, 1);
     hdr->restoration = dav1d_get_bits(gb, 1);
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-featurebits: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-featurebits: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
@@ -262,13 +264,13 @@
     }
     hdr->separate_uv_delta_q = !hdr->monochrome && dav1d_get_bits(gb, 1);
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-colorinfo: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-colorinfo: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
     hdr->film_grain_present = dav1d_get_bits(gb, 1);
 #if DEBUG_SEQ_HDR
-    printf("SEQHDR: post-filmgrain: off=%ld\n",
+    fprintf(stderr, "SEQHDR: post-filmgrain: off=%ld\n",
            dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
 
@@ -354,7 +356,7 @@
 };
 
 static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) {
-#define DEBUG_FRAME_HDR 0
+#define DEBUG_FRAME_HDR 1
 
 #if DEBUG_FRAME_HDR
     const uint8_t *const init_ptr = gb->ptr;
@@ -365,7 +367,7 @@
     hdr->show_existing_frame =
         !seqhdr->reduced_still_picture_header && dav1d_get_bits(gb, 1);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-show_existing_frame: off=%ld\n",
+    fprintf(stderr, "HDR: post-show_existing_frame: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     if (hdr->show_existing_frame) {
@@ -389,7 +391,7 @@
         hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ||
         seqhdr->reduced_still_picture_header || dav1d_get_bits(gb, 1);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-frametype_bits: off=%ld\n",
+    fprintf(stderr, "HDR: post-frametype_bits: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->disable_cdf_update = dav1d_get_bits(gb, 1);
@@ -410,11 +412,12 @@
     hdr->frame_size_override = seqhdr->reduced_still_picture_header ? 0 :
                                hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ? 1 : dav1d_get_bits(gb, 1);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-frame_size_override_flag: off=%ld\n",
+    fprintf(stderr, "HDR: post-frame_size_override_flag: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->frame_offset = seqhdr->order_hint ?
                         dav1d_get_bits(gb, seqhdr->order_hint_n_bits) : 0;
+    fprintf(stderr, "1 frame_offset=%d %d %d\n", hdr->frame_offset, seqhdr->order_hint, seqhdr->order_hint_n_bits);
     hdr->primary_ref_frame = !hdr->error_resilient_mode && hdr->frame_type & 1 ?
                              dav1d_get_bits(gb, 3) : DAV1D_PRIMARY_REF_NONE;
 
@@ -460,6 +463,7 @@
             hdr->refidx[1] = hdr->refidx[2] = -1;
             hdr->refidx[3] = dav1d_get_bits(gb, 3);
             hdr->refidx[4] = hdr->refidx[5] = hdr->refidx[6] = -1;
+            fprintf(stderr, "hdr set\n");
 
             int shifted_frame_offset[8];
             const int current_frame_offset = 1 << (seqhdr->order_hint_n_bits - 1);
@@ -469,6 +473,7 @@
                     get_poc_diff(seqhdr->order_hint_n_bits,
                                  c->refs[i].p.p.frame_hdr->frame_offset,
                                  hdr->frame_offset);
+				fprintf(stderr, "shifted_frame_offset[%d]=%d\n", i, shifted_frame_offset[i]);
             }
 
             int used_frame[8] = { 0 };
@@ -485,6 +490,7 @@
                     latest_frame_offset = hint;
                 }
             }
+            fprintf(stderr, "refidx[6]=%d\n", hdr->refidx[6]);
             if (latest_frame_offset != -1)
                 used_frame[hdr->refidx[6]] = 1;
 
@@ -523,6 +529,7 @@
                             hint >= latest_frame_offset)
                         {
                             hdr->refidx[i] = j;
+                            fprintf(stderr, "refidx[%d] <- %d\n", i, j);
                             latest_frame_offset = hint;
                         }
                     }
@@ -541,13 +548,17 @@
                 }
             }
             for (int i = 0; i < 7; i++) {
-                if (hdr->refidx[i] < 0)
+                if (hdr->refidx[i] < 0){
                     hdr->refidx[i] = ref;
+                    fprintf(stderr, "!refidx[%d] <- %d\n", i, ref);
+                }
             }
         }
         for (int i = 0; i < 7; i++) {
-            if (!hdr->frame_ref_short_signaling)
+            if (!hdr->frame_ref_short_signaling){
                 hdr->refidx[i] = dav1d_get_bits(gb, 3);
+                fprintf(stderr, ">refidx[%d] <- %d\n", i, hdr->refidx[i]);
+            }
             if (seqhdr->frame_id_numbers_present)
                 dav1d_get_bits(gb, seqhdr->delta_frame_id_n_bits);
         }
@@ -563,7 +574,7 @@
             hdr->frame_type & 1 && dav1d_get_bits(gb, 1);
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-frametype-specific-bits: off=%ld\n",
+    fprintf(stderr, "HDR: post-frametype-specific-bits: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -570,7 +581,7 @@
     hdr->refresh_context = !seqhdr->reduced_still_picture_header &&
                            !hdr->disable_cdf_update && !dav1d_get_bits(gb, 1);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-refresh_context: off=%ld\n",
+    fprintf(stderr, "HDR: post-refresh_context: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -644,7 +655,7 @@
         hdr->tiling.n_bytes = hdr->tiling.update = 0;
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-tiling: off=%ld\n",
+    fprintf(stderr, "HDR: post-tiling: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -667,7 +678,7 @@
         }
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-quant: off=%ld\n",
+    fprintf(stderr, "HDR: post-quant: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->quant.qm = dav1d_get_bits(gb, 1);
@@ -679,7 +690,7 @@
                                           hdr->quant.qm_u;
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-qm: off=%ld\n",
+    fprintf(stderr, "HDR: post-qm: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -764,7 +775,7 @@
             hdr->segmentation.seg_data.d[i].ref = -1;
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-segmentation: off=%ld\n",
+    fprintf(stderr, "HDR: post-segmentation: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -776,7 +787,7 @@
     hdr->delta.lf.res_log2 = hdr->delta.lf.present ? dav1d_get_bits(gb, 2) : 0;
     hdr->delta.lf.multi = hdr->delta.lf.present ? dav1d_get_bits(gb, 1) : 0;
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-delta_q_lf_flags: off=%ld\n",
+    fprintf(stderr, "HDR: post-delta_q_lf_flags: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -836,7 +847,7 @@
         }
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-lpf: off=%ld\n",
+    fprintf(stderr, "HDR: post-lpf: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -855,7 +866,7 @@
         hdr->cdef.uv_strength[0] = 0;
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-cdef: off=%ld\n",
+    fprintf(stderr, "HDR: post-cdef: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -897,7 +908,7 @@
         hdr->restoration.type[2] = DAV1D_RESTORATION_NONE;
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-restoration: off=%ld\n",
+    fprintf(stderr, "HDR: post-restoration: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -904,25 +915,27 @@
     hdr->txfm_mode = hdr->all_lossless ? DAV1D_TX_4X4_ONLY :
                      dav1d_get_bits(gb, 1) ? DAV1D_TX_SWITCHABLE : DAV1D_TX_LARGEST;
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-txfmmode: off=%ld\n",
+    fprintf(stderr, "HDR: post-txfmmode: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->switchable_comp_refs = hdr->frame_type & 1 ? dav1d_get_bits(gb, 1) : 0;
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-refmode: off=%ld\n",
+    fprintf(stderr, "HDR: post-refmode: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->skip_mode_allowed = 0;
     if (hdr->switchable_comp_refs && hdr->frame_type & 1 && seqhdr->order_hint) {
         const unsigned poc = hdr->frame_offset;
+        fprintf(stderr, "poc=%ud\n", poc);
         unsigned off_before = 0xFFFFFFFFU;
         int off_after = -1;
-        int off_before_idx, off_after_idx;
+        int off_before_idx = 0, off_after_idx = 0;;
         for (int i = 0; i < 7; i++) {
             if (!c->refs[hdr->refidx[i]].p.p.data[0]) return DAV1D_ERR(EINVAL);
             const unsigned refpoc = c->refs[hdr->refidx[i]].p.p.frame_hdr->frame_offset;
 
             const int diff = get_poc_diff(seqhdr->order_hint_n_bits, refpoc, poc);
+            fprintf(stderr, "%d diff=%d (%d %d %d) %d\n", i, diff, seqhdr->order_hint_n_bits, refpoc, poc, hdr->refidx[i]);
             if (diff > 0) {
                 if (off_after == -1 || get_poc_diff(seqhdr->order_hint_n_bits,
                                                     off_after, refpoc) > 0)
@@ -939,6 +952,7 @@
             }
         }
 
+    fprintf(stderr, "X %x %d\n", off_before, off_after);
         if (off_before != 0xFFFFFFFFU && off_after != -1) {
             hdr->skip_mode_refs[0] = imin(off_before_idx, off_after_idx);
             hdr->skip_mode_refs[1] = imax(off_before_idx, off_after_idx);
@@ -945,7 +959,7 @@
             hdr->skip_mode_allowed = 1;
         } else if (off_before != 0xFFFFFFFFU) {
             unsigned off_before2 = 0xFFFFFFFFU;
-            int off_before2_idx;
+            int off_before2_idx = 0;
             for (int i = 0; i < 7; i++) {
                 if (!c->refs[hdr->refidx[i]].p.p.data[0]) return DAV1D_ERR(EINVAL);
                 const unsigned refpoc = c->refs[hdr->refidx[i]].p.p.frame_hdr->frame_offset;
@@ -968,20 +982,22 @@
             }
         }
     }
+    fprintf(stderr, "skip_enabled %d -> ", hdr->skip_mode_allowed);
     hdr->skip_mode_enabled = hdr->skip_mode_allowed ? dav1d_get_bits(gb, 1) : 0;
+    fprintf(stderr, "%d\n", hdr->skip_mode_enabled);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-extskip: off=%ld\n",
+    fprintf(stderr, "HDR: post-extskip: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->warp_motion = !hdr->error_resilient_mode && hdr->frame_type & 1 &&
         seqhdr->warped_motion && dav1d_get_bits(gb, 1);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-warpmotionbit: off=%ld\n",
+    fprintf(stderr, "HDR: post-warpmotionbit: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
     hdr->reduced_txtp_set = dav1d_get_bits(gb, 1);
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-reducedtxtpset: off=%ld\n",
+    fprintf(stderr, "HDR: post-reducedtxtpset: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -1035,7 +1051,7 @@
         }
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-gmv: off=%ld\n",
+    fprintf(stderr, "HDR: post-gmv: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -1119,7 +1135,7 @@
         memset(&hdr->film_grain.data, 0, sizeof(hdr->film_grain.data));
     }
 #if DEBUG_FRAME_HDR
-    printf("HDR: post-filmgrain: off=%ld\n",
+    fprintf(stderr, "HDR: post-filmgrain: off=%ld\n",
            (gb->ptr - init_ptr) * 8 - gb->bits_left);
 #endif
 
@@ -1172,6 +1188,7 @@
 }
 
 int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int global) {
+    static int frame_sidx = 0;
     GetBits gb;
     int res;
 
@@ -1224,6 +1241,7 @@
             return len + init_byte_pos;
     }
 
+    fprintf(stderr, "type=%d\n", type);
     switch (type) {
     case DAV1D_OBU_SEQ_HDR: {
         Dav1dRef *ref = dav1d_ref_create(sizeof(Dav1dSequenceHeader));
@@ -1283,6 +1301,7 @@
         memset(c->frame_hdr, 0, sizeof(*c->frame_hdr));
         c->frame_hdr->temporal_id = temporal_id;
         c->frame_hdr->spatial_id = spatial_id;
+        fprintf(stderr, "frame hdr %d %d\n", temporal_id, spatial_id);
         if ((res = parse_frame_hdr(c, &gb)) < 0) {
             c->frame_hdr = NULL;
             return res;
@@ -1361,6 +1380,7 @@
         c->n_tiles += 1 + c->tile[c->n_tile_data].end -
                           c->tile[c->n_tile_data].start;
         c->n_tile_data++;
+        fprintf(stderr, "tile data %d\n", c->n_tile_data);
         break;
     }
     case DAV1D_OBU_METADATA: {
@@ -1487,6 +1507,7 @@
         break;
     }
 
+    fprintf(stderr, "seq frame %d %d\n", !!c->seq_hdr, !!c->frame_hdr);
     if (c->seq_hdr && c->frame_hdr) {
         if (c->frame_hdr->show_existing_frame) {
             if (!c->refs[c->frame_hdr->existing_frame_idx].p.p.data[0]) return DAV1D_ERR(EINVAL);
@@ -1541,10 +1562,15 @@
             }
             c->frame_hdr = NULL;
         } else if (c->n_tiles == c->frame_hdr->tiling.cols * c->frame_hdr->tiling.rows) {
-            if (!c->n_tile_data)
+            if (!c->n_tile_data) {
+				fprintf(stderr, "no tile data?\n");
                 return DAV1D_ERR(EINVAL);
-            if ((res = dav1d_submit_frame(c)) < 0)
+            }
+            fprintf(stderr, "frame submit %d\n", frame_sidx++);
+            if ((res = dav1d_submit_frame(c)) < 0) {
+				fprintf(stderr, "dav1d_submit_frame failed\n");
                 return res;
+            }
             assert(!c->n_tile_data);
             c->frame_hdr = NULL;
             c->n_tiles = 0;
--- a/src/picture.c
+++ b/src/picture.c
@@ -29,7 +29,18 @@
 
 #include <errno.h>
 #include <stdint.h>
+#ifndef __plan9__
 #include <stdio.h>
+#else
+#define errno -1
+static char *
+strerror(int)
+{
+	static char e[ERRMAX];
+	errstr(e, sizeof(e));
+	return e;
+}
+#endif
 #include <stdlib.h>
 #include <string.h>
 
@@ -131,6 +142,7 @@
     p->p.h = h;
     p->seq_hdr = seq_hdr;
     p->frame_hdr = frame_hdr;
+    fprintf(stderr, "pic frame offset: %d\n", frame_hdr ? frame_hdr->frame_offset : -1);
     p->content_light = content_light;
     p->mastering_display = mastering_display;
     p->itut_t35 = itut_t35;
@@ -260,7 +272,7 @@
     dst->progress = src->progress;
 }
 
-void dav1d_picture_unref_internal(Dav1dPicture *const p) {
+void dav1d_picture_unref_internal(Dav1dPicture *p) {
     validate_input(p != NULL);
 
     if (p->ref) {
--- /dev/null
+++ b/src/plan9/assert.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/config.h
@@ -1,0 +1,12 @@
+#ifndef __plan9_config_h__
+#define __plan9_config_h__
+
+// FIXME
+#define ARCH_X86_64 1
+#define BITDEPTH 8
+#define HAVE_ALIGNED_MALLOC 1
+#define CONFIG_8BPC 1
+//#define CONFIG_16BPC 1
+#define CONFIG_LOG 1
+
+#endif
--- /dev/null
+++ b/src/plan9/errno.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/inttypes.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/limits.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/malloc.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/plan9.h
@@ -1,0 +1,66 @@
+#ifndef __plan9_h__
+#define __plan9_h__
+
+#define DAV1D_VERSION "no."
+#define DAV1D_API_VERSION_MAJOR 9
+#define DAV1D_API_VERSION_MINOR 9
+#define DAV1D_API_VERSION_PATCH 9
+
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#include </sys/include/thread.h>
+
+#define EINVAL -1
+#define ENOMEM -2
+#define ENOPROTOOPT -3
+#define ERANGE -4
+#define EAGAIN -5
+#define EIO -6
+
+typedef s8int int8_t;
+typedef u8int uint8_t;
+typedef s16int int16_t;
+typedef u16int uint16_t;
+typedef s32int int32_t;
+typedef u32int uint32_t;
+typedef s64int int64_t;
+typedef u64int uint64_t;
+typedef uintptr size_t;
+typedef intptr ptrdiff_t;
+typedef intptr intptr_t;
+typedef uintptr uintptr_t;
+typedef long atomic_int;
+typedef ulong atomic_uint;
+
+#define __func__ "no."
+#define __attribute__(a)
+
+#define UINT_MAX 0xffffffffU
+#define INT_MAX 0x7fffffff
+#define INT_MIN (-INT_MAX-1)
+#define INT16_MIN ((int16_t)0x8000)
+#define INT16_MAX 0x7fff
+#define INT64_MIN ((int64_t)0x8000000000000000LL)
+#define SHRT_MAX 0x7fff
+#define SHRT_MIN (-SHRT_MAX-1)
+#define PRIu64 "llu"
+
+#define memory_order_acquire 0
+#define atomic_init(p,v) do { *(p) = (v); } while(0)
+#define atomic_store(p,v) do { *(p) = (v); } while(0)
+#define atomic_load(p) *(p)
+#define atomic_load_explicit(p,o) *(p)
+#define atomic_fetch_add(p,i) (*(p) += i)
+#define atomic_fetch_sub(p,i) (*(p) -= i)
+
+int __builtin_ctz(unsigned int x);
+int __builtin_clz(unsigned int x);
+int __builtin_clzll(unsigned long long x);
+
+#define _aligned_malloc(sz, align) mallocalign(sz, align, 0, 0)
+#define _aligned_free(p) free(p)
+
+#define llabs(a) ((vlong)(a)<0?-(vlong)(a):(vlong)(a))
+
+#endif
--- /dev/null
+++ b/src/plan9/stdarg.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/stdatomic.h
@@ -1,0 +1,4 @@
+#ifndef __plan9_stdatomic__h
+#define __plan9_stdatomic__h
+
+#endif
--- /dev/null
+++ b/src/plan9/stddef.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/stdint.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/stdlib.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/string.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/vcs_version.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9/version.h
@@ -1,0 +1,1 @@
+#include "plan9.h"
--- /dev/null
+++ b/src/plan9_builtins.c
@@ -1,0 +1,29 @@
+int
+__builtin_ctz(unsigned int x)
+{
+	unsigned int r;
+	if(x == 0)
+		return 32;
+	for(r = 0; (x & 1) == 0; x >>= 1, r++);
+	return r;
+}
+
+int
+__builtin_clz(unsigned int x)
+{
+	unsigned int r;
+	if(x == 0)
+		return 32;
+	for(r = 0; (x & (1UL<<31)) == 0; x <<= 1, r++);
+	return r;
+}
+
+int
+__builtin_clzll(unsigned long long x)
+{
+	unsigned long long r;
+	if(x == 0)
+		return 64;
+	for(r = 0; (x & (1ULL<<63)) == 0; x <<= 1, r++);
+	return r;
+}
--- /dev/null
+++ b/src/plan9_thread.c
@@ -1,0 +1,135 @@
+#include <u.h>
+#include <libc.h>
+#include </sys/include/thread.h>
+#include "thread.h"
+
+void
+dav1d_set_thread_name(const char *const name)
+{
+	threadsetname(name);
+}
+
+static void
+thre(void *x)
+{
+	pthread_t *t;
+	void *p;
+
+	t = x;
+	p = t->func(t->arg);
+	send(t->waitchan, p);
+	threadexits(nil);
+}
+
+int
+pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*func)(void*), void *arg)
+{
+	uint stack;
+
+	stack = attr->stack_size > 65536 ? attr->stack_size : 65536;
+	thread->waitchan = chancreate(sizeof(void*), 0);
+	thread->func = func;
+	thread->arg = arg;
+	thread->pid = proccreate(thre, thread, stack);
+
+	return 0;
+}
+
+int
+pthread_join(pthread_t *thread, void **res)
+{
+	// FIXME this is wrong ofc
+	fprint(2, "joining...\n");
+	if (thread->waitchan != nil) {
+		recv(thread->waitchan, res);
+		chanfree(thread->waitchan);
+		thread->waitchan = nil;
+	}
+	fprint(2, "joined\n");
+
+	return 0;
+}
+
+int
+pthread_once(pthread_once_t *once, void (*init_routine)(void))
+{
+	qlock(once);
+	if (once->done != 12345) {
+		init_routine();
+		once->done = 12345;
+	}
+	qunlock(once);
+	return 0;
+}
+
+int
+pthread_mutex_init(pthread_mutex_t *const mutex, const void *const attr)
+{
+	USED(attr);
+	memset(mutex, 0, sizeof(*mutex));
+    return 0;
+}
+
+int
+pthread_mutex_destroy(pthread_mutex_t *const mutex)
+{
+	USED(mutex);
+    return 0;
+}
+
+int
+pthread_mutex_lock(pthread_mutex_t *const mutex)
+{
+    qlock(mutex);
+    return 0;
+}
+
+int
+pthread_mutex_unlock(pthread_mutex_t *const mutex)
+{
+    qunlock(mutex);
+    return 0;
+}
+
+int
+pthread_cond_init(pthread_cond_t *const cond, const void *const attr)
+{
+    memset(cond, 0, sizeof(*cond));
+    cond->l = &cond->lock;
+    return 0;
+}
+
+int
+pthread_cond_destroy(pthread_cond_t *const cond)
+{
+    return 0;
+}
+
+int
+pthread_cond_wait(pthread_cond_t *const cond, pthread_mutex_t *const mutex)
+{
+	qlock(cond->l);
+	qunlock(mutex);
+	rsleep(cond);
+	qlock(mutex);
+	qunlock(cond->l);
+    return 0;
+}
+
+int
+pthread_cond_signal(pthread_cond_t *const cond)
+{
+	qlock(cond->l);
+	rwakeup(cond);
+	qunlock(cond->l);
+    return 0;
+}
+
+int
+pthread_cond_broadcast(pthread_cond_t *const cond)
+{
+	qlock(cond->l);
+	rwakeupall(cond);
+	qunlock(cond->l);
+    return 0;
+}
--- a/src/recon_tmpl.c
+++ b/src/recon_tmpl.c
@@ -28,7 +28,9 @@
 #include "config.h"
 
 #include <string.h>
+#ifndef __plan9__
 #include <stdio.h>
+#endif
 
 #include "common/attributes.h"
 #include "common/bitdepth.h"
@@ -607,6 +609,7 @@
 
         // sign
         const int sign = dav1d_msac_decode_bool_equi(&ts->msac);
+        //fprint(2, "# %p %p\n", dq_tbl, qm_tbl);
         const unsigned dq = (dq_tbl[1] * qm_tbl[rc] + 16) >> 5;
         if (dbg)
             printf("Post-sign[%d=%d=%d]: r=%d\n", i, rc, sign, ts->msac.rng);
--- a/src/refmvs.c
+++ b/src/refmvs.c
@@ -185,10 +185,10 @@
     const int frac = num * div_mult[den];
     const int y = mv.y * frac, x = mv.x * frac;
     // Round and clip according to AV1 spec section 7.9.3
-    return (union mv) { // 0x3fff == (1 << 14) - 1
-        .y = iclip((y + 8192 + (y >> 31)) >> 14, -0x3fff, 0x3fff),
-        .x = iclip((x + 8192 + (x >> 31)) >> 14, -0x3fff, 0x3fff)
-    };
+    union mv res; // 0x3fff == (1 << 14) - 1
+    res.y = iclip((y + 8192 + (y >> 31)) >> 14, -0x3fff, 0x3fff);
+    res.x = iclip((x + 8192 + (x >> 31)) >> 14, -0x3fff, 0x3fff);
+    return res;
 }
 
 static void add_temporal_candidate(const refmvs_frame *const rf,
@@ -274,10 +274,10 @@
                 diff[diff_count[0]++].mv.mv[0] = cand_mv;
             }
         } else {
-            mv i_cand_mv = (union mv) {
+            mv i_cand_mv = {{
                 .x = -cand_mv.x,
                 .y = -cand_mv.y
-            };
+            }};
 
             if (diff_count[0] < 2) {
                 diff[diff_count[0]++].mv.mv[0] =
@@ -357,7 +357,7 @@
     const uint8_t *const b_dim = dav1d_block_dimensions[bs];
     const int bw4 = b_dim[0], w4 = imin(imin(bw4, 16), rt->tile_col.end - bx4);
     const int bh4 = b_dim[1], h4 = imin(imin(bh4, 16), rt->tile_row.end - by4);
-    mv gmv[2], tgmv[2];
+    mv gmv[2], tgmv[2], imv = { .n = INVALID_MV };
 
     *cnt = 0;
     assert(ref.ref[0] >=  0 && ref.ref[0] <= 8 &&
@@ -366,16 +366,16 @@
         tgmv[0] = get_gmv_2d(&rf->frm_hdr->gmv[ref.ref[0] - 1],
                              bx4, by4, bw4, bh4, rf->frm_hdr);
         gmv[0] = rf->frm_hdr->gmv[ref.ref[0] - 1].type > DAV1D_WM_TYPE_TRANSLATION ?
-                 tgmv[0] : (mv) { .n = INVALID_MV };
+                 tgmv[0] : imv;
     } else {
-        tgmv[0] = (mv) { .n = 0 };
-        gmv[0] = (mv) { .n = INVALID_MV };
+        tgmv[0].n = 0;
+        gmv[0] = imv;
     }
     if (ref.ref[1] > 0) {
         tgmv[1] = get_gmv_2d(&rf->frm_hdr->gmv[ref.ref[1] - 1],
                              bx4, by4, bw4, bh4, rf->frm_hdr);
         gmv[1] = rf->frm_hdr->gmv[ref.ref[1] - 1].type > DAV1D_WM_TYPE_TRANSLATION ?
-                 tgmv[1] : (mv) { .n = INVALID_MV };
+                 tgmv[1] : imv;
     }
 
     // top
@@ -782,15 +782,17 @@
             if (cand_b->ref.ref[1] > 0 && ref_sign[cand_b->ref.ref[1] - 1] &&
                 (abs(cand_b->mv.mv[1].y) | abs(cand_b->mv.mv[1].x)) < 4096)
             {
-                for (int n = 0; n < bw8; n++, x++)
-                    rp[x] = (refmvs_temporal_block) { .mv = cand_b->mv.mv[1],
-                                                      .ref = cand_b->ref.ref[1] };
+                for (int n = 0; n < bw8; n++, x++) {
+                    rp[x].mv = cand_b->mv.mv[1];
+                    rp[x].ref = cand_b->ref.ref[1];
+                }
             } else if (cand_b->ref.ref[0] > 0 && ref_sign[cand_b->ref.ref[0] - 1] &&
                        (abs(cand_b->mv.mv[0].y) | abs(cand_b->mv.mv[0].x)) < 4096)
             {
-                for (int n = 0; n < bw8; n++, x++)
-                    rp[x] = (refmvs_temporal_block) { .mv = cand_b->mv.mv[0],
-                                                      .ref = cand_b->ref.ref[0] };
+                for (int n = 0; n < bw8; n++, x++) {
+                    rp[x].mv = cand_b->mv.mv[0];
+                    rp[x].ref = cand_b->ref.ref[0];
+                }
             } else {
                 for (int n = 0; n < bw8; n++, x++)
                     rp[x].ref = 0; // "invalid"
--- a/src/refmvs.h
+++ b/src/refmvs.h
@@ -148,9 +148,9 @@
     int bh4 = dav1d_block_dimensions[bs][1];
     refmvs_block **rr = &rt->r[(by4 & 31) + 5];
 
-    const refmvs_block tmpl = (refmvs_block) {
-        .ref.ref = { ref + 1, is_interintra ? 0 : -1 },
-        .mv.mv[0] = mv,
+    const refmvs_block tmpl = {
+        .ref = {.ref = { ref + 1, is_interintra ? 0 : -1 }},
+        .mv = {.mv = {mv}},
         .bs = bs,
         .mf = (mode == GLOBALMV && imin(bw4, bh4) >= 2) | ((mode == NEWMV) * 2),
     };
@@ -169,9 +169,9 @@
     int bh4 = dav1d_block_dimensions[bs][1];
     refmvs_block **rr = &rt->r[(by4 & 31) + 5];
 
-    const refmvs_block tmpl = (refmvs_block) {
-        .ref.ref = { 0, -1 },
-        .mv.mv[0] = mv,
+    const refmvs_block tmpl = {
+        .ref = {.ref = { 0, -1 }},
+        .mv = {.mv = {mv}},
         .bs = bs,
         .mf = 0,
     };
@@ -195,8 +195,8 @@
     refmvs_block **rr = &rt->r[(by4 & 31) + 5];
 
     assert(bw4 >= 2 && bh4 >= 2);
-    const refmvs_block tmpl = (refmvs_block) {
-        .ref.pair = ref.pair + 0x0101,
+    const refmvs_block tmpl = {
+        .ref = {.pair = ref.pair + 0x0101},
         .mv = mv,
         .bs = bs,
         .mf = (mode == GLOBALMV_GLOBALMV) | !!((1 << mode) & (0xbc)) * 2,
@@ -216,9 +216,9 @@
     int bh4 = dav1d_block_dimensions[bs][1];
     refmvs_block **rr = &rt->r[(by4 & 31) + 5];
 
-    const refmvs_block tmpl = (refmvs_block) {
-        .ref.ref = { 0, -1 },
-        .mv.mv[0].n = INVALID_MV,
+    const refmvs_block tmpl = {
+        .ref = {.ref = { 0, -1 }},
+        .mv = {.n = INVALID_MV},
         .bs = bs,
         .mf = 0,
     };
--- a/src/tables.c
+++ b/src/tables.c
@@ -391,10 +391,12 @@
         0, 0, 1 << 16,
         0, 0, 1 << 16,
     },
-    .alpha = 0,
-    .beta = 0,
-    .gamma = 0,
-    .delta = 0,
+    {{
+        .alpha = 0,
+        .beta = 0,
+        .gamma = 0,
+        .delta = 0,
+    }}
 };
 
 const int8_t dav1d_cdef_directions[2 + 8 + 2 /* dir */][2 /* pass */] = {
--- a/src/thread.h
+++ b/src/thread.h
@@ -128,6 +128,74 @@
     return 0;
 }
 
+#elif defined(__plan9__)
+
+typedef struct pthread_t pthread_t;
+typedef struct pthread_cond_t pthread_cond_t;
+typedef struct pthread_once_t pthread_once_t;
+typedef struct pthread_mutex_t pthread_mutex_t;
+
+struct pthread_cond_t {
+    Rendez;
+    QLock lock;
+};
+
+struct pthread_once_t {
+	QLock;
+	int done;
+};
+
+struct pthread_mutex_t {
+	QLock;
+};
+
+#define dav1d_init_thread() do {} while (0)
+
+#define PTHREAD_ONCE_INIT {0}
+
+struct pthread_t {
+    void *waitchan;
+    void *(*func)(void*);
+    void *arg;
+    int pid;
+};
+
+typedef struct {
+    unsigned stack_size;
+} pthread_attr_t;
+
+void dav1d_set_thread_name(const char *const name);
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*func)(void*), void *arg);
+int pthread_join(pthread_t *thread, void **res);
+int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
+
+static int pthread_attr_init(pthread_attr_t *const attr) {
+    attr->stack_size = 0;
+    return 0;
+}
+
+static int pthread_attr_destroy(pthread_attr_t *const attr) {
+	USED(attr);
+    return 0;
+}
+
+static int pthread_attr_setstacksize(pthread_attr_t *const attr,
+                                     const int stack_size)
+{
+    attr->stack_size = stack_size;
+    return 0;
+}
+
+int pthread_mutex_init(pthread_mutex_t *const mutex, const void *const attr);
+int pthread_mutex_destroy(pthread_mutex_t *const mutex);
+int pthread_mutex_lock(pthread_mutex_t *const mutex);
+int pthread_mutex_unlock(pthread_mutex_t *const mutex);
+int pthread_cond_init(pthread_cond_t *const cond, const void *const attr);
+int pthread_cond_destroy(pthread_cond_t *const cond);
+int pthread_cond_wait(pthread_cond_t *const cond, pthread_mutex_t *const mutex);
+int pthread_cond_signal(pthread_cond_t *const cond);
+int pthread_cond_broadcast(pthread_cond_t *const cond);
+
 #else
 
 #include <pthread.h>
--- a/tools/input/annexb.c
+++ b/tools/input/annexb.c
@@ -28,10 +28,22 @@
 
 #include "config.h"
 
-#include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifndef __plan9__
+#include <stdio.h>
+#else
+#define errno -1
+static char *
+strerror(int)
+{
+	static char e[ERRMAX];
+	errstr(e, sizeof(e));
+	return e;
+}
+#endif
 
 #include "common/intops.h"
 
--- a/tools/input/demuxer.h
+++ b/tools/input/demuxer.h
@@ -31,6 +31,7 @@
 #include "data.h"
 
 typedef struct DemuxerPriv DemuxerPriv;
+#pragma incomplete DemuxerPriv
 typedef struct Demuxer {
     int priv_data_size;
     const char *name;
@@ -41,5 +42,6 @@
     int (*read)(DemuxerPriv *ctx, Dav1dData *data);
     void (*close)(DemuxerPriv *ctx);
 } Demuxer;
+#pragma incomplete Demuxer
 
 #endif /* DAV1D_INPUT_DEMUXER_H */
--- a/tools/input/input.c
+++ b/tools/input/input.c
@@ -27,10 +27,21 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
+#ifndef __plan9__
+#include <stdio.h>
+#else
+#define errno -1
+static char *
+strerror(int)
+{
+	static char e[ERRMAX];
+	errstr(e, sizeof(e));
+	return e;
+}
+#endif
 
 #include "common/attributes.h"
 #include "common/intops.h"
--- a/tools/input/input.h
+++ b/tools/input/input.h
@@ -31,6 +31,7 @@
 #include "data.h"
 
 typedef struct DemuxerContext DemuxerContext;
+#pragma incomplete DemuxerContext
 
 int input_open(DemuxerContext **const c_out,
                const char *const name, const char *const filename,
--- a/tools/input/ivf.c
+++ b/tools/input/ivf.c
@@ -29,7 +29,18 @@
 
 #include <errno.h>
 #include <limits.h>
+#ifndef __plan9__
 #include <stdio.h>
+#else
+#define errno -1
+static char *
+strerror(int)
+{
+	static char e[ERRMAX];
+	errstr(e, sizeof(e));
+	return e;
+}
+#endif
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -130,6 +141,7 @@
     const ptrdiff_t sz = rl32(data);
     if ((res = fread(data, 8, 1, c->f)) != 1)
         return -1; // EOF
+    fprint(2, "# %zd %zd\n", off, sz);
     ptr = dav1d_data_create(buf, sz);
     if (!ptr) return -1;
     buf->m.offset = off;
@@ -139,6 +151,7 @@
         dav1d_data_unref(buf);
         return -1;
     }
+    fprint(2, "@ %zd\n", ftello(c->f));
 
     return 0;
 }
--- a/tools/input/section5.c
+++ b/tools/input/section5.c
@@ -28,11 +28,23 @@
 
 #include "config.h"
 
-#include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifndef __plan9__
+#include <stdio.h>
 #include <sys/types.h>
+#else
+#define errno -1
+static char *
+strerror(int)
+{
+	static char e[ERRMAX];
+	errstr(e, sizeof(e));
+	return e;
+}
+#endif
 
 #include "dav1d/headers.h"
 
@@ -158,7 +170,7 @@
         fseeko(c->f, len, SEEK_CUR); // skip packet, we'll read it below
     }
 
-    fseeko(c->f, -(off_t)total_bytes, SEEK_CUR);
+    fseeko(c->f, -(long)total_bytes, SEEK_CUR);
     uint8_t *ptr = dav1d_data_create(data, total_bytes);
     if (!ptr) return -1;
     if (fread(ptr, total_bytes, 1, c->f) != 1) {