encore.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:9k
- #include "encore.h"
- #include "vop_code.h"
- #include "text_dct.h"
- #include "bitstream.h"
- #include "vm_common_defs.h"
- #include "rate_ctl.h"
- typedef struct _REFERENCE
- {
- unsigned long handle;
- float framerate;
- long bitrate;
- long rc_period;
- long rc_reaction_period;
- long rc_reaction_ratio;
- long max_key_interval;
- int x_dim, y_dim;
- int prev_rounding;
- int search_range;
- int max_quantizer;
- int min_quantizer;
- long seq;
- long curr_run;
- Vop *current;
- Vop *reference;
- Vop *reconstruct;
- Vop *error;
- struct _REFERENCE *pnext;
- } REFERENCE;
- FILE *ftrace = NULL;
- int max_quantizer, min_quantizer;
- void init_vol_config(VolConfig *vol_config);
- void init_vop(Vop *vop);
- Int get_fcode (Int sr);
- int PutVoVolHeader(int vol_width, int vol_height, int time_increment_resolution, float frame_rate);
- int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out);
- int encore(unsigned long handle, unsigned long enc_opt, void *param1, void *param2)
- {
- static REFERENCE *ref = NULL;
- static VolConfig *vol_config;
-
- REFERENCE *ref_curr, *ref_last = NULL;
- int x_dim, y_dim, size, length;
- int headerbits = 0;
- Vop *curr;
- ref_curr = ref_last = ref;
- while (ref_curr != NULL)
- {
- if (ref_curr->handle == handle) break;
- ref_last = ref_curr;
- ref_curr = ref_last->pnext;
- }
-
- if (ref_curr == NULL)
- {
- if (enc_opt & ENC_OPT_RELEASE) return ENC_OK;
- ref_curr = (REFERENCE *)malloc(sizeof(REFERENCE));
- ref_curr->handle = handle;
- ref_curr->seq = 0;
- ref_curr->curr_run = 0;
- ref_curr->pnext = NULL;
- if (ref) ref_last->pnext = ref_curr;
- else ref = ref_curr;
- }
-
- if (enc_opt & ENC_OPT_INIT)
- {
- #ifdef _RC_
- ftrace = fopen("trace.txt", "w");
- fflush(ftrace);
- #endif
- init_fdct_enc();
- init_idct_enc();
-
- ref_curr->framerate = ((ENC_PARAM *)param1)->framerate;
- ref_curr->bitrate = ((ENC_PARAM *)param1)->bitrate;
- ref_curr->rc_period = ((ENC_PARAM *)param1)->rc_period;
- ref_curr->rc_reaction_period = ((ENC_PARAM *)param1)->rc_reaction_period;
- ref_curr->rc_reaction_ratio = ((ENC_PARAM *)param1)->rc_reaction_ratio;
- ref_curr->x_dim = ((ENC_PARAM *)param1)->x_dim;
- ref_curr->y_dim = ((ENC_PARAM *)param1)->y_dim;
- ref_curr->max_key_interval = ((ENC_PARAM *)param1)->max_key_interval;
- ref_curr->search_range = ((ENC_PARAM *)param1)->search_range;
- ref_curr->max_quantizer = ((ENC_PARAM *)param1)->max_quantizer;
- ref_curr->min_quantizer = ((ENC_PARAM *)param1)->min_quantizer;
- ref_curr->current = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
- ref_curr->reference = AllocVop(ref_curr->x_dim + 2 * 16,
- ref_curr->y_dim + 2 * 16);
- ref_curr->reconstruct = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
- ref_curr->error = AllocVop(ref_curr->x_dim, ref_curr->y_dim);
- init_vop(ref_curr->current);
- init_vop(ref_curr->reference);
- init_vop(ref_curr->reconstruct);
- init_vop(ref_curr->error);
- ref_curr->reference->hor_spat_ref = -16;
- ref_curr->reference->ver_spat_ref = -16;
- SetConstantImage(ref_curr->reference->y_chan, 0);
- vol_config = (VolConfig *)malloc(sizeof(VolConfig));
- init_vol_config(vol_config);
- vol_config->frame_rate = ref_curr->framerate;
- vol_config->bit_rate = ref_curr->bitrate;
- RateCtlInit(8 , vol_config->bit_rate / vol_config->frame_rate,
- ref_curr->rc_period, ref_curr->rc_reaction_period, ref_curr->rc_reaction_ratio);
- return ENC_OK;
- }
-
- if (enc_opt & ENC_OPT_RELEASE)
- {
- if (ref_curr == ref) ref = NULL;
- else ref_last->pnext = ref_curr->pnext;
- if (ref_curr->current) FreeVop(ref_curr->current);
- if (ref_curr->reference) FreeVop(ref_curr->reference);
- if (ref_curr->reconstruct) FreeVop(ref_curr->reconstruct);
- if (ref_curr->error) FreeVop(ref_curr->error);
- free(ref_curr);
- free(vol_config);
- if (ftrace) {
- fclose(ftrace);
- ftrace = NULL;
- };
- return ENC_OK;
- }
-
- max_quantizer = ref_curr->max_quantizer;
- min_quantizer = ref_curr->min_quantizer;
- x_dim = ref_curr->x_dim;
- y_dim = ref_curr->y_dim;
- size = x_dim * y_dim;
- curr = ref_curr->current;
- curr->width = x_dim;
- curr->height = y_dim;
- curr->sr_for = ref_curr->search_range;
- curr->fcode_for = get_fcode(curr->sr_for);
-
-
- YUV2YUV(x_dim, y_dim, ((ENC_FRAME *)param1)->image,
- curr->y_chan->f, curr->u_chan->f, curr->v_chan->f);
-
- curr->rounding_type = 1 - ref_curr->prev_rounding;
- Bitstream_Init((void *)(((ENC_FRAME *)param1)->bitstream));
- if (ref_curr->seq == 0) {
- headerbits = PutVoVolHeader(x_dim, y_dim, curr->time_increment_resolution, ref_curr->framerate);
- }
-
- #ifdef _RC_
- fflush(ftrace);
- fprintf(ftrace, "nCoding frame #%dn", ref_curr->seq);
- #endif
- if (ref_curr->curr_run % ref_curr->max_key_interval == 0) {
- curr->prediction_type = I_VOP;
- #ifdef _RC_
- fprintf(ftrace, "This frame is forced to be coded in INTRA.n");
- fprintf(ftrace, "It has been %d frame since the last INTRA.n", ref_curr->curr_run);
- #endif
- }
- else curr->prediction_type = P_VOP;
-
- VopCode(curr,
- ref_curr->reference,
- ref_curr->reconstruct,
- ref_curr->error,
- 1,
- (float)ref_curr->seq/ref_curr->framerate,
- vol_config);
- length = Bitstream_Close();
- ((ENC_FRAME *)param1)->length = length;
-
- RateCtlUpdate(length * 8);
- ref_curr->prev_rounding = curr->rounding_type;
- ref_curr->seq ++;
- ref_curr->curr_run ++;
- if (curr->prediction_type == I_VOP) {
- ((ENC_RESULT *)param2)->isKeyFrame = 1;
- ref_curr->curr_run = 1;
- } else
- ((ENC_RESULT *)param2)->isKeyFrame = 0;
- return ENC_OK;
- }
- void init_vol_config(VolConfig *vol_config)
- {
-
- vol_config->M = 1;
- vol_config->frame_skip = 1;
- vol_config->quantizer = 8;
- vol_config->intra_quantizer = 8;
- vol_config->modulo_time_base[0] =0;
- vol_config->modulo_time_base[1] =0;
- vol_config->frame_rate = 30;
- vol_config->bit_rate = 800000;
- }
- void init_vop(Vop *vop)
- {
-
- vop->quant_precision = 5;
- vop->bits_per_pixel = 8;
- vop->time_increment_resolution = 30000;
- vop->intra_acdc_pred_disable = 0;
- vop->intra_dc_vlc_thr = 0;
- vop->sr_for = 512;
- vop->fcode_for = get_fcode(512);
- vop->y_chan->type = SHORT_TYPE;
- vop->u_chan->type = SHORT_TYPE;
- vop->v_chan->type = SHORT_TYPE;
- vop->hor_spat_ref = 0;
- vop->ver_spat_ref = 0;
- }
- Int get_fcode (Int sr)
- {
- if (sr<=16) return 1;
- else if (sr<=32) return 2;
- else if (sr<=64) return 3;
- else if (sr<=128) return 4;
- else if (sr<=256) return 5;
- else if (sr<=512) return 6;
- else if (sr<=1024) return 7;
- else return (-1);
- }
- int PutVoVolHeader(int vol_width, int vol_height, int time_increment_resolution, float frame_rate)
- {
- int written = 0;
- int bits, fixed_vop_time_increment;
- Bitstream_PutBits(VO_START_CODE_LENGTH, VO_START_CODE);
- Bitstream_PutBits(5, 0);
- written += VO_START_CODE_LENGTH + 5;
- Bitstream_PutBits(VOL_START_CODE_LENGTH, VOL_START_CODE);
- Bitstream_PutBits(4, 0);
- written += VOL_START_CODE_LENGTH + 4;
- Bitstream_PutBits(1, 0);
- Bitstream_PutBits(8, 1);
- Bitstream_PutBits(1, 1);
- Bitstream_PutBits(4, 2);
- Bitstream_PutBits(3, 1);
- written += 1 + 8 + 1 + 4 + 3;
- Bitstream_PutBits(4, 1);
- Bitstream_PutBits(1, 0);
- Bitstream_PutBits(2, 0);
- Bitstream_PutBits(1, 1);
- written += 4 + 1 + 2 + 1;
- Bitstream_PutBits(16, time_increment_resolution);
- Bitstream_PutBits(1, 1);
- Bitstream_PutBits(1, 1);
- bits = (int)ceil(log((double)time_increment_resolution)/log(2.0));
- if (bits<1) bits=1;
- fixed_vop_time_increment = (int)(time_increment_resolution / frame_rate + 0.1);
- Bitstream_PutBits(bits, fixed_vop_time_increment);
- Bitstream_PutBits(1, 1);
- written += 16 + 1 + 1 + bits + 1;
- Bitstream_PutBits(13, vol_width);
- Bitstream_PutBits(1, 1);
- Bitstream_PutBits(13, vol_height);
- Bitstream_PutBits(1, 1);
- written += 13 + 1 + 13 + 1;
- Bitstream_PutBits(1, 0);
- Bitstream_PutBits(1, 1);
- Bitstream_PutBits(2, 0);
- Bitstream_PutBits(1, 0);
- written += 1 + 1 + 2 + 1;
- Bitstream_PutBits(1, 0);
- Bitstream_PutBits(1, 0);
- Bitstream_PutBits(1, 1);
- Bitstream_PutBits(1, 1);
- Bitstream_PutBits(1, 0);
- Bitstream_PutBits(1, 0);
- written += 1 + 1 + 1 + 1 + 1 + 1;
- written += Bitstream_NextStartCode();
- return(written);
- }
- int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out)
- {
-
-
- unsigned char *in;
- short int *out;
- long size;
- in = yuv;
-
- out = y_out;
- size = x_dim * y_dim;
- while (size --) *(out ++) = *(in ++);
- out = u_out;
- size = x_dim * y_dim / 4;
- while (size --) *(out ++) = *(in ++);
- out = v_out;
- size = x_dim * y_dim / 4;
- while (size --) *(out ++) = *(in ++);
- return 0;
- }