00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "encore.h"
00041
00042 #include "vop_code.h"
00043 #include "text_dct.h"
00044
00045 #include "bitstream.h"
00046 #include "vm_common_defs.h"
00047
00048 #include "rate_ctl.h"
00049
00050 typedef struct _REFERENCE
00051 {
00052 unsigned long handle;
00053 float framerate;
00054 long bitrate;
00055 long rc_period;
00056 long rc_reaction_period;
00057 long rc_reaction_ratio;
00058 long max_key_interval;
00059 int x_dim, y_dim;
00060 int prev_rounding;
00061 int search_range;
00062 int max_quantizer;
00063 int min_quantizer;
00064
00065 long seq;
00066 long curr_run;
00067
00068 Vop *current;
00069 Vop *reference;
00070 Vop *reconstruct;
00071 Vop *error;
00072
00073 struct _REFERENCE *pnext;
00074 } REFERENCE;
00075
00076 FILE *ftrace = NULL;
00077 int max_quantizer, min_quantizer;
00078
00079
00080 void init_vol_config(VolConfig *vol_config);
00081 void init_vop(Vop *vop);
00082 Int get_fcode (Int sr);
00083 int PutVoVolHeader(int vol_width, int vol_height, int time_increment_resolution, float frame_rate);
00084 int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out);
00085
00086
00087
00088 void encore_set_global(ENC_PARAM *param)
00089 {
00090 }
00091
00092
00093 int encore(unsigned long handle,
00094 unsigned long enc_opt,
00095 void *param1,
00096 void *param2)
00097 {
00098 static REFERENCE *ref = NULL;
00099 static VolConfig *vol_config;
00100
00101
00102 REFERENCE *ref_curr, *ref_last = NULL;
00103 int x_dim, y_dim, size, length;
00104 int headerbits = 0;
00105 Vop *curr;
00106
00107 ref_curr = ref_last = ref;
00108
00109
00110 while (ref_curr != NULL)
00111 {
00112 if (ref_curr->handle == handle) break;
00113 ref_last = ref_curr;
00114 ref_curr = ref_last->pnext;
00115 }
00116
00117 if (ref_curr == NULL)
00118 {
00119 if (enc_opt & ENC_OPT_RELEASE) return ENC_OK;
00120 ref_curr = (REFERENCE *)malloc(sizeof(REFERENCE));
00121 ref_curr->handle = handle;
00122 ref_curr->seq = 0;
00123 ref_curr->curr_run = 0;
00124 ref_curr->pnext = NULL;
00125 if (ref) ref_last->pnext = ref_curr;
00126 else ref = ref_curr;
00127 }
00128
00129
00130 if (enc_opt & ENC_OPT_INIT)
00131 {
00132 #ifdef _RC_
00133 ftrace = fopen("trace.txt", "w");
00134 fflush(ftrace);
00135 #endif
00136
00137 init_fdct_enc();
00138 init_idct_enc();
00139
00140
00141 ref_curr->framerate = ((ENC_PARAM *)param1)->framerate;
00142 ref_curr->bitrate = ((ENC_PARAM *)param1)->bitrate;
00143 ref_curr->rc_period = ((ENC_PARAM *)param1)->rc_period;
00144 ref_curr->rc_reaction_period = ((ENC_PARAM *)param1)->rc_reaction_period;
00145 ref_curr->rc_reaction_ratio = ((ENC_PARAM *)param1)->rc_reaction_ratio;
00146 ref_curr->x_dim = ((ENC_PARAM *)param1)->x_dim;
00147 ref_curr->y_dim = ((ENC_PARAM *)param1)->y_dim;
00148 ref_curr->max_key_interval = ((ENC_PARAM *)param1)->max_key_interval;
00149 ref_curr->search_range = ((ENC_PARAM *)param1)->search_range;
00150 ref_curr->max_quantizer = ((ENC_PARAM *)param1)->max_quantizer;
00151 ref_curr->min_quantizer = ((ENC_PARAM *)param1)->min_quantizer;
00152
00153 ref_curr->current = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
00154 ref_curr->reference = AllocVop(ref_curr->x_dim + 2 * 16,
00155 ref_curr->y_dim + 2 * 16);
00156 ref_curr->reconstruct = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
00157 ref_curr->error = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
00158 init_vop(ref_curr->current);
00159 init_vop(ref_curr->reference);
00160 init_vop(ref_curr->reconstruct);
00161 init_vop(ref_curr->error);
00162 ref_curr->reference->hor_spat_ref = -16;
00163 ref_curr->reference->ver_spat_ref = -16;
00164 SetConstantImage(ref_curr->reference->y_chan, 0);
00165
00166 vol_config = (VolConfig *)malloc(sizeof(VolConfig));
00167 init_vol_config(vol_config);
00168 vol_config->frame_rate = ref_curr->framerate;
00169 vol_config->bit_rate = ref_curr->bitrate;
00170
00171 RateCtlInit(8 , vol_config->bit_rate / vol_config->frame_rate,
00172 ref_curr->rc_period, ref_curr->rc_reaction_period, ref_curr->rc_reaction_ratio);
00173
00174 return ENC_OK;
00175 }
00176
00177
00178 if (enc_opt & ENC_OPT_RELEASE)
00179 {
00180 if (ref_curr == ref) ref = NULL;
00181 else ref_last->pnext = ref_curr->pnext;
00182
00183 if (ref_curr->current) FreeVop(ref_curr->current);
00184 if (ref_curr->reference) FreeVop(ref_curr->reference);
00185 if (ref_curr->reconstruct) FreeVop(ref_curr->reconstruct);
00186 if (ref_curr->error) FreeVop(ref_curr->error);
00187
00188 free(ref_curr);
00189 free(vol_config);
00190 if (ftrace) {
00191 fclose(ftrace);
00192 ftrace = NULL;
00193 };
00194 return ENC_OK;
00195 }
00196
00197
00198
00199
00200 max_quantizer = ref_curr->max_quantizer;
00201 min_quantizer = ref_curr->min_quantizer;
00202
00203 x_dim = ref_curr->x_dim;
00204 y_dim = ref_curr->y_dim;
00205 size = x_dim * y_dim;
00206
00207 curr = ref_curr->current;
00208 curr->width = x_dim;
00209 curr->height = y_dim;
00210 curr->sr_for = ref_curr->search_range;
00211 curr->fcode_for = get_fcode(curr->sr_for);
00212
00213
00214
00215 YUV2YUV(x_dim, y_dim, ((ENC_FRAME *)param1)->image,
00216 curr->y_chan->f,
00217 curr->u_chan->f,
00218 curr->v_chan->f);
00219
00220
00221 curr->rounding_type = 1 - ref_curr->prev_rounding;
00222
00223
00224 Bitstream_Init((void *)(((ENC_FRAME *)param1)->bitstream));
00225
00226
00227 if (ref_curr->seq == 0)
00228 {
00229 headerbits = PutVoVolHeader(x_dim,
00230 y_dim,
00231 curr->time_increment_resolution,
00232 ref_curr->framerate);
00233 }
00234
00235
00236 #ifdef _RC_
00237 fflush(ftrace);
00238 fprintf(ftrace, "\nCoding frame #%d\n", ref_curr->seq);
00239 #endif
00240
00241
00242 if (ref_curr->curr_run % ref_curr->max_key_interval == 0) {
00243 curr->prediction_type = I_VOP;
00244 #ifdef _RC_
00245 fprintf(ftrace, "This frame is forced to be coded in INTRA.\n");
00246 fprintf(ftrace, "It has been %d frame since the last INTRA.\n", ref_curr->curr_run);
00247 #endif
00248 }
00249 else curr->prediction_type = P_VOP;
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 VopCode(curr,
00262 ref_curr->reference,
00263 ref_curr->reconstruct,
00264 ref_curr->error,
00265 1,
00266 (float)ref_curr->seq/ref_curr->framerate,
00267 vol_config,
00268 ((ENC_FRAME *)param1)->quant);
00269
00270
00271
00272
00273
00274
00275
00276 length = Bitstream_Close();
00277 ((ENC_FRAME *)param1)->length = length;
00278
00279
00280
00281 RateCtlUpdate(length * 8);
00282
00283 ref_curr->prev_rounding = curr->rounding_type;
00284 ref_curr->seq ++;
00285 ref_curr->curr_run ++;
00286
00287 if (curr->prediction_type == I_VOP) {
00288 ((ENC_RESULT *)param2)->isKeyFrame = 1;
00289 ref_curr->curr_run = 1;
00290 } else
00291 ((ENC_RESULT *)param2)->isKeyFrame = 0;
00292
00293
00294 return ENC_OK;
00295 }
00296
00297
00298 void init_vol_config(VolConfig *vol_config)
00299 {
00300
00301 vol_config->M = 1;
00302 vol_config->frame_skip = 1;
00303 vol_config->quantizer = 8;
00304 vol_config->intra_quantizer = 8;
00305 vol_config->modulo_time_base[0] =0;
00306 vol_config->modulo_time_base[1] =0;
00307 vol_config->frame_rate = 30;
00308 vol_config->bit_rate = 800000;
00309 }
00310
00311
00312 void init_vop(Vop *vop)
00313 {
00314
00315 vop->quant_precision = 5;
00316 vop->bits_per_pixel = 8;
00317
00318 vop->time_increment_resolution = 30000;
00319 vop->intra_acdc_pred_disable = 0;
00320 vop->intra_dc_vlc_thr = 0;
00321
00322 vop->sr_for = 512;
00323 vop->fcode_for = get_fcode(512);
00324
00325 vop->y_chan->type = SHORT_TYPE;
00326 vop->u_chan->type = SHORT_TYPE;
00327 vop->v_chan->type = SHORT_TYPE;
00328
00329 vop->hor_spat_ref = 0;
00330 vop->ver_spat_ref = 0;
00331
00332 }
00333
00334 Int get_fcode (Int sr)
00335 {
00336 if (sr<=16) return 1;
00337 else if (sr<=32) return 2;
00338 else if (sr<=64) return 3;
00339 else if (sr<=128) return 4;
00340 else if (sr<=256) return 5;
00341 else if (sr<=512) return 6;
00342 else if (sr<=1024) return 7;
00343 else return (-1);
00344 }
00345
00346 int PutVoVolHeader(int vol_width,
00347 int vol_height,
00348 int time_increment_resolution,
00349 float frame_rate)
00350 {
00351 int written = 0;
00352 int bits, fixed_vop_time_increment;
00353
00354 Bitstream_PutBits(VO_START_CODE_LENGTH, VO_START_CODE);
00355 Bitstream_PutBits(5, 0);
00356 written += VO_START_CODE_LENGTH + 5;
00357
00358 Bitstream_PutBits(VOL_START_CODE_LENGTH, VOL_START_CODE);
00359 Bitstream_PutBits(4, 0);
00360 written += VOL_START_CODE_LENGTH + 4;
00361
00362 Bitstream_PutBits(1, 0);
00363 Bitstream_PutBits(8, 1);
00364 Bitstream_PutBits(1, 1);
00365 Bitstream_PutBits(4, 2);
00366 Bitstream_PutBits(3, 1);
00367 written += 1 + 8 + 1 + 4 + 3;
00368
00369 Bitstream_PutBits(4, 1);
00370
00371
00372
00373
00374
00375
00376
00377 Bitstream_PutBits(1, 0);
00378 Bitstream_PutBits(2, 0);
00379 Bitstream_PutBits(1, 1);
00380 written += 4 + 1 + 2 + 1;
00381
00382 Bitstream_PutBits(16, time_increment_resolution);
00383 Bitstream_PutBits(1, 1);
00384 Bitstream_PutBits(1, 1);
00385 bits = (int)ceil(log((double)time_increment_resolution)/log(2.0));
00386 if (bits<1) bits=1;
00387 fixed_vop_time_increment = (int)(time_increment_resolution / frame_rate + 0.1);
00388 Bitstream_PutBits(bits, fixed_vop_time_increment);
00389 Bitstream_PutBits(1, 1);
00390 written += 16 + 1 + 1 + bits + 1;
00391
00392 Bitstream_PutBits(13, vol_width);
00393 Bitstream_PutBits(1, 1);
00394 Bitstream_PutBits(13, vol_height);
00395 Bitstream_PutBits(1, 1);
00396 written += 13 + 1 + 13 + 1;
00397
00398 Bitstream_PutBits(1, 0);
00399 Bitstream_PutBits(1, 1);
00400 Bitstream_PutBits(2, 0);
00401 Bitstream_PutBits(1, 0);
00402 written += 1 + 1 + 2 + 1;
00403
00404 Bitstream_PutBits(1, 0);
00405 Bitstream_PutBits(1, 0);
00406 Bitstream_PutBits(1, 1);
00407 Bitstream_PutBits(1, 1);
00408 Bitstream_PutBits(1, 0);
00409 Bitstream_PutBits(1, 0);
00410 written += 1 + 1 + 1 + 1 + 1 + 1;
00411
00412 written += Bitstream_NextStartCode();
00413
00414 return(written);
00415 }
00416
00417 int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out)
00418 {
00419
00420
00421 unsigned char *in;
00422 short int *out;
00423 long size;
00424
00425 in = yuv;
00426
00427 out = y_out;
00428 size = x_dim * y_dim;
00429 while (size --) *(out ++) = *(in ++);
00430
00431 out = u_out;
00432 size = x_dim * y_dim / 4;
00433 while (size --) *(out ++) = *(in ++);
00434
00435 out = v_out;
00436 size = x_dim * y_dim / 4;
00437 while (size --) *(out ++) = *(in ++);
00438
00439 return 0;
00440 }
00441