void SubpelRefine::DoSubpel( EncQueue& my_buffer,int pic_num ) { m_predparams = &(my_buffer.GetPicture(pic_num).GetMEData().GetPicPredParams() ); //main loop for the subpel refinement int ref1,ref2; const PictureSort psort = my_buffer.GetPicture(pic_num).GetPparams().PicSort(); if (psort.IsInter()) { // Get the references const vector<int>& refs = my_buffer.GetPicture(pic_num).GetPparams().Refs(); int num_refs = refs.size(); ref1 = refs[0]; if (num_refs>1) ref2 = refs[1]; else ref2 = ref1; const PicArray& pic_data = my_buffer.GetPicture(pic_num).DataForME(m_encparams.CombinedME()); const PicArray& refup1_data = my_buffer.GetPicture(ref1).UpDataForME(m_encparams.CombinedME()); const PicArray& refup2_data = my_buffer.GetPicture(ref2).UpDataForME(m_encparams.CombinedME()); MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData(); // Now match the pictures MatchPic( pic_data , refup1_data , me_data ,1 ); if (ref1 != ref2 ) MatchPic( pic_data , refup2_data , me_data ,2 ); } }
void CoeffArray::SetBandWeights (const EncoderParams& encparams, const PictureParams& pparams, const CompSort csort) { const WltFilter wltfilter = encparams.TransformFilter(); const bool field_coding = encparams.FieldCoding(); const ChromaFormat cformat = pparams.CFormat(); const float cpd = encparams.CPD(); const PictureSort psort = pparams.PicSort(); int xlen, ylen, xl, yl, xp, yp; float xfreq, yfreq; float temp(0.0); // Compensate for chroma subsampling float chroma_xfac(1.0); float chroma_yfac(1.0); if( csort != Y_COMP) { if( cformat == format422) { chroma_xfac = 2.0; chroma_yfac = 1.0; } else if( cformat == format420 ) { chroma_xfac = 2.0; chroma_yfac = 2.0; } } xlen = 2 * m_band_list(1).Xl(); ylen = 2 * m_band_list(1).Yl(); if (cpd != 0.0) { for( int i = 1; i<=m_band_list.Length() ; i++ ) { xp = m_band_list(i).Xp(); yp = m_band_list(i).Yp(); xl = m_band_list(i).Xl(); yl = m_band_list(i).Yl(); xfreq = cpd * ( float(xp) + (float(xl)/2.0) ) / float(xlen); yfreq = cpd * ( float(yp) + (float(yl)/2.0) ) / float(ylen); if ( psort.IsInter() ) { xfreq /= 8.0; yfreq /= 8.0; } if(field_coding) yfreq/=2.0; temp = PerceptualWeight( xfreq/chroma_xfac , yfreq/chroma_yfac , csort ); m_band_list(i).SetWt(temp); }// i // Make sure dc is always the lowest weight float min_weight=m_band_list(m_band_list.Length()).Wt(); for( int b=1 ; b<=m_band_list.Length()-1 ; b++ ) min_weight = ((min_weight>m_band_list(b).Wt()) ? m_band_list(b).Wt() : min_weight); m_band_list( m_band_list.Length() ).SetWt( min_weight ); // Now normalize weights so that white noise is always weighted the same // Overall factor to ensure that white noise ends up with the same RMS, whatever the weight double overall_factor=0.0; //fraction of the total number of samples belonging to each subband double subband_fraction; for( int i=1 ; i<=m_band_list.Length() ; i++ ) { subband_fraction = 1.0/((double) m_band_list(i).Scale() * m_band_list(i).Scale()); overall_factor += subband_fraction/( m_band_list(i).Wt() * m_band_list(i).Wt() ); } overall_factor = std::sqrt( overall_factor ); //go through and normalise for( int i=m_band_list.Length() ; i>0 ; i-- ) m_band_list(i).SetWt( m_band_list(i).Wt() * overall_factor ); } else {//cpd=0 so set all weights to 1 for( int i=1 ; i<=m_band_list.Length() ; i++ ) m_band_list(i).SetWt( 1.0 ); } //Finally, adjust to compensate for the absence of scaling in the transform //Factor used to compensate: double lfac; double hfac; int filt_shift; switch (wltfilter){ case DD9_7 : lfac = 1.218660804;; hfac = 0.780720058; filt_shift = 1; break; case LEGALL5_3 : lfac = 1.179535649; hfac = 0.81649658; filt_shift = 1; break; case DD13_7 : lfac = 1.235705971; hfac = 0.780719354; filt_shift = 1; break; case HAAR0 : lfac = 1.414213562; hfac = 0.707106781; filt_shift = 0; break; case HAAR1 : lfac = 1.414213562; hfac = 0.707106781; filt_shift = 1; break; case DAUB9_7 : lfac = 1.149604398; hfac = 0.869864452; filt_shift = 1; break; default: lfac = 1.0; hfac = 1.0; filt_shift = 0; } int idx; int shift; int depth = (m_band_list.Length()-1)/3; // Do the DC subband idx = m_band_list.Length(); double cf = (1<<(depth*filt_shift)) / std::pow(lfac,2*depth ) ; m_band_list(idx).SetWt( m_band_list(idx).Wt()*cf); // Do the non-DC subbands for (int level=1; level<=depth; level++) { shift = (depth-level+1)*filt_shift; for ( int orient=3;orient>=1; --orient ) { idx = 3*(depth-level)+orient; // index into the subband list idx = 3*(depth-level)+orient; // Divide through by the weight for the LF subband that was decomposed // to create this level cf = 1.0/ std::pow(lfac,2*(depth-level) ); if ( m_band_list(idx).Xp() != 0 && m_band_list(idx).Yp() != 0) // HH subband cf /= (hfac * hfac); else // LH or HL subband cf /= (lfac * hfac); cf *= double(1<<shift); m_band_list(idx).SetWt( m_band_list(idx).Wt()*cf ); }// orient }//level }
bool PictureDecompressor::Decompress(ParseUnitByteIO& parseunit_byteio, PictureBuffer& my_buffer) { // get current byte position //int start_pos = parseunit_byteio.GetReadBytePosition(); try { // read picture data PictureByteIO picture_byteio(m_pparams, parseunit_byteio); picture_byteio.Input(); PictureSort fs; if (m_pparams.GetPictureType() == INTRA_PICTURE) fs.SetIntra(); else fs.SetInter(); if (m_pparams.GetReferenceType() == REFERENCE_PICTURE) fs.SetRef(); else fs.SetNonRef(); m_pparams.SetPicSort(fs); if (m_pparams.GetReferenceType() == REFERENCE_PICTURE) // Now clean the reference pictures from the buffer CleanReferencePictures( my_buffer ); // Check if the picture can be decoded if (m_pparams.PicSort().IsInter()){ const std::vector<int>& refs = m_pparams.Refs(); for (unsigned int i = 0; i < refs.size(); ++i) if ( !my_buffer.IsPictureAvail(refs[i]) ) return false; } // decode the rest of the picture if ( m_decparams.Verbose() ){ std::cout<<std::endl<<"Decoding picture "<<m_pparams.PictureNum()<<" in display order"; if ( m_pparams.PicSort().IsInter() ){ std::cout<<std::endl<<"References: "<<m_pparams.Refs()[0]; if ( m_pparams.Refs().size()>1 ) std::cout<<" and "<<m_pparams.Refs()[1]; } } PictureSort psort = m_pparams.PicSort(); auto_ptr<MvData> mv_data; if ( psort.IsInter() ) //do all the MV stuff DecompressMVData( mv_data, picture_byteio ); // Read the transform header TransformByteIO transform_byteio(picture_byteio, m_pparams, m_decparams); transform_byteio.Input(); if (m_pparams.PicSort().IsIntra() && m_decparams.ZeroTransform()){ DIRAC_THROW_EXCEPTION( ERR_UNSUPPORTED_STREAM_DATA, "Intra pictures cannot have Zero-Residual", SEVERITY_PICTURE_ERROR); } // Add a picture to the buffer to decode into PushPicture(my_buffer); //Reference to the picture being decoded Picture& my_picture = my_buffer.GetPicture(m_pparams.PictureNum()); if (!m_decparams.ZeroTransform()){ //decode components Picture& pic = my_buffer.GetPicture( m_pparams.PictureNum() ); CompDecompressor my_compdecoder( m_decparams , pic.GetPparams() ); PicArray* comp_data[3]; CoeffArray* coeff_data[3]; const int depth( m_decparams.TransformDepth() ); WaveletTransform wtransform( depth, m_decparams.TransformFilter() ); pic.InitWltData( depth ); for (int c=0; c<3; ++c){ ComponentByteIO component_byteio((CompSort) c, transform_byteio); comp_data[c] = &pic.Data((CompSort) c); coeff_data[c] = &pic.WltData((CompSort) c); SubbandList& bands = coeff_data[c]->BandList(); bands.Init(depth , coeff_data[c]->LengthX() , coeff_data[c]->LengthY()); my_compdecoder.Decompress(&component_byteio, *(coeff_data[c]), bands ); wtransform.Transform(BACKWARD,*(comp_data[c]), *(coeff_data[c])); } } else my_picture.Fill(0); if ( psort.IsInter() ){ Picture* my_pic = &my_buffer.GetPicture( m_pparams.PictureNum() ); const std::vector<int>& refs = m_pparams.Refs(); Picture* ref_pics[2]; ref_pics[0] = &my_buffer.GetPicture( refs[0] ); if (refs.size()>1) ref_pics[1] = &my_buffer.GetPicture( refs[1] ); else ref_pics[1] = ref_pics[0]; //motion compensate to add the data back in if we don't have an I picture MotionCompensator::CompensatePicture( m_decparams.GetPicPredParams() , ADD , *(mv_data.get()) , my_pic, ref_pics ); } my_picture.Clip(); if (m_decparams.Verbose()) std::cout<<std::endl; //exit success return true; }// try catch (const DiracException& e) { // skip picture throw e; } //exit failure return false; }