self.c
来自「实现在linux下的mpeg4编解码」· C语言 代码 · 共 900 行 · 第 1/2 页
C
900 行
//for encode#include "encore.h"#include "vop_code.h"#include "text_dct.h"//#include "rc_q2.h"#include "bitstream.h"#include "vm_common_defs.h"#include "rate_ctl.h"#include "time.h" //for decode#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#if ( (defined (WIN32)) && (! defined (_DECORE)) )#include <string.h>#include <io.h>#include <fcntl.h>#endif/*是预编译处理指令中的条件编译。 预编译处理是指在编译系统对文件进行编译---词法分析、语法分析、代码生成及优化之前,对一些特殊的编译语句先进行处理,然后将处理结果与源程序一起编译,生成目标文件。 预编译处理语句都是以#开头,其结尾不带分号,与普通程序语句相区别。 #endif用于结束条件编译,编译时与前面最近的#if作为一对,编译两者之间的部分程序段。*///#include "gen_usetime.h"#include "debug.h"#include "mp4_vars.h"#include "getbits.h"#include "yuv2rgb.h"#include "decore.h"static int decore_release()//for decode{ // closedecoder(); // [Ag][Review] /* I have to check and close the decoder only when it is really been opened: for some reason VirtualDub first of all wants to close the decoder and this cause a free(nothing) and a crash. */#ifndef _DECORE close (ld->infile);#endif // _DECORE return 1;}/***/static int flag_firstpicture = 1;//for decode/***/int STDCALL decore(unsigned long handle, unsigned long dec_opt,//for decode void *param1, void *param2){ if (handle) { switch (dec_opt) { case DEC_OPT_MEMORY_REQS: { DEC_PARAM *dec_param = (DEC_PARAM *)param1; DEC_MEM_REQS *dec_mem_reqs = (DEC_MEM_REQS *)param2; int coded_y_size = ((dec_param->x_dim + 64) * (dec_param->y_dim + 64)); int coded_c_size = (((dec_param->x_dim>>1) + 64) * ((dec_param->y_dim>>1) + 64)); int display_y_size = (dec_param->x_dim * dec_param->y_dim); int display_c_size = ((dec_param->x_dim * dec_param->y_dim) >> 2); int edged_size = coded_y_size + (2 * coded_c_size); int display_size = display_y_size + (2 * display_c_size); dec_mem_reqs->mp4_edged_ref_buffers_size = edged_size; dec_mem_reqs->mp4_edged_for_buffers_size = edged_size; dec_mem_reqs->mp4_display_buffers_size = display_size; dec_mem_reqs->mp4_state_size = sizeof(MP4_STATE); dec_mem_reqs->mp4_tables_size = sizeof(MP4_TABLES); dec_mem_reqs->mp4_stream_size = sizeof(MP4_STREAM); return DEC_OK; } case DEC_OPT_INIT: { DEC_PARAM *dec_param = (DEC_PARAM *) param1; decore_init(dec_param->x_dim, dec_param->y_dim, dec_param->output_format, dec_param->time_incr, dec_param->buffers); // init decoder resources return DEC_OK; } break; case DEC_OPT_RELEASE: { decore_release(); return DEC_OK; } break; case DEC_OPT_SETPP: { DEC_SET *dec_set = (DEC_SET *) param1; int postproc_level = dec_set->postproc_level; if ((postproc_level < 0) | (postproc_level > 100)) return DEC_BAD_FORMAT; if (postproc_level < 1) { mp4_state->post_flag = 0; return DEC_OK; } else { mp4_state->post_flag = 1; if (postproc_level < 10) { mp4_state->pp_options = PP_DEBLOCK_Y_H; } else if (postproc_level < 20) { mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V; } else if (postproc_level < 30) { mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y; } else if (postproc_level < 40) { mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | PP_DEBLOCK_C_H; } else if (postproc_level < 50) { mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | PP_DEBLOCK_C_H | PP_DEBLOCK_C_V; } else { mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | PP_DEBLOCK_C_H | PP_DEBLOCK_C_V | PP_DERING_C; } } return DEC_OK; } break; case DEC_OPT_SETOUT: { DEC_PARAM *dec_param = (DEC_PARAM *) param1; decore_setoutput(dec_param->output_format); return DEC_OK; } break; default: { DEC_FRAME *dec_frame = (DEC_FRAME *) param1; if (decore_frame(dec_frame->bitstream, dec_frame->length, dec_frame->bmp, dec_frame->stride, dec_frame->render_flag)) return DEC_OK; else return DEC_EXIT; } break; } } return DEC_BAD_FORMAT;}/***/int decore_alloc(DEC_BUFFERS buffers);//for decode//static int decore_init(int hor_size, int ver_size, int output_format, int time_inc, DEC_BUFFERS buffers)int decore_init(int hor_size, int ver_size, int output_format, int time_inc, DEC_BUFFERS buffers)//for decode{ mp4_state = (MP4_STATE *) buffers.mp4_state; mp4_tables = (MP4_TABLES *) buffers.mp4_tables; ld = (MP4_STREAM *) buffers.mp4_stream;#ifndef _DECORE // open input file if ((ld->infile = open (mp4_state->infilename, O_RDONLY /*| O_BINARY*/)) < 0) { _Print ("Input file %s not found\n", mp4_state->infilename); exit(91); } initbits (NULL, 0); mp4_state->juice_flag = 0;#else mp4_state->juice_flag = 1;#endif // _DECORE mp4_state->post_flag = 0; // read first vol and vop mp4_state->hdr.width = hor_size; mp4_state->hdr.height = ver_size; mp4_state->hdr.quant_precision = 5; mp4_state->hdr.bits_per_pixel = 8; mp4_state->hdr.quant_type = 0; if (flag_firstpicture == 1) { mp4_state->hdr.time_increment_resolution = 15; flag_firstpicture = 0; } mp4_state->hdr.complexity_estimation_disable = 1; decore_alloc (buffers); decore_setoutput (output_format); return 1;}/***/int decore_alloc(DEC_BUFFERS buffers)//for decode{ mp4_state->hdr.picnum = 0; mp4_state->hdr.mb_xsize = mp4_state->hdr.width / 16; mp4_state->hdr.mb_ysize = mp4_state->hdr.height / 16; mp4_state->hdr.mba_size = mp4_state->hdr.mb_xsize * mp4_state->hdr.mb_ysize; // set picture dimension global vars { mp4_state->horizontal_size = mp4_state->hdr.width; mp4_state->vertical_size = mp4_state->hdr.height; mp4_state->mb_width = mp4_state->horizontal_size / 16; mp4_state->mb_height = mp4_state->vertical_size / 16; mp4_state->coded_picture_width = mp4_state->horizontal_size + 64; mp4_state->coded_picture_height = mp4_state->vertical_size + 64; mp4_state->chrom_width = mp4_state->coded_picture_width >> 1; mp4_state->chrom_height = mp4_state->coded_picture_height >> 1; } // init decoder initdecoder (buffers); return 1;}/***/int decore_frame(unsigned char *stream, int length, unsigned char *bmp, unsigned int stride, int render_flag)//for decode{#ifndef _DECORE mp4_state->juice_flag = 0; _SetPrintCond(0, 1000, 0, 1000); _Print("- Picture %d\r", mp4_state->hdr.picnum);#else initbits (stream, length);#endif // _DECORE // mp4_state->hdr.time_increment_resolution = 15; // [Ag][Review] This must be passed by the app! getvolhdr(); getgophdr(); if (! getvophdr()) // read vop header return 0; get_mp4picture(bmp, stride, render_flag); // decode vop mp4_state->hdr.picnum++; return 1;}/***//***/int decore_setoutput(int output_format)//for decode{ mp4_state->flag_invert = +1; switch (output_format) { case DEC_RGB32: mp4_state->convert_yuv = yuv2rgb_32; mp4_state->flag_invert = -1; break; case DEC_RGB32_INV: mp4_state->convert_yuv = yuv2rgb_32; mp4_state->flag_invert = +1; break; case DEC_RGB24: mp4_state->convert_yuv = yuv2rgb_24; mp4_state->flag_invert = -1; break; case DEC_RGB24_INV: mp4_state->convert_yuv = yuv2rgb_24; mp4_state->flag_invert = +1; break; case DEC_RGB555: mp4_state->convert_yuv = yuv2rgb_555; mp4_state->flag_invert = -1; break; case DEC_RGB555_INV: mp4_state->convert_yuv = yuv2rgb_555; mp4_state->flag_invert = +1; break; case DEC_RGB565: mp4_state->convert_yuv = yuv2rgb_565; mp4_state->flag_invert = -1; break; case DEC_RGB565_INV: mp4_state->convert_yuv = yuv2rgb_565; mp4_state->flag_invert = +1; break; case DEC_420: mp4_state->convert_yuv = yuv12_out; break; case DEC_YUV2: mp4_state->convert_yuv = yuy2_out; break; case DEC_UYVY: mp4_state->convert_yuv = uyvy_out; break; } return 1;}/** * for a console application**/#ifndef _DECORE/***/static int dec_reinit();//for decodestatic void options (int *argcp, char **argvp[]);//for decodestatic void optionhelp (int *argcp);//for decodeint decode(char infile[],char outfile[])//for decode{ printf("读入文件\n"); char * infilename = infile; char *outputfilename = outfile; printf("设定初始参数\n"); DEC_MEM_REQS decMemReqs; DEC_PARAM decParam; decParam.x_dim = 352; decParam.y_dim = 288; decParam.output_format = 0; decParam.time_incr = 0; printf("MEMORY?\n"); decore(1, DEC_OPT_MEMORY_REQS, &decParam, &decMemReqs); printf("参数?\n"); decParam.buffers.mp4_edged_ref_buffers = malloc(decMemReqs.mp4_edged_ref_buffers_size); decParam.buffers.mp4_edged_for_buffers = malloc(decMemReqs.mp4_edged_for_buffers_size); decParam.buffers.mp4_display_buffers = malloc(decMemReqs.mp4_display_buffers_size); decParam.buffers.mp4_state = malloc(decMemReqs.mp4_state_size); decParam.buffers.mp4_tables = malloc(decMemReqs.mp4_tables_size); decParam.buffers.mp4_stream = malloc(decMemReqs.mp4_stream_size); memset(decParam.buffers.mp4_state, 0, decMemReqs.mp4_state_size); memset(decParam.buffers.mp4_tables, 0, decMemReqs.mp4_tables_size); memset(decParam.buffers.mp4_stream, 0, decMemReqs.mp4_stream_size); ((MP4_STATE *) decParam.buffers.mp4_state)->infilename = infilename; ((MP4_STATE *) decParam.buffers.mp4_state)->outputname = outputfilename; decore(1, DEC_OPT_INIT, &decParam, NULL);// startTimer(); printf("开始计时\n"); clock_t start, finish; double duration; start = clock(); // decode frames { DEC_FRAME decFrame; decFrame.bitstream = NULL; decFrame.bmp = NULL; decFrame.length = 0; decFrame.render_flag = 0; printf("解码中。。。\n"); while ( decore(1, 0, &decFrame, NULL) == DEC_OK ) ; }// stopTimer(); printf("解码完成,记时结束\n"); finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "解码所耗费的时间为%f 秒\n ", duration ); // displayTimer(mp4_state->hdr.picnum); return 1;}typedef struct _REFERENCE//for encode{ 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; /* the current run before the last key frame */ Vop *current; /* the current frame to be encoded */ Vop *reference; /* the reference frame - reconstructed previous frame */ Vop *reconstruct; /* intermediate reconstructed frame - used in inter */ Vop *error; /* intermediate error frame - used in inter to hold prediction error */ struct _REFERENCE *pnext;} REFERENCE;FILE *ftrace = NULL; //for encodeint max_quantizer, min_quantizer;//for encode/* private functions used only in this file */void init_vol_config(VolConfig *vol_config);//for encodevoid init_vop(Vop *vop); //for encodeInt 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)//for encode{ static REFERENCE *ref = NULL; static VolConfig *vol_config; // a link list to keep the reference frame for all instances REFERENCE *ref_curr, *ref_last = NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?