ref: 19cbe98daef0d058a0387f03cc36e44f9169e04b
dir: /stream_mc.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(RFFDG|RFPROC|RFNOMNT)) == 0){
close(0);
close(p[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 *
mcopen(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 *s, *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;
s = streams+ns;
if(nvideo < 1 && strcmp(v[1], "video") == 0){
if(mcfs(argv, &sp) > 0 && ivfopenb(Bfdopen(sp, OREAD), s, 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 mcops = {
.open = mcopen,
};