FFmpeg 视频解码,窗口显示

[cpp]  view plain  copy
  1.   
[cpp]  view plain  copy
  1. #ifndef __DECODE_STREAM_FROM_CAMERA__  
  2. #define __DECODE_STREAM_FROM_CAMERA__  
  3.   
  4.   
  5. extern "C"{  
  6. #include "libavcodec/avcodec.h"     
  7. #include "libavformat/avformat.h"    
  8. #include "libavdevice/avdevice.h"    
  9. #include "libavfilter/avfilter.h"    
  10. #include "libswscale/swscale.h"    
  11. #include "libswresample/swresample.h"    
  12. #include "libavutil/avutil.h"  
  13. }  
  14.   
  15. #pragma warning(disable:4996)  
  16.   
  17. class DecodeStream  
  18. {  
  19. public:  
  20.     DecodeStream();  
  21.     BOOL OpenStream(const char* url);  
  22.     BOOL FindStream();  
  23.     BOOL ReadStream(HWND hVideoWnd = NULL, int DlgItemID = 0);  
  24.     BOOL CloseStream();  
  25.     ~DecodeStream();  
  26. private:  
  27.     void ShowRGBToWnd(HWND hWnd, BYTE* data, int width, int height);  
  28. private:  
  29.     AVFormatContext *m_pFormatCtx;  
  30.     unsigned int m_videoStream;  
  31.     AVCodecContext  *m_pCodecCtx;  
  32.     AVCodec         *m_pCodec;  
  33.     AVFrame *m_pFrame, *m_pFrameRGB;  
  34.       
  35.     struct SwsContext *m_pSwsCtx;  
  36.     int m_frameFinished;  
  37.     int m_PictureSize;  
  38.     uint8_t *m_buf;  
  39.     int m_open;  
  40.     BYTE *m_bitBuffer;  
  41. };  
  42.   
  43.   
  44.   
  45. #endif //__DECODE_STREAM_FROM_CAMERA__  


[cpp]  view plain  copy
  1. #include "DecodeStream.h"  
  2.   
  3. DecodeStream::DecodeStream()  
  4. {  
  5.     m_pFormatCtx = avformat_alloc_context();  
  6.   
  7.     av_register_all();  
  8.     avformat_network_init();  
  9.     avdevice_register_all();  
  10.   
  11.     m_pFrame = av_frame_alloc();  
  12.     m_pFrameRGB = av_frame_alloc();  
  13.   
  14.     m_videoStream = -1;  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>m_bitBuffer = NULL;<span style="font-family: Arial, Helvetica, sans-serif;"></span>  
[cpp]  view plain  copy
  1. }  
  2.   
  3. BOOL DecodeStream::OpenStream(const char* url)  
  4. {  
  5.     AVDictionary* opts = NULL;  
  6.     av_dict_set(&opts, "stimeout""5000000", 0);  
  7.     AVInputFormat *ifmt = av_find_input_format("vfw");  
  8.     if (avformat_open_input(&m_pFormatCtx, url, ifmt, &opts) != 0)  
  9.     {  
  10.         return FALSE;  
  11.     }  
  12.     m_open = 1;  
  13.     return TRUE;  
  14. }  
  15.   
  16. BOOL DecodeStream::FindStream()  
  17. {  
  18.     if (avformat_find_stream_info(m_pFormatCtx, NULL) < 0)  
  19.     {  
  20.         avformat_close_input(&m_pFormatCtx);  
  21.         return FALSE;  
  22.     }  
  23.     for (size_t i = 0; i < m_pFormatCtx->nb_streams; i++)  
  24.         if (m_pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)  
  25.         {  
  26.             m_videoStream = i;  
  27.         }  
  28.     if (m_videoStream == -1)  
  29.     {  
  30.         avformat_close_input(&m_pFormatCtx);  
  31.         return FALSE;  
  32.     }  
  33.     m_pCodecCtx = m_pFormatCtx->streams[m_videoStream]->codec;  
  34.     m_pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id);  
  35.     if (m_pCodec == NULL)  
  36.     {  
  37.         avformat_close_input(&m_pFormatCtx);  
  38.         return FALSE;  
  39.     }  
  40.     if (avcodec_open2(m_pCodecCtx, m_pCodec, NULL) < 0)  
  41.     {  
  42.         avformat_close_input(&m_pFormatCtx);  
  43.         return FALSE;  
  44.     }  
  45.     m_PictureSize = avpicture_get_size(AV_PIX_FMT_BGR24, m_pCodecCtx->width, m_pCodecCtx->height);  
  46.     m_buf = (uint8_t*)av_malloc(m_PictureSize);  
  47.     if (m_buf == NULL)  
  48.     {  
  49.         avformat_close_input(&m_pFormatCtx);  
  50.         avcodec_close(m_pCodecCtx);  
  51.         return FALSE;  
  52.     }  
  53.     avpicture_fill((AVPicture *)m_pFrameRGB, m_buf, AV_PIX_FMT_BGR24, m_pCodecCtx->width, m_pCodecCtx->height);  
  54.     m_pSwsCtx = sws_getContext(m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt, m_pCodecCtx->width, m_pCodecCtx->height, AV_PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);  
  55.     return TRUE;  
  56. }  
  57.   
  58. BOOL DecodeStream::ReadStream(HWND hVideoWnd /* = NULL */int DlgItemID/* = 0*/)  
  59. {  
  60.     AVPacket* packet = av_packet_alloc();  
  61.     while (av_read_frame(m_pFormatCtx, packet) >= 0 && m_open == 1){  
  62.         if (packet->stream_index == m_videoStream){  
  63.             //真正的解码      
  64.             avcodec_decode_video2(m_pCodecCtx, m_pFrame, &m_frameFinished, packet);  
  65.             if (m_frameFinished){  
  66.   
  67.                 //转换图像格式,将解压出来的YUV420P的图像转换为BRG24的图像      
  68.                 sws_scale(m_pSwsCtx, m_pFrame->data, m_pFrame->linesize, 0, m_pCodecCtx->height, m_pFrameRGB->data, m_pFrameRGB->linesize);  
  69.                 if (hVideoWnd != NULL && ItemID != 0)  
  70.                     showRGBToWnd(hVideo, m_pFrameRGB->data[0], m_pCodecCtx->width, m_pCodecCtx->height);  
  71.             }  
  72.         }  
  73.         av_free_packet(packet);  
  74.     }  
  75.     avformat_close_input(&m_pFormatCtx);  
  76.     av_packet_free(&packet);  
  77.     sws_freeContext(m_pSwsCtx);  
  78.     avcodec_close(m_pCodecCtx);  
  79.     return TRUE;  
  80. }  
  81.   
  82. BOOL DecodeStream::CloseStream()  
  83. {  
  84.     m_open = 0;  
  85.     return TRUE;  
  86. }  
  87.   
  88. void DecodeStream::ShowRGBToWnd(HWND hWnd, BYTE* data, int width, int height)  
  89. {  
  90.     if (data == NULL)  
  91.         return;  
  92.   
  93.     static BITMAPINFO *bitMapinfo = NULL;  
  94.     static bool First = TRUE;  
  95.   
  96.     if (First)  
  97.     {  
  98.         m_bitBuffer = new BYTE[40 + 4 * 256];//开辟一个内存区域  
  99.   
  100.         if (m_bitBuffer == NULL)  
  101.         {  
  102.             return;  
  103.         }  
  104.         First = FALSE;  
  105.         memset(m_bitBuffer, 0, 40 + 4 * 256);  
  106.         bitMapinfo = (BITMAPINFO *)m_bitBuffer;  
  107.         bitMapinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
  108.         bitMapinfo->bmiHeader.biPlanes = 1;  
  109.         for (int i = 0; i < 256; i++)  
  110.         { //颜色的取值范围 (0-255)  
  111.             bitMapinfo->bmiColors[i].rgbBlue = bitMapinfo->bmiColors[i].rgbGreen = bitMapinfo->bmiColors[i].rgbRed = (BYTE)i;  
  112.         }  
  113.     }  
  114.     bitMapinfo->bmiHeader.biHeight = -height;  
  115.     bitMapinfo->bmiHeader.biWidth = width;  
  116.     bitMapinfo->bmiHeader.biBitCount = 3 * 8;  
  117.     CRect drect;  
  118.     GetClientRect(hWnd, drect);    //pWnd指向CWnd类的一个指针   
  119.     HDC hDC = GetDC(hWnd);     //HDC是Windows的一种数据类型,是设备描述句柄;  
  120.     SetStretchBltMode(hDC, COLORONCOLOR);  
  121.     StretchDIBits(hDC,  
  122.         0,  
  123.         0,  
  124.         drect.right,   //显示窗口宽度  
  125.         drect.bottom,  //显示窗口高度  
  126.         0,  
  127.         0,  
  128.         width,      //图像宽度  
  129.         height,      //图像高度  
  130.         data,  
  131.         bitMapinfo,  
  132.         DIB_RGB_COLORS,  
  133.         SRCCOPY  
  134.         );  
  135.     ReleaseDC(hWnd, hDC);  
  136. }  
  137.   
  138. DecodeStream::~DecodeStream()  
  139. {  
  140.     if (m_pFrame != NULL && m_pFrameRGB != NULL){  
  141.         av_free(m_pFrame);  
  142.         av_free(m_pFrameRGB);  
  143.     }  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>if(m_bitBuffer != NULL)  
[cpp]  view plain  copy
  1. <span style="white-space:pre">      </span>delete[] m_bitBuffer;  
  2. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值