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

📄 yuvkineco.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      }    }    data += width * height;    if (pln == 0) {      width  /= CWDIV(y4m_si_get_chroma(&h->_.si));      height /= CHDIV(y4m_si_get_chroma(&h->_.si));    }  }  return n;}static intputframe(YfTask_t *h, int c, YfFrame_t *frame){  if (c <= 1) {    if (c)      deinterlace(h, frame->data, h->_.width, h->_.height, h->u.noise.level0);  } else {    if (0 <= h->deintl) {      int n;      int bytes = FRAMEBYTES(y4m_si_get_chroma(&h->_.si), h->_.width, h->_.height);      YfFrame_t *fdst = (YfFrame_t *)((char *)h->frame + (h->nframes * bytes));      y4m_copy_frame_info(&fdst->fi, &frame->fi);      memcpy(fdst->data, frame->data, bytes - sizeof frame->fi);      n = deinterlace(h, fdst->data, h->_.width, h->_.height, h->u.noise.level0);      if (h->deintl < n) {	frame = fdst;	c -= 'O' - 'D';	h->deintlframes++;	if (n < h->deintlmin)	  h->deintlmin = n;      } else {	if (h->nointlmax < n)	  h->nointlmax = n;      }      n *= (2 * DEINTLRESO);      n /= (bytes - sizeof frame->fi);      if (sizeof h->deintldist / sizeof h->deintldist[0] <= n)	n = (sizeof h->deintldist / sizeof h->deintldist[0]) - 1;      h->deintldist[n]++;    }    if (h->cytype == 'C')      putcy(h, c);  }  return YfPutFrame(&h->_, frame);}static intdo_frame(YfTaskCore_t *handle, const YfTaskCore_t *h0, const YfFrame_t *frame0){  static const unsigned long fp1001s[] = {    0, 24000, 24024, 25025, 30000, 30030, 50050, 60000, 60060, };  YfTask_t *h = (YfTask_t *)handle;  int framebytes = FRAMEBYTES(y4m_si_get_chroma(&h->_.si), h->_.width, h->_.height);  int iadjust = ((h->_.fpscode == h->fpscode0)? 1:		 (((int64_t)h->iuse * fp1001s[h->_.fpscode] /		   fp1001s[h->fpscode0]) - h->iput));  int wdiv = CWDIV(y4m_si_get_chroma(&h->_.si));  int hdiv = CHDIV(y4m_si_get_chroma(&h->_.si));  /* copy frame to buffer */  if (frame0) {    int b = h->iget % h->nframes;    YfFrame_t *fget = (YfFrame_t *)((char *)h->frame + (b * framebytes));    y4m_copy_frame_info(&fget->fi, &frame0->fi);    memcpy(fget->data, frame0->data, framebytes - sizeof frame0->fi);    /* get frame summary */    if (h->cytype == 'O' || h->cytype =='N') {      /* do nothing */    } else if (!h->iget) {      h->framestat[b].odiff = 0 /* 9999999 */;      h->framestat[b].ediff = 0 /* 9999999 */;    } else {      int i, j, d;      unsigned int ypre, yget;      unsigned int noise;      int ipre = (h->iget - 1) % h->nframes;      YfFrame_t *fpre = (YfFrame_t *)((char *)h->frame + (ipre * framebytes));      memset(&h->framestat[b], 0, sizeof h->framestat[b]);      for (i = h->nfields; i < h->_.height; i += h->nfields) {	for (j = 0; j < h->_.width; j++) {	  ypre = fpre->data[(i * h->_.width) + j];	  yget = fget->data[(i * h->_.width) + j];	  noise = h->u.noise.level0;	  if (yget < noise)	    noise = yget;	  else if (256 - yget < noise)	    noise = 256 - yget;	  if ((d = ypre - yget) < 0) d = -d;	  h->framestat[b].diffdist[(d < NOISEMAX)? d: NOISEMAX]++;	  if (noise < d) {	    d -= noise;	    h->framestat[b].odiff += (((d * d) + 8) >> 4);	  }	  if (1 < h->nfields) {	    unsigned int ygte;	    ypre = fpre->data[((i - 1) * h->_.width) + j];	    ygte = fget->data[((i - 1) * h->_.width) + j];	    if ((d = yget - ygte) < 0) d = -d;	    if (noise < d) {	      d -= noise;	      h->framestat[b].eoediff -= (((d * d) + 16) >> 5);	    }	    if ((d = yget - ypre) < 0) d = -d;	    if (noise < d) {	      d -= noise;	      h->framestat[b].eoediff += (((d * d) + 16) >> 5);	    }	    ypre = fpre->data[((i + 1) * h->_.width) + j];	    ygte = fget->data[((i + 1) * h->_.width) + j];	    if ((d = yget - ygte) < 0) d = -d;	    if (noise < d) {	      d -= noise;	      h->framestat[b].eoediff -= (((d * d) + 16) >> 5);	    }	    if ((d = yget - ypre) < 0) d = -d;	    if (noise < d) {	      d -= noise;	      h->framestat[b].eoediff += (((d * d) + 16) >> 5);	    }	    if ((d = ypre - ygte) < 0) d = -d;	    if (noise < d) {	      d -= noise;	      h->framestat[b].ediff += (((d * d) + 8) >> 4);	    }	  }	}      }#define PER1024PIXEL(p,h,w) (((p)/=(w)), ((p)<<=10), ((p)/=(h)))      PER1024PIXEL(h->framestat[b].odiff, ((h->_.height / h->nfields) - 1), h->_.width);      if (1 < h->nfields) {	PER1024PIXEL(h->framestat[b].ediff, ((h->_.height / 2) - 1), h->_.width);	PER1024PIXEL(h->framestat[b].eoediff, ((h->_.height / 2) - 1), h->_.width);      }    }    h->iget++;  }  if (!h->cytype || h->cytype =='C') { /* 1st try */    /* process frames in buffer */    if (h->iget - h->iuse == h->nframes || !frame0) {      int b = h->iuse % h->nframes;      int i, idrp;      unsigned long dthr = 0;      char notdrop[48];      char debugbuf[1024];      debugbuf[0] = '\0';      if (1 < verbose) {	MPEG_timecode_t tc;	mpeg_timecode(&tc, h->iput, h->_.fpscode, 0.);	buf_debug(debugbuf, NULL, "%02d:%02d:%02d ", tc.m, tc.s, tc.f);      }      {				/* get threshold */	unsigned long dmin = 0xffffffffUL, dmax = 0;	int imin = -1, imax = -1;	for (i = 0; i < h->iget - h->iuse - 1; i++) {	  unsigned long odiff = h->framestat[(b + i) % h->nframes].odiff;	  if (1 < verbose)	    buf_debug(debugbuf, NULL, "%8ld:%-7lu",		      h->framestat[(b + i) % h->nframes].eoediff, odiff);	  if (odiff < dmin) {	    dmin = odiff;	    imin = i;		/* maybe repeated field */	  }	  if (dmax < odiff) {	    dmax = odiff;	    imax = i;		/* maybe cut changed */	  }	}	for (i = 0; i < h->iget - h->iuse - 1; i++)	  if (i != imin && i != imax)	    dthr += h->framestat[(b + i) % h->nframes].odiff; /* sum */	if (0 < i - 2) {	  dthr /= (i - 2);	/* average */	  dthr -= dmin;	  dthr *= h->dthr16;	  dthr += 15;		/* round up */	  dthr >>= 4;		/* /= 16 */	  dthr += dmin;	  dthr += h->u.noise.level0;	}      }      /* search frame to drop */      memset(notdrop, ((1 < h->nfields)? '2': '0'), sizeof notdrop);      notdrop[h->iget - h->iuse - 1] = '\0';      /* check motion top field (or frame of non-interlaced) */      for (i = 0; i < h->iget - h->iuse - 1; i++)	if (dthr < h->framestat[(b + i) % h->nframes].odiff)	  notdrop[i] |= 1;      if (1 < h->nfields) {	/* check field merged */	int merged = 0;#if 0	/* codes for video editing fade-in/out */	long dmax = -0x7fffffffL, d2nd = -0x7fffffffL, d3rd = -0x7fffffffL;	for (i = 1; i < (h->nframes / 2) + 2 && i < h->iget - h->iuse; i++) {	  long eoediff = h->framestat[(b + i) % h->nframes].eoediff;	  if (eoediff == -9999999)	    continue;	  if        (dmax < eoediff) {	    d3rd = d2nd; d2nd = dmax; dmax = eoediff;	  } else if (d2nd < eoediff) {	    d3rd = d2nd; d2nd = eoediff;	  } else if (d3rd < eoediff) {	    d3rd = eoediff;	  }	}	if (d3rd == -0x7fffffffL)	  d3rd = 0;	if (1 < verbose)	  buf_debug(debugbuf, NULL, "%6ld", d3rd);	for (i = 1; i < (h->nframes / 2) + 2 && i < h->iget - h->iuse; i++)	  if (h->framestat[(b + i) % h->nframes].eoediff < d3rd - (long)dthr)#else	    for (i = 1; i < h->iget - h->iuse - 1; i++)	      if (h->framestat[(b + i) % h->nframes].eoediff < -(long)dthr)#endif		{		  merged = 1;		  notdrop[i - 1] &= ~2;		  notdrop[i    ] &= ~2;		}	if (!merged)	  for (i = 0; i < h->iget - h->iuse - 1; i++)	    notdrop[i] &= ~2;      }      idrp = h->nframes / 2;      if (h->iget - h->iuse - 1 < idrp)	idrp = h->iget - h->iuse - 1;      while (0 <= idrp && notdrop[idrp] != '0')	idrp--;      if (idrp < 0) {	idrp = h->nframes / 2;	if (h->iget - h->iuse - 1 < idrp)	  idrp = h->iget - h->iuse - 1;	while (0 <= idrp && (notdrop[idrp] & 1))	  idrp--;      }      if (idrp < 0 && (h->nframes / 2) + 1 < h->iget - h->iuse - 1) {	idrp = (h->nframes / 2) + 1;	while (idrp < h->iget - h->iuse - 1 && (notdrop[idrp] & 1))	  idrp++;	if (idrp == h->iget - h->iuse - 1) {	  idrp = h->nframes / 2;	  goto DONE;	}      }      if (idrp == h->nframes / 2) {	unsigned long noisetotal;	int bdrp;#if 0	int diff1024;#endif	for (i = 0; i < idrp; i++)	  if (notdrop[i] == '0')	    goto DONE;	/* calculate noise level */	while ((noisetotal = (h->u.noise.total +			      (((h->_.height / h->nfields) - 1) * h->_.width))) <	       h->u.noise.total)	/* overflow */	  for (h->u.noise.total = 0, i = 0; i <= NOISEMAX; i++)	    h->u.noise.total += (h->u.noise.dist[i] >>= 1);	h->u.noise.total = noisetotal;	bdrp = (b + idrp) % h->nframes;	for (i = 0; i <= NOISEMAX; i++)	  h->u.noise.dist[i] += h->framestat[bdrp].diffdist[i];	noisetotal = NOISERATIO(noisetotal);	for (i = 0; i <= NOISEMAX; i++) {	  if (noisetotal < h->u.noise.dist[i])	    break;	  noisetotal -= h->u.noise.dist[i];	}#if 0	diff1024 = (i - h->u.noise.level) * 1024;#endif	h->u.noise.level = i;#if 0	if (diff1024) {	  for (i = 0; i < h->nframes; i++) {	    if (diff1024 < -(int)h->framestat[i].odiff)	      h->framestat[i].odiff = 0;	    else	      h->framestat[i].odiff += diff1024;	  }	  if (1 < h->nfields)	    for (i = 0; i < h->nframes; i++) {	      if (diff1024 < -(int)h->framestat[i].ediff)		h->framestat[i].ediff = 0;	      else		h->framestat[i].ediff += diff1024;	    }	}#endif      }    DONE:      if (1 < verbose)	buf_debug(debugbuf, NULL, "%3d%7lu %s%3d%3u",		  iadjust, dthr, notdrop, idrp, h->u.noise.level);      /* reconstruct frame field merged */      if (1 < h->nfields) {	int isrc, isrc0;	isrc0 = ((0 < iadjust && 0 < idrp)? (idrp - 1): idrp);	isrc = idrp + (h->nframes / 4) - 1;	if (h->iget - h->iuse - 2 < isrc)	  isrc = h->iget - h->iuse - 2;	for (; isrc0 <= isrc; --isrc) {	  int bsrc = (b + isrc) % h->nframes;	  int bdst = (bsrc + 1) % h->nframes;	  if ((isrc < idrp + (h->nframes / 4) - 1 ||	       dthr < h->framestat[bdst].ediff) &&	      h->framestat[bdst].eoediff <= 0 &&	      h->framestat[bdst].eoediff != -9999999) {	    YfFrame_t *fsrc = (YfFrame_t *)((char *)h->frame + (bsrc * framebytes));	    YfFrame_t *fdst = (YfFrame_t *)((char *)h->frame + (bdst * framebytes));	    for (i = 1; i < h->_.height; i += 2) /* copy bottom field Y */	      memcpy(&fdst->data[i * h->_.width],		     &fsrc->data[i * h->_.width], h->_.width);	    for (i = (h->_.height * wdiv) + 1; i < h->_.height * (wdiv + (2 / hdiv)); i += 2) /* UV */	      memcpy(&fdst->data[i * h->_.width / wdiv],		     &fsrc->data[i * h->_.width / wdiv],		     h->_.width / wdiv);	    if (1 < verbose)	      buf_debug(debugbuf, NULL, "%2d", isrc + 1);	    h->framestat[bdst].eoediff = -9999999;	  } else {	    if (1 < verbose)	      buf_debug(debugbuf, NULL, " -");	  }	}      }      if (1 < verbose)	buf_debug(debugbuf, NULL, "\n");      /* output frames */      for (i = 0; i < idrp; i++) {	int ret;	YfFrame_t *fout = (YfFrame_t *)((char *)h->frame + (b * framebytes));	if ((ret = putframe(h, 'O', fout)))	  return ret;	h->iput++;	h->iuse++;	b = h->iuse % h->nframes;      }      if (h->iuse < h->iget) {	YfFrame_t *fout = (YfFrame_t *)((char *)h->frame + (b * framebytes));	if (iadjust <= 0) {	  if (h->cytype == 'C')	    putcy(h, '_');	} else {	  int ret;	  if ((ret = putframe(h, 'o', fout)))	    return ret;	  h->iput++;	}	h->iuse++;      }    }  } else {			/* retry */    int i, c;    YfFrame_t *fsrc, *fdst;    int deintl = 0;    while (!*h->u.cy.p) {      char *s, *d;      char buff[128];      d = h->u.cy.p = h->u.cy.buff;      if (!fgets(buff, sizeof buff, h->cyfp)) {	perror("cycle list");	return 1;      }      for (s = buff; (c = *s); s++) { /* FIXME: frame# should be checked */	if (c == '#')	  break;	if (isalpha(c) || (c == '_' && h->cytype == 'O')) {	  if (h->u.cy.buff + 30 <= d) {	    WWARN("too long line in cycle list.");	    break;	  }	  *d++ = c;	}      }      *d = '\0';    }    fsrc = (YfFrame_t *)((char *)h->frame + (((h->iuse - 1) % h->nframes) * framebytes));    fdst = (YfFrame_t *)((char *)h->frame + (((h->iuse)     % h->nframes) * framebytes));    h->iuse++;    c = *h->u.cy.p++;    if (c == '_')      return 0;    if (islower(c)) {      if (iadjust <= 0)	return 0;      c += 'A' - 'a';    }    switch (c) {    case 'D':    case 'M':      if (h->cytype == 'N')	goto DEINTLDECIDED;      /* else do as E, N */    case 'E':    case 'N':      deintl = 1;    DEINTLDECIDED:      c += 'O' - 'D';		/* D->O, M->X, E->P(do as O), N->Y */      break;    }    i = 0;    switch (c) {    case 'X':      if (h->cytype == 'N')	break;      /* else do as Y */    case 'Y':      for (i = 1; i < h->_.height; i += 2) /* copy bottom field Y */	memcpy(&fdst->data[i * h->_.width],	       &fsrc->data[i * h->_.width], h->_.width);      for (i = (h->_.height * wdiv) + 1; i < h->_.height * (wdiv + (2 / hdiv)); i += 2) /* UV */	memcpy(&fdst->data[i * h->_.width / wdiv],	       &fsrc->data[i * h->_.width / wdiv],	       h->_.width / wdiv);      break;    case 'T':      for (i = 0; i < h->_.height; i += 2) /* duplicate top field Y */	memcpy(&fdst->data[(i + 1) * h->_.width],	       &fdst->data[(i)     * h->_.width], h->_.width);      for (i = (h->_.height * wdiv); i < h->_.height * (wdiv + (2 / hdiv)); i += 2) /* UV */	memcpy(&fdst->data[(i + 1) * h->_.width / wdiv],	       &fsrc->data[(i)     * h->_.width / wdiv],	       h->_.width / wdiv);      break;    case 'B':      for (i = 0; i < h->_.height; i += 2) /* duplicate bottom field Y */	memcpy(&fdst->data[(i)     * h->_.width],	       &fdst->data[(i + 1) * h->_.width], h->_.width);      for (i = (h->_.height * wdiv); i < h->_.height * (wdiv + (2 / hdiv)); i += 2) /* UV */	memcpy(&fdst->data[(i)     * h->_.width / wdiv],	       &fsrc->data[(i + 1) * h->_.width / wdiv],	       h->_.width / wdiv);      break;    }    if ((c = putframe(h, deintl, fdst)))      return c;    h->iput++;    if (i || deintl)      memcpy(fdst->data, frame0->data, framebytes - sizeof frame0->fi);  }  return 0;}

⌨️ 快捷键说明

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