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

📄 yuv4mpeg.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
y4m_xtag_list_t *y4m_si_xtags(y4m_stream_info_t *si){ return &(si->x_tags); }void y4m_init_frame_info(y4m_frame_info_t *info){  if (info == NULL) return;  /* init substructures */  y4m_init_xtag_list(&(info->x_tags));  /* set defaults */  y4m_clear_frame_info(info);}void y4m_clear_frame_info(y4m_frame_info_t *info){  if (info == NULL) return;  /* clear/initialize info */  info->spatial = Y4M_UNKNOWN;  info->temporal = Y4M_UNKNOWN;  info->presentation = Y4M_UNKNOWN;  y4m_xtag_clearlist(&(info->x_tags));}void y4m_copy_frame_info(y4m_frame_info_t *dest, const y4m_frame_info_t *src){  if ((dest == NULL) || (src == NULL)) return;  /* copy info */  dest->spatial = src->spatial;  dest->temporal = src->temporal;  dest->presentation = src->presentation;  y4m_copy_xtag_list(&(dest->x_tags), &(src->x_tags));}void y4m_fini_frame_info(y4m_frame_info_t *info){  if (info == NULL) return;  y4m_fini_xtag_list(&(info->x_tags));}void y4m_fi_set_presentation(y4m_frame_info_t *fi, int pres){ fi->presentation = pres; }int y4m_fi_get_presentation(const y4m_frame_info_t *fi){ return fi->presentation; }void y4m_fi_set_temporal(y4m_frame_info_t *fi, int sampling){ fi->temporal = sampling; }int y4m_fi_get_temporal(const y4m_frame_info_t *fi){ return fi->temporal; }void y4m_fi_set_spatial(y4m_frame_info_t *fi, int sampling){ fi->spatial = sampling; }int y4m_fi_get_spatial(const y4m_frame_info_t *fi){ return fi->spatial; }y4m_xtag_list_t *y4m_fi_xtags(y4m_frame_info_t *fi){ return &(fi->x_tags); }/************************************************************************* * * Tag parsing  * *************************************************************************//* Parse (the first) old, unofficial X-tag chroma specification,   and then remove that tag from the X-tag list. */static inthandle_old_chroma_xtag(y4m_stream_info_t *si){  y4m_xtag_list_t *xtags = y4m_si_xtags(si);  const char *tag = NULL;  int n, chroma;  for (n = y4m_xtag_count(xtags) - 1; n >= 0; n--) {    tag = y4m_xtag_get(xtags, n);    if (!strncmp("XYSCSS=", tag, 7)) break;  }  if ((tag == NULL) || (n < 0)) return Y4M_UNKNOWN;  mjpeg_warn("Deprecated X-tag for chroma found in a stream header...");  mjpeg_warn("...pester someone to upgrade the source's program!");  /* parse the tag */  tag += 7;  if (!strcmp("411", tag))           chroma = Y4M_CHROMA_411;  else if (!strcmp(tag, "420"))      chroma = Y4M_CHROMA_420JPEG;  else if (!strcmp(tag, "420MPEG2")) chroma = Y4M_CHROMA_420MPEG2;  else if (!strcmp(tag, "420PALDV")) chroma = Y4M_CHROMA_420PALDV;  else if (!strcmp(tag, "420JPEG"))  chroma = Y4M_CHROMA_420JPEG;  else if (!strcmp(tag, "444"))      chroma = Y4M_CHROMA_444;  else chroma = Y4M_UNKNOWN;  /* Remove the 'X' tag so that no one has to worry about it any more. */  y4m_xtag_remove(xtags, n);  /* Hmm... what if there are more XYSCSS tags?  Broken is as broken does;     thank goodness this is temporary code. */  return chroma;}int y4m_parse_stream_tags(char *s, y4m_stream_info_t *i){  char *token, *value;  char tag;  int err;  /* parse fields */  for (token = strtok(s, Y4M_DELIM);        token != NULL;        token = strtok(NULL, Y4M_DELIM)) {    if (token[0] == '\0') continue;   /* skip empty strings */    tag = token[0];    value = token + 1;    switch (tag) {    case 'W':  /* width */      i->width = atoi(value);      if (i->width <= 0) return Y4M_ERR_RANGE;      break;    case 'H':  /* height */      i->height = atoi(value);       if (i->height <= 0) return Y4M_ERR_RANGE;      break;    case 'F':  /* frame rate (fps) */      if ((err = y4m_parse_ratio(&(i->framerate), value)) != Y4M_OK)	return err;      if (i->framerate.n < 0) return Y4M_ERR_RANGE;      break;    case 'I':  /* interlacing */      switch (value[0]) {      case 'p':  i->interlace = Y4M_ILACE_NONE; break;      case 't':  i->interlace = Y4M_ILACE_TOP_FIRST; break;      case 'b':  i->interlace = Y4M_ILACE_BOTTOM_FIRST; break;      case 'm':  i->interlace = Y4M_ILACE_MIXED; break;      case '?':      default:	i->interlace = Y4M_UNKNOWN; break;      }      break;    case 'A':  /* sample (pixel) aspect ratio */      if ((err = y4m_parse_ratio(&(i->sampleaspect), value)) != Y4M_OK)	return err;      if (i->sampleaspect.n < 0) return Y4M_ERR_RANGE;      break;    case 'C':      i->chroma = y4m_chroma_parse_keyword(value);      if (i->chroma == Y4M_UNKNOWN)	return Y4M_ERR_HEADER;      break;    case 'X':  /* 'X' meta-tag */      if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err;      break;    default:      /* possible error on unknown options */      if (_y4mparam_allow_unknown_tags) {	/* unknown tags ok:  store in xtag list and warn... */	if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err;	mjpeg_warn("Unknown stream tag encountered:  '%s'", token);      } else {	/* unknown tags are *not* ok */	return Y4M_ERR_BADTAG;      }      break;    }  }  /* If feature_level > 0, then handle and/or remove any old-style XYSCSS     chroma tags.  The new-style 'C' tag takes precedence, however. */  if (_y4mparam_feature_level > 0) {    int xt_chroma = handle_old_chroma_xtag(i);    if (i->chroma == Y4M_UNKNOWN)      i->chroma = xt_chroma;    else if ((xt_chroma != Y4M_UNKNOWN) &&             (xt_chroma != i->chroma))      mjpeg_warn("Old chroma X-tag (ignored) does not match new chroma tag.");  }  /* Without 'C' tag or any other chroma spec, default to 420jpeg */  if (i->chroma == Y4M_UNKNOWN)     i->chroma = Y4M_CHROMA_420JPEG;  /* Error checking... */  /*      - Width and Height are required. */  if ((i->width == Y4M_UNKNOWN) || (i->height == Y4M_UNKNOWN))    return Y4M_ERR_HEADER;  /*      - Non-420 chroma and mixed interlace require level >= 1 */  if (_y4mparam_feature_level < 1) {    if ((i->chroma != Y4M_CHROMA_420JPEG) &&	(i->chroma != Y4M_CHROMA_420MPEG2) &&	(i->chroma != Y4M_CHROMA_420PALDV))      return Y4M_ERR_FEATURE;    if (i->interlace == Y4M_ILACE_MIXED)      return Y4M_ERR_FEATURE;  }  /* ta da!  done. */  return Y4M_OK;}static int y4m_parse_frame_tags(char *s, const y4m_stream_info_t *si,				y4m_frame_info_t *fi){  char *token, *value;  char tag;  int err;  /* parse fields */  for (token = strtok(s, Y4M_DELIM);        token != NULL;        token = strtok(NULL, Y4M_DELIM)) {    if (token[0] == '\0') continue;   /* skip empty strings */    tag = token[0];    value = token + 1;    switch (tag) {    case 'I':      /* frame 'I' tag requires feature level >= 1 */      if (_y4mparam_feature_level < 1) return Y4M_ERR_FEATURE;      if (si->interlace != Y4M_ILACE_MIXED) return Y4M_ERR_BADTAG;      switch (value[0]) {      case 't':  fi->presentation = Y4M_PRESENT_TOP_FIRST;        break;      case 'T':  fi->presentation = Y4M_PRESENT_TOP_FIRST_RPT;    break;      case 'b':  fi->presentation = Y4M_PRESENT_BOTTOM_FIRST;     break;      case 'B':  fi->presentation = Y4M_PRESENT_BOTTOM_FIRST_RPT; break;      case '1':  fi->presentation = Y4M_PRESENT_PROG_SINGLE;      break;      case '2':  fi->presentation = Y4M_PRESENT_PROG_DOUBLE;      break;      case '3':  fi->presentation = Y4M_PRESENT_PROG_TRIPLE;      break;      default: 	return Y4M_ERR_BADTAG;      }      switch (value[1]) {      case 'p':  fi->temporal = Y4M_SAMPLING_PROGRESSIVE; break;      case 'i':  fi->temporal = Y4M_SAMPLING_INTERLACED;  break;      default: 	return Y4M_ERR_BADTAG;      }      switch (value[2]) {      case 'p':  fi->spatial = Y4M_SAMPLING_PROGRESSIVE; break;      case 'i':  fi->spatial = Y4M_SAMPLING_INTERLACED;  break;      case '?':  fi->spatial = Y4M_UNKNOWN;              break;      default: 	return Y4M_ERR_BADTAG;      }      break;    case 'X':  /* 'X' meta-tag */      if ((err = y4m_xtag_add(&(fi->x_tags), token)) != Y4M_OK) return err;      break;    default:      /* possible error on unknown options */      if (_y4mparam_allow_unknown_tags) {	/* unknown tags ok:  store in xtag list and warn... */	if ((err = y4m_xtag_add(&(fi->x_tags), token)) != Y4M_OK) return err;	mjpeg_warn("Unknown frame tag encountered:  '%s'", token);      } else {	/* unknown tags are *not* ok */	return Y4M_ERR_BADTAG;      }      break;    }  }  /* error-checking and/or non-mixed defaults */  switch (si->interlace) {  case Y4M_ILACE_MIXED:    /* T and P are required if stream "Im" */    if ((fi->presentation == Y4M_UNKNOWN) || (fi->temporal == Y4M_UNKNOWN))      return Y4M_ERR_HEADER;    /* and S is required if stream is also 4:2:0 */    if ( ((si->chroma == Y4M_CHROMA_420JPEG) ||          (si->chroma == Y4M_CHROMA_420MPEG2) ||          (si->chroma == Y4M_CHROMA_420PALDV)) &&         (fi->spatial == Y4M_UNKNOWN) )      return Y4M_ERR_HEADER;    break;  case Y4M_ILACE_NONE:    /* stream "Ip" --> equivalent to frame "I1pp" */    fi->spatial = Y4M_SAMPLING_PROGRESSIVE;    fi->temporal = Y4M_SAMPLING_PROGRESSIVE;    fi->presentation = Y4M_PRESENT_PROG_SINGLE;    break;  case Y4M_ILACE_TOP_FIRST:    /* stream "It" --> equivalent to frame "Itii" */    fi->spatial = Y4M_SAMPLING_INTERLACED;    fi->temporal = Y4M_SAMPLING_INTERLACED;    fi->presentation = Y4M_PRESENT_TOP_FIRST;    break;  case Y4M_ILACE_BOTTOM_FIRST:    /* stream "Ib" --> equivalent to frame "Ibii" */    fi->spatial = Y4M_SAMPLING_INTERLACED;    fi->temporal = Y4M_SAMPLING_INTERLACED;    fi->presentation = Y4M_PRESENT_BOTTOM_FIRST;    break;  default:    /* stream unknown:  then, whatever */    break;  }  /* ta da!  done. */  return Y4M_OK;}/************************************************************************* * * Read/Write stream header * *************************************************************************/int y4m_read_stream_header(int fd, y4m_stream_info_t *i){   char line[Y4M_LINE_MAX];   char *p;   int n;   int err;  /* start with a clean slate */  y4m_clear_stream_info(i);   /* read the header line */   for (n = 0, p = line; n < Y4M_LINE_MAX; n++, p++) {     if (read(fd, p, 1) < 1)        return Y4M_ERR_SYSTEM;     if (*p == '\n') {       *p = '\0';           /* Replace linefeed by end of string */       break;     }   }   if (n >= Y4M_LINE_MAX)      return Y4M_ERR_HEADER;   /* look for keyword in header */   if (strncmp(line, Y4M_MAGIC, strlen(Y4M_MAGIC)))    return Y4M_ERR_MAGIC;   if ((err = y4m_parse_stream_tags(line + strlen(Y4M_MAGIC), i)) != Y4M_OK)     return err;   return Y4M_OK;}int y4m_write_stream_header(int fd, const y4m_stream_info_t *i){  char s[Y4M_LINE_MAX+1];  int n;  int err;  y4m_ratio_t rate = i->framerate;  y4m_ratio_t aspect = i->sampleaspect;  const char *chroma_keyword = y4m_chroma_keyword(i->chroma);  if ((i->chroma == Y4M_UNKNOWN) || (chroma_keyword == NULL))    return Y4M_ERR_HEADER;  if (_y4mparam_feature_level < 1) {    if ((i->chroma != Y4M_CHROMA_420JPEG) &&	(i->chroma != Y4M_CHROMA_420MPEG2) &&	(i->chroma != Y4M_CHROMA_420PALDV))      return Y4M_ERR_FEATURE;    if (i->interlace == Y4M_ILACE_MIXED)      return Y4M_ERR_FEATURE;  }  y4m_ratio_reduce(&rate);  y4m_ratio_reduce(&aspect);  n = snprintf(s, sizeof(s), "%s W%d H%d F%d:%d I%s A%d:%d C%s",	       Y4M_MAGIC,	       i->width,	       i->height,	       rate.n, rate.d,	       (i->interlace == Y4M_ILACE_NONE) ? "p" :	       (i->interlace == Y4M_ILACE_TOP_FIRST) ? "t" :	       (i->interlace == Y4M_ILACE_BOTTOM_FIRST) ? "b" :	       (i->interlace == Y4M_ILACE_MIXED) ? "m" : "?",	       aspect.n, aspect.d,	       chroma_keyword	       );  if ((n < 0) || (n > Y4M_LINE_MAX)) return Y4M_ERR_HEADER;  if ((err = y4m_snprint_xtags(s + n, sizeof(s) - n - 1, &(i->x_tags)))       != Y4M_OK)     return err;  /* non-zero on error */  return (y4m_write(fd, s, strlen(s)) ? Y4M_ERR_SYSTEM : Y4M_OK);}/************************************************************************* * * Read/Write frame header * *************************************************************************/int y4m_read_frame_header(int fd,			  const y4m_stream_info_t *si,			  y4m_frame_info_t *fi){  char line[Y4M_LINE_MAX];  char *p;  int n;  ssize_t remain;    /* start with a clean slate */  y4m_clear_frame_info(fi);  /* This is more clever than read_stream_header...     Try to read "FRAME\n" all at once, and don't try to parse     if nothing else is there...  */  remain = y4m_read(fd, line, sizeof(Y4M_FRAME_MAGIC)-1+1); /* -'\0', +'\n' */  if (remain < 0) return Y4M_ERR_SYSTEM;  if (remain > 0) {    /* A clean EOF should end exactly at a frame-boundary */    if (remain == sizeof(Y4M_FRAME_MAGIC))      return Y4M_ERR_EOF;    else      return Y4M_ERR_BADEOF;  }  if (strncmp(line, Y4M_FRAME_MAGIC, sizeof(Y4M_FRAME_MAGIC)-1))    return Y4M_ERR_MAGIC;  if (line[sizeof(Y4M_FRAME_MAGIC)-1] == '\n')    return Y4M_OK; /* done -- no tags:  that was the end-of-line. */  if (line[sizeof(Y4M_FRAME_MAGIC)-1] != Y4M_DELIM[0]) {    return Y4M_ERR_MAGIC; /* wasn't a space -- what was it? */  }  /* proceed to get the tags... (overwrite the magic) */  for (n = 0, p = line; n < Y4M_LINE_MAX; n++, p++) {    if (y4m_read(fd, p, 1))      return Y4M_ERR_SYSTEM;    if (*p == '\n') {      *p = '\0';           /* Replace linefeed by end of string */      break;    }  }  if (n >= Y4M_LINE_MAX) return Y4M_ERR_HEADER;

⌨️ 快捷键说明

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