zoukankan      html  css  js  c++  java
  • 利用ffmpeg解码h264流的代码

    这里也直接给出代码:

    h264dec.h:

    [cpp] view plain copy
     
    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:

    [cpp] view plain copy
     
    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:

    [cpp] view plain copy
     
    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:

    [cpp] view plain copy
     
      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] ");  
      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. }  
  • 相关阅读:
    react-native中使用mobox数据共享
    vue cli3项目的pc自适应布局_vw
    webpack配置多页面和提取css
    react-native报错Encountered two children with the same key, `%s`.
    __proto__和prototype
    json-server配置模拟数据
    全局判断登录是否过期代码
    react-native环境搭建
    css的垂直居中常用几种方法
    进程和线程
  • 原文地址:https://www.cnblogs.com/lidabo/p/5233609.html
Copyright © 2011-2022 走看看