dslinux/user/pixil/packages/dvdview/dvdview/src/video12 constants.hh dctblk.cc macroblock.hh output.hh vdecoder.cc vdecoder.hh viddec_mods.cc viddec_mods.hh vidsyntax.cc vidsyntax.hh vlc.cc vlc.hh
amadeus
dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:03 CEST 2006
Update of /cvsroot/dslinux/dslinux/user/pixil/packages/dvdview/dvdview/src/video12
In directory antilope:/tmp/cvs-serv11916/packages/dvdview/dvdview/src/video12
Added Files:
constants.hh dctblk.cc macroblock.hh output.hh vdecoder.cc
vdecoder.hh viddec_mods.cc viddec_mods.hh vidsyntax.cc
vidsyntax.hh vlc.cc vlc.hh
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it
--- NEW FILE: viddec_mods.hh ---
/********************************************************************************
video12/viddec_mods.hh
Main video decoder. Abstract classes for decoding modules.
purpose:
Abstract base classes declarations that encapsulate computation intensive
parts of the MPEG decoding process. So you can subclass these classes and
create implementations that are optimized for specific architectures.
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
05/Sep/2000 - Dirk Farin
- removed Init() method
04/Oct/1999 - Dirk Farin
- first revision
********************************************************************************
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_VIDEO12_VIDDEC_MODS_HH
#define DVDVIEW_VIDEO12_VIDDEC_MODS_HH
#include "types.hh"
#include "libvideogfx/graphics/basic/image.hh"
struct PixPtrs
{
Pixel* y;
Pixel* cr;
Pixel* cb;
};
struct PixPtrs_const
{
const Pixel* y;
const Pixel* cr;
const Pixel* cb;
};
// Do not change these bit positions, as they are hard-coded in parts of the video decoder.
#define MC_Last_HalfV 1
#define MC_Last_HalfH 2
#define MC_Next_HalfV 4
#define MC_Next_HalfH 8
class MotionCompensation_SglMB
{
public:
virtual ~MotionCompensation_SglMB() { }
struct MCData
{
PixPtrs_const lastimg;
PixPtrs currimg;
PixPtrs_const nextimg;
int bytesperline_lum;
int bytesperline_chr;
int blkheight;
int blkheight_chr;
int LumaHalfFlags;
int ChromaHalfFlags;
};
static MotionCompensation_SglMB* Create();
typedef void MCompFunc(MCData*);
virtual MCompFunc*const* AskMCompFunc_Sgl_Luma() const = 0; // Returns array of 16 func.pointers.
virtual MCompFunc*const* AskMCompFunc_Dbl_Luma() const = 0; // Returns array of 4 func.pointers.
virtual MCompFunc*const* AskMCompFunc_Sgl_Chroma(uint2 chroma) const = 0;
virtual MCompFunc*const* AskMCompFunc_Dbl_Chroma(uint2 chroma) const = 0;
void CallSglLuma(MCData* d) const { (AskMCompFunc_Sgl_Luma())[d->LumaHalfFlags](d); }
void CallDblLuma(MCData* d) const { (AskMCompFunc_Dbl_Luma())[d->LumaHalfFlags](d); }
void CallSglChroma(uint2 chroma,MCData* d)const{(AskMCompFunc_Sgl_Chroma(chroma))[d->ChromaHalfFlags](d);}
void CallDblChroma(uint2 chroma,MCData* d)const{(AskMCompFunc_Dbl_Chroma(chroma))[d->ChromaHalfFlags](d);}
};
#endif
--- NEW FILE: vidsyntax.hh ---
/*********************************************************************
video12/vidsyntax.hh
Main video decoder
purpose:
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
07/set/2000 - Dirk Farin
- Changed type of Framerate field in SequenceHeader from double to int
to overcome MMX problems.
05/Sep/2000 - Dirk Farin
- Syntax decoding functions extracted from vdecoder.cc.
30/Sep/1999 - Dirk Farin
- Integrated code into CVS.
05/May/1999 - Dirk Farin
- Took structure definitions out of viddec.hh
********************************************************************************
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_VIDEO12_VIDSYNTAX_HH
#define DVDVIEW_VIDEO12_VIDSYNTAX_HH
#include "types.hh"
#include "video12/macroblock.hh"
#include "libvideogfx/containers/array2.hh"
struct VideoSyntaxData
{
virtual ~VideoSyntaxData() { }
};
struct SequenceHeader : public VideoSyntaxData
{
uint32 m_Width,m_Height;
uint4 m_AspectRatio;
int m_Framerate; // *10000
uint32 m_Bitrate;
uint32 m_VBVBufferSize;
bool m_Constrained;
// MPEG-2 only data
uint4 m_Profile;
uint4 m_Level;
bool m_ProgressiveSequence;
uint2 m_ChromaFormat;
bool m_LowDelay;
// deduced data
bool m_IsMPEG2;
uint32 m_MBWidth,m_MBHeight; // width and height in macroblocks
};
struct QuantMatrices : public VideoSyntaxData
{
int m_LumIntra[64];
int m_LumInter[64];
int m_ChrIntra[64];
int m_ChrInter[64];
};
struct GOPHeader : public VideoSyntaxData
{
bool m_TimeCode_DropFrameFlag;
uint5 m_TimeCode_Hours;
uint6 m_TimeCode_Minutes;
uint6 m_TimeCode_Seconds;
uint6 m_TimeCode_Pictures;
bool m_ClosedGOP;
bool m_BrokenLink;
};
struct PictureHeader : public VideoSyntaxData
{
uint16 m_temporal_reference;
uint3 m_picture_coding_type;
uint16 m_vbv_delay;
bool m_fullpel_fw;
bool m_fullpel_bw;
uint3 m_fcode[2][2]; // [ 0 fw, 1 bw ] [ 0 h, 1 v ]
// MPEG2 only fields follow
bool m_IsMPEG2;
uint4 m_intra_dc_precision;
uint2 m_picture_structure;
bool m_top_field_first;
bool m_frame_pred_frame_dct;
bool m_concealment_motion_vectors;
uint1 m_q_scale_type;
uint1 m_intra_vlc_format;
bool m_alternate_scan;
bool m_repeat_first_field;
uint1 m_chroma420type;
bool m_progressive_frame;
bool m_composite_display_flag;
uint1 m_v_axis;
uint3 m_field_sequence;
uint1 m_sub_carrier;
uint7 m_burst_amplitude;
uint8 m_sub_carrier_phase;
// precalculated values
int m_intra_dc_precision_shift;
// extra data
int m_picturedata_length;
};
struct PictureData
{
Array2<Macroblock> m_codedimage;
// efficient allocation
static PictureData* GetPictureData(int mb_w,int mb_h);
static void FreePictureData(PictureData*);
void operator delete(void*) { Assert(0); /* Use FreePictureData() to delete PictureData objects.
Calling ::delete is safe but very inefficient. */ }
};
struct EndOfVideoStream : public VideoSyntaxData
{
};
void DecodeSequenceHeader(class MemBitstreamReader& bs,SequenceHeader& sh,QuantMatrices& qmat);
void DecodeSequenceHeaderExt(class MemBitstreamReader& bs2,SequenceHeader& sh);
void TraceSequenceHeader(const SequenceHeader& sh);
void DecodeGOPHeader(class MemBitstreamReader&,GOPHeader&);
void TraceGOPHeader(const GOPHeader&);
void DecodePictureHeader(class MemBitstreamReader&,PictureHeader&);
void DecodePictureCodingExt(class MemBitstreamReader&,PictureHeader&);
void TracePictureHeader(const PictureHeader&);
#endif
--- NEW FILE: dctblk.cc ---
typedef struct {
uint8 run;
uint8 level;
uint8 len;
} DCTtabb;
static DCTtabb DCT_16 [] = {
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{ 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
{ 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
{ 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
{ 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
};
static DCTtabb DCT_15 [] = {
{ 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
{ 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
{ 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
{ 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
{ 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
{ 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
{ 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
{ 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
{ 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
{ 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
{ 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
{ 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
};
static DCTtabb DCT_13 [] = {
{ 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
{ 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
{ 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
{ 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
{ 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
{ 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
{ 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
{ 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
{ 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
{ 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
{ 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
{ 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
};
static DCTtabb DCT_B14_10 [] = {
{ 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
{ 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
};
static DCTtabb DCT_B14_8 [] = {
{ 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
{ 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
{ 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
{ 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
{ 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
{ 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
{ 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
{ 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
{ 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
};
static DCTtabb DCT_B14AC_5 [] = {
{ 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
{ 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
{129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
};
static DCTtabb DCT_B14DC_5 [] = {
{ 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
{ 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
};
static DCTtabb DCT_B15_10 [] = {
{ 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
{ 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
};
static DCTtabb DCT_B15_8 [] = {
{ 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
{ 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
{ 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
{ 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
{ 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
{ 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
{ 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
{ 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
{ 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
{ 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
{ 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
{ 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
{ 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
{ 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
{ 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
{ 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
{ 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
{ 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
{ 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
{ 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
{ 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
{ 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
};
inline int DequantizeIntra(int value,int qscale,int matrix)
{
#if MMX_DCT
return value*qscale*matrix;
#else
return value*qscale*matrix/16;
#endif
}
inline int DequantizeInter(int value,int qscale,int matrix)
{
// Assert(value>0);
#if MMX_DCT
return (2*value+1) * matrix * qscale / 2;
#else
return (2*value+1) * matrix * qscale / 32;
#endif
}
inline void Saturate(int& value)
{
#if MMX_DCT
if (value<-2048*16) value=-2048*16;
else if (value> 2047*16) value= 2047*16;
#else
if (value<-2048) value=-2048;
else if (value> 2047) value= 2047;
#endif
}
static void get_mpeg1_intra_block(class FastBitBuf& bs,short* coeff,const int* scan,
int quantizer_scale,
const int* quant_matrix)
{
int i;
int j;
int val;
DCTtabb * tab;
uint32 bit_buf;
int bits;
i = 0;
bs.MakeLocalCopy(bit_buf,bits);
NEEDBITS (bit_buf, bits);
while (1) {
if (bit_buf >= 0x28000000) {
tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
i += tab->run;
if (i >= 64)
break; // end of block
normal_code:
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
val = DequantizeIntra(tab->level,quantizer_scale,quant_matrix[i]);
// if (bitstream_get (1)) val = -val;
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
Saturate(val);
coeff[j] = val;
bit_buf <<= 1;
NEEDBITS (bit_buf, bits);
continue;
} else if (bit_buf >= 0x04000000) {
tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
i += tab->run;
if (i < 64)
goto normal_code;
// escape code
i += UBITS (bit_buf << 6, 6) - 64;
if (i >= 64)
break; // illegal, but check needed to avoid buffer overflow
j = scan[i];
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
val = SBITS (bit_buf, 8);
if (! (val & 0x7f)) {
DUMPBITS (bit_buf, bits, 8);
val = UBITS (bit_buf, 8) + 2 * val;
}
val = DequantizeIntra(val,quantizer_scale,quant_matrix[i]);
Saturate(val);
coeff[j] = val;
DUMPBITS (bit_buf, bits, 8);
NEEDBITS (bit_buf, bits);
continue;
} else if (bit_buf >= 0x02000000) {
tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00800000) {
tab = DCT_13 - 16 + UBITS (bit_buf, 13);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00200000) {
tab = DCT_15 - 16 + UBITS (bit_buf, 15);
i += tab->run;
if (i < 64)
goto normal_code;
} else {
tab = DCT_16 + UBITS (bit_buf, 16);
bit_buf <<= 16;
bit_buf |= bs.GetNextWord() << (bits + 16);
i += tab->run;
if (i < 64)
goto normal_code;
}
break; // illegal, but check needed to avoid buffer overflow
}
DUMPBITS (bit_buf, bits, 2); // dump end of block code
bs.RestoreFromLocal(bit_buf,bits);
}
static void get_mpeg1_non_intra_block(class FastBitBuf& bs,short* coeff,const int* scan,
int quantizer_scale,
const int* quant_matrix)
{
int i;
int j;
int val;
DCTtabb * tab;
uint32 bit_buf;
int bits;
i = -1;
bs.MakeLocalCopy(bit_buf,bits);
NEEDBITS (bit_buf, bits);
if (bit_buf >= 0x28000000) {
tab = DCT_B14DC_5 - 5 + UBITS (bit_buf, 5);
goto entry_1;
} else
goto entry_2;
while (1) {
if (bit_buf >= 0x28000000) {
tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
entry_1:
i += tab->run;
if (i >= 64)
break; // end of block
normal_code:
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
val = DequantizeInter(tab->level,quantizer_scale,quant_matrix[i]);
// if (bitstream_get (1)) val = -val;
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
Saturate (val);
coeff[j] = val;
bit_buf <<= 1;
NEEDBITS (bit_buf, bits);
continue;
}
entry_2:
if (bit_buf >= 0x04000000) {
tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
i += tab->run;
if (i < 64)
goto normal_code;
// escape code
i += UBITS (bit_buf << 6, 6) - 64;
if (i >= 64)
break; // illegal, but check needed to avoid buffer overflow
j = scan[i];
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
val = SBITS (bit_buf, 8);
if (! (val & 0x7f)) {
DUMPBITS (bit_buf, bits, 8);
val = UBITS (bit_buf, 8) + 2 * val;
}
val = DequantizeInter(val + SBITS (val, 1),quantizer_scale,quant_matrix[i]);
Saturate (val);
coeff[j] = val;
DUMPBITS (bit_buf, bits, 8);
NEEDBITS (bit_buf, bits);
continue;
} else if (bit_buf >= 0x02000000) {
tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00800000) {
tab = DCT_13 - 16 + UBITS (bit_buf, 13);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00200000) {
tab = DCT_15 - 16 + UBITS (bit_buf, 15);
i += tab->run;
if (i < 64)
goto normal_code;
} else {
tab = DCT_16 + UBITS (bit_buf, 16);
bit_buf <<= 16;
bit_buf |= bs.GetNextWord() << (bits + 16);
i += tab->run;
if (i < 64)
goto normal_code;
}
break; // illegal, but check needed to avoid buffer overflow
}
DUMPBITS (bit_buf, bits, 2); // dump end of block code
bs.RestoreFromLocal(bit_buf,bits);
}
static void get_intra_block_B14(class FastBitBuf& bs,short* coeff,const int* scan,
int quantizer_scale,
const int* quant_matrix)
{
int i;
int j;
int val;
int mismatch;
DCTtabb * tab;
uint32 bit_buf;
int bits;
i = 0;
mismatch = ~coeff[0];
bs.MakeLocalCopy(bit_buf,bits);
NEEDBITS (bit_buf, bits);
while (1) {
if (bit_buf >= 0x28000000) {
tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
i += tab->run;
if (i >= 64)
break; // end of block
normal_code:
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
val = DequantizeIntra(tab->level , quantizer_scale , quant_matrix[i]);
// if (bitstream_get (1)) val = -val;
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
Saturate (val);
coeff[j] = val;
mismatch ^= val;
bit_buf <<= 1;
NEEDBITS (bit_buf, bits);
continue;
} else if (bit_buf >= 0x04000000) {
tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
i += tab->run;
if (i < 64)
goto normal_code;
// escape code
i += UBITS (bit_buf << 6, 6) - 64;
if (i >= 64)
break; // illegal, but check needed to avoid buffer overflow
j = scan[i];
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
val = DequantizeIntra(SBITS (bit_buf, 12) , quantizer_scale , quant_matrix[i]);
Saturate(val);
coeff[j] = val;
mismatch ^= val;
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
continue;
} else if (bit_buf >= 0x02000000) {
tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00800000) {
tab = DCT_13 - 16 + UBITS (bit_buf, 13);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00200000) {
tab = DCT_15 - 16 + UBITS (bit_buf, 15);
i += tab->run;
if (i < 64)
goto normal_code;
} else {
tab = DCT_16 + UBITS (bit_buf, 16);
bit_buf <<= 16;
bit_buf |= bs.GetNextWord () << (bits + 16);
i += tab->run;
if (i < 64)
goto normal_code;
}
break; // illegal, but check needed to avoid buffer overflow
}
coeff[63] ^= mismatch & 1;
DUMPBITS (bit_buf, bits, 2); // dump end of block code
bs.RestoreFromLocal(bit_buf,bits);
}
static void get_intra_block_B15(class FastBitBuf& bs,short* coeff,const int* scan,
int quantizer_scale,
const int* quant_matrix)
{
int i;
int j;
int val;
int mismatch;
DCTtabb * tab;
uint32 bit_buf;
int bits;
i = 0;
mismatch = ~coeff[0];
bs.MakeLocalCopy(bit_buf,bits);
NEEDBITS (bit_buf, bits);
while (1) {
if (bit_buf >= 0x04000000) {
tab = DCT_B15_8 - 4 + UBITS (bit_buf, 8);
i += tab->run;
if (i < 64) {
normal_code:
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
val = DequantizeIntra(tab->level , quantizer_scale , quant_matrix[i]);
// if (bitstream_get (1)) val = -val;
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
Saturate(val);
coeff[j] = val;
mismatch ^= val;
bit_buf <<= 1;
NEEDBITS (bit_buf, bits);
continue;
} else {
// end of block. I commented out this code because if we
// dont exit here we will still exit at the later test :)
//if (i >= 128) break; // end of block
// escape code
i += UBITS (bit_buf << 6, 6) - 64;
if (i >= 64)
break; // illegal, but check against buffer overflow
j = scan[i];
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
val = DequantizeIntra(SBITS (bit_buf, 12) , quantizer_scale , quant_matrix[i]);
Saturate(val);
coeff[j] = val;
mismatch ^= val;
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
continue;
}
} else if (bit_buf >= 0x02000000) {
tab = DCT_B15_10 - 8 + UBITS (bit_buf, 10);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00800000) {
tab = DCT_13 - 16 + UBITS (bit_buf, 13);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00200000) {
tab = DCT_15 - 16 + UBITS (bit_buf, 15);
i += tab->run;
if (i < 64)
goto normal_code;
} else {
tab = DCT_16 + UBITS (bit_buf, 16);
bit_buf <<= 16;
bit_buf |= bs.GetNextWord() << (bits + 16);
i += tab->run;
if (i < 64)
goto normal_code;
}
break; // illegal, but check needed to avoid buffer overflow
}
coeff[63] ^= mismatch & 1;
DUMPBITS (bit_buf, bits, 4); // dump end of block code
bs.RestoreFromLocal(bit_buf,bits);
}
static void get_non_intra_block(class FastBitBuf& bs,short* coeff,const int* scan,
int quantizer_scale,
const int* quant_matrix)
{
int i;
int j;
int val;
int mismatch;
DCTtabb * tab;
uint32 bit_buf;
int bits;
i = -1;
mismatch = 1;
bs.MakeLocalCopy(bit_buf,bits);
NEEDBITS (bit_buf, bits);
if (bit_buf >= 0x28000000) {
tab = DCT_B14DC_5 - 5 + UBITS (bit_buf, 5);
goto entry_1;
} else
goto entry_2;
while (1) {
if (bit_buf >= 0x28000000) {
tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
entry_1:
i += tab->run;
if (i >= 64)
break; // end of block
normal_code:
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
val = DequantizeInter(tab->level , quantizer_scale , quant_matrix[i]);
// if (bitstream_get (1)) val = -val;
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
Saturate(val);
coeff[j] = val;
mismatch ^= val;
bit_buf <<= 1;
NEEDBITS (bit_buf, bits);
continue;
}
entry_2:
if (bit_buf >= 0x04000000) {
tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
i += tab->run;
if (i < 64)
goto normal_code;
// escape code
i += UBITS (bit_buf << 6, 6) - 64;
if (i >= 64)
break; // illegal, but check needed to avoid buffer overflow
j = scan[i];
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
val = DequantizeInter(SBITS (bit_buf, 12) + SBITS (bit_buf, 1) , quantizer_scale, quant_matrix[i]);
Saturate(val);
coeff[j] = val;
mismatch ^= val;
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits);
continue;
} else if (bit_buf >= 0x02000000) {
tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00800000) {
tab = DCT_13 - 16 + UBITS (bit_buf, 13);
i += tab->run;
if (i < 64)
goto normal_code;
} else if (bit_buf >= 0x00200000) {
tab = DCT_15 - 16 + UBITS (bit_buf, 15);
i += tab->run;
if (i < 64)
goto normal_code;
} else {
tab = DCT_16 + UBITS (bit_buf, 16);
bit_buf <<= 16;
bit_buf |= bs.GetNextWord () << (bits + 16);
i += tab->run;
if (i < 64)
goto normal_code;
}
break; // illegal, but check needed to avoid buffer overflow
}
coeff[63] ^= mismatch & 1;
DUMPBITS (bit_buf, bits, 2); // dump end of block code
bs.RestoreFromLocal(bit_buf,bits);
}
--- NEW FILE: vidsyntax.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 "video12/vidsyntax.hh"
#include "video12/constants.hh"
#include "libvideogfx/utility/bitstream/membitsread.hh"
#include <iostream.h>
#include <iomanip.h>
const int PoolSize = 10;
static PictureData* pdpool[PoolSize];
static int pdpoolsize=0;
PictureData* PictureData::GetPictureData(int w,int h)
{
if (pdpoolsize==0)
{
PictureData* picdata = new PictureData;
if (w>0)
picdata->m_codedimage.Create(w,h);
return picdata;
}
else
{
pdpoolsize--;
PictureData* picdata = pdpool[pdpoolsize];
if (picdata->m_codedimage.AskWidth() != w ||
picdata->m_codedimage.AskHeight() != h)
{
if (w!=0)
picdata->m_codedimage.Create(w,h);
}
return picdata;
}
}
void PictureData::FreePictureData(PictureData* p)
{
if (pdpoolsize==PoolSize)
::delete p;
else
pdpool[pdpoolsize++] = p;
}
static const int frameratecode2framerate[16] =
{
0, 24000*10000/1001, 24*10000,25*10000, 30000*10000/1001, 30*10000,50*10000,60000*10000/1001,
60*10000, 0,0,0,0,0,0,0
};
#if 0
static const uint8 default_intra_matrix[8][8] = {
{ 8, 16, 19, 22, 26, 27, 29, 34 },
{ 16, 16, 22, 24, 27, 29, 34, 37 },
{ 19, 22, 26, 27, 29, 34, 34, 38 },
{ 22, 22, 26, 27, 29, 34, 37, 40 },
{ 22, 26, 27, 29, 32, 35, 40, 48 },
{ 26, 27, 29, 32, 35, 40, 48, 58 },
{ 26, 27, 29, 34, 38, 46, 56, 69 },
{ 27, 29, 35, 38, 46, 56, 69, 83 }
};
#endif
static const uint8 default_intra_matrix_zigzag[64] = {
8,16,16,19,16,19,22,22,22,22,22,22,26,24,26,27,27,27,26,26,26,26,27,27,29,29,29,34,34,
34,37,34,34,32,32,29,29,35,34,35,35,37,38,40,40,40,38,38,46,46,48,48,58,56,56,69,69,83
};
void DecodeSequenceHeader(class MemBitstreamReader& bs,SequenceHeader& sh,QuantMatrices& qmat)
{
SequenceHeader* seqh = &sh;
/**** Read sequence header ****/
Assert(bs.PeekBits(32)==STARTCODE_SEQUENCE_HEADER);
bs.SkipBits(32);
seqh->m_IsMPEG2 = false; /* This will be set to "true" if there is a Sequence-Extension following */
seqh->m_Width = bs.GetBits(12);
seqh->m_Height = bs.GetBits(12);
seqh->m_AspectRatio = bs.GetBits(4);
seqh->m_Framerate = frameratecode2framerate[bs.GetBits(4)];
/* TODO
if (seqh->m_Framerate == 0.0)
ShowNote(ErrSev_Warning,"MPEG stream error: framerate set to invalid value !");
*/
seqh->m_Bitrate = bs.GetBits(18);
bs.SkipBits(1);
seqh->m_VBVBufferSize = bs.GetBits(10);
seqh->m_Constrained = bs.GetBits(1);
// Reset qmatrices or set them to new values.
// Set Intra-Matrix
if (bs.GetBits(1))
{
for (int i=0;i<64;i++)
qmat.m_LumIntra[i] = qmat.m_ChrIntra[i] = bs.GetBits(8);
}
else
{
for (int i=0;i<64;i++)
qmat.m_LumIntra[i] = qmat.m_ChrIntra[i] = default_intra_matrix_zigzag[i];
}
// Set Inter-Matrix
if (bs.GetBits(1))
{
for (int i=0;i<64;i++)
qmat.m_LumInter[i] = qmat.m_ChrInter[i] = bs.GetBits(8);
}
else
{
for (int i=0;i<64;i++)
qmat.m_LumInter[i] = qmat.m_ChrInter[i] = 16;
}
// fill MPEG-2 entries to match MPEG-1 semantics
seqh->m_ProgressiveSequence = false;
seqh->m_ChromaFormat = CHROMA_420;
seqh->m_LowDelay = false;
}
void DecodeSequenceHeaderExt(class MemBitstreamReader& bs2,SequenceHeader& sh)
{
SequenceHeader* seqh = &sh;
/**** Decode Sequence-Extension ****/
seqh->m_IsMPEG2 = true;
seqh->m_Profile = bs2.GetBits(4);
seqh->m_Level = bs2.GetBits(4);
seqh->m_ProgressiveSequence = bs2.GetBits(1);
seqh->m_ChromaFormat = bs2.GetBits(2);
seqh->m_Width |= bs2.GetBits(2)<<12;
seqh->m_Height |= bs2.GetBits(2)<<12;
seqh->m_Bitrate |= bs2.GetBits(12)<<18;
bs2.SkipBits(1);
seqh->m_VBVBufferSize |= bs2.GetBits(8)<<10;
seqh->m_LowDelay = bs2.GetBits(1);
seqh->m_Framerate *= bs2.GetBits(2)+1;
seqh->m_Framerate /= bs2.GetBits(5)+1;
}
void TraceSequenceHeader(const SequenceHeader& sh)
{
#ifndef NDEBUG
const SequenceHeader* seqh = &sh;
{
cout << "SequenceHeader:\n"
<< " MPEG-2: " << (seqh->m_IsMPEG2?"true":"false") << endl
<< " width: " << seqh->m_Width << endl
<< " height: " << seqh->m_Height << endl
<< " aspect code: " << ((int)seqh->m_AspectRatio) << endl
<< " framerate: " << seqh->m_Framerate/10000 << '.' << seqh->m_Framerate%10000 << endl
<< " bitrate: " << seqh->m_Bitrate << endl
<< " VBV buf.size: " << seqh->m_VBVBufferSize << endl
<< " constrained: " << (seqh->m_Constrained?"true":"false") << endl
;
// << " load intra qm:" << (!seqh->m_qmatrices.m_Hint_Std_Intra_Lum?"true":"false") << endl
// << " load inter qm:" << (!seqh->m_qmatrices.m_Hint_Std_Inter_Lum?"true":"false") << endl;
if (seqh->m_IsMPEG2)
{
cout << " profile: ";
switch (seqh->m_Profile)
{
case PROFILE_Simple: cout << "Simple\n"; break;
case PROFILE_Main: cout << "Main\n"; break;
case PROFILE_SNRScalable: cout << "SNR\n"; break;
case PROFILE_SpatiallyScalable: cout << "Spatial\n"; break;
case PROFILE_High: cout << "High\n"; break;
default: cout << "UNKNOWN !\n"; break;
}
cout << " level: ";
switch (seqh->m_Level)
{
case LEVEL_Low: cout << "Low\n"; break;
case LEVEL_Main: cout << "Main\n"; break;
case LEVEL_High1440: cout << "High1440\n"; break;
case LEVEL_High: cout << "High\n"; break;
default: cout << "UNKNOWN !\n"; break;
}
cout << " progr. seq.: " << (seqh->m_ProgressiveSequence?"true":"false") << endl;
cout << " chroma format:";
switch (seqh->m_ChromaFormat)
{
case CHROMA_420: cout << "4:2:0\n"; break;
case CHROMA_422: cout << "4:2:2\n"; break;
case CHROMA_444: cout << "4:4:4\n"; break;
default: cout << "UNKNOWN !\n"; break;
}
cout << " low delay: " << (seqh->m_LowDelay?"true":"false") << endl;
}
}
#endif
}
void DecodeGOPHeader(class MemBitstreamReader& bs,GOPHeader& gopdata)
{
/**** Read GOP-Header ****/
Assert(bs.PeekBits(32)==STARTCODE_GROUP_START);
bs.SkipBits(32);
GOPHeader* goph = &gopdata;
goph->m_TimeCode_DropFrameFlag = bs.GetBits(1);
goph->m_TimeCode_Hours = bs.GetBits(5);
goph->m_TimeCode_Minutes = bs.GetBits(6);
bs.SkipBits(1);
goph->m_TimeCode_Seconds = bs.GetBits(6);
goph->m_TimeCode_Pictures = bs.GetBits(6);
goph->m_ClosedGOP = bs.GetBits(1);
goph->m_BrokenLink= bs.GetBits(1);
}
void TraceGOPHeader(const GOPHeader& gopdata)
{
const GOPHeader* goph = &gopdata;
#ifndef NDEBUG
cout << "GOP-Header:\n"
<< " Timecode: " << ((int)goph->m_TimeCode_Hours)
<< ':' << setfill('0') << setw(2) << ((int)goph->m_TimeCode_Minutes)
<< ':' << setw(2) << ((int)goph->m_TimeCode_Seconds)
<< '.' << setw(2) << ((int)goph->m_TimeCode_Pictures);
if (goph->m_TimeCode_DropFrameFlag) cout << " drop-frame-flag set";
cout << "\n closed GOP: " << (goph->m_ClosedGOP?"true":"false") << endl
<< " broken link: " << (goph->m_BrokenLink?"true":"false") << endl;
#endif
}
void DecodePictureHeader(class MemBitstreamReader& bs,PictureHeader& pichdr)
{
Assert(bs.PeekBits(32)==STARTCODE_PICTURE_START);
bs.SkipBits(32);
pichdr.m_temporal_reference = bs.GetBits(10);
pichdr.m_picture_coding_type = bs.GetBits(3);
pichdr.m_vbv_delay = bs.GetBits(16);
pichdr.m_fullpel_fw = false;
pichdr.m_fullpel_bw = false;
pichdr.m_fcode[0][0] = 7;
pichdr.m_fcode[0][1] = 7;
pichdr.m_fcode[1][0] = 7;
pichdr.m_fcode[1][1] = 7;
if (pichdr.m_picture_coding_type == 2 ||
pichdr.m_picture_coding_type == 3)
{
pichdr.m_fullpel_fw = bs.GetBits(1);
pichdr.m_fcode[0][0] =
pichdr.m_fcode[0][1] = bs.GetBits(3);
}
if (pichdr.m_picture_coding_type == 3)
{
pichdr.m_fullpel_bw = bs.GetBits(1);
pichdr.m_fcode[1][0] =
pichdr.m_fcode[1][1] = bs.GetBits(3);
}
while (bs.GetBits(1)==1)
{
bs.SkipBits(8);
}
// Set fields that are variable in MPEG-2 but constant in MPEG-1.
// These will be overwritten again, when decoding MPEG-2 Picture Coding Extension.
pichdr.m_IsMPEG2 = false;
pichdr.m_intra_dc_precision = 8;
pichdr.m_picture_structure = PICSTRUCT_FramePicture;
pichdr.m_concealment_motion_vectors = false;
pichdr.m_progressive_frame = true;
pichdr.m_q_scale_type = 0;
pichdr.m_intra_vlc_format = 0;
pichdr.m_alternate_scan = false;
pichdr.m_progressive_frame = true;
pichdr.m_composite_display_flag = false;
pichdr.m_frame_pred_frame_dct = true;
pichdr.m_intra_dc_precision_shift = 11-pichdr.m_intra_dc_precision;
}
void DecodePictureCodingExt(class MemBitstreamReader& bs2,PictureHeader& pichdr)
{
pichdr.m_IsMPEG2 = true;
pichdr.m_fullpel_fw = false;
pichdr.m_fullpel_bw = false;
pichdr.m_fcode[0][0] = bs2.GetBits(4);
pichdr.m_fcode[0][1] = bs2.GetBits(4);
pichdr.m_fcode[1][0] = bs2.GetBits(4);
pichdr.m_fcode[1][1] = bs2.GetBits(4);
pichdr.m_intra_dc_precision = bs2.GetBits(2)+8;
pichdr.m_picture_structure = bs2.GetBits(2);
pichdr.m_top_field_first = bs2.GetBits(1);
pichdr.m_frame_pred_frame_dct = bs2.GetBits(1);
pichdr.m_concealment_motion_vectors = bs2.GetBits(1);
pichdr.m_q_scale_type = bs2.GetBits(1);
pichdr.m_intra_vlc_format = bs2.GetBits(1);
pichdr.m_alternate_scan = bs2.GetBits(1);
pichdr.m_repeat_first_field = bs2.GetBits(1);
pichdr.m_chroma420type = bs2.GetBits(1);
pichdr.m_progressive_frame = bs2.GetBits(1);
pichdr.m_composite_display_flag = bs2.GetBits(1);
if (pichdr.m_composite_display_flag)
{
pichdr.m_v_axis = bs2.GetBits(1);
pichdr.m_field_sequence = bs2.GetBits(3);
pichdr.m_sub_carrier = bs2.GetBits(1);
pichdr.m_burst_amplitude = bs2.GetBits(7);
pichdr.m_sub_carrier_phase= bs2.GetBits(8);
}
pichdr.m_intra_dc_precision_shift = 11-pichdr.m_intra_dc_precision;
}
void TracePictureHeader(const PictureHeader& pichdr)
{
cout << "PictureHeader:\n"
<< " temporal reference: " << pichdr.m_temporal_reference << endl
<< " picture_coding_type: ";
switch (pichdr.m_picture_coding_type)
{
case PICTYPE_I: cout << 'I'; break;
case PICTYPE_P: cout << 'P'; break;
case PICTYPE_B: cout << 'B'; break;
case PICTYPE_D: cout << 'D'; break;
default: cout << "UNKNOWN !"; break;
}
cout << "\n vbv_delay: " << pichdr.m_vbv_delay << endl
<< " fullpel forward mv: " << (pichdr.m_fullpel_fw?"true":"false") << endl
<< " fullpel backward mv: " << (pichdr.m_fullpel_bw?"true":"false") << endl;
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
{
cout << " fcode[" << i << "][" << j << "] ("
<< (i?"bw/":"fw/") << (j?'v':'h')
<< "): " << ((int)pichdr.m_fcode[i][j]) << endl;
}
if (pichdr.m_IsMPEG2)
{
cout << " intra dc precision: " << ((int)pichdr.m_intra_dc_precision) << endl
<< " picture structure: ";
switch (pichdr.m_picture_structure)
{
case PICSTRUCT_TopField: cout << "top field\n"; break;
case PICSTRUCT_BottomField: cout << "bottom field\n"; break;
case PICSTRUCT_FramePicture: cout << "frame picture\n"; break;
}
cout << " top field first: " << (pichdr.m_top_field_first?"true":"false") << endl
<< " frame pred frame dct: " << (pichdr.m_frame_pred_frame_dct?"true":"false") << endl
<< " concealment mvs: " << (pichdr.m_concealment_motion_vectors?"true":"false") << endl
<< " q-scale type: " << ((int)pichdr.m_q_scale_type) << endl
<< " intra vlc format: " << ((int)pichdr.m_intra_vlc_format) << endl
<< " alternate scan: " << (pichdr.m_alternate_scan?"true":"false") << endl
<< " repeat first field: " << (pichdr.m_repeat_first_field?"true":"false") << endl
<< " chroma420type(obsolet):" << ((int)pichdr.m_chroma420type) << endl
<< " progressive frame: " << (pichdr.m_progressive_frame?"true":"false") << endl;
if (pichdr.m_composite_display_flag)
{
cout << " v-axis: " << ((int)pichdr.m_v_axis) << endl
<< " field sequence: " << ((int)pichdr.m_field_sequence) << endl
<< " sub carrier: " << ((int)pichdr.m_sub_carrier) << endl
<< " burst amplitude: " << ((int)pichdr.m_burst_amplitude) << endl
<< " sub carrier phase: " << ((int)pichdr.m_sub_carrier_phase) << endl;
}
}
}
#include "libvideogfx/containers/array2.cc"
template class Array2<Macroblock>;
--- NEW FILE: vlc.hh ---
/********************************************************************************
video12/vlc.hh
purpose:
Utility functions to decode Variable Length Codes
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
28/Dec/1998 - Dirk Farin
- Added support for table B15 (intra_vlc_format==1)
26/Dec/1998 - Dirk Farin
- Added GetMotionCode()
15/Nov/1998 - 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_VIDEO12_VLC_HH
#define DVDVIEW_VIDEO12_VLC_HH
#include "types.hh"
int GetMBAddrIncr (class FastBitBuf&);
int GetCBP (class FastBitBuf&);
int GetDClumSize (class FastBitBuf&);
int GetDCchromSize(class FastBitBuf&);
int GetMotionCode (class FastBitBuf&);
bool GetRunLen(FastBitBuf& bs,int& run,int& value ,bool B15,bool first,bool MPEG1);
const uint16 MBMODE_QUANT = 0x10;
const uint16 MBMODE_MVFWD = 0x08;
const uint16 MBMODE_MVBKW = 0x04;
const uint16 MBMODE_PATTERN = 0x02;
const uint16 MBMODE_INTRA = 0x01;
// extern int (* GetMBMode[5])(class FastBitBuf&); // use picture_coding_type to index into array
#endif
--- NEW FILE: vdecoder.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
[...2318 lines suppressed...]
}
#endif
#if 0
{
ImageParam_YUV param; d_outbuf[d_outbuf_len-1].m_image.GetParam(param);
Pixel*const* p = ((Image_YUV<Pixel>*)&d_outbuf[d_outbuf_len-1].m_image)->AskFrameU();
for (int y=0;y<param.height/2;y++)
for (int x=0;x<param.width/2;x++)
p[y][x]=128;
}
{
ImageParam_YUV param; d_outbuf[d_outbuf_len-1].m_image.GetParam(param);
Pixel*const* p = ((Image_YUV<Pixel>*)&d_outbuf[d_outbuf_len-1].m_image)->AskFrameV();
for (int y=0;y<param.height/2;y++)
for (int x=0;x<param.width/2;x++)
p[y][x]=128;
}
#endif
--- NEW FILE: vlc.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
[...1451 lines suppressed...]
dest[vlc_base+i].value = n;
dest[vlc_base+i].bits = src[n].nBits;
}
}
}
static class DummyInit_23487635
{
public:
DummyInit_23487635()
{
InitTAB(vlc_mbaddrinc_tab,vlc_mbaddr,-1);
InitTAB(vlc_mbmode_P_tab,vlc_mbmode_P,0);
InitTAB(vlc_mbmode_B_tab,vlc_mbmode_B,0);
InitTAB(vlc_cbp_tab,vlc_cbp,-1);
InitTAB(vlc_DClum_tab,vlc_DClum,-1);
InitTAB(vlc_DCchrom_tab,vlc_DCchrom,-1);
InitTAB(vlc_mcode_tab,vlc_mc,-1);
}
} dummyinit_23845673;
--- NEW FILE: output.hh ---
/********************************************************************************
video12/output.hh
purpose:
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
16/Apr/2000 - Dirk Farin
- new method: FreePictureData()
04/Oct/1999 - Dirk Farin
- integration into new architecture (code extracted out of
old vsink.h)
05/May/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_VIDEO12_OUTPUT_HH
#define DVDVIEW_VIDEO12_OUTPUT_HH
#include "types.hh"
#include "libvideogfx/graphics/basic/image.hh"
#include "video12/vidsyntax.hh"
#include "system/system1.hh"
struct DecodedImageData
{
DecodedImageData()
: // m_IsDirectBuffer(false),
m_picdata_needed(false),
m_picdata1(NULL), m_picdata2(NULL)
{ }
virtual ~DecodedImageData() { }
Image_YUV<Pixel> m_image;
int m_width,m_height; // Total size of frame picture.
int m_src_y_start,m_src_y_end; // Number of lines in m_image, filled with data.
int m_dst_y_start; // Position of decoded lines in destination image.
bool m_field_lines; // Skip every second line if in field mode.
bool m_may_modify; // If image contents may be modified by postprocessors.
bool ContainsOutputLine(int y)
{
if (y>=m_dst_y_start &&
y<=m_dst_y_start+m_src_y_end-m_src_y_start)
{
if (!m_field_lines)
return true;
if (m_field_lines && (m_dst_y_start&1)==(y&1))
return true;
}
return false;
}
int GetIndexForOutputLine(int y)
{
return y-m_dst_y_start+m_src_y_start;
}
#if 0
bool m_IsDirectBuffer; /* Data goes directly to the display.
The decoder will have to wait for the PTS before decoding.
In the other case, the decoder will decode as soon as
possible and wait for the PTS before actually sending
the output data.
*/
#endif
bool m_picdata_needed;
PictureHeader m_pichdr1; // first field or frame
PictureHeader m_pichdr2; // second field
PictureData* m_picdata1; // first field or frame
PictureData* m_picdata2; // second field
SystemTimingInformation m_timing; /* When two fields are contained, the times for
the first one. */
void FreePictureData()
{
if (m_picdata1) PictureData::FreePictureData(m_picdata1);
if (m_picdata2) PictureData::FreePictureData(m_picdata2);
m_picdata1 = m_picdata2 = NULL;
}
};
class DecodedPictureSink
{
public:
virtual ~DecodedPictureSink() { }
void ShowAllMBRows(DecodedImageData* data)
{
ImageParam_YUV param;
data->m_image.GetParam(param);
data->m_src_y_start = 0;
data->m_src_y_end = param.height-1;
data->m_dst_y_start = 0;
data->m_field_lines = false;
ShowMBRows(data);
}
virtual void BeginPicture(const DecodedImageData*) { }
virtual void ShowMBRows(DecodedImageData*) = 0;
virtual void FinishedPicture() { };
virtual bool NeedsPictureData(uint3 pictype) const { return false; }
virtual bool NeedsMBData (uint3 pictype) const { return false; }
};
class VideoOutput : public DecodedPictureSink
{
public:
virtual bool PictureAvailable() = 0;
virtual PTS AskPTSOfNextToBeDisplayed() const = 0;
virtual void ShowPicture() { }
};
#endif
--- NEW FILE: macroblock.hh ---
/*********************************************************************
video12/macroblock.hh
Macroblock syntax.
purpose:
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
30/Sep/1999 - Dirk Farin
- Integrated code into CVS.
05/May/99 - Dirk Farin
- Took structure definitions out of viddec.hh
********************************************************************************
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_VIDEO12_MACROBLOCK_HH
#define DVDVIEW_VIDEO12_MACROBLOCK_HH
#include "types.hh"
struct DCTBlock
{
short m_coeff[64]; // in custom order, implementation dependent
bool m_hasdata; // true iff m_coeff[][]!=0 exists
int m_nCoeffs;
};
struct MotionVector
{
int m_habs, m_vabs;
uint1 m_vertical_field_select; // 0 ist TopField.
int2 m_dmvector[2];
};
struct Macroblock
{
uint7 m_quantiser_scale_code; /* 1 bis 31 */
bool m_IsIntra;
DCTBlock m_blks[12];
// Fuer Frame-Pictures mit 'frame_pred_frame_dct==0' und vorhandenen DCT-Koeff.
bool m_FieldDCT;
enum FrameMotionType { FRMT_FieldBased=1, FRMT_FrameBased=2, FRMT_DualPrime=3 };
enum FieldMotionType { FIMT_FieldBased=1, FIMT_16x8MC=2, FIMT_DualPrime=3 };
union {
// MotionComp.Type fuer Pictures mit 'picture_structure==frame' und
// 'frame_pred_frame_dct==0'. Ist 'frame_pred_frame_dct==1', so wird FRMT_FrameBased angenommen,
// m_frame_motion_type aber nicht in den Bitstream codiert.
enum FrameMotionType m_frame_motion_type;
// MotionComp.Type fuer Pictures mit 'picture_structure!=frame'.
enum FieldMotionType m_field_motion_type;
};
uint2 m_motion_vector_count;
enum { MVFormat_Field, MVFormat_Frame } m_mv_format;
bool m_dmv;
inline void SetFrameMotionType(FrameMotionType,int temporal_weight_class=0);
inline void SetFieldMotionType(FieldMotionType);
MotionVector m_vector[4 /*r*/][2 /*s*/]; // t in der Struktur
bool m_HasMotionForward; // <- wird auch als Consealment-Vektor-Flag ( vector[0][0] ) benutzt
bool m_HasMotionBackward;
#define m_forward1 m_vector[0][0]
#define m_forward2 m_vector[1][0]
#define m_backward1 m_vector[0][1]
#define m_backward2 m_vector[1][1]
};
#include "error.hh"
inline void Macroblock::SetFrameMotionType(FrameMotionType t,int temporal_weight_class)
{
#if 0
m_motion_vector_count = 1;
m_mv_format = MVFormat_Frame;
#else
m_frame_motion_type = t;
m_mv_format = MVFormat_Frame;
if (t==FRMT_FrameBased)
{
m_motion_vector_count = 1;
m_dmv = 0;
}
else if (t==FRMT_FieldBased)
{
if (temporal_weight_class <= 1)
m_motion_vector_count = 2;
else
m_motion_vector_count = 1;
m_dmv = 0;
}
else if (t==FRMT_DualPrime)
{
m_motion_vector_count = 1;
m_dmv = 1;
}
else
{
// TODO Error(ErrSev_Warning,"Invalid stream: undefined \"frame motion type\". Using \"frame-based\"\n");
m_motion_vector_count = 1;
m_dmv = 0;
}
#endif
}
#include <iostream.h>
inline void Macroblock::SetFieldMotionType(FieldMotionType t)
{
#if 0
m_motion_vector_count = 1;
#else
m_field_motion_type = t;
m_mv_format = MVFormat_Field;
switch (t)
{
case FIMT_FieldBased:
m_motion_vector_count = 1;
m_dmv = 0;
break;
case FIMT_16x8MC:
//cout << "16x8\n";
m_motion_vector_count = 2;
m_dmv = 0;
break;
case FIMT_DualPrime:
m_motion_vector_count = 1;
m_dmv = 1;
break;
default:
Assert(0);
break;
}
#endif
}
#endif
--- NEW FILE: vdecoder.hh ---
/********************************************************************************
video12/vdecoder.hh
Video syntax decoder
purpose:
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
07/set/2000 - Dirk Farin
- Decoder is now tolerant against bitstream errors.
05/Sep/2000 - Dirk Farin
- Output reorganized again. B-pictures can now be sent slice-wise
to the output device.
- Major cleanup. Syntax decoding parts have been moved to vidsyntax.cc.
16/Apr/2000 - Dirk Farin
- Major architectur change. Output is now PUSH-oriented.
- PictureData additional information data structure is filled
out, when data is needed by postprocessors.
- Bugfix: The two very last pictures of the stream are shown now.
- Some cleanup, removing old obsolete code.
22/Oct/1999 - Dirk Farin
- Robust even when streams start in the middle of a sequence.
30/Sep/1999 - Dirk Farin
- integrated into CVS, major code cleanup and rewrite, quantization
is now done already in the syntax decoder for efficiency reasons
(coefficients that are 0 do not need to be quantized).
17/May/1999 - Dirk Farin
- Correct decoding of bitstreams with concealment MVs.
31/Jan/1999 - Dirk Farin
- Bugfix: MPEG-1 macroblock stuffing was not recognized.
13/Jan/1999 - Dirk Farin
- Bugfix: Skip USER-DATA startcode-packets. Streams with such
data could not be read in earlier versions.
11/Jan/1999 - Dirk Farin
- Allocation of PictureData is now done using a pool of
preallocated structures. This results in a huge reduction
of system time.
10/Jan/1999 - Dirk Farin
- Bugfix: Motionvektor decoding was erroneous when fcode was
not equal to 1.
09/Jan/1999 - Dirk Farin
- Bugfix: end of slice now detected, when remaining bits < 2 and
not < 8, as there may be some very small MBs at the end
of a slice (for example a MVFwd-only MB in P needs only
4 bits). The condition is not redundant as the second
condition (remaining bits!=0 to leave loop) does not work
when remaining bits==0.
07/Jan/1999 - Dirk Farin
- Bugfix: motionvector activation flags were not set
- Bugfix: motionvector predictors were not updated
19/Dec/1998 -> 26/Dec/1998 - 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_VIDEO12_VDECODER_HH
#define DVDVIEW_VIDEO12_VDECODER_HH
#include "video12/modules/mcomp_sgl_simple.hh"
#include "types.hh"
#include "video12/output.hh"
#include "video12/vidsyntax.hh"
#include "video12/constants.hh"
#include "error.hh"
struct VideoSyntaxTrace_Options
{
VideoSyntaxTrace_Options();
bool Trace_SeqH;
bool Trace_GOPH;
bool Trace_PicH;
bool Trace_SlcH;
bool Trace_MB;
bool Trace_SliceData;
bool Trace_DCTCoeff;
};
struct VideoFrameSkip_Options
{
VideoFrameSkip_Options();
bool DecodeI;
bool DecodeP;
bool DecodeB;
};
struct VideoDecoder_Options
: public VideoSyntaxTrace_Options,
public VideoFrameSkip_Options
{
};
class VideoDecoder
{
public:
VideoDecoder(class PacketSource&);
~VideoDecoder();
void SetOptions(const VideoDecoder_Options& opts) { d_options=opts; }
void SetSink(DecodedPictureSink& s) { d_sink=&s; }
void Reset() { d_SequenceHeaderRead=false; }
bool DecodeAFrame(); /* Decode a picture. It is NOT guaranteed that the picture will
appear at the output of the video decoder. It may be buffered
for some time or get completely lost because of jitter
reduction or the like.
However, it is guaranteed that no more than one picture will
appear at the output.
*/
private:
VideoDecoder_Options d_options;
class PacketSource* d_source;
class DecodedPictureSink* d_sink;
ImageSpec_YUV specs;
// Values out of last SequenceHeader.
bool d_IsMPEG2; // (redundant)
uint16 d_MBWidth,d_MBHeight; // (redundant) size of image in macroblock units
uint2 d_ChromaFormat; // (redundant)
int d_dctblks; // number of dct blocks in one macroblock
int d_intra_cbp; // CBP for intra blocks
int mb_chr_w,mb_chr_h; // Size of chroma components in a macroblock.
// Values out of last PictureHeader.
int d_dc_pred; // initial DC-prediction value
enum { None,DataPartitioning,SNR,Spatial,Temporal } d_scalability_mode;
// Syntax decoder
PictureHeader d_pichdr; // current picture data (macroblock array not used!)
PictureData* d_picdata;
void PostSequenceHeader();
void PostPictureHeader(const SystemTimingInformation& timing);
void DecodeExtensions(int n);
void DecodeSlice (class FastBitBuf&);
void FlushBSlice(int MBRow); /* Send physical MB-row 0 to output at the specified position
and reset decoding pointers to the first MB in row 0. */
void motion_vector (struct MotionVector&,int s,bool dmv,class FastBitBuf&);
// pushback buffer
class SysPacket_Packet* GetNextPacket();
void PushbackPacket(class SysPacket_Packet*);
class SysPacket_Packet* d_next_packet;
QuantMatrices d_quant_zz; // current quantization matrices in zig-zag-order
QuantMatrices d_quant_bs; // current quantization matrices in current bitstream scanning order
inline void AdvancePtrsMB();
inline void AdvancePtrsMBRow();
// -------------- Video Decoder ------------------
SequenceHeader d_seqdata;
bool d_SequenceHeaderRead; // If d_seqdata contains valid data.
bool d_BFrameAvailable; /* True iff a complete B-picture (1 frame picture or both fields) has
been decoded to d_curr and is ready for display. */
bool d_FirstFieldInFrame; /* True iff the next picture to be decoded is either the first field
or a frame picture. */
bool d_next_IsEmpty; /* True iff d_next does not contain an image. */
bool d_skip_this_frame;
DecodedImageData* d_last; // The picture that already has been displayed.
DecodedImageData* d_curr; // The currently decoded B-picture.
DecodedImageData* d_next; // The I/P-picture to be displayed after the pictures above.
Pixel*const* ptr_y; // current bitmaps while picture decoding
Pixel*const* ptr_cb; // current bitmaps while picture decoding
Pixel*const* ptr_cr; // current bitmaps while picture decoding
int bytesperline_lum;
int bytesperline_chr;
int lineskip_lum;
int lineskip_chr;
int d_field_offset; // 0 for topfield, frames / 1 for bottom field
// --- Pointers to current image data used in the calculations
// current decoding destination
Pixel* sp_curr_y;
Pixel* sp_curr_cr;
Pixel* sp_curr_cb;
// forward reference pictures
Pixel* sp_last_y [2]; // 0 - top field / 1 - bottom field
Pixel* sp_last_cr[2];
Pixel* sp_last_cb[2];
// backward reference pictures
Pixel* sp_next_y [2];
Pixel* sp_next_cr[2];
Pixel* sp_next_cb[2];
// Pointers to current decoding macroblock position
Pixel* dp_y;
Pixel* dp_cr;
Pixel* dp_cb;
enum TempRef { LAST,NEXT };
inline void SetSPOffsets(TempRef sp_tempref,int n,TempRef predref,bool field,bool topfield=true);
void SetReferencePtrsFrm(struct PixPtrs_const&,const struct MotionVector&);
void SetReferencePtrsFld(struct PixPtrs_const&,const struct MotionVector&);
void SetHalfPelFlags1(struct MotionCompensation_SglMB::MCData&,const struct MotionVector&);
void SetHalfPelFlags2(struct MotionCompensation_SglMB::MCData&,
const struct MotionVector& last,
const struct MotionVector& next);
void MC_Frame_FrameBased(const Macroblock& mb,uint16 mb_mode);
void MC_Frame_FieldBased(const Macroblock& mb,uint16 mb_mode);
void MC_Field_FieldBased(const Macroblock& mb,uint16 mb_mode);
void MC_Field_16x8(const Macroblock& mb,uint16 mb_mode);
// Decoder
int d_scan[2][64]; // scan pattern 0 - zigzag / 1 - alternate
class MotionCompensation_SglMB* d_motcomp;
};
//inline int DequantizeIntra(int value,int qscale,int matrix);
inline int DequantizeInter(int value,int qscale,int matrix);
//inline void Saturate(int& value);
class Excpt_StreamError : public Excpt_Base
{
public:
Excpt_StreamError(ErrorSeverity sev,const char* text) : Excpt_Base(sev,text) { }
};
class Excpt_Huffman : public Excpt_StreamError
{
public:
Excpt_Huffman(ErrorSeverity sev,const char* text) : Excpt_StreamError(sev,text) { }
};
#endif
--- NEW FILE: viddec_mods.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 "video12/viddec_mods.hh"
//#include "video12/modules/idct_std.hh"
//#include "video12/modules/mcomp_std.hh"
//#include "video12/modules/mcomp_scalar.hh"
//#include "video12/modules/mcomp_scalar_unaligned.hh"
#include "video12/modules/mcomp_sgl_simple.hh"
#if ENABLE_MMX
//#include "video12/modules/mcomp_mmx.hh"
#include "video12/modules/mcomp_sgl_mmx.hh"
#include "libvideogfx/arch/x86/CPUcapabilities.hh"
#endif
#if 0
MotionCompensation* MotionCompensation::Create()
{
#if 0 //ENABLE_MMX
if (cpucapabilities.HasMMX())
return new MotionCompensation_MMX;
#endif
#if 0 //UNALIGNED_MEMORYACCESS
return new MotionCompensation_Scalar_Unaligned;
#endif
return new MotionCompensation_Scalar;
return new MotionCompensation_Standard;
}
#endif
#include <iostream.h>
MotionCompensation_SglMB* MotionCompensation_SglMB::Create()
{
#if ENABLE_MMX
if (cpucapabilities.HasMMX())
return new MotionCompensation_SglMB_MMX;
#endif
return new MotionCompensation_SglMB_Simple;
}
--- NEW FILE: constants.hh ---
/********************************************************************************
video12/constants.hh
MPEG stream constants.
purpose:
notes:
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
04/Oct/1999 - Dirk Farin
- integrated code to CVS
********************************************************************************
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_VIDEO12_CONSTANTS_HH
#define DVDVIEW_VIDEO12_CONSTANTS_HH
#include "types.hh"
// -------------------------------- Startcodes -------------------------------------
// Video Startcodes
#define STARTCODE_PICTURE_START 0x00000100
#define STARTCODE_USER_DATA 0x000001B2
#define STARTCODE_SEQUENCE_HEADER 0x000001B3
#define STARTCODE_SEQUENCE_ERROR 0x000001B4
#define STARTCODE_EXTENSION_START 0x000001B5
#define STARTCODE_SEQUENCE_END 0x000001B7
#define STARTCODE_GROUP_START 0x000001B8
// System Startcodes
#define STARTCODE_ISO11172_END 0x000001B9
#define STARTCODE_PACK_START 0x000001BA
#define STARTCODE_SYSTEM_HEADER_START 0x000001BB
// Packet Startcodes
#define STARTCODE_VIDEO0 0x000001E0
#define STARTCODE_VIDEO1 0x000001E1
#define STARTCODE_VIDEO2 0x000001E2
#define STARTCODE_AUDIO0 0x000001C0
#define STARTCODE_AUDIO1 0x000001C1
#define STARTCODE_AUDIO2 0x000001C2
inline bool IsMPEG_SLICE_START (uint8 code) { return code>=0x01 && code<=0xAF; }
inline bool IsMPEG_VIDEO_STREAM(uint8 code) { return code>=0xE0 && code<=0xEF; }
inline bool IsMPEG_AUDIO_STREAM(uint8 code) { return code>=0xC0 && code<=0xDF; }
inline bool IsMPEG_PACKETCODE (uint8 code) { return code>=0xC0 && code<=0xEF; }
// ---------- extension_start_code_identifier -----------
const uint4 EXTID_SequenceExtension = 0x1;
const uint4 EXTID_SequenceDisplayExtension = 0x2;
const uint4 EXTID_QuantMatrixExtension = 0x3;
const uint4 EXTID_CopyrightExtension = 0x4;
const uint4 EXTID_SequenceScalableExtension = 0x5;
const uint4 EXTID_PictureDisplayExtension = 0x7;
const uint4 EXTID_PictureCodingExtension = 0x8;
const uint4 EXTID_PictureSpatialScalableExtension = 0x9;
const uint4 EXTID_PictureTemporalScalableExtension = 0xA;
// ---------- aspect_ratio_information ------------
const uint4 SAR_Square = 0x01; // Sample Aspect Ratio = 1.0 (square pixels)
const uint4 DAR_3_4 = 0x02; // Display Aspect Ratio = 3/4
const uint4 DAR_9_16 = 0x03; // Display Aspect Ratio = 9/16
const uint4 DAR_2_2_21 = 0x04; // Display Aspect Ratio = 2/2.21
// ---------- frame_rate_code ------------
const uint4 FRAMERATE_23_976 = 0x01; // 23.976 fps
const uint4 FRAMERATE_24 = 0x02; // 24 fps
const uint4 FRAMERATE_25 = 0x03; // 25 fps
const uint4 FRAMERATE_29_97 = 0x04; // 29.97 fps
const uint4 FRAMERATE_30 = 0x05; // 30 fps
const uint4 FRAMERATE_50 = 0x06; // 50 fps
const uint4 FRAMERATE_59_94 = 0x07; // 59.94 fps
const uint4 FRAMERATE_60 = 0x08; // 60 fps
// --------- profile_identification ----------
const uint3 PROFILE_Simple = 0x5;
const uint3 PROFILE_Main = 0x4;
const uint3 PROFILE_SNRScalable = 0x3;
const uint3 PROFILE_SpatiallyScalable = 0x2;
const uint3 PROFILE_High = 0x1;
// --------- level_identification ------------
const uint4 LEVEL_Low = 0xA;
const uint4 LEVEL_Main = 0x8;
const uint4 LEVEL_High1440 = 0x6;
const uint4 LEVEL_High = 0x4;
// --------- chroma_format ----------
const uint2 CHROMA_420 = 1;
const uint2 CHROMA_422 = 2;
const uint2 CHROMA_444 = 3;
// --------- picture_coding_type --------
const uint3 PICTYPE_I = 1;
const uint3 PICTYPE_P = 2;
const uint3 PICTYPE_B = 3;
const uint3 PICTYPE_D = 4;
// -------- picture_structure ---------
const uint2 PICSTRUCT_TopField = 1;
const uint2 PICSTRUCT_BottomField = 2;
const uint2 PICSTRUCT_FramePicture = 3;
#endif
More information about the dslinux-commit
mailing list