Logo Search packages:      
Sourcecode: camstream version File versions  Download package


  \class CIntgPanel
  \brief Integrator, reverse of Differentatior
  This class is a panel that is the reverse of a Differentiator: it's an
  integrator, that is, it accumulates differences to reconstruct the
  original image. It's name is derived from the electronic equivalent
  with resistors, capacitors and coils.
  Because of round-off errors, DCT (de)compression, bias, etc. (aka "noise")
  the integration is not perfect. So every once in a while a 'real' YUV
  image is needed to refresh the image.

#include "config.h"

#include <stdio.h>

#include "IntgPanel.h"
#include "video_asm.h"

  \fn CIntgPanel::CIntgPanel(CCamPanel *yuv_panel, CCamPanel *diff_panel, const char *name = "intg.yuv", const char *desc = "YUV Integrator")
  \brief Constructor
  \param yuv_panel The panel with unprocessed, 'real' YUV images.
  \param diff_panel The panel with the differential images.
  \param name The name of this panel; default "intg.yuv"
  \param desc The description of this panel; default "YUV integrator"
00036 CIntgPanel::CIntgPanel(CCamPanel *yuv_panel, CCamPanel *diff_panel, const char *name, const char *desc)
      : CCamPanel(name, desc, YUV420)
   pYUVPanel = yuv_panel;
   pDiffPanel = diff_panel;
   if (pYUVPanel == NULL || pDiffPanel == NULL)
   if (pYUVPanel->GetPanelType() != YUV420 ||
       pDiffPanel->GetPanelType() != YUV420) {
     pYUVPanel = NULL;
     pDiffPanel = NULL;
   if (pDiffPanel && pYUVPanel) {
     // Initial size

     // Register usage
     // Make sure updates in DiffPanel arrive here; we consider DiffPanel as our 'primary' parent

   // Initialize refresh counters; get fresh image ever 100 updates
   RefreshCountdown = 0;
   Refreshes = 100;

// private

void CIntgPanel::Calculate(int n, void *dst, void *src)
   if (dst == NULL || src == NULL)

   calc_intg128_smx(n, dst, src);
   calc_intg128(n, dst, src);
   // Non-assembly version
   int i;
   uchar *d, *s;
   d = (uchar *)dst;
   s = (uchar *)src;
   for (i = 0; i < n; i++) {
      *d += ((*s - 128) << 1);

// protected slots

void CIntgPanel::UpdatePanel()
   void *dsty, *dstu, *dstv;
   void *srcy, *srcu, *srcv;
   int pixels;

   dsty = ImgY.bits();
   dstu = ImgU.bits();
   dstv = ImgV.bits();

   pixels = image_w * image_h;   
   if (RefreshCountdown == 0) {
     srcy = pYUVPanel->GetImage(0).bits();
     srcu = pYUVPanel->GetImage(1).bits();
     srcv = pYUVPanel->GetImage(2).bits();
     memcpy(dsty, srcy, pixels     );
     memcpy(dstu, srcu, pixels >> 2);
     memcpy(dstv, srcv, pixels >> 2);
     RefreshCountdown = Refreshes;
   else {
     srcy = pDiffPanel->GetImage(0).bits();
     srcu = pDiffPanel->GetImage(1).bits();
     srcv = pDiffPanel->GetImage(2).bits();
     Calculate(pixels,      dsty, srcy);
     Calculate(pixels >> 2, dstu, srcu);
     Calculate(pixels >> 2, dstv, srcv);

   emit Updated();

// public

  \fn void CIntgPanel::SetRefresh(int n)
  \brief Set new refresh rate
  \param n New refresh rate
  Every once in a while, a fresh image is needed because using a differential
  and then going back with an integrator causes all kinds of errors, like
  round off errors, drifts, etc. Every N frames, a 'real' image will be
  requested instead of a diff. This function sets this refresh rate.
00145 void CIntgPanel::SetRefresh(int n)
   if (n > 0)
     Refreshes = n;
   if (RefreshCountdown > Refreshes)
     RefreshCountdown = Refreshes;

Generated by  Doxygen 1.6.0   Back to index