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