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


/* 
* init.cxx 
* 
* implementation for functions which is used to initialize encoder status. 
* 
* 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  
#include  
#include "../include/Exceptions.h" 
#include "../include/mot_est.h" 
#include "../include/HEnc.h" 
 
 
#ifdef  __cplusplus 
extern "C" { 
#endif 
 
 
 
extern putstrm putstrmctrl; 
extern int SpiralX[6561]; 
extern int SpiralY[6561]; 
 
/*! 
******************************************************************************* 
* 
*   Name:          alloc_mem 
*   Description:   allocate memory for buffers to be used by encoder 
*   Input:          
*   Output:         
*   Last modified: 2002/12/17 
* 
*******************************************************************************/ 
void alloc_mem(H263VencStatus *encoder, MCParam *mc, putstrm *strm) 
{ 
	int width = encoder->pels; 
	int height = encoder->lines; 
	int x = width/16; 
	int y = height/16; 
 
	int i, j; 
	unsigned char *tmp; 
	int edge  = encoder->mv_outside_frame ? 32*(width+height)+1024 : 0; 
	int skip1 = encoder->mv_outside_frame ? 16*(width+32)+16 : 0; 
	int skip2 = encoder->mv_outside_frame ? 8*(width/2+16)+8 : 0; 
	int offset1 = width * height; 
	int offset2 = offset1*5/4; 
	int offset3 = offset1*3/2; 
 
/* Allocate memory for image*/ 
 
	/* Buffer to all store reconstructed frames for reference */ 
	for (i = 0; i < encoder->buf_cycle; i++) 
	{ 
		if (NULL == (tmp = (unsigned char *)malloc(sizeof(unsigned char)*(offset1+edge)*3/2))) 
		{ 
			printf("no memory\n"); 
			exit(-1); 
		} 
		(encoder->frame_buf[i]).pLum = tmp + skip1; 
		(encoder->frame_buf[i]).pCb  = tmp + offset1 + edge + skip2; 
		(encoder->frame_buf[i]).pCr  = tmp + offset2 + edge*5/4 + skip2; 
	} 
    /* Buffer for B pictures */ 
    for (i = 0; i <= encoder->B_frame; i++) 
	{ 
		if (NULL == (tmp = (unsigned char *)malloc(sizeof(unsigned char)*offset1*3/2))) 
		{ 
			printf("no memory\n"); 
			exit(-1); 
		} 
		(encoder->BPicture[i]).pLum = tmp; 
		(encoder->BPicture[i]).pCb  = tmp + offset1; 
		(encoder->BPicture[i]).pCr  = tmp + offset2; 
	} 
    /* Buffer for interpolated lum picture */ 
	if (NULL == (tmp = (unsigned char *)malloc(sizeof(unsigned char)*(offset1+edge)*4))) 
	{ 
		printf("no memory\n"); 
		exit(-1); 
	} 
	encoder->prev_ipol = encoder->mv_outside_frame ? tmp+(width*2+64)*32+32 : tmp; 
	if (encoder->B_frame) 
	{ 
		if (NULL == (tmp = (unsigned char *)malloc(sizeof(unsigned char)*(offset1+edge)*4))) 
		{ 
			printf("no memory\n"); 
			exit(-1); 
		} 
		encoder->next_ipol = encoder->mv_outside_frame ? tmp+(width*2+64)*32+32 : tmp; 
	} 
/* initialize MC */ 
	for (i = 0; i < y+1; i++) 
	{ 
		for (j = 0; j < x+2; j++) 
		{ 
 
			if (NULL == (mc->mv_frame[0][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
				NULL == (mc->mv_frame[1][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
				NULL == (mc->mv_frame[2][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
				NULL == (mc->mv_frame[3][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
				NULL == (mc->mv_frame[4][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
				NULL == (mc->mv_frame[5][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))) 
			{ 
				printf("no memory!\n"); 
				exit(-1); 
			} 
		} 
	} 
	for (i = 1; i < x+1; i++) 
	{ 
		mc->mv_frame[0][0][i]->x = NO_VEC; 
		mc->mv_frame[0][0][i]->y = NO_VEC; 
		mc->mv_frame[0][0][i]->x_half = 0; 
		mc->mv_frame[0][0][i]->y_half = 0; 
		mc->mv_frame[0][0][i]->Mode = MODE_INTRA; 
	} 
	for (i = 0; i < y+1; i++) 
	{ 
		zeroVec(mc->mv_frame[0][i][0]); 
		mc->mv_frame[0][i][0]->Mode = MODE_INTRA; 
        zeroVec(mc->mv_frame[0][i][x+1]); 
		mc->mv_frame[0][i][x+1]->Mode = MODE_INTRA; 
	} 
 
	if(encoder->B_frame) 
	{ 
		for (i = 0; i < y; i++) 
		{ 
			for (j = 0; j < x; j++) 
			{ 
				 
				if (NULL == (mc->mv_lastframe[0][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
					NULL == (mc->mv_lastframe[1][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
					NULL == (mc->mv_lastframe[2][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
					NULL == (mc->mv_lastframe[3][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))|| 
					NULL == (mc->mv_lastframe[4][i][j] = (MotionVector *)malloc(sizeof(MotionVector)))) 
					 
				{ 
					printf("no memory!\n"); 
					exit(-1); 
				} 
			} 
		} 
		//! initialize backward mvs 
		for (i = 1; i < x+1; i++) 
		{ 
			mc->mv_frame[5][0][i]->x = NO_VEC; 
			mc->mv_frame[5][0][i]->y = NO_VEC; 
			mc->mv_frame[5][0][i]->x_half = 0; 
			mc->mv_frame[5][0][i]->y_half = 0; 
		} 
		for (i = 0; i < y+1; i++) 
		{ 
			zeroVec(mc->mv_frame[5][i][0]); 
			zeroVec(mc->mv_frame[5][i][x+1]); 
		} 
	} 
/* allocate memory for stream buffer */ 
	if(NULL == (strm->pout = (unsigned char*)malloc(sizeof(unsigned char)*strm->buff_size))) 
	{ 
		printf("no memory!\n"); 
		exit(-1); 
	} 
} 
 
/*! 
******************************************************************************* 
* 
*   Name:          ini_para 
*   Description:   initialize parameters of encoder at the beginning of encoding 
*   Input:          
*   Output:         
*   Last modified: 2002/12/5 
* 
*******************************************************************************/ 
int init_para (H263VencStatus *encoder, int P_rate, int QP, int QI, int QB, int gob, int framerate, int bitrate) 
{ 
 
	if(P_rate >= 0)                          //< p_rate 
	{ 
		encoder->p_rate = P_rate; 
	} 
	else 
	{ 
		printf("error value for p_rate\n"); 
		return 0; 
	} 
 	if(QP < 32 && QP > 0)                    //< QP 
	{ 
		encoder->QP     = QP; 
	} 
	else 
	{ 
		printf("error QUANT value for I frames\n"); 
		return 0; 
	} 
	if(QI < 32 && QI > 0)                    //< QI  
	{ 
		encoder->QI     = QI; 
	} 
	else 
	{ 
		printf("error QUANT value for P frames\n"); 
		return 0; 
	} 
	if(QB < 32 && QB > 0)                    //< QB  
	{ 
		encoder->QB     = QB; 
	} 
	else 
	{ 
		printf("error QUANT value for B frames\n"); 
		return 0; 
	} 
	if (!gob)                               //< gobsync 
		encoder->gobsync = 0; 
 
	encoder->gfid = 0;                      //< gfid  
 
	if (framerate >= 0)                     //< framerate 
	{ 
		encoder->framerate = framerate; 
	} 
	else 
	{ 
		printf(E_INITENC_WRONG_FRAMERATE); 
		return 0; 
	} 
	if (bitrate > 0) 
	{ 
		encoder->target_bitrate = bitrate*1024; 
	} 
	else if (bitrate == 0) 
	{		 
		encoder->target_bitrate = 0; 
	} 
	else 
	{ 
		printf("Error Target bitrate\n"); 
		return 0; 
	} 
	return 1; 
 
} 
 
/*! 
******************************************************************************* 
* 
*   Name:           
*   Description:    
*   Input:          
*   Output:         
*   Last modified: 2002/12/21 
* 
*******************************************************************************/ 
int  init_bitstrm(int type, unsigned int time) 
{ 
	putstrmctrl.bitout = 0; 
	putstrmctrl.pcnt = 8; 
	putstrmctrl.ptr = 0; 
	putstrmctrl.pic_type = type; 
	putstrmctrl.timestamp = time; 
 
	return 1; 
} 
 
/*! 
******************************************************************************* 
* 
*   Name:          init_control 
*   Description:   initialize control parameters at the beginning of encoding 
*   Input:          
*   Output:         
*   Last modified: 2002/12/21 
* 
*******************************************************************************/ 
int  init_control(H263VencStatus *encoder) 
{ 
	int i; 
	 
	encoder->PTYPE = INTRA; 
	encoder->total_Q = encoder->QI; 
	encoder->TR     = 0; 
	encoder->pic_nbr= 0; 
	encoder->pcount = 0; 
	encoder->B_count = 0; 
	encoder->totalBits = 0; 
	encoder->zero_index = 0; 
	encoder->ref_index = 0; 
	encoder->ref_pic = 0; 
	encoder->frame_skip = 0; 
	if (encoder->target_bitrate) 
	{ 
		for (i = 0; i < encoder->framerate; i++) 
		{ 
			encoder->framebits[i] = -1; 
		} 
	} 
	return 1; 
} 
/* 
******************************************************************************* 
* 
*   Name:          init_table 
*   Description:   initialize coded table and quantizer table 
*   Input:          
*   Output:         
*   Last modified: 2002/12/21 
* 
*******************************************************************************/ 
int  init_table(H263VencStatus *encoder) 
{ 
	int n; 
	int mbr = encoder->lines/16; 
	int mbc = encoder->pels/16; 
 
	for (n = 0; n < mbr+1; n++) 
	{ 
		encoder->coded_tab[n][0] = 0; 
		encoder->quant_tab[n][0] = 0; 
	} 
	for (n = 1; n < mbc+1; n++) 
	{ 
		encoder->coded_tab[0][n] = 0; 
		encoder->quant_tab[0][n] = 0; 
	} 
 
	return 1; 
} 
 
/*! 
******************************************************************************* 
* 
*   Name:          init_fs 
*   Description:   produce spiral for full search 
*   Input:          
*   Output:         
*   Author:        copyed from tml8.0  
*   Last modified: 2002/11/23 by lcl 
* 
*******************************************************************************/ 
void init_fs() 
{ 
	int i,j,k,l,l2; 
 
	k=1; 
	for (l=1; l < 41; l++) { 
		l2=l+l; 
		for (i=-l+1; i < l; i++) { 
			for (j=-l; j < l+1; j += l2) { 
				SpiralX[k] = i; 
				SpiralY[k] = j; 
				k++; 
			} 
		} 
 
		for (j=-l; j <= l; j++) { 
			for (i=-l;i <= l; i += l2) { 
				SpiralX[k] = i; 
				SpiralY[k] = j; 
				k++; 
			} 
		} 
	} 
} 
 
/*! 
******************************************************************************* 
* 
*   Name:           
*   Description:    
*   Input:          
*   Output:         
*   Last modified: 2002/12/21 
* 
*******************************************************************************/ 
int  init_MCPara(MCParam *MC, int search_range, int search_method) 
{ 
	MC->mv = NULL; 
	if(search_range > 0 && search_range < 16) 
	{ 
		MC->search_range = search_range; 
	} 
	else 
	{ 
		printf (E_INITENC_WRONG_SEARCH_RANGE); 
		return 0; 
	} 
	if(search_method >= 0 && search_method <4) 
	{ 
		MC->method = search_method; 
	} 
	else 
	{ 
		printf (E_INITENC_WRONG_SEARCH_METHOD); 
		return 0; 
	} 
	MC->search_range_8x8 = 0;  /*< if this is set to zero, only half pel estimation of 8x8 block 
                                           will be performed actually*/ 
 
    //initiation of m_MCStatus.mv_frame was done in function alloc_mem 
 
    //initialize matrix for full search 
	if (0 == search_method) 
	{ 
		init_fs(); 
	} 
	 
	return 1; 
} 
/*! 
******************************************************************************* 
* 
*   Name:          GetSourceFrame 
*   Description:   Get the address of source image to be encoded 
*   Input:         address of source image, width and height of picture 
*   Output:         
*   Last modified: 2002/12/4 
* 
*******************************************************************************/ 
int  GetSourceFrame(H263VencStatus * encoder, unsigned char* pCap) 
{ 
	int offset1; 
	int offset2; 
 
	if (NULL ==  pCap) 
	{ 
		printf(E_INITENC_NO_PICTURE); 
		return 0; 
	} 
	 
	offset1 = encoder->lines * encoder->pels; 
	offset2 = offset1*5/4; 
 
	encoder->frameToEncode.pLum = pCap; 
	encoder->frameToEncode.pCb  = pCap + offset1; 
	encoder->frameToEncode.pCr  = pCap + offset2; 
 
	return 1; 
 
} 
 
 
/*! 
******************************************************************************* 
* 
*   Name:          close_encoder 
*   Description:   Set free memory allocated at the beginning of encoding 
*   Input:          
*   Output:         
*   Last modified: 2002/12/4 
* 
*******************************************************************************/ 
void close_encoder (H263VencStatus *encoder, MCParam *mc, putstrm *pStrm) 
{ 
	int i, j; 
	int width = encoder->pels; 
	int height = encoder->lines; 
	unsigned char *tmp; 
 
	for (i = 0; i < height/16+1; i++) 
	{ 
		for (j = 0; j < width/16+2; j++) 
		{ 
			free(mc->mv_frame[0][i][j]); 
			free(mc->mv_frame[1][i][j]); 
			free(mc->mv_frame[2][i][j]); 
			free(mc->mv_frame[3][i][j]); 
			free(mc->mv_frame[4][i][j]); 
			free(mc->mv_frame[5][i][j]); 
		} 
	} 
	if (encoder->B_frame) 
	{ 
		for (i = 0; i < height/16; i++) 
		{ 
			for (j = 0; j < width/16; j++) 
			{ 
				free(mc->mv_lastframe[0][i][j]); 
				free(mc->mv_lastframe[1][i][j]); 
				free(mc->mv_lastframe[2][i][j]); 
				free(mc->mv_lastframe[3][i][j]); 
				free(mc->mv_lastframe[4][i][j]); 
			} 
		} 
	} 
 
	for (i = 0; i < encoder->buf_cycle; i++) 
	{ 
		tmp = encoder->mv_outside_frame ? (encoder->frame_buf[i].pLum - (width+32)*16-16) : encoder->frame_buf[i].pLum; 
		free(tmp); 
	} 
 
	for (i = 0; i < encoder->B_frame; i++) 
	{ 
		tmp = encoder->BPicture[i].pLum; 
		free(tmp); 
	} 
 
	tmp = encoder->mv_outside_frame ? encoder->prev_ipol-(width*2+64)*32-32 : encoder->prev_ipol;  
	free(tmp); 
	if (encoder->B_frame) 
	{ 
		tmp = encoder->mv_outside_frame ? encoder->next_ipol-(width*2+64)*32-32 : encoder->next_ipol;  
		free(tmp); 
	} 
	 
	free(pStrm->pout); 
} 
 
 
#ifdef  __cplusplus 
} 
#endif