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 );

    }
}
Exemple #2
0
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


}
Exemple #3
0
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;
}