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

📄 ppmtoy4m.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ppmtoy4m.c:  Generate a YUV4MPEG2 stream from one or more PPM images * *              Converts R'G'B' to ITU-Rec.601 Y'CbCr colorspace and *               performs 4:2:0 chroma subsampling. * * *  Copyright (C) 2004 Matthew J. 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. * */#include <config.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <yuv4mpeg.h>#include <mpegconsts.h>#include "subsample.h"#include "colorspace.h"#ifndef O_BINARY# define O_BINARY 0#endif#define DEFAULT_CHROMA_MODE Y4M_CHROMA_444/* command-line parameters */typedef struct _cl_info {  y4m_ratio_t aspect;      y4m_ratio_t framerate;   int interlace;           int interleave;  int offset;  int framecount;  int repeatlast;  int ss_mode;  int verbosity;  int fdin;  int bgr;} cl_info_t;/* PPM image information */typedef struct _ppm_info {  int width;  int height;} ppm_info_t;staticvoid usage(const char *progname){  fprintf(stdout, "\n");  fprintf(stdout, "usage:  %s [options] [ppm-file]\n", progname);  fprintf(stdout, "\n");  fprintf(stdout, "Reads RAW PPM image(s), and produces YUV4MPEG2 stream on stdout.\n");  fprintf(stdout, "Converts computer graphics R'G'B' colorspace to digital video Y'CbCr,\n");  fprintf(stdout, " and performs chroma subsampling.\n");  fprintf(stdout, "\n");  fprintf(stdout, "If 'ppm-file' is not specified, reads from stdin.\n");  fprintf(stdout, "\n");  fprintf(stdout, " options:  (defaults specified in [])\n");  fprintf(stdout, "\n");  fprintf(stdout, "  -o n     frame offset (skip n input frames) [0]\n");  fprintf(stdout, "  -n n     frame count (output n frames; 0 == all of them) [0]\n");  fprintf(stdout, "  -F n:d   framerate [30000:1001 = NTSC]\n");  fprintf(stdout, "  -A w:h   pixel aspect ratio [1:1]\n");  fprintf(stdout, "  -I x     interlacing [p]\n");  fprintf(stdout, "             p = none/progressive\n");  fprintf(stdout, "             t = top-field-first\n");  fprintf(stdout, "             b = bottom-field-first\n");  fprintf(stdout, "  -L       treat PPM images as 2-field interleaved\n");  fprintf(stdout, "  -r       repeat last input frame\n");  {    int m;    const char *keyword;    fprintf(stdout, "  -S mode  chroma subsampling mode [%s]\n",	    y4m_chroma_keyword(DEFAULT_CHROMA_MODE));    for (m = 0;	 (keyword = y4m_chroma_keyword(m)) != NULL;	 m++)      if (chroma_sub_implemented(m))	fprintf(stdout, "            '%s' -> %s\n",		keyword, y4m_chroma_description(m));  }  /*  fprintf(stdout, "  -R type  subsampling filter type\n");*/  fprintf(stdout, "  -v n     verbosity (0,1,2) [1]\n");  fprintf(stdout, "  -B       PPM image is packed with BGR pixels [RGB]\n");}staticvoid parse_args(cl_info_t *cl, int argc, char **argv){  int c;  cl->offset = 0;  cl->framecount = 0;  cl->aspect = y4m_sar_SQUARE;  cl->interlace = Y4M_ILACE_NONE;  cl->framerate = y4m_fps_NTSC;  cl->interleave = 0;  cl->repeatlast = 0;  cl->ss_mode = DEFAULT_CHROMA_MODE;  cl->verbosity = 1;  cl->bgr = 0;  cl->fdin = 0; /* default to stdin */  while ((c = getopt(argc, argv, "BA:F:I:Lo:n:rS:v:h")) != -1) {    switch (c) {    case 'A':      if (y4m_parse_ratio(&(cl->aspect), optarg) != Y4M_OK) {	mjpeg_error("Could not parse ratio:  '%s'", optarg);	goto ERROR_EXIT;      }      break;    case 'F':      if (y4m_parse_ratio(&(cl->framerate), optarg) != Y4M_OK) {	mjpeg_error("Could not parse ratio:  '%s'", optarg);	goto ERROR_EXIT;      }      break;    case 'I':      switch (optarg[0]) {      case 'p':  cl->interlace = Y4M_ILACE_NONE;  break;      case 't':  cl->interlace = Y4M_ILACE_TOP_FIRST;  break;      case 'b':  cl->interlace = Y4M_ILACE_BOTTOM_FIRST;  break;      default:	mjpeg_error("Unknown value for interlace: '%c'", optarg[0]);	goto ERROR_EXIT;	break;      }      break;    case 'L':      cl->interleave = 1;      break;    case 'B':      cl->bgr = 1;      break;    case 'o':      if ((cl->offset = atoi(optarg)) < 0)	mjpeg_error_exit1("Offset must be >= 0:  '%s'", optarg);      break;    case 'n':      if ((cl->framecount = atoi(optarg)) < 0)	mjpeg_error_exit1("Frame count must be >= 0:  '%s'", optarg);      break;    case 'r':      cl->repeatlast = 1;      break;    case 'S':      cl->ss_mode = y4m_chroma_parse_keyword(optarg);      if (cl->ss_mode == Y4M_UNKNOWN) {	mjpeg_error("Unknown subsampling mode option:  %s", optarg);	goto ERROR_EXIT;      } else if (!chroma_sub_implemented(cl->ss_mode)) {	mjpeg_error("Unsupported subsampling mode option:  %s", optarg);	goto ERROR_EXIT;      }      break;    case 'v':      cl->verbosity = atoi(optarg);      if ((cl->verbosity < 0) || (cl->verbosity > 2))	mjpeg_error("Verbosity must be 0, 1, or 2:  '%s'", optarg);      break;    case 'h':      usage(argv[0]);      exit(0);      break;    case '?':    default:      goto ERROR_EXIT;      break;    }  }  /* optional remaining argument is a filename */  if (optind == (argc - 1)) {    if ((cl->fdin = open(argv[optind], O_RDONLY | O_BINARY)) == -1)      mjpeg_error_exit1("Failed to open '%s':  %s",			argv[optind], strerror(errno));  } else if (optind != argc)     goto ERROR_EXIT;  mjpeg_default_handler_verbosity(cl->verbosity);  mjpeg_info("Command-line Parameters:");  mjpeg_info("             framerate:  %d:%d",	     cl->framerate.n, cl->framerate.d);  mjpeg_info("    pixel aspect ratio:  %d:%d",	     cl->aspect.n, cl->aspect.d);  mjpeg_info("         pixel packing:  %s",	     cl->bgr?"BGR":"RGB");  mjpeg_info("             interlace:  %s%s",	     mpeg_interlace_code_definition(cl->interlace),	     (cl->interlace == Y4M_ILACE_NONE) ? "" :	     (cl->interleave) ? " (interleaved PPM input)" :	     " (field-sequential PPM input)");  mjpeg_info("        starting frame:  %d", cl->offset);  if (cl->framecount == 0)    mjpeg_info("           # of frames:  all%s",	       (cl->repeatlast) ? ", repeat last frame forever" :	       ", until input exhausted");  else    mjpeg_info("           # of frames:  %d%s",	       cl->framecount,	       (cl->repeatlast) ? ", repeat last frame until done" :	       ", or until input exhausted");  mjpeg_info("    chroma subsampling:  %s",	     y4m_chroma_description(cl->ss_mode));  /* DONE! */  return; ERROR_EXIT:  mjpeg_error("For usage hints, use option '-h'.  Please take a hint.");  exit(1);}/* * returns:  0 - success, got header *           1 - EOF, no new frame *          -1 - failure */#define DO_READ_NUMBER(var)                                     \  do {                                                          \    if (!isdigit(s[0]))                                         \      mjpeg_error_exit1("PPM read error:  bad char");         \    (var) = ((var) * 10) + (s[0] - '0');                        \  } while (((n = read(fd, s, 1)) == 1) && (!isspace(s[0])));    \  if (n <= 0) return -1;                                        #define DO_SKIP_WHITESPACE()                                     \  incomment = 0;                                                 \  while ( ((n = read(fd, s, 1)) == 1) &&                         \	  ((isspace(s[0])) || (s[0] == '#') || (incomment)) ) {  \    if (s[0] == '#') incomment = 1;                              \    if (s[0] == '\n') incomment = 0;                             \  }                                                              \  if (n <= 0) return -1;                                         staticint read_ppm_header(int fd, int *width, int *height){  char s[6];  int incomment;  int n;  int maxval = 0;    *width = 0;  *height = 0;  /* look for "P6" */  n = y4m_read(fd, s, 3);  if (n > 0)     return 1;  /* EOF */  if ((n < 0) || (strncmp(s, "P6", 2)))    mjpeg_error_exit1("Bad Raw PPM magic!");  incomment = 0;  DO_SKIP_WHITESPACE();  DO_READ_NUMBER(*width);  DO_SKIP_WHITESPACE();  DO_READ_NUMBER(*height);  DO_SKIP_WHITESPACE();  DO_READ_NUMBER(maxval);  if (maxval != 255)    mjpeg_error_exit1("Expecting maxval == 255, not %d!", maxval);  return 0;}staticvoid alloc_buffers(uint8_t *buffers[], int width, int height){  mjpeg_debug("Alloc'ing buffers");  buffers[0] = malloc(width * height * 2 * sizeof(buffers[0][0]));  buffers[1] = malloc(width * height * 2 * sizeof(buffers[1][0]));  buffers[2] = malloc(width * height * 2 * sizeof(buffers[2][0]));}staticvoid read_ppm_into_two_buffers(int fd,

⌨️ 快捷键说明

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