⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lavpipe.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  lavpipe - combines several input streams and pipes them trough *            arbitrary filters in order to finally output a resulting *            video stream based on a given "recipe" (pipe list) * *  Copyright (C) 2001, pHilipp Zabel <pzabel@gmx.de> *  Copyright (C) 2001, Matthew Marjanovic <maddog@mir.com> * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 *  of the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <ctype.h>#include <string.h>#include <sys/types.h>#include <signal.h>#include "mjpeg_logging.h"#include "pipelist.h"#include "yuv4mpeg.h"static void usage(void){  fprintf(  stderr,   "Usage: lavpipe [options] <pipe list>\n"  "Options: -o num   Frame offset - skip num frames in the beginning\n"  "                  if num is negative, all but the last num frames are skipped\n"  "         -n num   Only num frames are processed (0 means all frames)\n"  "         -v num  Verbosity of output [0..2]\n"  );}staticchar **parse_spawn_command(char *cmdline){  char **argv;  char *p = cmdline;  int i, argc = 0;    if (p == NULL) return NULL;  if (*p == '\0') return NULL;  argc = 0;  while (*p != '\0') {        while (!isspace(*p)) {      p++;      if (*p == '\0') {	argc++;	goto END_OF_LINE;      }    }    argc++;         while (isspace(*p)) {      p++;      if (*p == '\0') goto END_OF_LINE;    }  } END_OF_LINE:  argv = malloc(argc+1 * sizeof(argv[0]));  for (p = cmdline, i=0; i < argc; i++) {    argv[i] = p;    while (!isspace(*(++p)));    p[0] = '\0';    while (isspace(*(++p)))      if (p[0] == '\0') break;  }  argv[argc] = NULL;    return argv;}static pid_t fork_child_sub(char *command, int *fd_in, int *fd_out){  int n;  int pipe_in[2];  int pipe_out[2];  char **myargv;  pid_t pid;    if (fd_in) {    if (pipe(pipe_in)) {      mjpeg_error_exit1( "Couldn't create input pipe from %s", command);    }  }  if (fd_out) {    if (pipe(pipe_out)) {      mjpeg_error_exit1( "Couldn't create output pipe to %s", command);    }  }           if ((pid = fork ()) < 0) {    mjpeg_error_exit1("Couldn't fork %s", command);  }     if (pid == 0) {    /* child redirects stdout to pipe_in */    if (fd_in) {      close(pipe_in[0]);      close(1);      n = dup(pipe_in[1]);      if (n != 1) exit (1);    }    /* child redirects stdin to pipe_out */    if (fd_out) {      close(pipe_out[1]);      close(0);      n = dup(pipe_out[0]);      if (n != 0) exit(1);    }    myargv = parse_spawn_command(command);    execvp(myargv[0], myargv);    return -1;  } else {    /* parent */    if (fd_in != NULL) {      close(pipe_in[1]);      *fd_in = pipe_in[0];    }    if (fd_out != NULL) {      close(pipe_out[0]);      *fd_out = pipe_out[1];    }    return pid;  }}static pid_t fork_child(const char *command,			int offset, int num,			int *fd_in, int *fd_out){  char tmp1[1024], tmp2[1024];  char *current = tmp1;  char *next = tmp2;  char *p;  strncpy(current, command, 1024);     /* replace $o by offset */  p = strstr(current, "$o");  if (p) {    p[0] = '\0';    p += 2;    snprintf(next, 1024, "%s%d%s", current, offset, p);    p = current;    current = next;    next = p;  }    /* replace $n by number of frames */  p = strstr(current, "$n");  if (p) {    p[0] = '\0';    p += 2;    snprintf(next, 1024, "%s%d%s", current, num, p);    p = current;    current = next;    next = p;  }    mjpeg_debug( "Executing: '%s'", current);  return fork_child_sub(current, fd_in, fd_out);}static void alloc_yuv_buffers(unsigned char *yuv[3], int w, int h){  yuv[0] = malloc (w * h * sizeof(yuv[0][0]));  yuv[1] = malloc (w * h / 4 * sizeof(yuv[1][0]));  yuv[2] = malloc (w * h / 4 * sizeof(yuv[2][0]));}static void free_yuv_buffers(unsigned char *yuv[3]){  free(yuv[0]);  free(yuv[1]);  free(yuv[2]);  yuv[0] = yuv[1] = yuv[2] = NULL;}static void init_pipe_source(pipe_source_t *ps, char *command){  ps->command = strdup(command);  y4m_init_stream_info(&(ps->streaminfo));  y4m_init_frame_info(&(ps->frameinfo));  ps->pid = -1;  ps->fd = -1;  ps->frame_num = 0;}static void fini_pipe_source(pipe_source_t *ps){  free(ps->command);  y4m_fini_stream_info(&(ps->streaminfo));  y4m_fini_frame_info(&(ps->frameinfo));}static void spawn_pipe_source(pipe_source_t *ps, int offset, int count){  ps->pid = fork_child(ps->command,		       offset, count,		       &(ps->fd), NULL);  ps->frame_num = offset;  mjpeg_debug("spawned source '%s'", ps->command);}static void decommission_pipe_source(pipe_source_t *source){  if (source->fd >= 0) {    close(source->fd);    source->fd = -1;  }  if (source->pid > 0) {    mjpeg_debug("DIE DIE DIE pid %d", source->pid);    kill(source->pid, SIGINT);    source->pid = -1;  }}static void init_pipe_filter(pipe_filter_t *pf, const char *command){  pf->command = strdup(command);  y4m_init_stream_info(&(pf->out_streaminfo));  y4m_init_stream_info(&(pf->in_streaminfo));  y4m_init_frame_info(&(pf->frameinfo));  pf->yuv[0] = pf->yuv[1] = pf->yuv[2] = NULL;  pf->pid = -1;  pf->out_fd = -1;  pf->in_fd = -1;}static void fini_pipe_filter(pipe_filter_t *pf){  free(pf->command);  free_yuv_buffers(pf->yuv);  y4m_fini_stream_info(&(pf->out_streaminfo));  y4m_fini_stream_info(&(pf->in_streaminfo));  y4m_fini_frame_info(&(pf->frameinfo));}static void spawn_pipe_filter(pipe_filter_t *pf, int offset, int count){  pf->pid = fork_child(pf->command,		       offset, count,		       &(pf->in_fd), &(pf->out_fd));  mjpeg_debug("spawned filter '%s'", pf->command);}static void decommission_pipe_filter(pipe_filter_t *filt){  if (filt->in_fd >= 0) {    close(filt->in_fd);    filt->in_fd = -1;  }  if (filt->out_fd >= 0) {    close(filt->out_fd);    filt->out_fd = -1;  }  if (filt->pid > 0) {    mjpeg_debug("DIE DIE DIE pid %d", filt->pid);    kill(filt->pid, SIGINT);    filt->pid = -1;  }  free_yuv_buffers(filt->yuv);}    /* * make sure all the sources needed for this segment are cued up *  and ready to produce frames * */staticvoid open_segment_inputs(PipeSegment *seg, pipe_filter_t *filt,			 int frame, int segnum, int total_frames,			 PipeList *pl, commandline_params_t *cl,			 pipe_source_t *sources) {  int i, j, k;    for (i = 0; i < seg->input_count; i++) {    int in_index = seg->input_index[i];    int in_offset = seg->input_offset[i];    pipe_source_t *source = &(sources[in_index]);    mjpeg_debug("OSI:  input %d == source %d: '%s'",		i, in_index, source->command);    /* spawn the source if not already running */    if (source->fd < 0) {            /* calculate # of frames we want to get from this stream */      /* need to look if we can use this in successive sequences and	 what param_frames is */            int offset = in_offset + frame;      int count = seg->frame_count - frame; /* until end of sequence */            for (j = segnum + 1; j < pl->segment_count; j++) {	PipeSegment *other = pl->segments[j];	/*	mjpeg_debug("checking  i %d   j %d", i, j); */	for (k = 0; k < other->input_count; k++) {	  /*	  mjpeg_debug("checking  i %d   j %d  k %d", i, j, k); */	  if (in_index == other->input_index[k]) {	    if ((offset + count) == other->input_offset[k]) {	      count += other->frame_count; /* add another sequence */	    } else	      goto FINISH_CHECK; /* need to reopen with other offset */	  } else	    goto FINISH_CHECK; /* stream will not be used in				  segment j anymore */	}      }    FINISH_CHECK:      /*      mjpeg_debug("finish-check  i %d   j %d  k %d", i, j, k); */      if (count > cl->frames - total_frames) {	count = cl->frames - total_frames;      }      /******** why have 'count'?  let the source keep making frames...	 ...we'll just kill it when we are done anyway! *********/      /*      spawn_pipe_source(source, offset, count);*/      spawn_pipe_source(source, offset, 0);      if (y4m_read_stream_header(source->fd, &(source->streaminfo)) != Y4M_OK)	mjpeg_error_exit1("Bad source header!");      mjpeg_debug("read header");      y4m_log_stream_info(LOG_DEBUG, "src: ", &(source->streaminfo));    } else {      mjpeg_debug("...source %d is still alive.", in_index);    }        if (i == 0) {      /* first time:  copy stream info to filter */      y4m_copy_stream_info(&(filt->out_streaminfo), &(source->streaminfo));      mjpeg_debug("copied info");    } else {      /* n-th time:  make sure source streams match */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -