利用ffmpeg解码h264流的代码

简介: 这里也直接给出代码: h264dec.h:   [cpp] view plain copy   #pragma once   #include "tdll.h"   #include "avcodec.

这里也直接给出代码:

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]\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. }  
目录
相关文章
|
2月前
|
算法 数据处理 开发者
FFmpeg库的使用与深度解析:解码音频流流程
FFmpeg库的使用与深度解析:解码音频流流程
43 0
|
2月前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(三)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
49 0
|
2月前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(二)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
50 0
|
2月前
|
存储 编解码 调度
剖析ffmpeg视频解码播放:时间戳的处理
剖析ffmpeg视频解码播放:时间戳的处理
70 0
|
4月前
ffmpeg 命令提取音视频数据-ffmpeg导出h265裸流-ffmpeg导出h264裸流
ffmpeg 命令提取音视频数据-ffmpeg导出h265裸流-ffmpeg导出h264裸流
76 0
|
6月前
|
存储 编解码 Linux
FFmpeg+SDL播放器开发实践:解析、解码、渲染全流程详解
FFmpeg+SDL播放器开发实践:解析、解码、渲染全流程详解
|
2月前
|
编解码 算法 vr&ar
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(二)
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换
47 1
|
2月前
|
存储 编解码 算法
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(一)
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换
89 1
|
2月前
ffmpeg `AVCodecContext`的`frame_number`字段查看解码器是否正在产生输出帧
ffmpeg `AVCodecContext`的`frame_number`字段查看解码器是否正在产生输出帧
14 0
|
2月前
|
安全 数据处理 数据格式
深入浅出:FFmpeg 音频解码与处理AVFrame全解析(三)
深入浅出:FFmpeg 音频解码与处理AVFrame全解析
47 0