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

📄 lavpipe.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      if (y4m_si_get_width(&(filt->out_streaminfo)) != 	  y4m_si_get_width(&(source->streaminfo))) 	mjpeg_error_exit1("Stream mismatch:  frame width");      if (y4m_si_get_height(&(filt->out_streaminfo)) != 	  y4m_si_get_height(&(source->streaminfo))) 	mjpeg_error_exit1("Stream mismatch:  frame height");      if (y4m_si_get_interlace(&(filt->out_streaminfo)) != 	  y4m_si_get_interlace(&(source->streaminfo))) 	mjpeg_error_exit1("Stream mismatch:  interlace");      mjpeg_debug("verified info");    }  }  }staticvoid setup_segment_filter(PipeSegment *seg, pipe_filter_t *filt, int frame){  mjpeg_debug("OSO:  '%s'", filt->command);  if (strcmp(filt->command, "-")) {    /* ...via a filter command:     *     o spawn filter process     *     o write source stream info to filter     *     o read filter's result stream info     *     o alloc yuv buffers for source->filter transfers     */    /* ... why does the 'count' matter, if lavpipe controls the frame     *      flow anyway???????? */    spawn_pipe_filter(filt, frame, (seg->frame_count - frame));    y4m_write_stream_header(filt->out_fd, &(filt->out_streaminfo));    y4m_read_stream_header(filt->in_fd, &(filt->in_streaminfo));    mjpeg_debug("SSF:  read filter result stream header");    y4m_log_stream_info(LOG_DEBUG, "result: ", &(filt->in_streaminfo));    alloc_yuv_buffers(filt->yuv, 		      y4m_si_get_width(&(filt->out_streaminfo)),		      y4m_si_get_height(&(filt->out_streaminfo)));  } else {    /* ...no filter; direct output:     *     o result stream info is just a copy of the source stream info     */    filt->out_fd = filt->in_fd = -1;    y4m_copy_stream_info(&(filt->in_streaminfo), &(filt->out_streaminfo));    mjpeg_debug("SSF:  copied source header");  }}staticvoid process_segment_frames(pipe_sequence_t *ps, int segnum,			    int *frame, int *total_frames){  pipe_source_t *sources = ps->sources;  pipe_filter_t *the_output = &(ps->output);  PipeList *pl = &(ps->pl);  commandline_params_t *cl = &(ps->cl);  PipeSegment *seg = ps->pl.segments[segnum];  pipe_filter_t *filt = &(ps->filters[segnum]);  mjpeg_debug("PSF:  segment %d,  initial frame = %d", segnum, *frame);  while (*frame < seg->frame_count) {    int i;        for (i = 0; i < seg->input_count; i++) {      int in_index = seg->input_index[i];      pipe_source_t *source = &(sources[in_index]);      unsigned char **yuv;            if (filt->out_fd >= 0)        /* filter present; write/read through filter's buffer first */	yuv = filt->yuv;      else	/* no filter present; source -> direct to output buffer */	yuv = the_output->yuv;      mjpeg_debug("read frame %03d > input %d, src %d  fd = %d", 		  *frame, i, in_index, source->fd);      if (y4m_read_frame(source->fd,			 &(source->streaminfo), &(source->frameinfo),			 yuv) != Y4M_OK) {	int err = errno;	mjpeg_error("ERRNO says:  %s", strerror(err));	mjpeg_error_exit1("lavpipe: input stream error in stream %d,"			  "sequence %d, frame %d", 			  i, segnum, *frame);      }      source->frame_num += 1;            if (filt->out_fd >= 0)	y4m_write_frame(filt->out_fd,			&(filt->out_streaminfo), &(filt->frameinfo),			yuv);    }        if (filt->in_fd >= 0) {      if (y4m_read_frame(filt->in_fd,			 &(filt->in_streaminfo), &(filt->frameinfo),			 the_output->yuv) != Y4M_OK) {	mjpeg_error_exit1( "lavpipe: filter stream error in sequence %d,"			   "frame %d",			   segnum, *frame);      }    }        /* output result */    y4m_write_frame(the_output->out_fd, 		    &(the_output->out_streaminfo), 		    &(the_output->frameinfo),		    the_output->yuv);        (*frame)++;    if (++(*total_frames) == cl->frames) {      segnum = pl->segment_count - 1; /* = close all input files below */      break;    }  }}/*  * this is just being picky, but... *  * Close all sources used by current segment, but only if they will *  cannot be used in current state by upcoming segments. * */staticvoid close_segment_inputs(pipe_sequence_t *ps, int segnum, int frame){  PipeList *pl = &(ps->pl);  pipe_source_t *sources = ps->sources;  PipeSegment *seg = pl->segments[segnum];  int i;  for (i = 0; i < seg->input_count; i++) {    int current_index = seg->input_index[i];    pipe_source_t *source = &(sources[current_index]);    if (source->fd >= 0) {      /* if it's still alive...       * ...iterate over remaining segments, and see if they can       *    use this source.        */      int s;      for (s = segnum + 1; s < pl->segment_count; s++) {	int j;	PipeSegment *next_seg = pl->segments[s];		for (j = 0; j < next_seg->input_count; j++) {	  int index = next_seg->input_index[j];	  int offset = next_seg->input_offset[j];	  	  if ( (index == current_index) &&	       (offset == source->frame_num) ) {	    /* A segment input offset matches the current frame...	     * ...this source can still be used.	     */	    mjpeg_info("allowing input %d (source %d) to live",		       i, current_index);	    goto KEEP_SOURCE;	  }	}      }      mjpeg_info( "closing input %d (source %d)", i, current_index);      decommission_pipe_source(source);KEEP_SOURCE: ;    }  }}staticvoid parse_command_line(int argc, char *argv[], commandline_params_t *cl){  char c;  int err;  cl->verbose = 1;  cl->offset = 0;  cl->frames = 0;   cl->listfile = NULL;    err = 0;  while ((c = getopt(argc, argv, "o:n:v:")) != EOF) {    switch (c) {    case 'o':      cl->offset = atoi(optarg);      break;    case 'n':      cl->frames = atoi(optarg);      break;    case 'v':      cl->verbose = atoi(optarg);      if ( (cl->verbose < 0) || (cl->verbose > 2) ) {	usage();	exit(1);      }      break;    default:      err++;    }  }  if ((optind >= argc) || (err)) {    usage();    exit(1);  }  cl->listfile = strdup(argv[optind]);}staticvoid initialize_pipe_sequence(pipe_sequence_t *ps, int argc, char **argv){  int i;  commandline_params_t *cl = &(ps->cl);  PipeList *pl = &(ps->pl);  init_pipe_filter(&(ps->output), "");  ps->output.out_fd = 1;  /* parse command-line arguments */  parse_command_line(argc, argv, cl);  /* set-up logging */  (void)mjpeg_default_handler_verbosity(cl->verbose);  /* read pipe 'recipe' */  if (read_pipe_list(cl->listfile, pl) < 0) {    mjpeg_error_exit1( "lavpipe: couldn't open \"%s\"", cl->listfile);  }    /* a negative offset means "from the end" */  if (cl->offset < 0) {    cl->offset = pl->frame_count + cl->offset;  }     if ((cl->offset >= pl->frame_count) ||      (cl->offset < 0)) {    mjpeg_error_exit1( "error: offset greater than # of frames in input");  }  /* zero frame count means "all frames" */  if (cl->frames == 0) {    cl->frames = pl->frame_count - cl->offset;  }  if ((cl->offset + cl->frames) > pl->frame_count) {    mjpeg_warn( "input too short for -n %d", cl->frames);    cl->frames = pl->frame_count - cl->offset;  }    /* initialize pipe sources */  ps->sources = malloc(pl->source_count * sizeof(ps->sources[0]));  for (i = 0; i < pl->source_count; i++)     init_pipe_source(&(ps->sources[i]), pl->source_cmd[i]);  /* initialize pipe filters */  ps->filters = malloc(pl->segment_count * sizeof(ps->filters[0]));  for (i = 0; i < pl->segment_count; i++)     init_pipe_filter(&(ps->filters[i]), pl->segments[i]->output_cmd);  }staticvoid process_pipe_sequence(pipe_sequence_t *ps){  int segm_num;       /* current segment number */  int segm_frame;     /* frame number, within a segment */  int sequ_frame;     /* cumulative/total frame number  */  int first_iteration;    /* find start segment/frame, given overall lavpipe offset ("-o") */  segm_frame = ps->cl.offset;  for (segm_num = 0;       segm_frame >= ps->pl.segments[segm_num]->frame_count;       segm_num++) {    segm_frame -= ps->pl.segments[segm_num]->frame_count;  }  /* process the segments */  first_iteration = 1;  sequ_frame = 0;  while ( (segm_num < ps->pl.segment_count) && 	  (sequ_frame < ps->cl.frames) ) {    PipeSegment *seg = ps->pl.segments[segm_num];    pipe_filter_t *filt = &(ps->filters[segm_num]);        mjpeg_debug("starting segment %d, frame %d", segm_num, segm_frame);        open_segment_inputs(seg, filt, segm_frame, segm_num, sequ_frame,			&ps->pl, &ps->cl, ps->sources);    setup_segment_filter(seg, filt, segm_frame);        if (first_iteration) {      /* Initialize the final output stream, just once */            /* The final output stream parameters are taken from the output       *  parameters of the first segment's output filter.       * (If there is no filter (i.e. "-", direct output), then the       *  parameters will end up coming from the first segment's source       *  stream.)       */      y4m_copy_stream_info(&(ps->output.out_streaminfo),			   &(filt->in_streaminfo));      y4m_write_stream_header(ps->output.out_fd, &(ps->output.out_streaminfo));      alloc_yuv_buffers(ps->output.yuv, 			y4m_si_get_width(&(ps->output.out_streaminfo)),			y4m_si_get_height(&(ps->output.out_streaminfo)));      mjpeg_debug("output stream initialized");      first_iteration = 0;    } else {      /* For succeeding segments, make sure that the new filter's stream is       *  consistent with the final output stream.       */      if (y4m_si_get_width(&(filt->in_streaminfo)) != 	  y4m_si_get_width(&(ps->output.out_streaminfo)))	mjpeg_error_exit1("Stream mismatch:  frame width");      if (y4m_si_get_height(&(filt->in_streaminfo)) != 	  y4m_si_get_height(&(ps->output.out_streaminfo)))	mjpeg_error_exit1("Stream mismatch:  frame height");      if (y4m_si_get_interlace(&(filt->in_streaminfo)) != 	  y4m_si_get_interlace(&(ps->output.out_streaminfo)))	mjpeg_error_exit1("Stream mismatch:  interlace");      mjpeg_debug("filter stream verified");    }              process_segment_frames(ps, segm_num, &segm_frame, &sequ_frame);    decommission_pipe_filter(filt);    close_segment_inputs(ps, segm_num, segm_frame);        /* prepare for next sequence */    segm_num++;    segm_frame = 0;  }}staticvoid cleanup_pipe_sequence(pipe_sequence_t *ps){  int i;  PipeList *pl = &(ps->pl);  /* free/fini everything */  fini_pipe_filter(&ps->output);  for (i = 0; i < pl->source_count; i++)     fini_pipe_source(&(ps->sources[i]));  free(ps->sources);  for (i = 0; i < pl->segment_count; i++)     fini_pipe_filter(&(ps->filters[i]));  free(ps->filters);}int main (int argc, char *argv[]) {  pipe_sequence_t ps;  initialize_pipe_sequence(&ps, argc, argv);  process_pipe_sequence(&ps);  cleanup_pipe_sequence(&ps);  return 0;}

⌨️ 快捷键说明

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