www.pudn.com > henclib263.rar > pictureP.cxx


/* 
* pictureP.cxx 
* 
* implementation for frame(P frame) level funtions. 
* 
* Copyright (c) 2002-2004 Li Chun-lin(li_chunlin@263.net) 
* 
* This program is free software; you can redistribute it and/or 
* modify it under the terms of the GNU General Public License 
* as published by the Free Software Foundation; either version 2 
* of the License, or (at your option) any later version. 
*  
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
* GNU General Public License for more details. 
 
* You should have received a copy of the GNU General Public License 
* along with this program; if not, write to the Free Software 
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
*/ 
#include "../include/mot_est.h" 
#include "../include/macroblock.h" 
#include "../include/vlc.h" 
#include "../include/image.h" 
#include "../include/bitstream.h" 
 
 
#ifdef  __cplusplus 
extern "C" { 
#endif 
 
/*! 
******************************************************************************* 
* 
*   Name:          EncPfrm 
*   Description:   Encode one P Picture 
*   Input:           
*   Output:         
*   Last modified: 2002/12/5 by lcl 
* 
*******************************************************************************/ 
int EncPfrm(H263VencStatus *encoder, MCParam *MC) 
{ 
	int     pix_x, pix_y; 
	int     mb_x, mb_y; 
	int     lines = encoder->lines; 
	int     pels = encoder->pels; 
	short qcoeff[384]; 
	int     mb_mode; 
	int     cod; 
	int     cbp; 
	int     dquant = 0; 
	int     newgob; 
	int     frame_total_bits = 0; 
	int     gob_nbr = 0; 
	int     gob_quant = encoder->total_Q; 
	int     TRP = encoder->TR - encoder->ref_pic*(encoder->frame_skip+1); 
 
	interpolate_lum(encoder); 
	grabVec(encoder, MC, 0);              //???? Find MV on frame level or MB level? 
	if (encoder->B_frame) 
	{ 
		saveVec(MC, lines/16, pels/16); 
	} 
 
	if (encoder->version2) 
	{ 
		frame_total_bits += EncPicHdrPlus(encoder); 
	} 
	else 
	{ 
		frame_total_bits += EncPicHdr(encoder); 
	} 
 
	for (pix_y = 0, mb_y = 0; pix_y < lines; pix_y+=16, mb_y++) 
	{ 
		newgob = 0; 
		if(encoder->gobsync && pix_y && mb_y%(encoder->gobsync) == 0) 
		{ 
			gob_nbr++; 
			frame_total_bits += EncGOBHdr(gob_nbr, encoder->gfid, gob_quant, encoder->TR, TRP); 
			newgob = 1; 
		} 
		for (pix_x = 0, mb_x = 0; pix_x < pels; pix_x+=16, mb_x++) 
		{ 
			mb_mode = (MC->mv_frame[0][mb_y+1][mb_x+1])->Mode; //!< set mode of current mb 
			cod = 0; 
			if (MODE_INTRA == mb_mode || MODE_INTRA_Q == mb_mode) 
			{  
				cbp = MB_Encode_I(encoder, pix_x, pix_y, qcoeff); 
				/* take down the coded information of current mb */ 
				encoder->coded_tab[mb_y+1][mb_x+1] = 1; 
				encoder->quant_tab[mb_y+1][mb_x+1] = encoder->total_Q;			 
				frame_total_bits += EncMBHdr(encoder->PTYPE, mb_mode, cod, cbp, dquant);         //!<   write MCBPC, CBPY, DQUANT 
				frame_total_bits += EncCoeff(1, cbp, qcoeff, 64);          //!<   write coefficients 
 
			} 
			else 
			{ 
		    	cbp = MB_Encode_P(encoder, pix_x, pix_y, MC, qcoeff); 
				if ((0 == cbp) && ZeroVector(MC->mv_frame[0][mb_y+1][mb_x+1]))  //!< skipped 
				{ 
					cod = 1; 
				} 
				/* take down the coded information of current mb */ 
				encoder->coded_tab[mb_y+1][mb_x+1] = cod ? 0 : (mb_mode == MODE_INTER4V ? 3 : 2); 
				encoder->quant_tab[mb_y+1][mb_x+1] = encoder->total_Q; 
				frame_total_bits += EncMBHdr(encoder->PTYPE, mb_mode, cod, cbp, dquant);         //!<  write COD, MCBPC, CBPY, DQUANT 
                if (!cod) 
				{ 
					frame_total_bits += EncMVD(MC, mb_x, mb_y, mb_mode, newgob); 
					frame_total_bits += EncCoeff(0, cbp, qcoeff, 64);                   //!<  write coefficients 
				} 
			} 
 
		} 
	} 
 
	frame_total_bits += alignbits(); 
	clear_buff(); 
 
	if (encoder->filter) 
	{ 
		EdgeFilter(encoder); 
	} 
	if (encoder->mv_outside_frame) 
	{ 
		MakeEdgeImage(encoder); 
	} 
 
	return frame_total_bits; 
 
} 
 
#ifdef  __cplusplus 
} 
#endif