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