• PUDN用户
    了解作者
  • Visual C++
    开发工具
  • 8KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 37
    下载次数
  • 2010-04-12 20:04
    上传日期
实现用H264标准的编码和解码,用C++描述的一个轻量程序
h264_encoder.rar
  • h264_encoder
  • h264_encoder.c
    35.5KB
内容介绍
#include <string.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> //常量 const short qua_t[4][4] = {{8192,5243,8192,5243},{5243,3355,5243,3355},{8192,5243,8192,5243},{5243,3355,5243,3355}}; const short dqua_t[4][4] = {{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}}; //变量 //! Syntaxelement typedef struct syntaxelement { int value1; //!< numerical value of syntax element int value2; //!< for blocked symbols, e.g. run/level int len; //!< length of code int inf; //!< info part of UVLC code } SyntaxElement; unsigned char *pimagedata;//原始图像 unsigned char *pimagedata_i; //unsigned char *ppredata;//预测图像 //unsigned char *presdata;//残差图像 unsigned char *preconscructdata;//重建图像 //unsigned char *phuifuresdata;//恢复残差图像 unsigned char x_origin_mb[16][16]; unsigned char x_vpre_mb[16][16]; unsigned char x_hpre_mb[16][16]; unsigned char x_dpre_mb[16][16]; unsigned char x_ppre_mb[16][16]; unsigned char x_pre_mb[16][16]; unsigned char x_reconscruct[16][16]; short x_vres_mb[16][16]; short x_hres_mb[16][16]; short x_dres_mb[16][16]; short x_pres_mb[16][16]; short x_res_mb[16][16]; unsigned char vdata[16]; unsigned char hdata[16]; unsigned char left_up; short *pdc_mb, *pdq_mb; short *pwfe; short *reget_res; unsigned char *code; unsigned int totalbitoffset; int nnzTable[60][80];//用于装每个4x4块非零系数个数的数组 char ptable[300]; //函数 void Intraforecast1616(); unsigned int intra_vfc1616(); unsigned int intra_hfc1616(); unsigned int intra_dfc1616(unsigned char method); unsigned int intra_pfc1616(); void dct_qua(short *pres_mb); void dct_fast(short *p1, short *p2); void hadamand_fast(short *p1, short *p2); void ihadamand_fast(short *p1, short *p2); void idct_iq(short *pdc,short *pdq); void idct_fast(short *p1, short *p2); void mb_reform(short *pdq_mb, short *reget_res); void ImageInverse(unsigned char *ps, unsigned char *pd); /*************************编码函数组*****************************/ void cavlc_encode(int block_type, short *data, int x_mb_num, int num_in_macro); int writeSyntaxElement_CoeffToken(SyntaxElement *se); void writeUVLCbuffer(SyntaxElement *se, unsigned int totalbitoffset); void writeSyntaxElement_TrailingOnesSignFlag(int sf); int writeSyntaxElement_LevelPrefix(SyntaxElement *se); int writeSyntaxElement_LevelSuffix(SyntaxElement *se); int writeSyntaxElement_TotalZeros(SyntaxElement *se); int writeSyntaxElement_RunBefore(SyntaxElement *se); void zigZag(short *pdc,short *pdq); void zigZagOrder(int type, short *ps, short *pd); void golomb_ue(char mpm); int judgeTable(long x, long y, int total_coeff); /*************************编码函数组*****************************/ void Intraforecast1616() { //对一帧中不同位置的宏块进行判别,采用不同的处理方案,宏块标识符采用该宏块横纵坐标的组合 //所有的帧都是IDR帧,一个帧只包含一个像条,像条大小为320*240,故包含300个宏块 int x_mb_num, m; unsigned int sv,sh,sd,sp; int i,j; x_mb_num = 0; long t1,t2,t3; totalbitoffset = 0; short *pwfeTemp; char macro_predict_mode; int mpm = 0; for(x_mb_num=0;x_mb_num<300;x_mb_num++) { t1 = x_mb_num % 20; t2 = (x_mb_num - t1) * 256 + 16 * t1;//这样找到的是宏块首地址的前一个位置 //但对于指针偏移量而言,就是宏块首地址 for(i=0;i<16;i++)//读入一个宏块 for(j=0;j<16;j++) { x_origin_mb[i][j] = *(pimagedata + t2 + i*320 +j); } if(x_mb_num == 0) { intra_dfc1616(1); macro_predict_mode = 2; //对得到的残差块进行DCT与量化 //直接修改变换量化的存储区 //由于不管采用哪种预测,最后所得的变换量化值只有一个, //故最后储存区一个就可以了 for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_dpre_mb[i][j]; } for(i=0;i<16;i++) for(j=0;j<16;j++) { x_res_mb[i][j] = x_dres_mb[i][j]; } dct_qua((short*)x_res_mb); // for(i=0;i<16;i++) // for(j=0;j<16;j++) // { // *(ppredata + t2 + i*320 +j) = x_pre_mb[i][j]; // *(presdata + t2 + i*320 +j) = abs(x_res_mb[i][j]); // } } else if(x_mb_num <= 19) { for(m=0;m<16;m++)//读入V vdata[m] = *(preconscructdata + (t2-1) + m*320); //vdata[m] = *(pimagedata + (t2-1) + m*320); sh = intra_hfc1616(); sd = intra_dfc1616(2); if(sh < sd)//比较SAE//将预测值写入缓存//将预测残差写入缓存 { macro_predict_mode = 1; for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_hpre_mb[i][j]; } for(i=0;i<16;i++) for(j=0;j<16;j++) { x_res_mb[i][j] = x_hres_mb[i][j]; } } else { macro_predict_mode = 2; for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_dpre_mb[i][j]; } for(i=0;i<16;i++) for(j=0;j<16;j++) { x_res_mb[i][j] = x_dres_mb[i][j]; } } dct_qua((short*)x_res_mb); // for(i=0;i<16;i++) // for(j=0;j<16;j++) // { // *(ppredata + t2 + i*320 +j) = x_pre_mb[i][j]; // *(presdata + t2 + i*320 +j) = abs(x_res_mb[i][j]); // } } else if(t1 == 0)//((~((x_mb_num / 10) & 0x1)) && ((x_mb_num % 10) == 0)) { for(m=0;m<16;m++)//读入H hdata[m] = *(preconscructdata + (t2-320) + m); //hdata[m] = *(pimagedata + (t2-320) + m); sv = intra_vfc1616(); sd = intra_dfc1616(3); if(sv < sd)//比较SAE//将预测值写入缓存//将预测残差写入缓存 { macro_predict_mode = 0; for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_vpre_mb[i][j]; } for(i=0;i<16;i++) for(j=0;j<16;j++) { x_res_mb[i][j] = x_vres_mb[i][j]; } } else { macro_predict_mode = 2; for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_dpre_mb[i][j]; } for(i=0;i<16;i++) for(j=0;j<16;j++) { x_res_mb[i][j] = x_dres_mb[i][j]; } } dct_qua((short*)x_res_mb); // for(i=0;i<16;i++) // for(j=0;j<16;j++) // { // *(ppredata + t2 + i*320 +j) = x_pre_mb[i][j]; // *(presdata + t2 + i*320 +j) = abs(x_res_mb[i][j]); // } } else { //读入V和H t3 = t2 - 1 - 320;//宏块首地址左上方位置 left_up = *(preconscructdata + t3); for(m=0;m<16;m++) vdata[m] = *(preconscructdata + t3 + (m+1) * 320); //vdata[m] = *(pimagedata + t3 + (m+1) * 320); for(m=0;m<16;m++) hdata[m] = *(preconscructdata + t3 + (m+1)); //hdata[m] = *(pimagedata + t3 + (m+1)); sv = intra_vfc1616(); sh = intra_hfc1616(); sd = intra_dfc1616(4); sp = intra_pfc1616(); unsigned int t4; if(sv < sh) t4 =sv; else t4 = sh; if(sd < t4) t4 = sd; if(sp < t4) t4 = sp; if(t4 == sp) { macro_predict_mode = 3; for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_ppre_mb[i][j]; } for(i=0;i<16;i++) for(j=0;j<16;j++) { x_res_mb[i][j] = x_pres_mb[i][j]; } } else if(t4 == sd) { macro_predict_mode = 2; for(i=0;i<16;i++) for(j=0;j<16;j++) { x_pre_mb[i][j] = x_dpre_mb[i][j];
评论
    相关推荐
    • h264parseSPS.zip
      解析h264编码中的sps帧获取视频信息
    • H264BSAnalyzer.rar
      H264BSAnalyzer h264视频分析的源代码,整合比较完善.
    • H.264编码
      H.264编码H264CODEC目录: \bin 目录下是已编译成功的编解码器程序以及相应说明 \ldecod 目录下是H.264视频解码器程序代码。 \lencod 目录下是H.264视频编码器程序代码。 \rtpdump 目录下是H.264实时传输协议...
    • H.264官方中文版.zip
      H.264官方中文版 手册 对媒体开发有帮助,需要的朋友拿去
    • h264 编码,解码
      h264 硬件编解码,文件。编码,解码。
    • ios 2.4.3 H264编码
      史上最全 ,当前最新的视频编解码核心库, 通过开源代码重新编译出的可供IOS开发直接使用的视频编码库。不懂的人嫌贵,懂的人会体会其价值。
    • Android 视频H264编码
      提供H264编解码目前还算蛮好用的。本程序还存在小BUG下载请慎用。不喜勿喷!
    • H264编码流程图
      H264编码流程图
    • android硬编码h264
      android 用新api mediacodec硬编码h264, 发送到vlc播放。
    • Android h264编码
      Android h264编码