self.c~
来自「实现在linux下的mpeg4编解码」· C~ 代码 · 共 893 行 · 第 1/2 页
C~
893 行
ref_curr = ref_last = ref; while (ref_curr != NULL) { if (ref_curr->handle == handle) break; ref_last = ref_curr; ref_curr = ref_last->pnext; } // create a reference for the new handle when no match is found 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; } // initialize for a handle if requested if (enc_opt & ENC_OPT_INIT) {#ifdef _RC_ ftrace = fopen("trace.txt", "w"); fflush(ftrace);#endif init_fdct_enc(); init_idct_enc(); // initializing rate control 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 /* initial quant*/, 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; } // release the reference associated with the handle if requested 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; } // initialize the parameters (need to be cleaned later) 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); // do transformation for the input image // this is needed because the legacy MoMuSys code uses short int for each data YUV2YUV(x_dim, y_dim, ((ENC_FRAME *)param1)->image, curr->y_chan->f, curr->u_chan->f, curr->v_chan->f); // adjust the rounding_type for the current image 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 #%d\n", 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; // Code the image data (YUV) of the current image VopCode(curr, ref_curr->reference, ref_curr->reconstruct, ref_curr->error, 1, //enable_8x8_mv, (float)ref_curr->seq/ref_curr->framerate, // time vol_config); length = Bitstream_Close(); ((ENC_FRAME *)param1)->length = length; // update the rate control parameters 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;}int encode(char infile[],char outfile[])//for encode{ printf("待编码文件%s\n",infile); printf("编码后文件%s\n",outfile); printf("读入文件\n"); FILE *f_in = fopen(infile,"rb"); FILE *f_out= fopen(outfile,"wb"); printf("设置参数值\n"); ENC_PARAM encParam; encParam.x_dim = 352; encParam.y_dim = 288; encParam.framerate=30; encParam.bitrate=800000; encParam.rc_period=200; encParam.rc_reaction_period=10; encParam.rc_reaction_ratio=20; encParam.max_key_interval=300; encParam.max_quantizer=16; encParam.min_quantizer=1; encParam.search_range=15; printf("编码前检测\n"); encore(1, ENC_OPT_INIT, &encParam, NULL);// startTimer(); clock_t start, finish; double duration; printf("开始计时\n"); start = clock(); // decode frames { printf("编码参数配置"); int size=encParam.x_dim*encParam.y_dim*3/2; int frames,i; ENC_FRAME encFrame; ENC_RESULT Result; encFrame.image=(void *)malloc(size); // encFrame.bitstream=NULL; encFrame.bitstream=(void *)malloc(size); encFrame.length=0; Result.isKeyFrame=0; printf("待编码文件重读入\n"); fseek(f_in,0,SEEK_END); frames=ftell(f_in)/size; fseek(f_in,0,SEEK_SET); rewind(f_in); printf("编码中。。。\n"); for(i=0;i<frames;i++) { fread((char *)encFrame.image,1,size,f_in); if(encore(1,ENC_OPT_WRITE, &encFrame, &Result) != ENC_OK) //编码时有错误检测 { printf("Error accurs when encode Frame %d\n",i); return 0; } fwrite((char *)encFrame.bitstream,1,encFrame.length,f_out); } } encore(1, ENC_OPT_RELEASE, NULL, NULL); printf("关闭文件\n"); fclose(f_in); fclose(f_out); finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "总共耗时%f秒 \n ", duration ); // stopTimer();// displayTimer(mp4_state->hdr.picnum);}int main (int argc, char *argv[],char argn[]){ if(argc == 1) { printf("用法:./mp4enc 目标文件名 生成文件名 n(1表示编码2解码)"); } if(strcmp(argv[3],"enc")==0) { encode(argv[1],argv[2]); } else if(strcmp(argv[3],"dec")==0) {printf("jie"); decode(argv[1],argv[2]); } return 1;}void init_vol_config(VolConfig *vol_config){ /* configure VOL */ 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){ /* initialize VOPs */ vop->quant_precision = 5; vop->bits_per_pixel = 8;// vop->time_increment_resolution = 15 ; 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); /* vo_id = 0 */ written += VO_START_CODE_LENGTH + 5; Bitstream_PutBits(VOL_START_CODE_LENGTH, VOL_START_CODE); Bitstream_PutBits(4, 0); /* vol_id = 0 */ written += VOL_START_CODE_LENGTH + 4; Bitstream_PutBits(1, 0); /* random_accessible_vol = 0 */ Bitstream_PutBits(8, 1); /* video_object_type_indication = 1 video */ Bitstream_PutBits(1, 1); /* is_object_layer_identifier = 1 */ Bitstream_PutBits(4, 2); /* visual_object_layer_ver_id = 2 */ Bitstream_PutBits(3, 1); /* visual_object_layer_priority = 1 */ written += 1 + 8 + 1 + 4 + 3; Bitstream_PutBits(4, 1); /* aspect_ratio_info = 1 */ Bitstream_PutBits(1, 0); /* vol_control_parameter = 0 */ Bitstream_PutBits(2, 0); /* vol_shape = 0 rectangular */ Bitstream_PutBits(1, 1); /* marker */ written += 4 + 1 + 2 + 1; Bitstream_PutBits(16, time_increment_resolution); Bitstream_PutBits(1, 1); /* marker */ Bitstream_PutBits(1, 1); /* fixed_vop_rate = 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); /* marker */ written += 16 + 1 + 1 + bits + 1; Bitstream_PutBits(13, vol_width); Bitstream_PutBits(1, 1); /* marker */ Bitstream_PutBits(13, vol_height); Bitstream_PutBits(1, 1); /* marker */ written += 13 + 1 + 13 + 1; Bitstream_PutBits(1, 0); /* interlaced = 0 */ Bitstream_PutBits(1, 1); /* OBMC_disabled = 1 */ Bitstream_PutBits(2, 0); /* vol_sprite_usage = 0 */ Bitstream_PutBits(1, 0); /* not_8_bit = 0 */ written += 1 + 1 + 2 + 1; Bitstream_PutBits(1, 0); /* vol_quant_type = 0 */ Bitstream_PutBits(1, 0); /* vol_quarter_pixel = 0 */ Bitstream_PutBits(1, 1); /* complexity_estimation_disabled = 1 */ Bitstream_PutBits(1, 1); /* resync_marker_disabled = 1 */ Bitstream_PutBits(1, 0); /* data_partitioning_enabled = 0 */ Bitstream_PutBits(1, 0); /* scalability = 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){ // All this conversion does is to turn data from unsigned char to short int, // since legacy MoMuSys uses short int. 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;}static void options (int *argcp, char **argvp[]){ (*argvp)++; (*argcp)--; while (*argcp > 1 && (*argvp)[1][0] == '-') { switch (toupper ((*argvp)[1][1])) { case 'O': mp4_state->output_flag = 1; mp4_state->outputname = (*argvp)[2]; (*argvp) += 2; (*argcp) -= 2; break; case 'J': mp4_state->juice_flag = 1; mp4_state->juice_hor = atoi ((*argvp)[2]); mp4_state->juice_ver = atoi ((*argvp)[3]); (*argvp) += 3; (*argcp) -= 3; break; default: printf ("Error: Undefined option -%c ignored\n", (*argvp)[1][1]); } }}/***/static void optionhelp(int *argcp){ if (*argcp < 2) { _Print ("Usage: opendivx_dec bitstream {options} \n"); _Print ("Options: -o {outputfilename} YUV concatenated file output\n"); _Print (" -j {hor_size ver_size} juice stream and its picture format\n"); exit (0); }}int dec_reinit(){ if (ld->infile != 0) lseek (ld->infile, 0l, 0); initbits (NULL, 0); return 1;}/***/#endif // !_DECORE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?