00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00041
00042
00043
00045
00046 #include <libdirac_common/dirac_assertions.h>
00047 #include <libdirac_decoder/seq_decompress.h>
00048 #include <libdirac_common/common.h>
00049 #include <libdirac_common/golomb.h>
00050 #include <libdirac_common/frame_buffer.h>
00051 #include <libdirac_decoder/frame_decompress.h>
00052 using namespace dirac;
00053
00054 SequenceDecompressor::SequenceDecompressor(std::istream* ip,bool verbosity)
00055 :
00056 m_all_done(false),
00057 m_infile(ip),
00058 m_current_code_fnum(0),
00059 m_delay(1),
00060 m_last_frame_read(-1),
00061 m_show_fnum(-1)
00062 {
00063 m_decparams.SetBitsIn( new BitInputManager(m_infile) );
00064 m_decparams.SetVerbose( verbosity );
00065 ReadStreamHeader();
00066
00067
00068 int xpad_luma,xpad_chroma;
00069
00070
00071 int ypad_luma,ypad_chroma;
00072
00073
00074 int x_chroma_fac,y_chroma_fac;
00075
00076
00077
00078
00079 if ( m_sparams.CFormat() == format411 )
00080 {
00081 x_chroma_fac = 4;
00082 y_chroma_fac = 1;
00083 }
00084 else if ( m_sparams.CFormat() == format420 )
00085 {
00086 x_chroma_fac = 2;
00087 y_chroma_fac = 2;
00088 }
00089 else if ( m_sparams.CFormat() == format422 )
00090 {
00091 x_chroma_fac = 2;
00092 y_chroma_fac = 1;
00093 }
00094 else
00095 {
00096 x_chroma_fac = 1;
00097 y_chroma_fac = 1;
00098 }
00099
00100 int xl_chroma=m_sparams.Xl() / x_chroma_fac;
00101 int yl_chroma=m_sparams.Yl() / y_chroma_fac;
00102
00103
00104 m_decparams.SetXNumMB( m_sparams.Xl() / m_decparams.LumaBParams(0).Xbsep() );
00105 m_decparams.SetYNumMB( m_sparams.Yl() / m_decparams.LumaBParams(0).Ybsep() );
00106 if ( m_decparams.XNumMB() * m_decparams.ChromaBParams(0).Xbsep() < xl_chroma )
00107 {
00108 m_decparams.SetXNumMB( m_decparams.XNumMB() + 1 );
00109 xpad_chroma = m_decparams.XNumMB() * m_decparams.ChromaBParams(0).Xbsep() - xl_chroma;
00110 }
00111 else
00112 xpad_chroma=0;
00113
00114 if (m_decparams.YNumMB()*m_decparams.ChromaBParams(0).Ybsep()<yl_chroma)
00115 {
00116 m_decparams.SetYNumMB( m_decparams.YNumMB() + 1 );
00117 ypad_chroma=m_decparams.YNumMB()*m_decparams.ChromaBParams(0).Ybsep()-yl_chroma;
00118 }
00119 else
00120 ypad_chroma=0;
00121
00122
00123 m_decparams.SetXNumBlocks( 4*m_decparams.XNumMB() );
00124 m_decparams.SetYNumBlocks( 4*m_decparams.YNumMB() );
00125
00126
00127
00128
00129
00130
00131 int xpad_len = xl_chroma+xpad_chroma;
00132 int ypad_len = yl_chroma+ypad_chroma;
00133
00134 if ( xpad_len%16 != 0 )
00135 xpad_chroma=( ( xpad_len/16 ) + 1 )*16 - xl_chroma;
00136 if ( ypad_len%16 != 0)
00137 ypad_chroma = ( ( ypad_len/16 ) + 1 )*16 - yl_chroma;
00138
00139 xpad_luma = xpad_chroma*x_chroma_fac;
00140 ypad_luma = ypad_chroma*y_chroma_fac;
00141
00142
00143 m_fbuffer= new FrameBuffer( m_sparams.CFormat() , m_sparams.Xl() + xpad_luma , m_sparams.Yl() + ypad_luma );
00144
00145 m_fdecoder = new FrameDecompressor (m_decparams , m_sparams.CFormat() );
00146 }
00147
00148 SequenceDecompressor::~SequenceDecompressor()
00149 {
00150 delete m_fbuffer;
00151 delete m_fdecoder;
00152 delete &m_decparams.BitsIn();
00153 }
00154
00155 bool SequenceDecompressor::ReadNextFrameHeader()
00156 {
00157 return m_fdecoder->ReadFrameHeader(*m_fbuffer);
00158 }
00159
00160 const FrameParams& SequenceDecompressor::GetNextFrameParams() const
00161 {
00162 return m_fdecoder->GetFrameParams();
00163 }
00164
00165 Frame& SequenceDecompressor::DecompressNextFrame(bool skip )
00166 {
00167
00168
00169
00170
00171
00172
00173
00174 TEST (m_fdecoder != NULL);
00175
00176 if (m_current_code_fnum!=0){
00177
00178 m_fbuffer->Clean(m_show_fnum);
00179 }
00180
00181 bool new_frame_to_display=false;
00182
00183 if (!skip)
00184 new_frame_to_display = m_fdecoder->Decompress(*m_fbuffer);
00185
00186
00187
00188 m_show_fnum=std::max(m_current_code_fnum-m_delay,0);
00189 if (new_frame_to_display || skip)
00190 {
00191 m_current_code_fnum++;
00192 }
00193
00194 return m_fbuffer->GetFrame(m_show_fnum);
00195 }
00196
00197 Frame& SequenceDecompressor::GetNextFrame()
00198 {
00199 return m_fbuffer->GetFrame(m_show_fnum);
00200 }
00201
00202 void SequenceDecompressor::ReadStreamHeader()
00203 {
00204
00205
00206
00207 OLBParams bparams;
00208
00209
00210
00211
00212
00213
00214
00215 char seq_start[5];
00216 for (int i=0;i<5;++i)
00217 {
00218 seq_start[i]=m_decparams.BitsIn().InputByte();
00219 }
00220
00221
00222
00223 m_sparams.SetBitstreamVersion( m_decparams.BitsIn().InputByte() );
00224
00225
00226
00227 TESTM (m_sparams.BitstreamVersion() == BITSTREAM_VERSION, "Bitstream version match");
00228
00229
00230 m_sparams.SetXl( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00231 m_sparams.SetYl( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00232
00233
00234 m_sparams.SetFrameRate( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00235
00236
00237 bparams.SetXblen( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00238 bparams.SetYblen( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00239 bparams.SetXbsep( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00240 bparams.SetYbsep( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
00241
00242
00243 m_decparams.SetXNumBlocks( int(UnsignedGolombDecode( m_decparams.BitsIn())) );
00244 m_decparams.SetYNumBlocks( int(UnsignedGolombDecode( m_decparams.BitsIn())) );
00245 m_decparams.SetXNumMB( m_decparams.XNumBlocks()/4 );
00246 m_decparams.SetYNumMB( m_decparams.YNumBlocks()/4 );
00247
00248
00249 m_sparams.SetCFormat( ChromaFormat(UnsignedGolombDecode( m_decparams.BitsIn())) );
00250 m_decparams.SetBlockSizes( bparams , m_sparams.CFormat() );
00251
00252
00253 m_decparams.SetInterlace( m_decparams.BitsIn().InputBit() );
00254 m_sparams.SetInterlace( m_decparams.Interlace() );
00255
00256
00257 m_decparams.BitsIn().FlushInput();
00258 }