Ejemplo n.º 1
0
void PictureBuffer::PushPicture( const PictureParams& pp )
{// Put a new picture onto the top of the stack

    // if picture is present - return
    if (IsPictureAvail(pp.PictureNum()))
        return;

//    if ( pp.PicSort().IsRef() )
//        m_ref_count++;

    Picture* pptr = new Picture(pp);
    // add the picture to the buffer
    m_pic_data.push_back(pptr);
    
    // put the picture number into the index table
    std::pair<unsigned int,unsigned int> temp_pair(pp.PictureNum() , m_pic_data.size()-1 );
    m_pnum_map.insert(temp_pair);
}
Ejemplo n.º 2
0
void SequenceCompressor::UpdateIntraPicCBRModel( const PictureParams& pparams, const bool is_a_cut ){
    // For intra pictures we want to update before coding
    // especially if they're inserted

    if ( pparams.PicSort().IsIntra() && m_current_display_pnum > 0 &&
             m_encparams.NumL1() != 0){
        // Calculate the new QF for encoding the following I picture
        if ( is_a_cut )
            m_ratecontrol->SetCutPictureQualFactor();
        else
            m_ratecontrol->CalcNextIntraQualFactor();
    }
}
Ejemplo n.º 3
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


}
Ejemplo n.º 4
0
void FieldSequenceCompressor::SetPicTypeAndRefs( PictureParams& pparams )
{
// FIXME: won't work with adaptive GOP properly
    // Set the temporal prediction parameters for field coding

    const int pnum = pparams.PictureNum();
    const int rel_pnum = pparams.PictureNum()-m_gop_start_num;
    const int gop_len = m_encparams.GOPLength();
    const int num_L1 = m_encparams.NumL1();

    pparams.SetRetiredPictureNum( -1 );
    pparams.Refs().clear();

    if ( num_L1>0 ){

        if ( (rel_pnum/2) % gop_len == 0){
            // Field 1 is Intra Field
            if (gop_len > 1){
                pparams.SetPicSort( PictureSort::IntraRefPictureSort());
                // I picture expires after we've coded the next L1 picture
                pparams.SetExpiryTime( gop_len * 2);
                pparams.SetExpiryTime( 2*m_L1_sep );
                if ( pnum%2){
                    pparams.SetPicSort( PictureSort::InterRefPictureSort());
                    // Ref the previous I field
                    pparams.Refs().push_back( pnum-1 );
                }
            }
            else{
                // I-picture only coding
                pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
                pparams.SetExpiryTime( gop_len );
            }
        }
        else if ((rel_pnum/2) % m_L1_sep == 0){

            pparams.SetPicSort( PictureSort::InterRefPictureSort());

            if (pnum%2){
                // Field 2
                // Ref the first field of same picture
                pparams.Refs().push_back( pnum - 1);
                // Ref the previous field 2 of I or L1 picture
                pparams.Refs().push_back( pnum - m_L1_sep*2 );
            }
            else{
                // Field 1
                // Ref the field 1 of previous I or L1 picture
                pparams.Refs().push_back( pnum - m_L1_sep*2 );
                // Ref the field 2 of previous I or L1 picture
                pparams.Refs().push_back( pnum - m_L1_sep*2 + 1 );
            }

            // Expires after the next L1 or I picture
            pparams.SetExpiryTime( (m_L1_sep+1)*2-1 );
        if ((rel_pnum/2) % m_encparams.L1Sep() == 0 )
            pparams.SetExpiryTime((2*m_encparams.L1Sep())+1*2-1);
        }
        else if ((rel_pnum/2+1) % m_L1_sep == 0){
            // Bi-directional non-reference fields.
            if (pnum%2)
                pparams.SetPicSort( PictureSort::InterNonRefPictureSort());
            else
                pparams.SetPicSort( PictureSort::InterRefPictureSort());

            pparams.Refs().push_back(pnum-1);
            if (m_enc_pbuffer.IsPictureAvail(pnum+2))
                pparams.Refs().push_back(pnum+2);

            pparams.SetExpiryTime( 1 );
        }
        else{
            // Bi-directional reference fields.
            pparams.SetPicSort( PictureSort::InterRefPictureSort());

            pparams.Refs().push_back(pnum-1);
            int next_ref = (((pnum/2)/m_L1_sep+1)*m_L1_sep)*2+(pnum%2);
            if (m_enc_pbuffer.IsPictureAvail(next_ref))
                pparams.Refs().push_back(next_ref);
            pparams.SetExpiryTime( 4 );
        }

    }
    else{
        pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
        pparams.SetExpiryTime( 2 );
    }
}
Ejemplo n.º 5
0
void FrameSequenceCompressor::SetPicTypeAndRefs( PictureParams& pparams )
{
    // Set the temporal prediction parameters for frame coding

    const int pnum = pparams.PictureNum();
    const int rel_pnum = pnum - m_gop_start_num;
    const int gop_len = m_encparams.GOPLength();
    const int num_L1 = m_encparams.NumL1();

    pparams.SetRetiredPictureNum( -1 );
    pparams.Refs().clear();

    if ( num_L1>0 ){

        if ( rel_pnum % gop_len == 0){
            if (gop_len > 1)
                pparams.SetPicSort( PictureSort::IntraRefPictureSort());
            else // I-picture only coding
                pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());

            // I picture expires after we've coded the next I picture
            pparams.SetExpiryTime( 2*m_L1_sep );
        }
        else if (rel_pnum % m_L1_sep == 0){
            pparams.SetPicSort( PictureSort::InterRefPictureSort());

            // Ref the previous I or L1 picture
            pparams.Refs().push_back( pnum - m_L1_sep );

            // if we don't have the first L1 picture ...
            if ( ((rel_pnum-m_L1_sep) % gop_len>0) && m_L1_sep>1)
                // ... other ref is the prior I/L1 picture but one
                pparams.Refs().push_back( pnum - 2*m_L1_sep  );

            // Expires after the next L1 or I picture
            pparams.SetExpiryTime( 2*m_L1_sep );
        if (rel_pnum % m_encparams.L1Sep() == 0 )
            pparams.SetExpiryTime(2*m_encparams.L1Sep());
        }
        else if ((rel_pnum+1) % m_L1_sep == 0){
            pparams.SetPicSort( PictureSort::InterNonRefPictureSort());

            // .. and the previous picture
            pparams.Refs().push_back(pnum-1);
            // Refs are the next I or L1 picture ...
            if (m_enc_pbuffer.IsPictureAvail(pnum+1))
                pparams.Refs().push_back(pnum+1);

            pparams.SetExpiryTime( 1 );
        }
        else{
            pparams.SetPicSort( PictureSort::InterRefPictureSort());

            // .. and the previous picture
            pparams.Refs().push_back(pnum-1);
            // Refs are the next I or L1 picture ...
            int next_ref = ((pnum/m_L1_sep)+1)*m_L1_sep;
            if (m_enc_pbuffer.IsPictureAvail(next_ref))
                pparams.Refs().push_back(next_ref);

            pparams.SetExpiryTime( 2 );
        }

    }
    else{
        pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
        pparams.SetExpiryTime( 1 );
    }

}
Ejemplo n.º 6
0
//Constructor
CompDecompressor::CompDecompressor( DecoderParams& decp, const PictureParams& pp)
:
    m_decparams(decp),
    m_pparams(pp),
    m_psort( pp.PicSort() )
{}