⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picture.cc

📁 Motion JPEG编解码器源代码
💻 CC
📖 第 1 页 / 共 2 页
字号:
 ************************************************************************/void Picture::Adjust2ndField(){	secondfield = true;    gop_start = false;	if( pict_struct == TOP_FIELD )		pict_struct =  BOTTOM_FIELD;	else		pict_struct =  TOP_FIELD;		if( pict_type == I_TYPE )	{		ipflag = 1;		pict_type = P_TYPE;				forw_hor_f_code = encparams.motion_data[0].forw_hor_f_code;		forw_vert_f_code = encparams.motion_data[0].forw_vert_f_code;		back_hor_f_code = 15;		back_vert_f_code = 15;		sxf = encparams.motion_data[0].sxf;		syf = encparams.motion_data[0].syf;		}}void Picture::EncodeMacroBlocks(){     vector<MacroBlock>::iterator mbi = mbinfo.begin();	for( mbi = mbinfo.begin(); mbi < mbinfo.end(); ++mbi)	{        mbi->Encode();	}}void Picture::IQuantize(){    int k;	for (k=0; k<encparams.mb_per_pict; k++)	{        mbinfo[k].IQuantize( quantizer );	}}void Picture::ActivityMeasures( double &act_sum, double &var_sum){	int i,j,k,l;	double actj,sum;	double varsum;	int blksum;	sum = 0.0;	varsum = 0.0;	k = 0;	for (j=0; j<encparams.enc_height2; j+=16)		for (i=0; i<encparams.enc_width; i+=16)		{			/* A.Stevens Jul 2000 Luminance variance *has* to be a			   rotten measure of how active a block in terms of bits			   needed to code a lossless DCT.  E.g. a half-white			   half-black block has a maximal variance but pretty			   small DCT coefficients.			   So.... instead of luminance variance as used in the			   original we use the absolute sum of DCT coefficients as			   our block activity measure.  */			varsum += (double)mbinfo[k].final_me.var;			if( mbinfo[k].final_me.mb_type  & MB_INTRA )			{				/* Compensate for the wholly disproprotionate weight				 of the DC coefficients.  Shold produce more sensible				 results...  yes... it *is* an mostly empirically derived				 fudge factor ;-)				*/				blksum =  -80*COEFFSUM_SCALE;				for( l = 0; l < 6; ++l )					blksum += 						quantizer.WeightCoeffIntra( mbinfo[k].RawDCTblocks()[l] ) ;			}			else			{				blksum = 0;				for( l = 0; l < 6; ++l )					blksum += 						quantizer.WeightCoeffInter( mbinfo[k].RawDCTblocks()[l] ) ;			}			/* It takes some bits to code even an entirely zero block...			   It also makes a lot of calculations a lot better conditioned			   if it can be guaranteed that activity is always distinctly			   non-zero.			 */			actj = (double)blksum / (double)COEFFSUM_SCALE;			if( actj < 12.0 )				actj = 12.0;			mbinfo[k].act = (double)actj;			sum += (double)actj;			++k;		}	act_sum = sum;	var_sum = varsum;}/* inverse transform prediction error and add prediction */void Picture::ITransform(){    vector<MacroBlock>::iterator mbi;	for( mbi = mbinfo.begin(); mbi < mbinfo.end(); ++mbi)	{		mbi->ITransform();	}}void Picture::MotionSubSampledLum( ){	int linestride;    EncoderParams &eparams = encparams;	/* In an interlaced field the "next" line is 2 width's down rather	   than 1 width down  .       TODO: Shoudn't we be treating the frame as interlaced for       frame based interlaced encoding too... or at least for the       interlaced ME modes?    */	if (!eparams.fieldpic)	{		linestride = eparams.phy_width;	}	else	{		linestride = 2*eparams.phy_width;	}	psubsample_image( org_img[0], 					 linestride,					 org_img[0]+eparams.fsubsample_offset, 					 org_img[0]+eparams.qsubsample_offset );}/* ************************************************ * * QuantiseAndEncode - Quantise and Encode a picture. * * NOTE: It may seem perverse to quantise at the same time as * coding-> However, actually makes (limited) sense * - feedback from the *actual* bit-allocation may be used to adjust  * quantisation "on the fly". This is good for fast 1-pass no-look-ahead coding-> * - The coded result is in any even only buffered not actually written * out. We can back off and try again with a different quantisation * easily. * - The alternative is calculating size and generating actual codes seperately. * The poorer cache coherence of this latter probably makes the performance gain * modest. * * *********************************************** */void Picture::QuantiseAndEncode(RateCtl &ratectl){    InitRateControl( ratectl );        PutHeaders();    /* Now the actual quantisation and encoding->.. */          int i, j, k;    int MBAinc;    MacroBlock *cur_mb = 0;	int mquant_pred = ratectl.InitialMacroBlockQuant(*this);	k = 0;        /* TODO: We're currently hard-wiring each macroblock row as a       slice.  For MPEG-2 we could do this better and reduce slice       start code coverhead... */	for (j=0; j<encparams.mb_height2; j++)	{        PutSliceHdr(j, mquant_pred);        Reset_DC_DCT_Pred();        Reset_MV_Pred();        MBAinc = 1; /* first MBAinc denotes absolute position */        /* Slice macroblocks... */		for (i=0; i<encparams.mb_width; i++)		{            prev_mb = cur_mb;			cur_mb = &mbinfo[k];            int suggested_mquant = ratectl.MacroBlockQuant( *cur_mb );            cur_mb->mquant = suggested_mquant;			/* Quantize macroblock : N.b. the MB_PATTERN bit may be               set as a side-effect of this call. */            cur_mb->Quantize( quantizer);                        /* Output mquant and update prediction if it changed in this macroblock */            if( cur_mb->cbp && suggested_mquant != mquant_pred )            {                mquant_pred = suggested_mquant;                cur_mb->final_me.mb_type |= MB_QUANT;            }                            /* Check to see if Macroblock is skippable, this may set               the MB_FORWARD bit... */            bool slice_begin_or_end = (i==0 || i==encparams.mb_width-1);            cur_mb->SkippedCoding(slice_begin_or_end);            if( cur_mb->skipped )            {                ++MBAinc;            }            else            {                coding->PutAddrInc(MBAinc); /* macroblock_address_increment */                MBAinc = 1;                                coding->PutMBType(pict_type,cur_mb->final_me.mb_type); /* macroblock type */                if ( (cur_mb->final_me.mb_type & (MB_FORWARD|MB_BACKWARD)) && !frame_pred_dct)                    coding->PutBits(cur_mb->final_me.motion_type,2);                if (pict_struct==FRAME_PICTURE 	&& cur_mb->cbp && !frame_pred_dct)                    coding->PutBits(cur_mb->field_dct,1);                if (cur_mb->final_me.mb_type & MB_QUANT)                {                    coding->PutBits(q_scale_type                             ? map_non_linear_mquant[cur_mb->mquant]                            : cur_mb->mquant>>1,5);                }                if (cur_mb->final_me.mb_type & MB_FORWARD)                {                    /* forward motion vectors, update predictors */                    PutMVs( cur_mb->final_me, false );                }                if (cur_mb->final_me.mb_type & MB_BACKWARD)                {                    /* backward motion vectors, update predictors */                    PutMVs( cur_mb->final_me,  true );                }                if (cur_mb->final_me.mb_type & MB_PATTERN)                {                    coding->PutCPB((cur_mb->cbp >> (BLOCK_COUNT-6)) & 63);                }                            /* Output VLC DCT Blocks for Macroblock */                cur_mb->PutBlocks( );                /* reset predictors */                if (!(cur_mb->final_me.mb_type & MB_INTRA))                    Reset_DC_DCT_Pred();                if (cur_mb->final_me.mb_type & MB_INTRA ||                     (pict_type==P_TYPE && !(cur_mb->final_me.mb_type & MB_FORWARD)))                {                    Reset_MV_Pred();                }            }            ++k;        } /* Slice MB loop */    } /* Slice loop */	int padding_needed;    bool recoding_suggested;    ratectl.UpdatePict( *this, padding_needed);    coding->AlignBits();    if( padding_needed > 0 )    {        mjpeg_debug( "Padding coded picture to size: %d extra bytes",                      padding_needed );        for( i = 0; i < padding_needed; ++i )        {            coding->PutBits(0, 8);        }    }        /* Handle splitting of output stream into sequences of desired size */    if( end_seq )    {        coding->PutSeqEnd();    }    }/* ***************** * * InitRateControl - Setup rate controller new current picture / GOP/ Sequence * ******************/void Picture::InitRateControl( RateCtl &ratecontrol ){     /* Handle splitting of output stream into sequences of desired size */    if( new_seq )    {        ratecontrol.InitSeq(true);    }        /* Handle start of GOP stuff:       We've reach a new GOP so we emit what we coded for the       previous one as (for the moment) and mark the resulting coder       state for eventual backup.       Currently, we never backup more that to the start of the current GOP.     */    if( gop_start )    {        ratecontrol.InitGOP( np, nb);    }    ratecontrol.CalcVbvDelay(*this);    ratecontrol.InitNewPict(*this); /* set up rate control */}int Picture::SizeCodedMacroBlocks() const{     return coding->ByteCount() * 8; }double Picture::IntraCodedBlocks() const{     vector<MacroBlock>::const_iterator mbi = mbinfo.begin();    int intra = 0;    for( mbi = mbinfo.begin(); mbi < mbinfo.end(); ++mbi)    {        if( mbi->final_me.mb_type&MB_INTRA )            ++intra;    }    return static_cast<double>(intra) / mbinfo.size();}/* ********************* * * Commit   -   Commit to the current encoding of the frame * flush the coder buffer content to the elementary stream output. * * *********************/  void Picture::Commit() {    coding->FlushBuffer(); }/*  * Local variables: *  c-file-style: "stroustrup" *  tab-width: 4 *  indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -