dslinux/user/pixil/packages/dvdview/dvdview/src/vpostproc buffer.cc buffer.hh postproc.cc postproc.hh pp_filteredresize.cc pp_filteredresize.hh pp_fps.cc pp_fps.hh pp_imgtype.cc pp_imgtype.hh pp_mblks.cc pp_mblks.hh pp_mv.cc pp_mv.hh pp_mvcol.cc pp_mvcol.hh pp_qscale.cc pp_qscale.hh pp_resize.cc pp_resize.hh

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:06 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/packages/dvdview/dvdview/src/vpostproc
In directory antilope:/tmp/cvs-serv11916/packages/dvdview/dvdview/src/vpostproc

Added Files:
	buffer.cc buffer.hh postproc.cc postproc.hh 
	pp_filteredresize.cc pp_filteredresize.hh pp_fps.cc pp_fps.hh 
	pp_imgtype.cc pp_imgtype.hh pp_mblks.cc pp_mblks.hh pp_mv.cc 
	pp_mv.hh pp_mvcol.cc pp_mvcol.hh pp_qscale.cc pp_qscale.hh 
	pp_resize.cc pp_resize.hh 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: pp_fps.cc ---

#include "vpostproc/pp_fps.hh"
#include "libvideogfx/graphics/draw/draw.hh"

#include <sys/time.h>
#include <unistd.h>

#include <iostream.h>

int ac_s = 0*2;
int ac_e = ac_s+15;

static char* fps_text = 
"*****  ****    ***\n"
"*      *   *  *   *\n"
"*      *   *  *      * \n"
"***    ****    ***\n"
"*      *          *  *\n"
"*      *      *   *\n"
"*      *       ***";

static char* num_text[11] = {
  " *** \n"
  "*   *\n"
  "*   *\n"
  "*   *\n"
  "*   *\n"
  "*   *\n"
  " *** \n"
  ,
  "  ** \n"
  " * * \n"
  "*  * \n"
  "   * \n"
  "   * \n"
  "   * \n"
  "   * \n"
  ,
  " *** \n"
  "*   *\n"
  "*   *\n"
  "   * \n"
  "  *  \n"
  " *   \n"
  "*****\n"
  ,
  " *** \n"
  "*   *\n"
  "    *\n"
  "  ** \n"
  "    *\n"
  "*   *\n"
  " *** \n"
  ,
  "  *  \n"
  " *   \n"
  "*  * \n"
  "*****\n"
  "   * \n"
  "   * \n"
  "   * \n"
  ,
  "*****\n"
  "*    \n"
  "*    \n"
  "**** \n"
  "    *\n"
  "*   *\n"
  " *** \n"
  ,
  " *** \n"
  "*   *\n"
  "*    \n"
  "**** \n"
  "*   *\n"
  "*   *\n"
  " *** \n"
  ,
  "*****\n"
  "    *\n"
  "   * \n"
  " ****\n"
  "  *  \n"
  "  *  \n"
  "  *  \n"
  ,
  " *** \n"
  "*   *\n"
  "*   *\n"
  " *** \n"
  "*   *\n"
  "*   *\n"
  " *** \n"
  ,
  " *** \n"
  "*   *\n"
  "*   *\n"
  " ****\n"
  "    *\n"
  "*   *\n"
  " *** \n"
  ,
  "     \n"
  "     \n"
  "     \n"
  "     \n"
  "     \n"
  " **  \n"
  " **  \n" };

VideoPostprocessor_FramesPerSec::VideoPostprocessor_FramesPerSec(int len,int period)
{
  dataval = new timeval[len];
  nDataval=len;
  idx_in=0;

  for (int i=0;i<len;i++)
    gettimeofday(&dataval[i],NULL);

  assert(period>=1);
  update_cnt=0;
  update_period=period;
}

VideoPostprocessor_FramesPerSec::~VideoPostprocessor_FramesPerSec()
{
  delete[] dataval;
}

inline bool VideoPostprocessor_FramesPerSec::NeedsPictureData(uint3 pictype) const
{
  assert(d_next);
  return d_next->NeedsPictureData(pictype);
}

bool VideoPostprocessor_FramesPerSec::NeedsMBData(uint3 pictype) const
{
  assert(d_next);
  return d_next->NeedsMBData(pictype);
}

extern void ShowDIMG(DecodedImageData* dimg);

int VideoPostprocessor_FramesPerSec::Draw(const char* text,int x0,int y0,
					  DecodedImageData* drawimg)
{
  Pixel*const* py = drawimg->m_image.AskFrameY();
  Pixel*const* pu = drawimg->m_image.AskFrameU();
  Pixel*const* pv = drawimg->m_image.AskFrameV();

  ImageParam_YUV param;
  drawimg->m_image.GetParam(param);

  int maxx=0;
  int dx=0,dy=0;
  const char* p = text;
  while (*p)
    {
      if (*p=='\n')
	{
	  dx=0; dy+=2;
	}
      else
	{
	  if (*p=='*')
	    {
	      //cout << y0+dy << "/" << y0+dy+1 << endl;
	      //ShowDIMG(drawimg);

	      Assert(drawimg->ContainsOutputLine(y0+dy));
	      Assert(drawimg->ContainsOutputLine(y0+dy+1));

	      int ypos = drawimg->GetIndexForOutputLine(y0+dy);

	      py[ypos  ][x0+dx]=py[ypos  ][x0+dx+1]=255;
	      py[ypos+1][x0+dx]=py[ypos+1][x0+dx+1]=255;

	      if (param.chroma==Chroma420)
		{
		  pu[(ypos)/2][(x0+dx)/2]=128;
		  pv[(ypos)/2][(x0+dx)/2]=128;
		}
	      else if (param.chroma==Chroma422)
		{
		  pu[ypos][(x0+dx)/2]=pu[ypos+1][(x0+dx)/2]=128;
		  pv[ypos][(x0+dx)/2]=pv[ypos+1][(x0+dx)/2]=128;
		}
	      else
		{
		  Assert(param.chroma==Chroma444);

		  pu[ypos][(x0+dx)  ]=pu[ypos+1][(x0+dx)  ]=128;
		  pu[ypos][(x0+dx)+1]=pu[ypos+1][(x0+dx)+1]=128;
		  pv[ypos][(x0+dx)  ]=pv[ypos+1][(x0+dx)  ]=128;
		  pv[ypos][(x0+dx)+1]=pv[ypos+1][(x0+dx)+1]=128;
		}
	    }
	  dx+=2;

	  if (dx>maxx) maxx=dx;
	}
      p++;
    }

  return x0+maxx;
}

void VideoPostprocessor_FramesPerSec::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(ac_s,ac_e,true);
  d_next->BeginPicture(dimg);
}

void VideoPostprocessor_FramesPerSec::ShowMBRows(DecodedImageData* dimg)
{
  long udiff;

  if (dimg->m_dst_y_start==0) // do it only once per frame
    {
      // calculate fps

      timeval* now = &dataval[idx_in];

      gettimeofday(&dataval[idx_in],NULL);
      idx_in++;
      if (idx_in==nDataval) idx_in=0;

      timeval* past = &dataval[idx_in];

      if (update_cnt==0)
	{
	  long sec_diff = now->tv_sec - past->tv_sec;
	  udiff = sec_diff * 1000000;
	  assert(sec_diff>=0);
	  udiff += now->tv_usec-past->tv_usec;

	  fps = ((nDataval-1)*100)*1000000/udiff;

	  update_cnt=update_period-1;
  //cout << "-> FPS: " << fps << "/100   " << udiff << endl;
	}
      else
	{
	  update_cnt--;
	}
    }

  DecodedImageData* drawimg = Accumulate(dimg);

  if (!drawimg)
    return;

  Assert(drawimg->m_may_modify);

  ImageParam_YUV param;
  drawimg->m_image.GetParam(param);

  int x0 = 4; //param.width-2*(25 /*fps:*/ + 5*7);
  int y0 = ac_s+2; //param.height-2*(10);

  x0 &= ~1;
  y0 &= ~1;

  // draw "FPS:"

  x0 = Draw(fps_text,x0,y0,drawimg);

  if (fps>=10000) x0=Draw(num_text[((int)(fps/10000))%10],x0,y0,drawimg); else x0 += 2*5; x0+=4;
  if (fps>= 1000) x0=Draw(num_text[((int)(fps/ 1000))%10],x0,y0,drawimg); else x0 += 2*5; x0+=4;
  x0=Draw(num_text[((int)(fps/100))%10],x0,y0,drawimg);
  x0=Draw(num_text[10],x0,y0,drawimg);
  x0=Draw(num_text[((int)(fps/10))%10],x0,y0,drawimg); x0+=4;
  x0=Draw(num_text[((int)(fps))%10],x0,y0,drawimg);

  d_next->ShowMBRows(drawimg);
}

void VideoPostprocessor_FramesPerSec::FinishedPicture()
{
  d_next->FinishedPicture();
}

--- NEW FILE: pp_filteredresize.cc ---

#include "vpostproc/pp_filteredresize.hh"
#include "../config.h"

VideoPostprocessor_FilteredResize::~VideoPostprocessor_FilteredResize()
{
  if (d_ltab_h) delete[] d_ltab_h;
  if (d_ltab_v) delete[] d_ltab_v;
  if (d_ctab_h) delete[] d_ctab_h;
  if (d_ctab_v) delete[] d_ctab_v;
}


void VideoPostprocessor_FilteredResize::SetScaledSize(int w,int h)
{
  width=w;
  height=h;
  d_do_resize=true;

  if (d_ltab_h) delete[] d_ltab_h;
  if (d_ltab_v) delete[] d_ltab_v;
  if (d_ctab_h) delete[] d_ctab_h;
  if (d_ctab_v) delete[] d_ctab_v;

  d_ltab_h = NULL;
  d_ltab_v = NULL;
  d_ctab_h = NULL;
  d_ctab_v = NULL;

  tab_initialized=false;
}


void VideoPostprocessor_FilteredResize::ShowMBRows(DecodedImageData* decimg)
{
  /* Only resize image, if resizing is enabled and the target size is different
     from the input size. */

  if (!d_do_resize || (decimg->m_width==width && decimg->m_height==height))
    {
      d_next->ShowMBRows(decimg);
      return;
    }

  // Accumulate image pieces until the complete image is complete.

  DecodedImageData* dimg = Accumulate(decimg);
  if (!dimg)
    { return; }


  // Get input image size

  ImageParam_YUV param;
  dimg->m_image.GetParam(param);


  // Create new image with new size

  ImageSpec_YUV spec;
  dimg->m_image.GetParam(spec);
  spec.width  = width;
  spec.height = height;
  newdimg.m_image.Create(spec);

  newdimg.m_width  = width;
  newdimg.m_height = height;

  newdimg.m_src_y_start=0;
  newdimg.m_src_y_end  =height-1;
  newdimg.m_dst_y_start=0;
  newdimg.m_field_lines=false;
  newdimg.m_may_modify =true;

  newdimg.m_timing = dimg->m_timing;


  int oldcw = param.GetChromaWidth();
  int oldch = param.GetChromaHeight();
  int newcw = spec.GetChromaWidth();
  int newch = spec.GetChromaHeight();


  // Fill resizing tabs if not done yet

  if (!tab_initialized)
    {
      d_ltab_h = new int[width];
      d_ltab_v = new int[height];
      d_ctab_h = new int[newcw];
      d_ctab_v = new int[newch];

      for (int x=0;x<width;x++)	 d_ltab_h[x] = (dimg->m_width-1)*x/(width-1);
      for (int y=0;y<height;y++) d_ltab_v[y] = (dimg->m_height-1)*y/(height-1);
      for (int x=0;x<newcw;x++)	 d_ctab_h[x] = (oldcw-1)*x/(newcw-1);
      for (int y=0;y<newch;y++)  d_ctab_v[y] = (oldch-1)*y/(newch-1);

      tab_initialized=true;
    }


  Pixel*const* dpy = newdimg.m_image.AskFrameY();
  Pixel*const* dpu = newdimg.m_image.AskFrameU();
  Pixel*const* dpv = newdimg.m_image.AskFrameV();

  const Pixel*const* spy = dimg->m_image.AskFrameY_const();
  const Pixel*const* spu = dimg->m_image.AskFrameU_const();
  const Pixel*const* spv = dimg->m_image.AskFrameV_const();

  // Prepare floating point unit

#ifdef ENABLE_MMX
  __asm__
    (
     "emms\n\t"
     );
#endif

  // Select filter

  double xfact = ((double)width )/dimg->m_width;
  double yfact = ((double)height)/dimg->m_height;

  // unfiltered resizing
  for (int y=0;y<height;y++)
    for (int x=0;x<width;x++)
      {
	dpy[y][x] = spy[d_ltab_v[y]][d_ltab_h[x]];
      }

  // filter left half with appropriate filter
  if (abs(xfact-1.333) < abs(xfact-2.0) &&
      abs(xfact-1.333) < abs(xfact-2.666))
    {
      cout << "FILTER 4/3\n";

      for (int y=0;y<height;y++)
	for (int x=4;x<width/2-4;x++)
	  {
	    int temp=(int)(0.94*dpy[y][x]+0.39*dpy[y][x+1]-0.13*dpy[y][x+2]
			   -0.07*dpy[y][x-2]+0.02*dpy[y][x-3]);

	    if (temp<0) temp=0;
	    if (temp>255) temp=255;

	    int mi=min((int)dpy[y][x-2],(int)dpy[y][x]);
	    mi=min((int)dpy[y][x+2],mi);
	    int mx=max((int)dpy[y][x-2],(int)dpy[y][x]);
	    mx=max((int)dpy[y][x+2],mx);
	    if (temp<mi) temp=mi;
	    if (temp>mx) temp=mx;
	    dpy[y][x]=(unsigned char)temp;

	    //x++;
	    //y++;
	  }
    }
  else
    {
      cout << "NOFILTER\n";
    }

  for (int y=0;y<newch;y++)
    for (int x=0;x<newcw;x++)
      {
	dpu[y][x] = spu[d_ctab_v[y]][d_ctab_h[x]];
	dpv[y][x] = spv[d_ctab_v[y]][d_ctab_h[x]];
      }


  // Forward image data to next postprocessor

  d_next->ShowMBRows(&newdimg);
}


void VideoPostprocessor_FilteredResize::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,true);  // Accumulate complete picture

  d_next->BeginPicture(dimg);
}


void VideoPostprocessor_FilteredResize::FinishedPicture()
{
  d_next->FinishedPicture();
}

--- NEW FILE: pp_qscale.cc ---

#include "vpostproc/pp_qscale.hh"
#include "video12/constants.hh"

#include <iostream.h>


void VideoPostprocessor_QScale::ShowMBRows(DecodedImageData* decimg)
{
  DecodedImageData* dimg = Accumulate(decimg);
  if (!dimg)
    { return; }

  Assert(dimg->m_picdata1);
  Assert(dimg->m_picdata1->m_codedimage.IsInitialized());

  int blkheight;

  if (dimg->m_pichdr1.m_picture_structure == PICSTRUCT_FramePicture)
    blkheight=16;
  else
    blkheight=32;

  const Array2<Macroblock>& mbs = dimg->m_picdata1->m_codedimage;
  Pixel*const* yptr = dimg->m_image.AskFrameY();

  for (int y=0;y<mbs.AskHeight();y++)
    for (int x=0;x<mbs.AskWidth();x++)
      {
	int q=mbs.Ask_const(y,x).m_quantiser_scale_code;
	if (q>blkheight) q=blkheight;

	for (int i=1;i<=q;i++)
	  {
	    if ((y+1)*blkheight-i < decimg->m_height )
	      yptr[(y+1)*blkheight-i][x*16+15] = 255;
	  }
      }

  d_next->ShowMBRows(dimg);
}

void VideoPostprocessor_QScale::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,true);

  d_next->BeginPicture(dimg);
}

void VideoPostprocessor_QScale::FinishedPicture()
{
  d_next->FinishedPicture();
}

--- NEW FILE: buffer.cc ---

#include "vpostproc/buffer.hh"
#include "video12/constants.hh"


#define FLAG_InQueue 1
#define FLAG_InUse   2
#define FLAG_NotAllocated 4

VideoImageBuffer::VideoImageBuffer(int MaxPoolSize)
  : d_queuelength(0),
    d_maxqueuelength(MaxPoolSize),
    d_maxpoolsize(MaxPoolSize)
{
  d_queue      = new DecodedImageData*[d_maxpoolsize];
  d_bufferpool = new DecodedImageData*[d_maxpoolsize];
  d_flags      = new uint8[d_maxpoolsize];

  for (int i=0;i<d_maxpoolsize;i++)
    d_flags[i]=FLAG_NotAllocated;
}


VideoImageBuffer::~VideoImageBuffer()
{
  for (int i=0;i<d_maxpoolsize;i++)
    {
      //cout << (d_flags[i] & (FLAG_InUse|FLAG_InQueue)) << endl;
      //assert((d_flags[i] & (FLAG_InUse|FLAG_InQueue))==0);
    }

  for (int i=0;i<d_maxpoolsize;i++)
    {
      if (!(d_flags[i] & FLAG_NotAllocated))
	{
	  if (d_bufferpool[i]->m_picdata1) delete d_bufferpool[i]->m_picdata1;
	  if (d_bufferpool[i]->m_picdata2) delete d_bufferpool[i]->m_picdata2;
	  delete d_bufferpool[i];
	}
    }

  delete[] d_bufferpool;
  delete[] d_queue;
  delete[] d_flags;
}


bool VideoImageBuffer::BufferFull() const
{
  return d_queuelength == d_maxqueuelength;
}


DecodedImageData* VideoImageBuffer::GetNextImage()
{
  Assert(d_queuelength>=1); // queue not empty

  DecodedImageData* d=d_queue[0];

  for (int i=0;i<d_queuelength-1;i++)
    d_queue[i]=d_queue[i+1];
  d_queuelength--;

  return d;
}


void VideoImageBuffer::FreeImage(DecodedImageData* d)
{
  for (int i=0;i<d_maxpoolsize;i++)
    if (d_bufferpool[i]==d)
      d_flags[i] &= ~FLAG_InQueue;
}

#if 0
DecodedImageData* VideoImageBuffer::GetOutputBuffer(ImageSpec_YUV spec,
						    uint3 picture_type,
						    bool maymodify)
{
  Assert(0);
#if 0
  for (int i=0;i<d_maxpoolsize;i++)
    if ((d_flags[i] & (FLAG_InUse|FLAG_InQueue))==0)
      {
	if (d_flags[i] & FLAG_NotAllocated)
	  {
#if 0
	    cout << "ALLOCATION !!!\n";
#endif

	    d_bufferpool[i] = new DecodedImageData;
	    d_bufferpool[i]->m_image.Create(spec);
	  }

	d_flags[i]=FLAG_InUse;
	return d_bufferpool[i];
      }

  cout << "CAPACITY EXCEEDED\n";

  Assert(0); // Capacity exceeded.
#endif
}
#endif

void VideoImageBuffer::ShowMBRows(DecodedImageData* d)
{
  /*
  cout << "ShowOutputBuffer at ";
  if (d->m_timing.HasPTS) cout << d->m_timing.pts << endl;
  else cout << "undefined\n";
  */

  for (int i=0;i<d_maxpoolsize;i++)
    if (d_bufferpool[i]==d)
      {
	d_flags[i] |= FLAG_InQueue;
      }

  Assert(d_queuelength<d_maxqueuelength);
  d_queue[d_queuelength]=d;
  d_queuelength++;
}

#if 0
void VideoImageBuffer::FreeOutputBuffer(DecodedImageData* d)
{
  Assert(0);
#if 0
  assert(d->m_picdata1==NULL);

  for (int i=0;i<d_maxpoolsize;i++)
    if (d_bufferpool[i]==d)
      {
	d_flags[i] &= ~FLAG_InUse;
      }
#endif
}
#endif

--- NEW FILE: pp_imgtype.cc ---

#include "vpostproc/pp_imgtype.hh"
#include "video12/constants.hh"

#include <iostream.h>


void VideoPostprocessor_ImageType::Render(DecodedImageData* dimg)
{
  Assert(dimg->m_picdata1);

  if (dimg->m_picdata1->m_picture_structure == PICSTRUCT_FramePicture)
    cout << "Frame ";
  else
    cout << "Field ";

  if (dimg->m_picdata1->m_picture_coding_type == PICTYPE_B)
    cout << "B\n";
  else if (dimg->m_picdata1->m_picture_coding_type == PICTYPE_P)
    cout << "P\n";
  else if (dimg->m_picdata1->m_picture_coding_type == PICTYPE_I)
    cout << "I\n";
  else
    cout << "D\n";
}

--- NEW FILE: pp_fps.hh ---
/********************************************************************************
  vpostproc/pp_fps.hh

  purpose:
    Show frames per second.

  notes:

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   07/Sep/2000 - Dirk Farin
     - Complete reorganisation because of output architecture change.
   01/Sep/2000 - Dirk Farin
     - first implementation
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_FPS_HH
#define DVDVIEW_VPOSTPROC_PP_FPS_HH

#include "vpostproc/postproc.hh"


class VideoPostprocessor_FramesPerSec : public VideoPostprocessor_Accumulate
{
public:
  VideoPostprocessor_FramesPerSec(int len=20,int period=10);
  ~VideoPostprocessor_FramesPerSec();

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

  bool  NeedsPictureData(uint3 pictype) const;
  bool  NeedsMBData     (uint3 pictype) const;

private:
  int Draw(const char* text,int x0,int y0, DecodedImageData* dimg);

  struct timeval* dataval;
  int nDataval;
  int idx_in;
  int fps;

  int update_period;
  int update_cnt;
};

#endif

--- NEW FILE: buffer.hh ---
/********************************************************************************
  vpostproc/buffer.hh

  purpose:
    Converts the PUSH-semantic of the decoder pipeline to a PULL-interface.

  notes:

  to do:

  author(s):
   - Dirk Farin, farin at ti.uni-mannheim.de

  modifications:
    12/Apr/2000 - Dirk Farin
     - extracted source from video decoder
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_BUFFER_HH
#define DVDVIEW_VPOSTPROC_BUFFER_HH

#include "libvideogfx/graphics/basic/image.hh"
#include "video12/output.hh"


class VideoImageBuffer : public DecodedPictureSink
{
public:
   VideoImageBuffer(int MaxPoolSize=4);
  ~VideoImageBuffer();

  bool              BufferEmpty() const { return d_queuelength==0; }
  bool              BufferFull() const;
  DecodedImageData* GetNextImage();
  void              FreeImage(DecodedImageData*);


  virtual void ShowMBRows(DecodedImageData*);

private:
  DecodedImageData** d_queue;
  int d_queuelength;
  int d_maxqueuelength;

  DecodedImageData** d_bufferpool;
  uint8* d_flags;
  int d_maxpoolsize;
};

#endif

--- NEW FILE: pp_resize.cc ---

#include "vpostproc/pp_resize.hh"


VideoPostprocessor_Resize::~VideoPostprocessor_Resize()
{
  if (d_ltab_h) delete[] d_ltab_h;
  if (d_ltab_v) delete[] d_ltab_v;
  if (d_ctab_h) delete[] d_ctab_h;
  if (d_ctab_v) delete[] d_ctab_v;
}


void VideoPostprocessor_Resize::SetScaledSize(int w,int h)
{
  width=w;
  height=h;
  d_do_resize=true;

  if (d_ltab_h) delete[] d_ltab_h;
  if (d_ltab_v) delete[] d_ltab_v;
  if (d_ctab_h) delete[] d_ctab_h;
  if (d_ctab_v) delete[] d_ctab_v;

  d_ltab_h = NULL;
  d_ltab_v = NULL;
  d_ctab_h = NULL;
  d_ctab_v = NULL;

  tab_initialized=false;
}


void VideoPostprocessor_Resize::ShowMBRows(DecodedImageData* decimg)
{
  /* Only resize image, if resizing is enabled and the target size is different
     from the input size. */

  if (!d_do_resize || (decimg->m_width==width && decimg->m_height==height))
    {
      d_next->ShowMBRows(decimg);
      return;
    }

  // Accumulate image pieces until the complete image is complete.

  DecodedImageData* dimg = Accumulate(decimg);
  if (!dimg)
    { return; }


  // Get input image size

  ImageParam_YUV param;
  dimg->m_image.GetParam(param);


  // Create new image with new size

  ImageSpec_YUV spec;
  dimg->m_image.GetParam(spec);
  spec.width  = width;
  spec.height = height;
  newdimg.m_image.Create(spec);

  newdimg.m_width  = width;
  newdimg.m_height = height;

  newdimg.m_src_y_start=0;
  newdimg.m_src_y_end  =height-1;
  newdimg.m_dst_y_start=0;
  newdimg.m_field_lines=false;
  newdimg.m_may_modify =true;

  newdimg.m_timing = dimg->m_timing;


  int oldcw = param.GetChromaWidth();
  int oldch = param.GetChromaHeight();
  int newcw = spec.GetChromaWidth();
  int newch = spec.GetChromaHeight();


  // Fill resizing tabs if not done yet

  if (!tab_initialized)
    {
      d_ltab_h = new int[width];
      d_ltab_v = new int[height];
      d_ctab_h = new int[newcw];
      d_ctab_v = new int[newch];

      for (int x=0;x<width;x++)	 d_ltab_h[x] = (dimg->m_width-1)*x/(width-1);
      for (int y=0;y<height;y++) d_ltab_v[y] = (dimg->m_height-1)*y/(height-1);
      for (int x=0;x<newcw;x++)	 d_ctab_h[x] = (oldcw-1)*x/(newcw-1);
      for (int y=0;y<newch;y++)  d_ctab_v[y] = (oldch-1)*y/(newch-1);

      tab_initialized=true;
    }


  // Resize image by simple resampling

  Pixel*const* dpy = newdimg.m_image.AskFrameY();
  Pixel*const* dpu = newdimg.m_image.AskFrameU();
  Pixel*const* dpv = newdimg.m_image.AskFrameV();

  const Pixel*const* spy = dimg->m_image.AskFrameY_const();
  const Pixel*const* spu = dimg->m_image.AskFrameU_const();
  const Pixel*const* spv = dimg->m_image.AskFrameV_const();

  for (int y=0;y<height;y++)
    for (int x=0;x<width;x++)
      {
	dpy[y][x] = spy[d_ltab_v[y]][d_ltab_h[x]];
      }

  for (int y=0;y<newch;y++)
    for (int x=0;x<newcw;x++)
      {
	dpu[y][x] = spu[d_ctab_v[y]][d_ctab_h[x]];
	dpv[y][x] = spv[d_ctab_v[y]][d_ctab_h[x]];
      }


  // Forward image data to next postprocessor

  d_next->ShowMBRows(&newdimg);
}


void VideoPostprocessor_Resize::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,true);  // Accumulate complete picture

  d_next->BeginPicture(dimg);
}


void VideoPostprocessor_Resize::FinishedPicture()
{
  d_next->FinishedPicture();
}

--- NEW FILE: pp_mv.cc ---

#include "vpostproc/pp_mv.hh"
#include "video12/constants.hh"
#include "libvideogfx/graphics/draw/draw.hh"

#include <iostream.h>


inline bool VideoPostprocessor_MotionVector::NeedsPictureData(uint3 pictype) const
{
  assert(d_next);

  return ((pictype == PICTYPE_B && d_show_b) ||
	  (pictype == PICTYPE_P && d_show_p) ||
	  d_next->NeedsPictureData(pictype));
}

bool VideoPostprocessor_MotionVector::NeedsMBData(uint3 pictype) const
{
  return NeedsPictureData(pictype);
}


void VideoPostprocessor_MotionVector::ShowMBRows(DecodedImageData* decimg)
{
  if (!decimg->m_picdata1)
    {
      d_next->ShowMBRows(decimg);
      return;
    }

  if (decimg->m_pichdr1.m_picture_coding_type == PICTYPE_B && !d_show_b)
    {
      d_next->ShowMBRows(decimg);
      return;
    }

  if (decimg->m_pichdr1.m_picture_coding_type == PICTYPE_P && !d_show_p)
    {
      d_next->ShowMBRows(decimg);
      return;
    }

  DecodedImageData* dimg = Accumulate(decimg);
  if (!dimg)
    { return; }

  Assert(dimg->m_picdata1);
  Assert(dimg->m_picdata1->m_codedimage.IsInitialized());

  int blkheight;
  if (dimg->m_pichdr1.m_picture_structure == PICSTRUCT_FramePicture)
    blkheight=16;
  else
    blkheight=32;

  const Array2<Macroblock>& mbs = dimg->m_picdata1->m_codedimage;
  Pixel*const* yptr = dimg->m_image.AskFrameY();

  Bitmap<Pixel>& bm_y = dimg->m_image.AskBitmap(Image<Pixel>::Bitmap_Y);
  Bitmap<Pixel>& bm_u = dimg->m_image.AskBitmap(Image<Pixel>::Bitmap_U);
  Bitmap<Pixel>& bm_v = dimg->m_image.AskBitmap(Image<Pixel>::Bitmap_V);

  for (int y=0;y<mbs.AskHeight();y++)
    for (int x=0;x<mbs.AskWidth();x++)
      {
        const Macroblock& mb = dimg->m_picdata1->m_codedimage.Ask_const(y,x);

	int x0 = x*16+8;
	int y0 = y*blkheight+blkheight/2;

        if (mb.m_HasMotionForward && d_show_forward)
          {
	    int x1 = x0+mb.m_forward1.m_habs/2;
	    int y1 = y0+mb.m_forward1.m_vabs/2;

	    DrawLine(bm_y,x0,y0,x1,y1,(Pixel)255);
	    if (d_colored)
	      {
		DrawLine(bm_u,x0/2,y0/2,x1/2,y1/2,(Pixel)250);
		DrawLine(bm_v,x0/2,y0/2,x1/2,y1/2,(Pixel)250);
	      }
	  }

        if (mb.m_HasMotionBackward && d_show_backward)
          {
	    int x1 = x0+mb.m_backward1.m_habs/2;
	    int y1 = y0+mb.m_backward1.m_vabs/2;

	    DrawLine(bm_y,x0,y0,x1,y1,(Pixel)255);
	    if (d_colored)
	      {
		DrawLine(bm_u,x0/2,y0/2,x1/2,y1/2,(Pixel)10);
		DrawLine(bm_v,x0/2,y0/2,x1/2,y1/2,(Pixel)10);
	      }
	  }
      }

  d_next->ShowMBRows(dimg);
}


void VideoPostprocessor_MotionVector::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,true);

  d_next->BeginPicture(dimg);
}

void VideoPostprocessor_MotionVector::FinishedPicture()
{
  d_next->FinishedPicture();
}

--- NEW FILE: pp_mblks.cc ---

#include "vpostproc/pp_mblks.hh"
#include "video12/constants.hh"


Pixel maximize(Pixel v)
{
  if (v<128) return 255;
  else       return   0;
}


void VideoPostprocessor_MBBoundaries::ShowMBRows(DecodedImageData* decimg)
{
  DecodedImageData* dimg = Accumulate(decimg);
  if (!dimg)
    { return; }

  int blkheight;
  if (dimg->m_pichdr1.m_picture_structure == PICSTRUCT_FramePicture)
    blkheight=16;
  else
    blkheight=32;


  Pixel*const* pix = dimg->m_image.AskFrameY();
  ImageParam_YUV param;
  dimg->m_image.GetParam(param);

  if (d_maxmode)
    {
      for (int y=0;y<param.height;y+=blkheight)
	for (int x=0;x<param.width;x+=16)
	  {
	    pix[y][x] = maximize(pix[y][x]);
	    if (d_bigmarks)
	      {
		pix[y            ][x+15] = maximize(pix[y            ][x+15]);
		pix[y+blkheight-1][x   ] = maximize(pix[y+blkheight-1][x   ]);
		pix[y+blkheight-1][x+15] = maximize(pix[y+blkheight-1][x+15]);
	      }
	  }
    }
  else
    {
      Assert(d_staticmode);

      for (int y=0;y<param.height;y+=blkheight)
	for (int x=0;x<param.width;x+=16)
	  {
	    pix[y][x] = d_val;
	    if (d_bigmarks)
	      {
		pix[y            ][x+15] = d_val;
		pix[y+blkheight-1][x   ] = d_val;
		pix[y+blkheight-1][x+15] = d_val;
	      }
	  }
    }

  d_next->ShowMBRows(dimg);
}

void VideoPostprocessor_MBBoundaries::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,true);

  d_next->BeginPicture(dimg);
}

void VideoPostprocessor_MBBoundaries::FinishedPicture()
{
  d_next->FinishedPicture();
}

--- NEW FILE: pp_mblks.hh ---
/********************************************************************************
  vpostproc/pp_mblks.hh
    Marks makroblock-boundaries.

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   20/Sep/2000 - Dirk Farin
     - Adaptation to new output architecture
   14/Apr/2000 - Dirk Farin
     - reimplementation
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_MBLKS_HH
#define DVDVIEW_VPOSTPROC_PP_MBLKS_HH

#include "vpostproc/postproc.hh"


class VideoPostprocessor_MBBoundaries : public VideoPostprocessor_Accumulate
{
public:
  VideoPostprocessor_MBBoundaries() : d_bigmarks(false), d_maxmode(true), d_staticmode(false) { }
  ~VideoPostprocessor_MBBoundaries() { }

  void SetBigMarks(bool flag=true) { d_bigmarks=flag; }
  void SetMaximizeMode(bool flag=true) { d_maxmode=flag; d_staticmode=!flag; }
  void SetStaticMode(Pixel p=255,bool flag=true) { d_staticmode=flag; d_maxmode=!flag; d_val=p; }

  bool NeedsPictureData(uint3 pictype) const { return true; }

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

private:
  bool  d_bigmarks;
  bool  d_maxmode;
  bool  d_staticmode;
  Pixel d_val;
};

#endif

--- NEW FILE: postproc.hh ---
/********************************************************************************
  vpostproc/postproc.hh
    Video frame post processor.

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   19/Sep/2000 - Dirk Farin
     - Accumulate-Postprocessor helper class to ease postprocessor writing.
   07/Sep/2000 - Dirk Farin
     - Complete reorganisation because of output architecture change.
   19/Jan/1999 - Dirk Farin
     - interface definition
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_POSTPROC_HH
#define DVDVIEW_VPOSTPROC_POSTPROC_HH

#include "video12/output.hh"
#include "output/accumulator.hh"
#include "libvideogfx/containers/array.hh"


class VideoPostprocessor : public DecodedPictureSink
{
public:
  VideoPostprocessor();
  virtual ~VideoPostprocessor();

  virtual void SetNext(DecodedPictureSink* next)
    {
      d_next = next;
      Assert(d_next);
    }

  virtual void BeginPicture(const DecodedImageData* dimg) { d_next->BeginPicture(dimg); }
  virtual void ShowMBRows(DecodedImageData*) = 0;
  virtual void FinishedPicture() { d_next->FinishedPicture(); }

  virtual bool  NeedsPictureData(uint3 pictype) const { return d_next->NeedsPictureData(pictype); }
  virtual bool  NeedsMBData     (uint3 pictype) const { return d_next->NeedsMBData(pictype); }

protected:
  class DecodedPictureSink* d_next;
};


class VideoPostprocessor_Accumulate : public VideoPostprocessor,
				      public ImageDataAccumulator
{
public:
  void SetNext(DecodedPictureSink* next)
  {
    VideoPostprocessor::SetNext(next);
    ImageDataAccumulator::SetNext(next);
  }
};


#if 0
  /* Forward all lines that may not be modified and are not in the given range to
     the next postprocessor and exclude these lines from the line range in the
     image data.
     True is returned, if the input image data contains at least one line contained
     in the line range.

     The usage is as follows: If you know that you will operate on the lines in
     the given range, call this method before. Image parts that are not operated
     on will be forwarded to the next postprocessor. The image data range is
     modified to only include those lines that you need to draw to and that are
     present in the image data.
  */
  bool DisplayUnmodifyableLinesOutOfRange(DecodedImageData*,int first,int last);
#endif

#if 0
class VideoPostprocessor_Copy : public VideoPostprocessor
{
public:
  VideoPostprocessor_Copy() : d_width(0), d_height(0) { }

protected:
  /* Prepare image data for overwriting. If the given image contents may not be
     modified, the part that will be written to is copied. All other parts
     are implicitly forwarded to the next postprocessor stage. If false is returned,
     the input image does not contain any lines that will be drawn to. In this
     case, all input lines are implicitly forwarded to the next stage. */
  bool GetLinesForDrawing(DecodedImageData*,int first,int last);

  DecodedImageData d_dimg;

private:
  int d_width,d_height;
};
#endif


#endif

--- NEW FILE: pp_resize.hh ---
/********************************************************************************
  vpostproc/pp_resize.hh
    Resizes output image.

  purpose:

  notes:
    This is a hack, and I'm not sure if the postprocessor chain is the
    right place to do resizing, as the MB-data does not correspond to
    the image afterwards. Moreover, we have all the problems that result
    from resizing interlaced pictures.

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   22/Sep/2000 - Dirk Farin
     - first implementation
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_RESIZE_HH
#define DVDVIEW_VPOSTPROC_PP_RESIZE_HH

#include "vpostproc/postproc.hh"


class Resize_Interface
{
public:
  virtual ~Resize_Interface() { }

  virtual void SetScaledSize(int w,int h) = 0;
  virtual void ResetScaledSize() = 0;
};

class VideoPostprocessor_Resize : public VideoPostprocessor_Accumulate,
				  public Resize_Interface
{
public:
  VideoPostprocessor_Resize() : d_do_resize(false),
				d_ltab_h(NULL), d_ltab_v(NULL),
				d_ctab_h(NULL), d_ctab_v(NULL), tab_initialized(false) { }
  ~VideoPostprocessor_Resize();

  void SetScaledSize(int w,int h);
  void ResetScaledSize() { d_do_resize=false; }

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

private:
  bool  d_do_resize;
  int   width,height;

  DecodedImageData newdimg;

  int *d_ltab_h,*d_ltab_v;
  int *d_ctab_h,*d_ctab_v;
  bool tab_initialized;
};

#endif

--- NEW FILE: pp_mv.hh ---
/********************************************************************************
  vpostproc/pp_mv.hh

  purpose:
    Show motionvectors.

  notes:

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   20/Sep/2000 - Dirk Farin
     - Adaptation to new output architecture
   15/Apr/2000 - Dirk Farin
     - reimplementation
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_MV_HH
#define DVDVIEW_VPOSTPROC_PP_MV_HH

#include "vpostproc/postproc.hh"


class VideoPostprocessor_MotionVector : public VideoPostprocessor_Accumulate
{
public:
  VideoPostprocessor_MotionVector() : d_show_forward(true), d_show_backward(true),
  d_colored(false), d_show_p(true), d_show_b(true) { }

  void SelectMVs(bool showforw,bool showback)
  {
    d_show_forward = showforw;
    d_show_backward = showback;
  }

  void SelectFrametypes(bool p,bool b)
  {
    d_show_p=p; d_show_b=b;
  }

  void ColoredVectors(bool flag=true) { d_colored=flag; }

  bool NeedsPictureData(uint3 pictype) const;
  bool NeedsMBData(uint3 pictype) const;

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

private:
  bool d_show_forward;
  bool d_show_backward;
  bool d_show_p,d_show_b;
  bool d_colored;
};

#endif

--- NEW FILE: pp_imgtype.hh ---
/********************************************************************************
  vpostproc/pp_imgtype.hh

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   15/Apr/00 - Dirk Farin
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_IMGTYPE_HH
#define DVDVIEW_VPOSTPROC_PP_IMGTYPE_HH

#include "vpostproc/postproc.hh"


class VideoPostprocessor_ImageType : public VideoPostprocessor
{
public:
  VideoPostprocessor_ImageType() { }

  bool NeedsPictureData(uint3 pictype) const { return true; }
  void Render(DecodedImageData*);

private:
};

#endif

--- NEW FILE: pp_filteredresize.hh ---
/********************************************************************************
  vpostproc/pp_filteredresize.hh
    Resizes output image with additional filtering to enhance quality.

  purpose:

  notes:

  to do:

  author(s):
   - Carlo Daffara, cdaffara at mail.conecta.it
   - Dirk Farin, farin at ti.uni-mannheim.de

  modifications:
   16/Oct/2000 - Carlo Daffara
     - first implementation
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_FILTEREDRESIZE_HH
#define DVDVIEW_VPOSTPROC_PP_FILTEREDRESIZE_HH

#include "vpostproc/postproc.hh"
#include "vpostproc/pp_resize.hh"


class VideoPostprocessor_FilteredResize : public VideoPostprocessor_Accumulate,
					  public Resize_Interface
{
public:
  VideoPostprocessor_FilteredResize() : d_do_resize(false),
					d_ltab_h(NULL), d_ltab_v(NULL),
					d_ctab_h(NULL), d_ctab_v(NULL), tab_initialized(false) { }
  ~VideoPostprocessor_FilteredResize();

  void SetScaledSize(int w,int h);
  void ResetScaledSize() { d_do_resize=false; }

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

private:
  bool  d_do_resize;
  int   width,height;

  DecodedImageData newdimg;

  int *d_ltab_h,*d_ltab_v;
  int *d_ctab_h,*d_ctab_v;
  bool tab_initialized;
};

#endif

--- NEW FILE: postproc.cc ---

#include "vpostproc/postproc.hh"

#define DEBUGINFO 0


VideoPostprocessor::VideoPostprocessor()
  : d_next(NULL)
{
}

VideoPostprocessor::~VideoPostprocessor()
{
}

--- NEW FILE: pp_mvcol.cc ---

#include "vpostproc/pp_mvcol.hh"
#include "video12/constants.hh"
#include "libvideogfx/graphics/color/colorspace.hh"
#include <math.h>

#include <iostream.h>

#ifndef PI
#define PI 3.1415926535
#endif


bool VideoPostprocessor_MVCol::NeedsPictureData(uint3 pictype) const
{
  return true;

  assert(d_next);

  return ((pictype == PICTYPE_B && d_showb) ||
	  (pictype == PICTYPE_P && d_showp) ||
	  d_next->NeedsPictureData(pictype));
}

bool VideoPostprocessor_MVCol::NeedsMBData(uint3 pictype) const
{
  return NeedsPictureData(pictype);
}

void VideoPostprocessor_MVCol::ShowMBRows(DecodedImageData* decimg)
{
  DecodedImageData* dimg = Accumulate(decimg);
  if (!dimg)
    { return; }

  Pixel*const* yy = dimg->m_image.AskFrameY();
  Pixel*const* cb = dimg->m_image.AskFrameU();
  Pixel*const* cr = dimg->m_image.AskFrameV();

  ImageParam_YUV param;
  dimg->m_image.GetParam(param);

  int cw = ((param.chroma==Chroma444)?16:8);
  int ch = ((param.chroma==Chroma420)?8:16);

  if (!dimg->m_picdata1)
    { if (d_hold) RedrawHold(yy,cb,cr,cw,ch); d_next->ShowMBRows(decimg); return; }

  // Skip drawing in unselected picture types. If hold mode is selected, draw
  // old vectors again instead.

  if (dimg->m_pichdr1.m_picture_coding_type==PICTYPE_I)
    { if (d_hold) RedrawHold(yy,cb,cr,cw,ch); d_next->ShowMBRows(decimg); return; }

  if (dimg->m_pichdr1.m_picture_coding_type==PICTYPE_P && !d_showp)
    { if (d_hold) RedrawHold(yy,cb,cr,cw,ch); d_next->ShowMBRows(decimg); return; }

  if (dimg->m_pichdr1.m_picture_coding_type==PICTYPE_B && !d_showb)
    { if (d_hold) RedrawHold(yy,cb,cr,cw,ch); d_next->ShowMBRows(decimg); return; }


  if (!d_blks.IsInitialized())
    {
      int w = param.width;
      int h = param.height;
      
      d_blks.Create((w+15)/16,(h+15)/16);
    }

  if (dimg->m_pichdr1.m_picture_structure == PICSTRUCT_FramePicture)
    d_fields=false;
  else
    d_fields=true;


  // Draw and store new vectors.

  int h = dimg->m_picdata1->m_codedimage.AskHeight();
  int w = dimg->m_picdata1->m_codedimage.AskWidth();

  for (int y=0;y<h;y++)
    for (int x=0;x<w;x++)
      {
        const Macroblock& mb = dimg->m_picdata1->m_codedimage.Ask_const(y,x);

	BlockColorInfo bci;

	double magnitude=0.0;
	double angle;

	{
	  // forward MV

	  int h,v;

	  double m;

	  if (mb.m_HasMotionForward && d_fwd)
	    {
	      h = abs(mb.m_forward1.m_habs);
	      v = abs(mb.m_forward1.m_vabs);

	      m = sqrt((double)(h*h+v*v));
	      magnitude=m;
	    }
	    

	  // backward MV
	    
	  if (mb.m_HasMotionBackward && d_bkw)
	    {
	      h = abs(mb.m_backward1.m_habs);
	      v = abs(mb.m_backward1.m_vabs);

	      m = sqrt((double)(h*h+v*v));
	      magnitude += m;
	      magnitude /= 2;
	    }
	}

	{
	  int h=0,v=0;
	    
	  if (mb.m_HasMotionForward && d_fwd)
	    {
	      h += mb.m_forward1.m_habs;
	      v += mb.m_forward1.m_vabs;
	    }
	    

	  // backward MV
	    
	  if (mb.m_HasMotionBackward && d_bkw)
	    {
	      h -= mb.m_backward1.m_habs;
	      v -= mb.m_backward1.m_vabs;
	    }

	  if (h!=0 || v!=0)
	    {
	      double w;
	      if (h==0)
		{
		  if (v<0) w=PI/2.0;
		  else     w=PI*3.0/2.0;
		}
	      else
		{
		  if (h>0)
		    {
		      w = atan(((double)-v)/h);
		      if (w<0) w+= 2*PI;
		    }
		  else
		    {
		      w = -atan(((double)v)/h);
		      w+= PI;
		    }
		}

	      angle=w;
	    }
	}

	magnitude /= 32; if (magnitude>1.0) magnitude=1.0;
	angle /= 2*PI;   if (angle>2*PI) angle=2*PI;

	bci.hue = angle;
	if (magnitude==0)
	  bci.sat=0;
	else
	  bci.sat = magnitude*0.5 + 0.5;

	d_blks.Ask(y,x)=bci;
      }

  RedrawHold(yy,cb,cr,cw,ch);

  d_next->ShowMBRows(dimg);
}


void VideoPostprocessor_MVCol::RedrawHold(Pixel*const* yp,Pixel*const* cb,Pixel*const* cr,
					  int cw,int ch)
{
  if (!d_blks.IsInitialized())
    return;

  // Redraw stored vectors.

  int h = d_blks.AskHeight();
  int w = d_blks.AskWidth();

  int blkh = 16;
  if (d_fields) blkh*=2;

  if (d_fields) h/=2;

  for (int y=0;y<h;y++)
    for (int x=0;x<w;x++)
      {
	BlockColorInfo bci;

	bci=d_blks.Ask(y,x);
	for (int yy=0;yy<ch;yy++)
	  for (int xx=0;xx<cw;xx++)
	    {
	      double rd,gd,bd;
	      uint8 r,g,b;
	      uint8 yc,uc,vc;

	      double hue = bci.hue;
	      double sat = bci.sat;
	      double val = ((double)(yp[blkh*y+yy][16*x+xx]))/255;

	      HSB2RGB(hue,sat,val, rd,gd,bd);
	      r = (uint8)(255*rd);
	      g = (uint8)(255*gd);
	      b = (uint8)(255*bd);
	      RGB2YUV(r,g,b,yc,uc,vc);

	      //yp[16*y+yy][16*x+xx] = yc;
	      cb[ch*y+yy][cw*x+xx] = uc;
	      cr[ch*y+yy][cw*x+xx] = vc;
	    }
      }
}


void VideoPostprocessor_MVCol::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,true);

  d_next->BeginPicture(dimg);
}

void VideoPostprocessor_MVCol::FinishedPicture()
{
  d_next->FinishedPicture();
}


#include "libvideogfx/containers/array2.cc"
template class Array2<BlockColorInfo>;

--- NEW FILE: pp_qscale.hh ---
/********************************************************************************
  vpostproc/pp_qscale.hh

  purpose:
    Show QScale of macroblocks.

  notes:

  to do:

  author(s):
   - Dirk Farin, Kapellenweg 15, 72070 Tuebingen, Germany,
     email: farindk at trick.informatik.uni-stuttgart.de

  modifications:
   15/Apr/00 - Dirk Farin
     - reimplementation
 ********************************************************************************
    Copyright (C) 1999  Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    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
 ********************************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_QSCALE_HH
#define DVDVIEW_VPOSTPROC_PP_QSCALE_HH

#include "vpostproc/postproc.hh"


class VideoPostprocessor_QScale : public VideoPostprocessor_Accumulate
{
public:
  VideoPostprocessor_QScale() { }

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

  bool NeedsPictureData(uint3 pictype) const { return true; }
  bool NeedsMBData(uint3 pictype) const { return true; }
private:
};

#endif

--- NEW FILE: pp_mvcol.hh ---
/*********************************************************************
  postproc_mvcol.hh
    Video frame post processor (Motionvectors).

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, farin at ti.uni-mannheim.de
     University Mannheim, Dept. Circuitry and Simulation
     B 6,26 EG, room 0.10 / D-68131 Mannheim / Germany

  modifications:
   20/Sep/2000 - Dirk Farin
     - Adaptation to new output architecture
   06/May/1999 - Dirk Farin
     - first implementation
 *********************************************************************/

#ifndef DVDVIEW_VPOSTPROC_PP_MVCOL_HH
#define DVDVIEW_VPOSTPROC_PP_MVCOL_HH

#include "libvideogfx/containers/array2.hh"
#include "vpostproc/postproc.hh"
#include "vpostproc/pp_mvcol.hh"

struct BlockColorInfo
{
  double hue,sat;
};


class VideoPostprocessor_MVCol : public VideoPostprocessor_Accumulate
{
public:
  VideoPostprocessor_MVCol()
    : d_showp(true), d_showb(false),
      d_hold(false), d_fwd(true), d_bkw(true) { }
  ~VideoPostprocessor_MVCol() { }

  void SetHoldMode(bool hold=false) { d_hold=hold; }
  void SelectMVs(bool showforw,bool showback) { d_fwd=showforw; d_bkw=showback; }
  void SelectFrametypes(bool p=true,bool b=false) { d_showp=p, d_showb=b; }

  bool NeedsPictureData(uint3 pictype) const;
  bool NeedsMBData(uint3 pictype) const;

  void BeginPicture(const DecodedImageData*);
  void ShowMBRows(DecodedImageData*);
  void FinishedPicture();

private:
  bool d_showp,d_showb;
  bool d_hold;
  bool d_fwd,d_bkw;

  bool d_fields;

  void RedrawHold(Pixel*const* yy,Pixel*const* cb,Pixel*const* cr,int cw,int ch);

  Array2<BlockColorInfo> d_blks;
};

#endif




More information about the dslinux-commit mailing list