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