dslinux/user/pixil/packages/dvdview/dvdview/src/output accumulator.cc accumulator.hh out_mgavid.cc out_mgavid.hh out_ppm.cc out_ppm.hh out_x11.cc out_x11.cc.org out_x11.hh out_x11.hh.org out_yuv.cc out_yuv.hh

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


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

Added Files:
	accumulator.cc accumulator.hh out_mgavid.cc out_mgavid.hh 
	out_ppm.cc out_ppm.hh out_x11.cc out_x11.cc.org out_x11.hh 
	out_x11.hh.org out_yuv.cc out_yuv.hh 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: out_x11.cc.org ---
/********************************************************************************
    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
 ********************************************************************************/

#include "output/out_x11.hh"
#include "config.h"
#include "libvideogfx/x11/imgwin.hh"


VideoSink_X11::VideoSink_X11()
  : imgwin(NULL), first(true), pic_available(false)
{
}


VideoSink_X11::~VideoSink_X11()
{
  if (imgwin)
    {
      delete imgwin;
      delete x11img;
      delete transformation;
    }
}

#if 0
void VideoSink_X11::ShowMBRows(DecodedImageData* dimg)
{
  const Image_YUV<Pixel>& img = dimg->m_image;

  nextpts = dimg->m_timing.pts;

  if (first)
    {
      ImageParam_YUV param;
      img.GetParam(param);
      d_height = param.height;

      //StartAccumulation(0,d_height-1,false);

      assert(imgwin==NULL);
      imgwin=new ImageWindow_X11;
      x11img=new DisplayImage_X11;
      transformation=new Image2Raw;

      imgwin->SetPosition(10,10);
      imgwin->Create(dimg->m_width,dimg->m_height,
		     "DVDview (c) 1998-2000 Dirk Farin");
      x11img->Create(dimg->m_width,dimg->m_height,imgwin->AskWindow());

      XImage& ximg = x11img->AskXImage();

      RawImageSpec_RGB spec;
      spec.bytes_per_line = bpl = ximg.bytes_per_line;
      spec.bits_per_pixel = ximg.bits_per_pixel;
      spec.little_endian  = (ximg.byte_order==LSBFirst);
      spec.SetRGBMasks(ximg.red_mask,ximg.green_mask,ximg.blue_mask);

      transformation->SetOutputSpec(spec);
  
      first=false;
    }

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

  transformation->TransformYUV(decimg->m_image,
			       (uint8*)(x11img->AskXImage().data+bpl*decimg->m_dst_y_start),
			       decimg->m_src_y_start,decimg->m_src_y_end);


  if (decimg->m_dst_y_start - decimg->m_src_y_start + decimg->m_src_y_end==decimg->m_height-1)
    {
      x11img->PutImage();
    }
  //imgwin->Display_const(decimg->m_image);
}


void VideoSink_X11::FinishedPicture()
{
  pic_available=true;
  StartAccumulation(0,d_height-1,false);
}

#else
void VideoSink_X11::ShowMBRows(DecodedImageData* dimg)
{
  const Image_YUV<Pixel>& img = dimg->m_image;

  nextpts = dimg->m_timing.pts;

  if (first)
    {
      ImageParam_YUV param;
      img.GetParam(param);
      d_height = param.height;

      StartAccumulation(0,d_height-1,false);

      assert(imgwin==NULL);
      imgwin=new ImageWindow_X11;
      x11img=new DisplayImage_X11;
      transformation=new Image2Raw;

      imgwin->SetPosition(10,10);
      imgwin->Create(dimg->m_width,dimg->m_height,
		     "DVDview (c) 1998-2000 Dirk Farin");
      x11img->Create(dimg->m_width,dimg->m_height,imgwin->AskWindow());

      XImage& ximg = x11img->AskXImage();

      RawImageSpec_RGB spec;
      spec.bytes_per_line = bpl = ximg.bytes_per_line;
      spec.bits_per_pixel = ximg.bits_per_pixel;
      spec.little_endian  = (ximg.byte_order==LSBFirst);
      spec.SetRGBMasks(ximg.red_mask,ximg.green_mask,ximg.blue_mask);

      transformation->SetOutputSpec(spec);
  
      first=false;
    }

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

  transformation->TransformYUV(decimg->m_image , (uint8*)(x11img->AskXImage().data));

  x11img->PutImage();
}


void VideoSink_X11::FinishedPicture()
{
  pic_available=true;
  StartAccumulation(0,d_height-1,false);
}
#endif

--- NEW FILE: accumulator.cc ---

#include "output/accumulator.hh"
#include <string.h>

#define DEBUGINFO 0

#if DEBUGINFO
void ShowDIMG(DecodedImageData* dimg)
{
  cout << dimg->m_src_y_start << "-" << dimg->m_src_y_end << " to "
       << dimg->m_dst_y_start << "-" << dimg->m_dst_y_start+dimg->m_src_y_end-dimg->m_src_y_start
       << (dimg->m_may_modify ? " may modify" : " may not modify") << endl;
}
#endif


void ImageDataAccumulator::StartAccumulation(int first,int last,bool modify)
{
  // Round range up multiples of 4, so we don't have any problems with choma even in
  // field pictures.

  //first &= ~3;
  //last = (last+3) & ~3;   DOESN't WORK (watch chroma with "spaceneedle.mpg")

  // cout << "START ACCUMULATION " << first << " -> " << last << endl;

  d_line_available.CreateRange(first,last);
  bool* p = d_line_available.Data();
  for (int i=first;i<=last;i++)
    p[i]=false;

  d_modifyable_copy = modify;
}


DecodedImageData* ImageDataAccumulator::Accumulate(DecodedImageData* dimg)
{
  const int first = d_line_available.AskStartIdx();                      // first line to accumulate into
  const int last  = min(dimg->m_height-1,d_line_available.AskEndIdx());  // last line to accumulate into

  const int ys = dimg->m_dst_y_start;                        // first output line
  const int ye = ys + dimg->m_src_y_end-dimg->m_src_y_start; // last output line

#if DEBUGINFO
  cout << "--- Accumulate into: " << first << " to " << last << endl;
  ShowDIMG(dimg);
#endif


  /* If image area is completely out of the range used, it can simply be sent to
     the next postprocessor.
  */

  if (ye < first) { if (DEBUGINFO) cout << "show all (above)\n"; d_sink->ShowMBRows(dimg); return NULL; }
  if (ys > last)  { if (DEBUGINFO) cout << "show all (below)\n"; d_sink->ShowMBRows(dimg); return NULL; }

  /* If image area completely contains the used range and it may be modified or no
     write-access is required, simply return the area. */

  if (ys<=first && ye>=last && (!d_modifyable_copy || dimg->m_may_modify) && !dimg->m_field_lines)
    {
#if DEBUGINFO
      cout << "return complete region\n";
#endif
      return dimg;
    }


  /* Save values out of dimg as we may leave it unchanged at the end of our function. */

  const int old_src_y_start = dimg->m_src_y_start;
  const int old_src_y_end   = dimg->m_src_y_end;
  const int old_dst_y_start = dimg->m_dst_y_start;
  const int old_may_modify  = dimg->m_may_modify;


  /* Forward the areas that are not used to the next postprocessor. */

  if (ys < first)
    {
      // show lines above drawing region

      int before = first-ys;
      //cout << "lines before: " << before << endl;


      // show unmodified lines

      dimg->m_src_y_end = dimg->m_src_y_start+before-1;

      if (dimg->m_field_lines && (before&1)==0) dimg->m_src_y_end--;  // make displayed line range tight

      Assert(d_sink);
      d_sink->ShowMBRows(dimg);
#if DEBUGINFO
      cout << "show unmodified above: ";  ShowDIMG(dimg);
#endif

      // remove already shown lines

      if (dimg->m_field_lines && (before&1)==1) before++;  // obey parity of accumulated lines

      dimg->m_src_y_end = old_src_y_end;
      dimg->m_src_y_start += before;
      dimg->m_dst_y_start += before;
    }

  if (ye>last)
    {
      // show lines below drawing region

      int after = ye-last;
      //cout << "lines after: " << after << endl;

      dimg->m_src_y_start = dimg->m_src_y_end-after+1;
      dimg->m_dst_y_start = ye-after+1;

      if (dimg->m_field_lines && (after&1)==0)
	{
	  dimg->m_src_y_start++;
	  dimg->m_dst_y_start++;
	}

      Assert(d_sink);
      d_sink->ShowMBRows(dimg);
#if DEBUGINFO
      cout << "show unmodified below: ";  ShowDIMG(dimg);
#endif

      // remove already shown lines

      if (dimg->m_field_lines && (after&1)==1) after++;  // obey parity of accumulated lines

      dimg->m_src_y_start = old_src_y_start;
      dimg->m_dst_y_start = old_dst_y_start;
      dimg->m_src_y_end -= after;
    }



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

  if (d_width != param.width ||
      d_height < d_line_available.AskSize())
    {
      ImageSpec_YUV spec; ((ImageParam_YUV&)spec)=param;
      spec.height = d_line_available.AskSize();
      d_dimg.m_image.Create(spec);

      d_width  = spec.width;
      d_height = spec.height;

      d_dimg.m_width      =dimg->m_width;
      d_dimg.m_height     =dimg->m_height;
      d_dimg.m_src_y_start=0;
      d_dimg.m_src_y_end  =d_line_available.AskSize()-1;
      d_dimg.m_dst_y_start=d_line_available.AskStartIdx();
      d_dimg.m_field_lines=false;
      d_dimg.m_may_modify =true;
    }

  d_dimg.m_picdata1   =dimg->m_picdata1;
  d_dimg.m_picdata2   =dimg->m_picdata2;
  d_dimg.m_pichdr1    =dimg->m_pichdr1;
  d_dimg.m_pichdr2    =dimg->m_pichdr2;
  d_dimg.m_timing     =dimg->m_timing;

  int lineskip = (dimg->m_field_lines ? 2 : 1);
  int y0 = -dimg->m_src_y_start+dimg->m_dst_y_start-first;

  bool* line = d_line_available.Data();

#if DEBUGINFO
  cout << "Copy from " << dimg->m_src_y_start << " to " << dimg->m_src_y_end << endl;
  cout << "y0: " << y0 << endl;
#endif

  // accumulate luminance data (and 4:2:2 or 4:4:4 chrominance data)

  int chromawidth = param.GetChromaWidth();

  for (int y=0; ;y+=lineskip)
    {
      int src_y = dimg->m_src_y_start+y;
      int dst_y = dimg->m_dst_y_start+y;
      int dat_y = dimg->m_dst_y_start-first+y;

      if (src_y > dimg->m_src_y_end)
	break;

      // cout << "copy line " << y << " to " << y+y0 << endl;
      memcpy(d_dimg.m_image.AskFrameY()[dat_y],
	     dimg->m_image.AskFrameY()[src_y],d_width);
      line[dst_y]=true;

      if (param.chroma==Chroma422 || param.chroma==Chroma444)
	{
	  memcpy(d_dimg.m_image.AskFrameU()[dat_y],
		 dimg->m_image.AskFrameU()[src_y],chromawidth);
	  memcpy(d_dimg.m_image.AskFrameV()[dat_y],
		 dimg->m_image.AskFrameV()[src_y],chromawidth);
	}
    }

  // accumulate 4:2:0 chrominance data

  if (param.chroma==Chroma420)
    {
      int parity = (dimg->m_src_y_start&1);

      for (int y=0; ;y+=lineskip)
	{
	  int src_y,dst_y,dat_y;

	  if (dimg->m_field_lines)
	    {
	      src_y = ((dimg->m_src_y_start/2)&~1) +parity+y;
	      dst_y = ((dimg->m_dst_y_start/2)&~1) +parity+y;
	      dat_y = (((dimg->m_dst_y_start-first)/2)&~1) +parity+y;
	    }
	  else
	    {
	      src_y = dimg->m_src_y_start/2+y;
	      dst_y = dimg->m_dst_y_start/2+y;
	      dat_y = (dimg->m_dst_y_start-first)/2+y;
	    }

	  if (src_y > dimg->m_src_y_end/2)
	    break;

	  memcpy(d_dimg.m_image.AskFrameU()[dat_y],
		 dimg->m_image.AskFrameU()[src_y],d_width/2);
	  memcpy(d_dimg.m_image.AskFrameV()[dat_y],
		 dimg->m_image.AskFrameV()[src_y],d_width/2);
	}
    }


  // restore old values into dimg

  dimg->m_src_y_start = old_src_y_start;
  dimg->m_src_y_end   = old_src_y_end;
  dimg->m_dst_y_start = old_dst_y_start;
  dimg->m_may_modify  = old_may_modify;


  for (int i=last;i>=first;i--)
    if (line[i]==false)
      {
	if (DEBUGINFO) cout << "line " << i << " is still missing...\n";
	return NULL;
      }

  if (DEBUGINFO) cout << "image data range is complete..!\n";

  return &d_dimg;
}


template class Array<bool>;
#include "libvideogfx/containers/array.cc"

--- NEW FILE: out_x11.hh.org ---
/********************************************************************************
  output/out_x11.hh

  purpose:
    X11 output.

  notes:

  to do:

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

  modifications:
   20/Sep/2000 - Dirk Farin
    - first implementation, based on old X11 output code.
 ********************************************************************************
    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_OUTPUT_OUT_X11_HH
#define DVDVIEW_OUTPUT_OUT_X11_HH

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


class VideoSink_X11 : public VideoOutput,
		      public ImageDataAccumulator
{
public:
   VideoSink_X11();
  ~VideoSink_X11();

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

  bool PictureAvailable() { return pic_available; }
  PTS  AskPTSOfNextToBeDisplayed() const { return nextpts; }
  void ShowPicture() { pic_available=false; }

private:
  //class ImageWindow_Autorefresh_X11* imgwin;
  class ImageWindow_X11* imgwin;    // the window itself
  class DisplayImage_X11* x11img;   // the image to be displayed
  class Image2Raw* transformation;  // the transformation for image representation convertion
  int bpl;

  bool first;
  int  d_height;

  bool pic_available;
  PTS  nextpts;
};

#endif

--- NEW FILE: out_ppm.cc ---
/********************************************************************************
    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
 ********************************************************************************/

#include "output/out_ppm.hh"
#include "libvideogfx/graphics/fileio/rw_ppm.hh"
#include "libvideogfx/graphics/color/colorspace.hh"
#include <fstream.h>
#include <stdio.h>


VideoSink_PPMFile::VideoSink_PPMFile()
  : cnt(0), pic_available(false)
{
}


VideoSink_PPMFile::~VideoSink_PPMFile()
{
}


void VideoSink_PPMFile::ShowMBRows(DecodedImageData* dimg)
{
  nextpts = dimg->m_timing.pts;

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

  char buffer[100];
  sprintf(buffer,"img%05d.ppm",cnt);
  ofstream ostr(buffer);

  Image_RGB<Pixel> rgbimg;

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

  switch (param.chroma)
    {
    case Chroma420: YUV2RGB_420(decimg->m_image,rgbimg); break;
    case Chroma422: YUV2RGB_422(decimg->m_image,rgbimg); break;
    case Chroma444: YUV2RGB_444(decimg->m_image,rgbimg); break;
    }

  WriteImage_PPM6(rgbimg,ostr);

  cnt++;
}


void VideoSink_PPMFile::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,false);
}

void VideoSink_PPMFile::FinishedPicture()
{
  pic_available=true;
}

--- NEW FILE: out_x11.cc ---
/********************************************************************************
    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
 ********************************************************************************/

#include "output/out_x11.hh"
#include "config.h"
#include "libvideogfx/nanox/imgwin.hh"


VideoSink_X11::VideoSink_X11()
  : imgwin(NULL), first(true), pic_available(false), nocreate(false)
{
}

void VideoSink_X11::reset()
{
  //  delete imgwin;
  //  imgwin = 0;
  first=true;
  nocreate = true;
  pic_available = false;
}


VideoSink_X11::~VideoSink_X11()
{
  if (imgwin)
    {
      delete imgwin;
      delete x11img;
      delete transformation;
    }
}

#if 0
void VideoSink_X11::ShowMBRows(DecodedImageData* dimg)
{
  const Image_YUV<Pixel>& img = dimg->m_image;

  nextpts = dimg->m_timing.pts;

  if (first)
    {
      ImageParam_YUV param;
      img.GetParam(param);
      d_height = param.height;

      //StartAccumulation(0,d_height-1,false);

      if(!imgwin) {
	imgwin=new ImageWindow_X11;
	x11img=new DisplayImage_X11;
	transformation=new Image2Raw;
	
	imgwin->SetPosition(10,10);
	imgwin->Create(dimg->m_width,dimg->m_height,
		       "DVDview (c) 1998-2000 Dirk Farin");
	x11img->Create(dimg->m_width,dimg->m_height,imgwin->AskWindow());
	
	XImage& ximg = x11img->AskXImage();
      }

      RawImageSpec_RGB spec;
      spec.bytes_per_line = bpl = ximg.bytes_per_line;
      spec.bits_per_pixel = ximg.bits_per_pixel;
      spec.little_endian  = (ximg.byte_order==LSBFirst);
      spec.SetRGBMasks(ximg.red_mask,ximg.green_mask,ximg.blue_mask);

      transformation->SetOutputSpec(spec);
  
      first=false;
    }

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

  transformation->TransformYUV(decimg->m_image,
			       (uint8*)(x11img->AskXImage().data+bpl*decimg->m_dst_y_start),
			       decimg->m_src_y_start,decimg->m_src_y_end);


  if (decimg->m_dst_y_start - decimg->m_src_y_start + decimg->m_src_y_end==decimg->m_height-1)
    {
      x11img->PutImage();
    }
  //imgwin->Display_const(decimg->m_image);
}


void VideoSink_X11::FinishedPicture()
{
  pic_available=true;
  StartAccumulation(0,d_height-1,false);
}

#else
void VideoSink_X11::ShowMBRows(DecodedImageData* dimg)
{
  const Image_YUV<Pixel>& img = dimg->m_image;

  nextpts = dimg->m_timing.pts;

  if (first)
    {
      ImageParam_YUV param;
      img.GetParam(param);
      d_height = param.height;

      StartAccumulation(0,d_height-1,false);

      if(!imgwin) {
	imgwin=new ImageWindow_X11;
	x11img=new DisplayImage_X11;
	transformation=new Image2Raw;
	
	imgwin->SetPosition(10,10);
	imgwin->Create(dimg->m_width,dimg->m_height,
		       "DVDview (c) 1998-2000 Dirk Farin");
	x11img->Create(dimg->m_width,dimg->m_height,imgwin->AskWindow());
      }	
      XImage& ximg = x11img->AskXImage();

      RawImageSpec_RGB spec;
      spec.bytes_per_line = bpl = ximg.bytes_per_line;
      spec.bits_per_pixel = ximg.bits_per_pixel;
      spec.little_endian  = (ximg.byte_order==LSBFirst);
      spec.SetRGBMasks(ximg.red_mask,ximg.green_mask,ximg.blue_mask);

      transformation->SetOutputSpec(spec);
  
      first=false;
    }

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

  transformation->TransformYUV(decimg->m_image , (uint8*)(x11img->AskXImage().data));

  x11img->PutImage();
}


void VideoSink_X11::FinishedPicture()
{
  pic_available=true;
  StartAccumulation(0,d_height-1,false);
}
#endif

--- NEW FILE: out_ppm.hh ---
/********************************************************************************
  output/out_ppm.hh

  purpose:
    PPM file-output.

  notes:

  to do:

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

  modifications:
   25/Sep/2000 - Dirk Farin
    - first implementation, based on old YUV file output code.
 ********************************************************************************
    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_OUTPUT_OUT_PPM_HH
#define DVDVIEW_OUTPUT_OUT_PPM_HH

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


class VideoSink_PPMFile : public VideoOutput,
			  public ImageDataAccumulator
{
public:
   VideoSink_PPMFile();
  ~VideoSink_PPMFile();

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

  bool PictureAvailable() { return pic_available; }
  PTS  AskPTSOfNextToBeDisplayed() const { return nextpts; }
  void ShowPicture() { pic_available=false; }

private:
  int  cnt;

  bool pic_available;
  PTS  nextpts;
};

#endif

--- NEW FILE: out_yuv.hh ---
/********************************************************************************
  output/out_yuv.hh

  purpose:
    YUV file-output.

  notes:

  to do:

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

  modifications:
   25/Sep/2000 - Dirk Farin
    - first implementation, based on old YUV file output code.
 ********************************************************************************
    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_OUTPUT_OUT_YUV_HH
#define DVDVIEW_OUTPUT_OUT_YUV_HH

#include "libvideogfx/graphics/basic/image.hh"
#include "video12/output.hh"
#include "output/accumulator.hh"
#include "libvideogfx/graphics/fileio/write_yuv.hh"
#include <fstream.h>


class VideoSink_YUVFile : public VideoOutput,
			  public ImageDataAccumulator
{
public:
   VideoSink_YUVFile();
  ~VideoSink_YUVFile();

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

  bool PictureAvailable() { return pic_available; }
  PTS  AskPTSOfNextToBeDisplayed() const { return nextpts; }
  void ShowPicture() { pic_available=false; }

private:
  bool first;
  ofstream ostr;
  FileWriter_YUV1 writer;

  bool pic_available;
  PTS  nextpts;
};

#endif

--- NEW FILE: out_x11.hh ---
/********************************************************************************
  output/out_x11.hh

  purpose:
    X11 output.

  notes:

  to do:

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

  modifications:
   20/Sep/2000 - Dirk Farin
    - first implementation, based on old X11 output code.
 ********************************************************************************
    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_OUTPUT_OUT_X11_HH
#define DVDVIEW_OUTPUT_OUT_X11_HH

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


class VideoSink_X11 : public VideoOutput,
		      public ImageDataAccumulator
{
public:
   VideoSink_X11();
  ~VideoSink_X11();

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

  bool PictureAvailable() { return pic_available; }
  PTS  AskPTSOfNextToBeDisplayed() const { return nextpts; }
  void ShowPicture() { pic_available=false; }

  void reset();

private:
  //class ImageWindow_Autorefresh_X11* imgwin;
  class ImageWindow_X11* imgwin;    // the window itself
  class DisplayImage_X11* x11img;   // the image to be displayed
  class Image2Raw* transformation;  // the transformation for image representation convertion
  int bpl;

  bool first;
  int  d_height;

  bool nocreate;

  bool pic_available;
  PTS  nextpts;
};

#endif

--- NEW FILE: out_mgavid.cc ---
/********************************************************************************
    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
 ********************************************************************************/

#include "output/out_mgavid.hh"
#include "config.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>


VideoSink_MGA::VideoSink_MGA()
  : first(true), scaled(false), width(0), height(0), pic_available(false)
{
  fileh = open("/dev/mga_vid",O_RDWR);
}


VideoSink_MGA::~VideoSink_MGA()
{
  if (fileh>0) close(fileh);
}


#include <libvideogfx/graphics/fileio/write_yuv.hh>

void VideoSink_MGA::ShowMBRows(DecodedImageData* dimg)
{
  const Image_YUV<Pixel>& img = dimg->m_image;

  nextpts = dimg->m_timing.pts;

  if (dimg->m_width*dimg->m_height > 1024*680)
    {
      /* TODO: how can we detect if MGA will work? */
      MessageDisplay::Show(ErrSev_Warning,"image size could be too large for MGA device");
    }

  /*
  cout << "MGA-Show lines from " << dimg->m_src_y_start << " to "
       << dimg->m_src_y_end << " at " << dimg->m_dst_y_start
       << (dimg->m_field_lines ? " as field" : " as frame") << endl;
  */

  assert(fileh>0);

  ImageParam_YUV param;
  img.GetParam(param);

  if (first)
    {
      first=false;

      assert(param.chroma==Chroma420 || param.chroma==Chroma422);
      if (param.chroma==Chroma422)
	{
	  MessageDisplay::Show(ErrSev_Warning,"displaying 4:2:2 video on 4:2:0 MGA device");
	}

      config.src_width   = param.width;
      config.src_height  = param.height;
      if (scaled)
	{
	  config.dest_width  = width;
	  config.dest_height = height;
	}
      else
	{
	  config.dest_width  = param.width;
	  config.dest_height = param.height;
	}

      config.x_org = 0;
      config.y_org = 0;
      config.colkey_on = 0;

      if (ioctl(fileh,MGA_VID_CONFIG,&config))
	{
	  perror("error in MGA_VID_CONFIG.\n");
	}

      if (ioctl(fileh,MGA_VID_ON,0))
	{
	  perror("error in MGA_VID_ON.\n");
	}
      base = (uint_8*)mmap(0,256*4096,PROT_WRITE,MAP_SHARED,fileh,0);
      if (base==MAP_FAILED)
	{
	  perror("error in mmap of MGA memory.\n");
	}
    }

  const Pixel*const* yp = img.AskFrameY_const();
  const Pixel*const* up = img.AskFrameU_const();
  const Pixel*const* vp = img.AskFrameV_const();

  int lineskip = (dimg->m_field_lines ? 2 : 1);

  int chroma_vfact = 2/ChromaSubV(param.chroma);

  if (config.card_type == MGA_G400)
    {
      int bes_pitch = (config.src_width+31) & ~31;
      uint_8* dest = base;
      int hoffs;

      dest += dimg->m_dst_y_start*bes_pitch;

      for (int h=dimg->m_src_y_start;h<=dimg->m_src_y_end;h+=lineskip)
	{
	  __builtin_memcpy(dest,yp[h],config.src_width);
	  dest += bes_pitch*lineskip;
	}

      dest = base+bes_pitch*config.src_height;
      dest += (dimg->m_dst_y_start+1)/2*bes_pitch/2;

      for (int h=(dimg->m_src_y_start+1)/2;h<=dimg->m_src_y_end/2;h+=lineskip)
	{
	  __builtin_memcpy(dest,up[h*chroma_vfact],config.src_width/2);
	  dest += bes_pitch/2*lineskip;
	}

      dest = base+bes_pitch*5*config.src_height/4;
      dest += (dimg->m_dst_y_start+1)/2*bes_pitch/2;

      for (int h=(dimg->m_src_y_start+1)/2;h<=dimg->m_src_y_end/2;h+=lineskip)
	{
	  __builtin_memcpy(dest,vp[h*chroma_vfact],config.src_width/2);
	  dest += bes_pitch/2*lineskip;
	}
    }
  else
    {
      // No G400 so we have a g200 don't we  ?

      assert(config.card_type == MGA_G200);  // Just to be sure :)  G450?

      int bespitch = (config.src_width + 31) & ~31;
      uint_8* dest = base + dimg->m_dst_y_start*bespitch;

      for(int h=dimg->m_src_y_start; h <= dimg->m_src_y_end; h+=lineskip)
	{
	  __builtin_memcpy(dest, yp[h],config.src_width);
	  dest += bespitch*lineskip;
	}

      dest = base+bespitch*config.src_height;
      dest += (dimg->m_dst_y_start+1)/2*bespitch;

      for (int h=(dimg->m_src_y_start+1)/2;h<=dimg->m_src_y_end/2;h+=lineskip)
        {
#if ENABLE_MMX
	  const Pixel*  cb = up[h*chroma_vfact];
	  const Pixel*  cr = vp[h*chroma_vfact];
	  uint_8* mem = dest;

	  for(int w=0; w < config.src_width/2/8; w++)
	    {
	      asm volatile (
			    "movq       (%1),%%mm0\n\t"
			    "movq       %%mm0,%%mm1\n\t"
			    "punpcklbw  (%2),%%mm0\n\t" 
			    "punpckhbw  (%2),%%mm1\n\t" 
			    "movq       %%mm0,(%0)\n\t"
			    "movq       %%mm1,8(%0)\n\t"
			    : : "r" (mem), "r" (cb),"r" (cr)
#if PGCC_COMPILER
			    : "mm0","mm1"
#endif
			    );
	      cb += 8;
	      cr += 8;
	      mem += 16;
	    }

	  dest += bespitch*lineskip;
#else
	  uint_8* mem = dest;

	  for(int w=0; w < config.src_width/2; w++)
	    {
	      *mem++ = up[h*chroma_vfact][w];
	      *mem++ = vp[h*chroma_vfact][w];
	    }

	  dest += bespitch*lineskip;
#endif
	}
    }
}


--- NEW FILE: out_mgavid.hh ---
/********************************************************************************
  output/out_mgavid.hh

  purpose:
    MGA_VID (Matrox G200/G400 BES output).

  notes:

  to do:

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

  modifications:
   27/Jun/2000 - Christophe Labouisse <labouiss at cybercable.fr>
    - G200 support
   13/Jun/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_OUTPUT_OUT_MGAVID_HH
#define DVDVIEW_OUTPUT_OUT_MGAVID_HH

#include "libvideogfx/graphics/basic/image.hh"
#include "video12/output.hh"
#include "vpostproc/pp_resize.hh"
#include "thirdparty/mga_vid.h"


class VideoSink_MGA : public VideoOutput,
		      public Resize_Interface
{
public:
   VideoSink_MGA();
  ~VideoSink_MGA();

  bool MGA_Available() const { return fileh != -1; }
  
  void SetScaledSize(int w,int h) { width=w; height=h; scaled=true; }
  void ResetScaledSize() { scaled=false; }

  void ShowMBRows(DecodedImageData*);
  void FinishedPicture() { pic_available=true; }

  bool PictureAvailable() { return pic_available; }
  PTS  AskPTSOfNextToBeDisplayed() const { return nextpts; }
  void ShowPicture() { pic_available=false; }

private:
  int fileh;
  bool first;
  mga_vid_config_t config;
  uint_8* base;

  bool scaled;
  int width,height;

  bool pic_available;
  PTS  nextpts;
};

#endif

--- NEW FILE: accumulator.hh ---
/********************************************************************************
  output/accumulator.hh
    Build continuous regions of image data from output stripes.

  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
     - Moved class definition to a file of its own.
   19/Sep/2000 - Dirk Farin
     - Accumulate helper class to ease postprocessor and display writing.
 ********************************************************************************
    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_OUTPUT_ACCUMULATOR_HH
#define DVDVIEW_OUTPUT_ACCUMULATOR_HH

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

class ImageDataAccumulator
{
public:
  ImageDataAccumulator() : d_width(0), d_height(0), d_sink(NULL) { }
  virtual ~ImageDataAccumulator() { }

  void SetNext(DecodedPictureSink* next) { d_sink = next; } /* The image sink, where unused
							       image strip data is sent to. */
  void              StartAccumulation(int first,int last,         // range to accumulate
				      bool modifyable_copy=true); // if we are going to write to the data
  DecodedImageData* Accumulate(DecodedImageData*);  // !NULL -> image is complete

private:
  DecodedImageData d_dimg;

  Array<bool> d_line_available;
  bool        d_modifyable_copy;

  int         d_width,d_height;

  class DecodedPictureSink* d_sink;
};

#endif

--- NEW FILE: out_yuv.cc ---
/********************************************************************************
    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
 ********************************************************************************/

#include "output/out_yuv.hh"


VideoSink_YUVFile::VideoSink_YUVFile()
  : first(true), pic_available(false)
{
}


VideoSink_YUVFile::~VideoSink_YUVFile()
{
  if (!first) ostr.close();
}


void VideoSink_YUVFile::ShowMBRows(DecodedImageData* dimg)
{
  nextpts = dimg->m_timing.pts;

  if (first)
    {
      ostr.open("sequence.yuv");
      writer.SetYUVStream(ostr);
      first=false;
    }

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

  writer.WriteImage(decimg->m_image);
}


void VideoSink_YUVFile::BeginPicture(const DecodedImageData* dimg)
{
  StartAccumulation(0,dimg->m_height-1,false);
}

void VideoSink_YUVFile::FinishedPicture()
{
  pic_available=true;
}




More information about the dslinux-commit mailing list