?? multi_enc.c
字號:
/************************************************************************ * * *多重編碼結構:
通過標準輸入格式讀入一系列已編碼(PGm編碼)的YUV圖片,
利用DIVX CODEC進行編碼并寫入按一定幀率寫入指定文件中
************************************************************************/#include <stdio.h>#include <malloc.h>#include <stdlib.h>#include "encore.h"#define MY_APP_ID 0x0815 // doesn't matter#define XDIM 320#define YDIM 240#define BUFFERSIZE 1512000 // This should be more than enough for 1 frame#define MAXFILENR 200 // number of framesstatic float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256];
static float RGBYUV01684[256], RGBYUV03316[256];
static float RGBYUV04187[256], RGBYUV00813[256];
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
# define CLIP(a,i,s) (((a) > (s)) ? (s) : MAX(a,i))
/************************************************************************
*
* int RGB2YUV (int x_dim, int y_dim, void *bmp, YUV *yuv)
*
* Purpose : It takes a 24-bit RGB bitmap and convert it into
* YUV (4:2:0) format
*
* Input : x_dim the x dimension of the bitmap
* y_dim the y dimension of the bitmap
* bmp pointer to the buffer of the bitmap
* yuv pointer to the YUV structure
*
* Output : 0 OK
* 1 wrong dimension
* 2 memory allocation error
*
* Side Effect :
* None
************************************************************************/
void InitLookupTable()
{
int i;
for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i;
for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i;
for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i;
for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i;
for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i;
for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i;
for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i;
}
int convertRGB (void *bmp, void *yuv, long type, long x_dim, long y_dim)
{
static int init_done = 0;
long i, j, size, stride;
unsigned char *r, *g, *b;
unsigned char *y, *u, *v;
unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv;
unsigned char *y_buffer, *u_buffer, *v_buffer;
unsigned char *sub_u_buf, *sub_v_buf;
if (init_done == 0)
{
InitLookupTable();
init_done = 1;
}
// check to see if x_dim and y_dim are divisible by 2
if ((x_dim % 2) || (y_dim % 2)) return 1;
size = x_dim * y_dim;
if (type == 17) stride = 3;
else if (type == 18) stride = 4;
// allocate memory
y_buffer = (unsigned char *)yuv;
sub_u_buf = y_buffer + size;
sub_v_buf = y_buffer + size * 5 / 4;
u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
if (!(u_buffer && v_buffer))
{
if (u_buffer) free(u_buffer);
if (v_buffer) free(v_buffer);
return 2;
}
b = (unsigned char *)bmp;
y = y_buffer;
u = u_buffer;
v = v_buffer;
// convert RGB to YUV
for (j = 0; j < y_dim; j ++)
{
y = y_buffer + (y_dim - j - 1) * x_dim;
u = u_buffer + (y_dim - j - 1) * x_dim;
v = v_buffer + (y_dim - j - 1) * x_dim;
for (i = 0; i < x_dim; i ++) {
g = b + 1;
r = b + 2;
*y = (unsigned char)CLIP (( RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]), 0, 255.f);
*u = (unsigned char)CLIP ((- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2 + 128), 0, 255.f);
*v = (unsigned char)CLIP (( (*r)/2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128), 0, 255.f);
b += stride;
y ++;
u ++;
v ++;
}
}
// subsample UV
for (j = 0; j < y_dim/2; j ++)
{
psu = sub_u_buf + j * x_dim / 2;
psv = sub_v_buf + j * x_dim / 2;
pu1 = u_buffer + 2 * j * x_dim;
pu2 = u_buffer + (2 * j + 1) * x_dim;
pv1 = v_buffer + 2 * j * x_dim;
pv2 = v_buffer + (2 * j + 1) * x_dim;
for (i = 0; i < x_dim/2; i ++)
{
*psu = (*pu1 + *(pu1+1) + *pu2 + *(pu2+1)) / 4;
*psv = (*pv1 + *(pv1+1) + *pv2 + *(pv2+1)) / 4;
psu ++;
psv ++;
pu1 += 2;
pu2 += 2;
pv1 += 2;
pv2 += 2;
}
}
free(u_buffer);
free(v_buffer);
return 0;
}
int main(){
FILE *f_in; char *bmp_buffer;
char *divx_buffer; char *yuv_buffer; char *in_buffer[3];
int status; int frame_size; FILE* filehandle; int filenr; char filename[80]; ENC_PARAM enc_param; ENC_FRAME enc_frame; ENC_RESULT enc_result; frame_size = XDIM*YDIM + XDIM/2*YDIM/2 + XDIM/2*YDIM/2; // full Y, subsamples U,V/* ...skip check for malloc failure... don't do that in application!!! */ bmp_buffer=(char*) malloc(3*XDIM*YDIM); yuv_buffer=(char*) malloc(frame_size); divx_buffer=(char*) malloc(BUFFERSIZE); /*********************************************************************//* DIVX PART Start *//*********************************************************************//* Init the encoder */ enc_param.x_dim = XDIM; enc_param.y_dim = YDIM; enc_param.framerate = 24.0; enc_param.bitrate = 900000; enc_param.rc_period = 300; //2000; enc_param.rc_reaction_period = 10; enc_param.rc_reaction_ratio = 20; enc_param.search_range = 128; //128; enc_param.max_quantizer = 15; enc_param.min_quantizer = 2;//1; // these setting are explained in the // "Encoder"-forum at www.projectmayo.com status = encore(MY_APP_ID, ENC_OPT_INIT, &enc_param, NULL); fprintf(stderr,"Encore INIT return %d\n",status);/*********************************************************************//* Main Part *//*********************************************************************/ for (filenr=1;filenr<MAXFILENR;filenr++) // main loop over frames {///* read raw YUV from stdin */ sprintf(filename,"bmp%05d.bmp",filenr);
f_in=fopen(filename,"rb"); fseek(f_in,54L,0); // skip PGM header, we don't need it here fread(bmp_buffer,XDIM,YDIM*3,f_in); // read YUV-data fclose(f_in);/* Encode one frame */ in_buffer[0]=yuv_buffer;
in_buffer[1]=yuv_buffer + XDIM*YDIM;
in_buffer[2]=yuv_buffer + XDIM*YDIM + XDIM/2*YDIM/2;
convertRGB (bmp_buffer, yuv_buffer, 17, XDIM, YDIM);
enc_frame.image = (void *) yuv_buffer; enc_frame.bitstream = (void *) divx_buffer; enc_frame.length = 0; // will be filled by routine status = encore(MY_APP_ID, ENC_OPT_WRITE, &enc_frame, &enc_result); // fprintf(stderr,"Frame %d:\nEncore ENCODE return %d, divx-stream length=%ld bytes\n",filenr,status,enc_frame.length);// fprintf(stderr,"Encore RESULT IsKeyFrame=%d\n",enc_result.isKeyFrame);/* Write encoded data to stdout */ sprintf(filename,"frame%05d.divx",filenr); filehandle = fopen(filename,"wb"); if (!filehandle) { fprintf(stderr,"Error writing file!\n"); return 2; } fwrite(divx_buffer,1,enc_frame.length,filehandle); fclose(filehandle); } // end of for-loop over all frames /*********************************************************************//* DIVX PART Stop *//*********************************************************************//* Stop the encoder */ status = encore(MY_APP_ID, ENC_OPT_RELEASE, &enc_frame, NULL); // END Encoding fprintf(stderr,"Encore RELEASE return %d\n",status); free(divx_buffer); free(yuv_buffer); free(bmp_buffer);
return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -