Sigrid Solveig Haflínudóttirivf: ignore av1 codec private data74533c84 years agoHistory
172 lines · 3.5 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include "common.h"#include "packet.h" enum {	Timedenum = 1000ULL,}; static intivfframe(Biobuf *out, u8int *p, int sz, uvlong ts, int avcsplit){	u8int d[12];	int n, len; 	d[0] = sz;	d[1] = sz >> 8;	d[2] = sz >> 16;	d[3] = 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)		return -1;	if(avcsplit){		for(n = 0; n < sz; n += len+4){			len = p[n+0]<<24 | p[n+1]<<16 | p[n+2]<<8 | p[n+3];			p[n+0] = 0;			p[n+1] = 0;			p[n+2] = 0;			p[n+3] = 1;		}	} 	return sz > 0 ? (Bwrite(out, p, sz) != sz ? -1 : 0) : 0;} intivfpacket(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts, int key){	u8int d[0x20], *x, *y, *e;	int i, n, len;	uvlong dur; 	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; 			if(ctx->codec.priv.sz > 0){				if(ctx->fmt == FmtAv01)					goto skip;				if(ctx->fmt != FmtAvc1){					werrstr("no idea what to do with codec private data for non-AVC1");					goto err;				} 				x = ctx->codec.priv.data;				e = x + ctx->codec.priv.sz;				if(x[0] != 1){					werrstr("avc config: invalid version %d", x[0]);					goto err;				}				if((x[4] & 3) != 3){					werrstr("avc config: NAL size %d not implemented", (x[4] & 3)+1);					goto err;				}				/* sps */				x[0] = 0;				x[1] = 0;				x[2] = 0;				x[3] = 1;				n = x[5] & 0x1f;				y = x+6;				for(i = 0; i < n; i++){					len = y[0] << 8 | y[1];					y += 2;					if(y+len > e){						werrstr("sps out of range");						goto err;					}					ctx->ps[ctx->nps].p = malloc(4+len);					memmove(ctx->ps[ctx->nps].p, x, 4);					memmove(ctx->ps[ctx->nps].p+4, y, len);					ctx->ps[ctx->nps++].n = 4+len;					ctx->frid++;					y += len;				}				/* pps */				n = *y++;				for(i = 0; i < n; i++){					len = y[0] << 8 | y[1];					y += 2;					if(y+len > e){						werrstr("pps out of range");						goto err;					}					ctx->ps[ctx->nps].p = malloc(4+len);					memmove(ctx->ps[ctx->nps].p, x, 4);					memmove(ctx->ps[ctx->nps].p+4, y, len);					ctx->ps[ctx->nps++].n = 4+len;					ctx->frid++;					y += len;				}			}		} skip:		if(key && ctx->fmt == FmtAvc1){			for(i = 0; i < ctx->nps; i++)				ivfframe(out, ctx->ps[i].p, ctx->ps[i].n, 0, 0);		}		if(ivfframe(out, p->data, p->sz, ts, ctx->fmt == FmtAvc1) != 0)			goto err;		ctx->frid++;	} 	return 0;err:	werrstr("ivfpacket: %r");	return -1;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t