ref: c2d2a672624e73d18c32a25ba66cad39d7691070
dir: /ivf.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "common.h" enum { Timedenum = 1000ULL, }; int ivfpacket(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts) { u8int d[0x20]; uvlong dur; int n, len; dur = ctx->duration / 1000000ULL; ts = ts / 1000000ULL; for(; np > 0; np--, p++){ if(ctx->frid == 0){ memmove(d, "DKIF", 4); d[4] = 0; d[5] = 0; d[6] = 0x20; d[7] = 0; if(ctx->fmt == FmtAv01) memmove(d+8, "AV01", 4); else if(ctx->fmt == FmtAvc1) memmove(d+8, "AVC1", 4); else if(ctx->fmt == FmtVp08) memmove(d+8, "VP80", 4); else if(ctx->fmt == FmtVp09) memmove(d+8, "VP90", 4); else{ werrstr("unsupported video format %T", ctx->fmt); goto err; } d[12] = ctx->video.width; d[13] = ctx->video.width >> 8; d[14] = ctx->video.height; d[15] = ctx->video.height >> 8; /* timebase denum */ d[16] = Timedenum; d[17] = Timedenum >> 8; d[18] = Timedenum >> 16; d[19] = Timedenum >> 24; /* timebase num */ d[20] = 1; d[21] = 0; d[22] = 0; d[23] = 0; /* FIXME is it a "number of frames" or "total duration?" */ d[24] = dur; d[25] = dur >> 8; d[26] = dur >> 16; d[27] = dur >> 24; d[28] = dur >> 32; /* FIXME is it 64 bits? */ d[29] = dur >> 40; d[30] = dur >> 48; d[31] = dur >> 56; if(Bwrite(out, d, 0x20) != 0x20) goto err; } d[0] = p[0].sz; d[1] = p[0].sz >> 8; d[2] = p[0].sz >> 16; d[3] = p[0].sz >> 24; d[4] = ts; d[5] = ts >> 8; d[6] = ts >> 16; d[7] = ts >> 24; d[8] = ts >> 32; d[9] = ts >> 40; d[10] = ts >> 48; d[11] = ts >> 56; if(Bwrite(out, d, 12) != 12) goto err; if(ctx->fmt == FmtAvc1){ for(n = 0; n < p[0].sz; n += len+4){ len = p[0].data[n+0]<<24 | p[0].data[n+1]<<16 | p[0].data[n+2]<<8 | p[0].data[n+3]; p[0].data[n+0] = 0; p[0].data[n+1] = 0; p[0].data[n+2] = 0; p[0].data[n+3] = 1; } } if(Bwrite(out, p[0].data, p[0].sz) != p[0].sz) goto err; ctx->frid++; } return 0; err: werrstr("ivfpacket: %r"); return -1; }