ref: 4812d7f4d60a30404a8f0d0cb1f244ae288387d5
dir: /stream_mp4.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "stream.h" #include "misc.h" enum { Maxstreams = 2, }; static int mcfs(char **argv, int *pipefd) { int p[2], pid, fd; pipe(p); if((pid = rfork(RFPROC|RFFDG|RFREND)) == 0){ close(0); dup(p[1], 1); close(p[1]); if(!debug){ dup(fd = open("/dev/null", OWRITE), 2); close(fd); } exec("/bin/mcfs", argv); sysfatal("exec: %r"); } close(p[1]); if(pid < 0) close(p[0]); *pipefd = p[0]; return pid; } static Stream * mp4open(char *filename, int *num, int *failed) { Waitmsg *w; char *line; int p, pid, n, ns; Biobuf b; char *argv[] = { "mcfs", "-i", filename, nil, nil, }; Stream *streams; int nvideo, naudio, sp; char *v[8]; if((pid = mcfs(argv, &p)) < 0) return nil; if((streams = calloc(Maxstreams, sizeof(Stream))) == nil) return nil; Binit(&b, p, OREAD); for(ns = naudio = nvideo = 0; ns < Maxstreams && (line = Brdstr(&b, '\n', 1)) != nil;){ n = tokenize(line, v, nelem(v)); if(n > 4 && str2fmt(v[2]) >= 0){ argv[1] = "-t"; argv[2] = v[0]; /* stream id */ argv[3] = filename; if(nvideo < 1 && strcmp(v[1], "video") == 0){ if(mcfs(argv, &sp) > 0 && ivfopenb(Bfdopen(sp, OREAD), streams+ns, failed) == 0){ nvideo++; ns++; } }else if(naudio < 1 && strcmp(v[1], "audio") == 0){ /* FIXME add audio streams */ } } free(line); } Bterm(&b); *num = ns; if(ns < 1){ werrstr("no streams"); *failed = 1; free(streams); streams = nil; while((w = wait()) != nil){ if(w->pid == pid){ if(w->msg[0] != 0){ werrstr("%s", w->msg); goto err; } free(w); break; } free(w); } } return streams; err: free(w); free(streams); return nil; } Streamops mp4ops = { .open = mp4open, };