📄 encode.c
字号:
#include <windows.h>
#include <commdlg.h>
#include <assert.h>
#include <io.h>
#include "sim.h"
#include "public.h"
#define DEBUG_DENG // deng
void RGB565toYUV411();
void RGB555toYUV411();
void RGB888toYUV411();
//==================================================================
long InitEncoder(unsigned char **EncoderInput ,unsigned char **EncoderOutput,int PictureWidth , int PictureHeight)
{
int i,j,k;
MotionVector *curr_pos;
if( (PictureWidth>352) || (PictureHeight>288) )
return -1 ;
DEF_INTRA_QUANT = 10 ;
DEF_INTER_QUANT = 10 ;
advanced = DEF_ADV_MODE; // deng: was YES ;
syntax_arith_coding = DEF_SAC_MODE; // DENG: was YES ;
bits = (Bits *)malloc(sizeof(Bits));
total_bits = (Bits *)malloc(sizeof(Bits));
intra_bits = (Bits *)malloc(sizeof(Bits));
res = (Results *)malloc(sizeof(Results));
total_res = (Results *)malloc(sizeof(Results));
pic = (Pict *)malloc(sizeof(Pict));
recon_data_P =(MB_Structure *)malloc(sizeof(MB_Structure));
diff =(MB_Structure *)malloc(sizeof(MB_Structure));
headerlength = DEF_HEADERLENGTH;
/* Initalize idct_tables */
init_idct();
/* Init VLC_tables */
initbits();
memset(pic, 0, sizeof(Pict));
memset(bits, 0, sizeof(Bits));
pic->unrestricted_mv_mode = DEF_UMV_MODE;
QP = DEF_INTER_QUANT;
QPI = DEF_INTRA_QUANT;
ChangableQP = DEF_INTER_QUANT;
ref_frame_rate = (float)DEF_REF_FRAME_RATE;
chosen_frameskip = DEF_FRAMESKIP + 1;
orig_frameskip = DEF_ORIG_SKIP + 1;
pic->seek_dist = DEF_SEEK_DIST;
pic->use_gobsync = DEF_INSERT_SYNC;
pic->source_format = DEF_CODING_FORMAT;
start = DEF_START_FRAME;
end = DEF_STOP_FRAME;
pic->target_frame_rate = (float)DEF_TARGET_FRAME_RATE;
targetrate = 0;
frames = 0;
total_frames_passed = 0;
pic->TR = 0;
pic->QP_mean = (float)0;
user_pels = PictureWidth;
user_lines = PictureHeight;
if( user_pels % 16 != 0 )
{ pels =( user_pels/16 + 1 ) * 16 ;
}else{
pels = PictureWidth;
}
if( user_lines % 16 != 0 )
{ lines =( user_lines/16 + 1 ) * 16 ;
}else{
lines = PictureHeight;
}
cpels = pels/2;
mbc = pels/MB_SIZE;
mbr = lines/MB_SIZE;
lsize = (long)pels*lines;
csize = lsize>>2;
widthA = pels + 64 ;
widthA2 = (widthA << 1 );
heightA = lines + 64 ;
pic->bit_rate = targetrate;
pic->src_frame_rate = (int)(ref_frame_rate / orig_frameskip);
DelayBetweenFramesInSeconds = (float) 1.0/(float)pic->src_frame_rate;
InitializeRateControl();
frame_rate = ref_frame_rate / (float)(orig_frameskip * chosen_frameskip);
bit_count = 0;
// if(!(hCurrRGB = GlobalAlloc(GHND,lsize*2L)))
if(!(hCurrRGB = GlobalAlloc(GHND,lsize*3L)))
error_handler("\ncannot alloc memory");
EncoderRGBInput = (unsigned char _huge *)GlobalLock(hCurrRGB) ;
* EncoderInput = EncoderRGBInput ;
if(!(hCurr_image = GlobalAlloc(GHND,lsize*3L/2L)))
error_handler("\ncannot alloc memory");
curr_image.lum = (unsigned char _huge *)GlobalLock(hCurr_image);
curr_image.Cb = curr_image.lum + lsize;
curr_image.Cr = curr_image.Cb + csize;
if(!(hRecon_image = GlobalAlloc(GHND,lsize*3L/2L)))
error_handler("\ncannot alloc memory");
recon_image.lum = (unsigned char _huge *)GlobalLock(hRecon_image);
recon_image.Cb = recon_image.lum + lsize;
recon_image.Cr = recon_image.Cb + csize;
B = 16;
if(!(hPr_edge = GlobalAlloc(GHND, (long)(pels+4*B)*(lines+4*B)*3L/2L)))
error_handler("\ncannot alloc memory");
pr_edge.lum = (unsigned char _huge *)GlobalLock(hPr_edge);
pr_edge.Cr = pr_edge.lum + (long)(pels+4*B)*(lines+4*B);
pr_edge.Cb = pr_edge.Cr + (long)(pels+4*B)*(lines+4*B)/4;
prev_recon.lum = pr_edge.lum + (long)(pels + 4*B)*2*B + 2*B;
prev_recon.Cr = pr_edge.Cr + (long)(pels/2 + 2*B)*B + B;
prev_recon.Cb = pr_edge.Cb + (long)(pels/2 + 2*B)*B + B;
if(!(hMV = GlobalAlloc(GHND,(long)6L*(MBR+1)*(MBC+2)*sizeof(MotionVector)+16L)))
error_handler("\ncannot alloc memory");
curr_pos = (MotionVector *)GlobalLock(hMV);
for(i = 0; i < 6; i++)
{
for(j = 0; j < mbr+1; j++)
{
for(k = 0; k < mbc+2; k++)
{
pMV[i][j][k] = curr_pos;
curr_pos ++;
}
}
}
if(!(hStreamBuf= GlobalAlloc(GHND,lsize*3L/2L)))
error_handler("\ncannot alloc memory");
InternalEncoderOutput = (unsigned char*)GlobalLock(hStreamBuf);
* EncoderOutput = InternalEncoderOutput;
return lsize ;
}
//==================================================================
int VideoFormat;
void SetVideoFormat(int NewVideoFormat)
{
VideoFormat = NewVideoFormat;
}
void _Fill_current_image();
int EncodeOneIntra(void)
{
extern int arith_used;
#ifndef DEBUG_DENG // orig
switch(VideoFormat)
{
case 555: RGB555toYUV411(); break;
case 565: RGB565toYUV411(); break;
case 888: RGB888toYUV411(); break;
default: RGB888toYUV411();
}
#else // deng modify
_Fill_current_image();
#endif
//advanced = NO ;
//memcpy(curr_image.lum,EncoderRGBInput,lsize*3L/2L);
bit_buf = InternalEncoderOutput ;
bit_count = 0;
pic->picture_coding_type = PCT_INTRA;
pic->QUANT = QPI;
CodeOneIntra(&curr_image, &recon_image, QPI, bits, pic);
if (arith_used)
{
bits->header += encoder_flush();
arith_used = 0;
}
bits->header += alignbits();
AddBitsPicture(bits);
memcpy(intra_bits,bits,sizeof(Bits));
ZeroBits(total_bits);
ZeroRes(total_res);
pic->QUANT = QP;
return bit_count ;
}
int EncodeOneInter(void)
{
extern int arith_used;
#ifndef DEBUG_DENG // orig
switch(VideoFormat)
{
case 555: RGB555toYUV411(); break;
case 565: RGB565toYUV411(); break;
case 888: RGB888toYUV411(); break;
default: RGB888toYUV411();
}
#else // deng modify
_Fill_current_image();
#endif
//advanced = NO ;
bit_buf = InternalEncoderOutput ;
bit_count = 0;
pic->picture_coding_type = PCT_INTER;
//pic->TR += ((frameskip*orig_frameskip) % 256); // DENG : was commented.
QP = pic->QUANT;
CodeOneOrTwo(&curr_image, &recon_image, QP, 0 , bits, pic);
if (arith_used)
{
bits->header += encoder_flush();
arith_used = 0;
}
bits->header += alignbits(); // pictures shall be byte aligned
AddBitsPicture(bits);
AddBits(total_bits, bits);
return bit_count ;
}
int SetAdvancedMode(int mode)
{
int tempmode = advanced ;
if( mode != 0 && mode!= 1 )
return tempmode ;
advanced = mode ;
return tempmode ;
}
int SetCompressRatio(int newQP)
{
int tempQP = QP ;
if( newQP < 1 || newQP > 31 ) return tempQP;
ChangableQP = newQP;
QP = newQP;
QPI = newQP;
return QP;
}
//==================================================================
void FreeEncoder(void)
{
if(hCurr_image!=NULL)
{
GlobalUnlock(hCurr_image);
GlobalFree(hCurr_image);
hCurr_image = NULL ;
}
if(hRecon_image!=NULL)
{
GlobalUnlock(hRecon_image);
GlobalFree(hRecon_image);
hRecon_image = NULL ;
}
if( hPr_edge!=NULL )
{
GlobalUnlock(hPr_edge);
GlobalFree(hPr_edge);
hPr_edge = NULL ;
}
if( hCurrRGB!=NULL )
{
GlobalUnlock(hCurrRGB);
GlobalFree(hCurrRGB);
hCurrRGB = NULL ;
}
if( hStreamBuf != NULL )
{
GlobalUnlock(hStreamBuf);
GlobalFree(hStreamBuf);
hStreamBuf = NULL ;
}
if(hMV!=NULL)
{
GlobalUnlock(hMV);
GlobalFree(hMV);
hMV = NULL ;
}
if( bits != NULL )
{
free(bits);
bits = NULL ;
}
if( total_bits != NULL )
{
free(total_bits);
total_bits = NULL ;
}
if( intra_bits != NULL )
{
free(intra_bits);
intra_bits = NULL ;
}
if( res != NULL )
{
free(res);
res = NULL ;
}
if( total_res != NULL )
{
free(total_res);
total_res = NULL ;
}
if( pic != NULL )
{
free(pic);
pic = NULL ;
}
if( recon_data_P != NULL )
{
free(recon_data_P);
recon_data_P = NULL ;
}
if( diff != NULL )
{
free(diff);
diff = NULL ;
}
}
void RGB565toYUV411()
{
long rgbPos=0;
int i,j;
int y,r,g,b,u[4],v[4];
int ImageH = lines ;
int ImageW = pels ;
unsigned int image = 0 ;
unsigned short _huge * CodeSrc ;
CodeSrc = (unsigned short _huge *)EncoderRGBInput ;
for(i=0;i<user_lines;i+=2)
{
for(j=0;j<user_pels;j+=2)
{
rgbPos = i * ImageW + j ;
r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[0] = (r - y)*127/179;
//u[0] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[0] = ((r - y)*743962)>>20;
u[0] = ((b - y)*589244)>>20;
*(curr_image.lum + rgbPos) =(unsigned char ) y;
rgbPos ++ ;
r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[1] = (r - y)*127/179;
//u[1] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[1] = ((r - y)*743962)>>20;
u[1] = ((b - y)*589244)>>20;
*(curr_image.lum+rgbPos) =(unsigned char ) y;
rgbPos += pels - 1 ;
r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[2] = (r - y)*127/179;
//u[2] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[2] = ((r - y)*743962)>>20;
u[2] = ((b - y)*589244)>>20;
*(curr_image.lum+rgbPos) = (unsigned char )y;
rgbPos ++;
r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[3] = (r - y)*127/179;
//u[3] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[3] = ((r - y)*743962)>>20;
u[3] = ((b - y)*589244)>>20;
*(curr_image.lum + rgbPos) =(unsigned char ) y;
curr_image.Cb[i*ImageW/4 +j/2] =(unsigned char ) ((u[0]+u[1]+u[2]+u[3])/4 + 0x7f);
curr_image.Cr[i*ImageW/4 +j/2] = (unsigned char )((v[0]+v[1]+v[2]+v[3])/4 + 0x7f);
}
}
}
void RGB555toYUV411()
{
long rgbPos=0;
int i,j;
int y,r,g,b,u[4],v[4];
int ImageH = lines ;
int ImageW = pels ;
unsigned int image = 0 ;
unsigned short _huge * CodeSrc ;
CodeSrc = (unsigned short _huge *)EncoderRGBInput ;
for(i=0;i<user_lines;i+=2)
{
for(j=0;j<user_pels;j+=2)
{
rgbPos = i * ImageW + j ;
r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[0] = (r - y)*127/179;
//u[0] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[0] = ((r - y)*743962)>>20;
u[0] = ((b - y)*589244)>>20;
*(curr_image.lum + rgbPos) =(unsigned char ) y;
rgbPos ++ ;
r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[1] = (r - y)*127/179;
//u[1] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[1] = ((r - y)*743962)>>20;
u[1] = ((b - y)*589244)>>20;
*(curr_image.lum+rgbPos) =(unsigned char ) y;
rgbPos += pels - 1 ;
r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[2] = (r - y)*127/179;
//u[2] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[2] = ((r - y)*743962)>>20;
u[2] = ((b - y)*589244)>>20;
*(curr_image.lum+rgbPos) = (unsigned char )y;
rgbPos ++;
r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
b = ((*(CodeSrc + rgbPos))&0x1f)<<3;
//y = 0.299*r + 0.587*g + 0.114*b;
//v[3] = (r - y)*127/179;
//u[3] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[3] = ((r - y)*743962)>>20;
u[3] = ((b - y)*589244)>>20;
*(curr_image.lum + rgbPos) =(unsigned char ) y;
curr_image.Cb[i*ImageW/4 +j/2] =(unsigned char ) ((u[0]+u[1]+u[2]+u[3])/4 + 0x7f);
curr_image.Cr[i*ImageW/4 +j/2] = (unsigned char )((v[0]+v[1]+v[2]+v[3])/4 + 0x7f);
}
}
}
void RGB888toYUV411()
{
long rgbPos=0;
int i,j;
int y,r,g,b,u[4],v[4];
int ImageH = lines ;
int ImageW = pels ;
unsigned int image = 0 ;
BYTE _huge* CodeSrc ;
CodeSrc = (BYTE _huge *)EncoderRGBInput ;
for(i=0;i<user_lines;i+=2)
{
for(j=0;j<user_pels;j+=2) //2*2
{
rgbPos = i*ImageW + j;
r = *(CodeSrc + rgbPos*3);
g = *(CodeSrc + rgbPos*3 + 1);
b = *(CodeSrc + rgbPos*3 + 2);
//y = 0.299*r + 0.587*g + 0.114*b;
//v[0] = (r - y)*127/179;
//u[0] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[0] = ((r - y)*743962)>>20;
u[0] = ((b - y)*589244)>>20;
*(curr_image.lum + rgbPos) =(unsigned char)y;
rgbPos ++;
r = *(CodeSrc + rgbPos*3);
g = *(CodeSrc + rgbPos*3 + 1);
b = *(CodeSrc + rgbPos*3 + 2);
//y = 0.299*r + 0.587*g + 0.114*b;
//v[1] = (r - y)*127/179;
//u[1] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[1] = ((r - y)*743962)>>20;
u[1] = ((b - y)*589244)>>20;
*(curr_image.lum+rgbPos) =(unsigned char ) y;
rgbPos += pels - 1 ;
r = *(CodeSrc + rgbPos*3);
g = *(CodeSrc + rgbPos*3 + 1);
b = *(CodeSrc + rgbPos*3 + 2);
//y = 0.299*r + 0.587*g + 0.114*b;
//v[2] = (r - y)*127/179;
//u[2] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[2] = ((r - y)*743962)>>20;
u[2] = ((b - y)*589244)>>20;
*(curr_image.lum+rgbPos) = (unsigned char )y;
rgbPos ++;
r = *(CodeSrc + rgbPos*3);
g = *(CodeSrc + rgbPos*3 + 1);
b = *(CodeSrc + rgbPos*3 + 2);
//y = 0.299*r + 0.587*g + 0.114*b;
//v[3] = (r - y)*127/179;
//u[3] = (b - y)*127/226;
y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
v[3] = ((r - y)*743962)>>20;
u[3] = ((b - y)*589244)>>20;
*(curr_image.lum + rgbPos) =(unsigned char ) y;
curr_image.Cb[i*ImageW/4 +j/2] =(unsigned char ) ((u[0]+u[1]+u[2]+u[3])/4 + 0x7f);
curr_image.Cr[i*ImageW/4 +j/2] = (unsigned char )((v[0]+v[1]+v[2]+v[3])/4 + 0x7f);
}
}
}
int GetH263Version(void)
{
VersionNum = 100 ;
return VersionNum;
}
//deng: add
// fill the current image buffer with YUV 4:1:1, (e.g. QCIF source format)
void _Fill_current_image()
{
int n = pels*lines;
int i,k;
k = 0;
for ( i = 0;i< n; i++)
curr_image.lum[i] = EncoderRGBInput[k++];
for ( i = 0;i< n/4; i++)
curr_image.Cb[i] = EncoderRGBInput[k++];
for ( i = 0;i< n/4; i++)
curr_image.Cr[i] = EncoderRGBInput[k++];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -