利用ffmpeg解码h264流的代码

这里也直接给出代码:

h264dec.h:

  1. #pragma once  
  2. #include "tdll.h"  
  3. #include "avcodec.h"  
  4. #include "postprocess.h"  
  5. //#include "EMVideoCodec.h"  
  6.   
  7. class h264dec /*: public IH264Decoder*/  
  8. {  
  9. public:  
  10.     virtual bool InitH264Deocder(int width,int height);  
  11.     virtual bool H264Decode(unsigned char * inbuf, const int & inlen,unsigned char * outbuf,int & outlen);  
  12.     virtual void StopH264Decoder();  
  13.     virtual void ReleaseConnection();  
  14.   
  15. public:  
  16.     h264dec(void);  
  17.     virtual ~h264dec(void);  
  18. private:  
  19.     Tdll *dll;  
  20.   
  21.     bool LoadDllFun();  
  22.     void (*avcodec_init)(void);  
  23.     void (*avcodec_register_all)(void);  
  24.     AVCodecContext* (*avcodec_alloc_context)(void);  
  25.     AVFrame* (*avcodec_alloc_frame)(void);  
  26.     AVCodec *(*avcodec_find_decoder)(enum CodecID id);  
  27.     int (*avcodec_decode_video)(AVCodecContext *avctx, AVFrame *picture,int *got_picture_ptr,  
  28.                                 uint8_t *buf, int buf_size);  
  29.     int  (*avcodec_open)(AVCodecContext *avctx, AVCodec *codec);  
  30.     int  (*avcodec_close)(AVCodecContext *avctx);  
  31.     void (*av_free)(void *ptr);       
  32.       
  33.     bool InitPostproc(int w,int h);  
  34.     void ClosePostproc();  
  35.     pp_context_t *(*pp_get_context)(int width, int height, int flags);  
  36.     void (*pp_free_context)(pp_context_t *ppContext);  
  37.     void (*pp_free_mode)(pp_mode_t *mode);  
  38.     pp_mode_t *(*pp_get_mode_by_name_and_quality)(char *name, int quality);  
  39.     void  (*pp_postprocess)(uint8_t * src[3], int srcStride[3],  
  40.                  uint8_t * dst[3], int dstStride[3],  
  41.                  int horizontalSize, int verticalSize,  
  42.                  QP_STORE_T *QP_store,  int QP_stride,  
  43.          pp_mode_t *mode, pp_context_t *ppContext, int pict_type);  
  44. private:  
  45.     AVCodec         *pdec;  
  46.     AVCodecContext  *pdecContext;  
  47.     AVFrame         *pdecFrame;  
  48.     int             m_width;  
  49.     int             m_height;  
  50.   
  51.     Tdll* prodll;  
  52.     pp_context_t *pp_context;  
  53.     pp_mode_t    *pp_mode;  
  54. };  

h264dec.cpp:

  1. #include "StdAfx.h"  
  2. #include ".\h264dec.h"  
  3.   
  4. h264dec::h264dec(void)  
  5. :dll(NULL)  
  6. ,pdec(NULL)  
  7. ,pdecContext(NULL)  
  8. ,pdecFrame(NULL)  
  9. ,pp_context(NULL)  
  10. ,pp_mode(NULL)  
  11. ,prodll(NULL)  
  12. {  
  13. }  
  14.   
  15. h264dec::~h264dec(void)  
  16. {  
  17. }  
  18.   
  19. bool h264dec::LoadDllFun()  
  20. {  
  21.     dll=new Tdll(L"libavcodec.dll");  
  22.     dll->loadFunction((void**)&avcodec_init,"avcodec_init");  
  23.     dll->loadFunction((void**)&avcodec_register_all,"avcodec_register_all");  
  24.     dll->loadFunction((void**)&avcodec_alloc_context,"avcodec_alloc_context");  
  25.     dll->loadFunction((void**)&avcodec_alloc_frame,"avcodec_alloc_frame");  
  26.     dll->loadFunction((void**)&avcodec_find_decoder,"avcodec_find_decoder");  
  27.     dll->loadFunction((void**)&avcodec_open,"avcodec_open");   
  28.     dll->loadFunction((void**)&avcodec_decode_video,"avcodec_decode_video");  
  29.     dll->loadFunction((void**)&avcodec_close,"avcodec_close");  
  30.     dll->loadFunction((void**)&av_free,"av_free");  
  31.     if (!dll->ok)  
  32.         return false;  
  33.   
  34.     prodll = new Tdll(L"postproc.dll");  
  35.     prodll->loadFunction((void**)&pp_get_context,"pp_get_context");  
  36.     prodll->loadFunction((void**)&pp_free_context,"pp_free_context");  
  37.     prodll->loadFunction((void**)&pp_free_mode,"pp_free_mode");  
  38.     prodll->loadFunction((void**)&pp_get_mode_by_name_and_quality,"pp_get_mode_by_name_and_quality");  
  39.     prodll->loadFunction((void**)&pp_postprocess,"pp_postprocess");  
  40.     if(!prodll->ok)  
  41.         return false;  
  42.   
  43.     avcodec_init();  
  44.     avcodec_register_all();  
  45.     return true;  
  46. }  
  47.   
  48. bool h264dec::InitH264Deocder(int width,int height)  
  49. {  
  50.     if(!LoadDllFun())  
  51.         return false;  
  52.     if(!InitPostproc(width,height))  
  53.         return false;  
  54.   
  55.     m_width=width;  
  56.     m_height=height;  
  57.     pdec = avcodec_find_decoder(CODEC_ID_H264);  
  58.     if (pdec == NULL )    
  59.         return false;  
  60.   
  61.     pdecContext = avcodec_alloc_context();  
  62.     pdecFrame = avcodec_alloc_frame();  
  63.   
  64.     pdecContext->width  = width;  
  65.     pdecContext->height = height;  
  66.     pdecContext->pix_fmt = PIX_FMT_YUV420P;  
  67.     /* open it */  
  68.     if (avcodec_open(pdecContext, pdec) < 0)   
  69.     {  
  70.         return false;  
  71.     }  
  72.     return true;  
  73. }  
  74.   
  75. bool h264dec::InitPostproc(int w,int h)  
  76. {  
  77.     int i_flags = 0;  
  78.     i_flags |= PP_CPU_CAPS_MMX | PP_CPU_CAPS_MMX2 | PP_FORMAT_420;  
  79.     pp_context = pp_get_context( w, h, i_flags );  
  80.     if(!pp_context)  
  81.         return false;  
  82.     pp_mode = pp_get_mode_by_name_and_quality( "default", 6 );  
  83.     if(!pp_mode)  
  84.         return false;  
  85.     return true;  
  86. }  
  87.   
  88. bool h264dec::H264Decode(unsigned char * inbuf, const int & inlen,unsigned char * outbuf,int & outlen)  
  89. {  
  90.     int got_frame;  
  91.     BYTE* showImage[3];  
  92.     int showheight[3],showLx[3];  
  93.   
  94.     int len;  
  95.     len=avcodec_decode_video(pdecContext, pdecFrame, &got_frame, inbuf, inlen);  
  96.     if(len < 0)  
  97.         return false;  
  98.   
  99.     if(got_frame)  
  100.     {  
  101.         showImage[0]=outbuf;  
  102.         showImage[1]=showImage[0]+m_width*m_height;  
  103.         showImage[2]=showImage[1]+m_width*m_height/4;  
  104.         showLx[0]=m_width;showLx[1]=m_width>>1;showLx[2]=m_width>>1;  
  105.         showheight[0]=m_height;showheight[1]=m_height>>1;showheight[2]=m_height>>1;  
  106.         pp_postprocess(pdecFrame->data,pdecFrame->linesize,showImage,showLx,m_width,m_height,pdecFrame->qscale_table,  
  107.             pdecFrame->qstride,pp_mode,pp_context,pdecFrame->pict_type);  
  108.         //GetImage( pdecFrame->data,  
  109.         //          showImage,  
  110.         //          pdecFrame->linesize,  
  111.         //          showLx,  
  112.         //          showheight);  
  113.         outlen=m_width*m_height*3/2;  
  114.     }  
  115.     else  
  116.     {  
  117.         outlen = 0;  
  118.     }  
  119.   
  120.     return true;  
  121. }  
  122.   
  123. void h264dec::StopH264Decoder()  
  124. {  
  125.     if (pdecContext != NULL)   
  126.     {       
  127.         avcodec_close(pdecContext);  
  128.         av_free( pdecContext );  
  129.         pdecContext = NULL;  
  130.         if(pdecFrame){  
  131.             av_free(pdecFrame);  
  132.             pdecFrame = NULL;  
  133.         }  
  134.     }  
  135.     if(dll){  
  136.         delete dll;  
  137.         dll=0;  
  138.     }  
  139.   
  140.     ClosePostproc();  
  141. }  
  142.   
  143. void h264dec::ClosePostproc()  
  144. {  
  145.     if(pp_mode){  
  146.         pp_free_mode( pp_mode );  
  147.         pp_mode=0;  
  148.     }  
  149.     if(pp_context){  
  150.         pp_free_context(pp_context);  
  151.         pp_context=0;  
  152.     }  
  153.     if(prodll){  
  154.         delete prodll;  
  155.         prodll=0;  
  156.     }  
  157. }  
  158.   
  159. void h264dec::ReleaseConnection()  
  160. {  
  161.     delete this;  
  162. }  

tdll.h:

  1. #ifndef _TDLL_  
  2. #define _TDLL_  
  3.   
  4. class Tdll  
  5. {  
  6. private:  
  7.     HMODULE hdll;  
  8.     void loadDll(const char *dllName);  
  9. public:  
  10.     bool ok;  
  11.     Tdll(const TCHAR *dllName1)  
  12.     {  
  13.         hdll=LoadLibrary(dllName1);  
  14.         if (!hdll)  
  15.         {  
  16.             hdll=NULL;  
  17.         }  
  18.         ok=(hdll!=NULL);  
  19.     };  
  20.     ~Tdll()  
  21.     {  
  22.         if (hdll)  
  23.             FreeLibrary(hdll);  
  24.     }  
  25.     void loadFunction(void **fnc,const char *name)  
  26.     {  
  27.         *fnc=GetProcAddress(hdll,name);  
  28.         ok&=(*fnc!=NULL);  
  29.     };  
  30. };    
  31.   
  32. #endif  

main.cpp:

  1. #include "stdafx.h"  
  2. #include "h264dec.h"  
  3. #include "postprocess.h"  
  4.   
  5. #define INBUF_SIZE 100 * 1024;  
  6.   
  7.   
  8. static int FindStartCode (unsigned char *Buf, int zeros_in_startcode)  
  9. {  
  10.     int info;  
  11.     int i;  
  12.   
  13.     info = 1;  
  14.     for (i = 0; i < zeros_in_startcode; i++)  
  15.     {  
  16.         if(Buf[i] != 0)  
  17.             info = 0;  
  18.     }  
  19.   
  20.     if(Buf[i] != 1)  
  21.         info = 0;  
  22.     return info;  
  23. }  
  24.   
  25. static bool Check_StartCode(unsigned char *Buf, int pos)  
  26. {  
  27.     int info3 = 0;  
  28.   
  29.     info3 = FindStartCode(&Buf[pos-4], 3);  
  30.     return info3 == 1;  
  31.   
  32. }  
  33.   
  34. static int getNextNal(FILE* inpf, unsigned char* Buf)  
  35. {  
  36.     int pos = 0;  
  37.     int StartCodeFound = 0;  
  38.     int info2 = 0;  
  39.     int info3 = 0;  
  40.   
  41.     int nCount = 0;  
  42.     while(!feof(inpf) && ++nCount <= 4)  
  43.     {  
  44.         Buf[pos++]=fgetc(inpf);  
  45.     }  
  46.   
  47.     if(!Check_StartCode(Buf, pos))  
  48.     {  
  49.         return 0;  
  50.     }  
  51.   
  52.   
  53.     while(!feof(inpf) && (Buf[pos++]=fgetc(inpf))==0);  
  54.   
  55.     while (!StartCodeFound)  
  56.     {  
  57.         if (feof (inpf))  
  58.         {  
  59.             //          return -1;  
  60.             return pos-1;  
  61.         }  
  62.         Buf[pos++] = fgetc (inpf);  
  63.   
  64.         StartCodeFound = Check_StartCode(Buf, pos);  
  65.     }  
  66.   
  67.     fseek (inpf, -4, SEEK_CUR);  
  68.     return pos - 4;  
  69. }  
  70.   
  71. int main(int argc, char* argv[])  
  72. {  
  73.     if (argc != 5)  
  74.     {  
  75.         printf("please input: PP_Demo.exe filename1[input] Width Height filename2[output]\n");  
  76.     }  
  77.       
  78.     //params set  
  79.     unsigned short usWidth = atoi(argv[2]);  
  80.     unsigned short usHeight = atoi(argv[3]);  
  81.       
  82.     //create dec&pp  
  83.     h264dec *pdec = new h264dec;  
  84.     if(!pdec->InitH264Deocder(usWidth, usHeight))  
  85.     {  
  86.         return false;  
  87.     }  
  88.   
  89.   
  90.   
  91.     unsigned char *p_In_Frame = new unsigned char[usWidth * usHeight * 3/2];  
  92.     unsigned char *p_Out_Frame = new unsigned char[usWidth * usHeight * 3/2];  
  93.     FILE* ifp = fopen(argv[1],"rb");  
  94.     FILE* ofp = fopen(argv[4],"wb");  
  95.   
  96.     bool b_continue = true;  
  97.     int nReadUnit = usWidth * usHeight * 3/2;  
  98.     while(!feof(ifp))  
  99.     {  
  100.         int nCount = getNextNal(ifp, p_In_Frame);  
  101.   
  102.         if(nCount == 0)  
  103.         {  
  104.             continue;  
  105.         }  
  106.           
  107.         unsigned char *ptr = p_In_Frame;  
  108.         int n_Outlen = 0;  
  109.         pdec->H264Decode(ptr, nCount, p_Out_Frame, n_Outlen);  
  110.           
  111.         if(n_Outlen > 0)  
  112.         {  
  113.             fwrite(p_Out_Frame, 1, n_Outlen, ofp);  
  114.         }  
  115.     }  
  116.   
  117.   
  118.     //realse  
  119.     delete []p_In_Frame;  
  120.     delete []p_Out_Frame;  
  121.     pdec->StopH264Decoder();  
  122.     pdec->ReleaseConnection();  
  123.     fclose(ifp);  
  124.     fclose(ofp);  
  125.   
  126.     return 0;  
  127. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值