码迷,mamicode.com
首页 > 其他好文 > 详细

Qt基于FFmpeg播放本地 H.264(H264)文件(灿哥哥的博客)

时间:2016-07-25 07:03:49      阅读:1526      评论:0      收藏:0      [点我收藏+]

标签:

最近在弄H264的硬件编解码,基于DM3730,但是为了调试方便,在小红帽上用FFmpeg实现了H264的软件编解码。现在弄了一个Windows的例子,给需要的同学参考一下,如果大家觉得有帮助,可以小手一抖,帮我点个赞技术分享

这个例子是Qt Mingw版本的,FFmpeg可以去官网下载,也可以自己编译,编译方法可以参考我的博文。

Windows 7(Win7)下MinGW+msys编译ffmpeg,并加入H264编码支持

linux下交叉编译ffmpeg,并加入H264编码支持

linux下编译ffmpeg,并加入H264编码支持

下面是H264解码类

ch264decoder.h

 

[cpp] view plain copy
 
 技术分享技术分享
  1. #ifndef CH264DECODER_H  
  2. #define CH264DECODER_H  
  3.   
  4. #include <string.h>  
  5. //C++引用C语言的头文件  
  6. extern "C"  
  7. {  
  8. #include "libavformat/avformat.h"  
  9. #include "libswresample/swresample.h"  
  10. #include "libavutil/opt.h"  
  11. #include "libavutil/channel_layout.h"  
  12. #include "libavutil/parseutils.h"  
  13. #include "libavutil/samplefmt.h"  
  14. #include "libavutil/fifo.h"  
  15. #include "libavutil/intreadwrite.h"  
  16. #include "libavutil/dict.h"  
  17. #include "libavutil/mathematics.h"  
  18. #include "libavutil/pixdesc.h"  
  19. #include "libavutil/avstring.h"  
  20. #include "libavutil/imgutils.h"  
  21. #include "libavcodec/avcodec.h"  
  22. #include "libavfilter/avfilter.h"  
  23. #include "libavfilter/buffersrc.h"  
  24. #include "libavfilter/buffersink.h"  
  25. }  
  26.   
  27. class CH264Decoder  
  28. {  
  29. public:  
  30.     CH264Decoder();  
  31.     ~CH264Decoder();  
  32.     /************************************************* 
  33.       Function:initial 
  34.       Description:初始化 
  35.       Input:无 
  36.       Output:无 
  37.       Return:错误代码 
  38.       Others:无 
  39.     *************************************************/  
  40.     int initial();  
  41.     /************************************************* 
  42.       Function:decode 
  43.       Description:解码 
  44.       Input:pDataIn-待解码数据,nInSize-待解码数据长度 
  45.       Output:pDataOut-解码后的数据,nWidth-解码后的图像宽度,nHeight-解码后的图像高度 
  46.       Return:错误代码 
  47.       Others:解码后的数据为RGB16格式 
  48.     *************************************************/  
  49.     int decode(uint8_t *pDataIn, int nInSize, uint8_t *pDataOut, int *nWidth, int *nHeight);  
  50.     /************************************************* 
  51.       Function:unInitial 
  52.       Description:销毁 
  53.       Input:无 
  54.       Output:无 
  55.       Return:无 
  56.       Others:无 
  57.     *************************************************/  
  58.     void unInitial();  
  59.   
  60. private:  
  61.     void deleteYUVTab();  
  62.     void createYUVTab_16();  
  63.     void displayYUV_16(unsigned int *pdst, unsigned char *y, unsigned char *u,unsigned char *v,  
  64.                        int width, int height, int src_ystride, int src_uvstride, int dst_ystride);  
  65. private:  
  66.     int *colortab;  
  67.     int *u_b_tab;  
  68.     int *u_g_tab;  
  69.     int *v_g_tab;  
  70.     int *v_r_tab;  
  71.   
  72.     unsigned int *rgb_2_pix;  
  73.     unsigned int *r_2_pix;  
  74.     unsigned int *g_2_pix;  
  75.     unsigned int *b_2_pix;  
  76.   
  77.     AVCodec *codec;  
  78.     AVCodecContext *context;  
  79.     AVFrame *frame;  
  80.     AVPacket packet;  
  81. };  
  82.   
  83. #endif // CH264DECODER_H  

ch264decoder.cpp

[cpp] view plain copy
 
 技术分享技术分享
  1. #include "ch264decoder.h"  
  2. #include <QDebug>  
  3.   
  4. CH264Decoder::CH264Decoder()  
  5. {  
  6.     createYUVTab_16();  
  7. }  
  8.   
  9. CH264Decoder::~CH264Decoder()  
  10. {  
  11.     deleteYUVTab();  
  12. }  
  13.   
  14. void CH264Decoder::deleteYUVTab()  
  15. {  
  16.     av_free(colortab);  
  17.     av_free(rgb_2_pix);  
  18. }  
  19.   
  20. void CH264Decoder::createYUVTab_16()  
  21. {  
  22.     int i;  
  23.     int u, v;  
  24.   
  25.     colortab = (int *)av_malloc(4*256*sizeof(int));  
  26.     u_b_tab = &colortab[0*256];  
  27.     u_g_tab = &colortab[1*256];  
  28.     v_g_tab = &colortab[2*256];  
  29.     v_r_tab = &colortab[3*256];  
  30.   
  31.     for (i=0; i<256; i++)  
  32.     {  
  33.         u = v = (i-128);  
  34.   
  35.         u_b_tab[i] = (int) ( 1.772 * u);  
  36.         u_g_tab[i] = (int) ( 0.34414 * u);  
  37.         v_g_tab[i] = (int) ( 0.71414 * v);  
  38.         v_r_tab[i] = (int) ( 1.402 * v);  
  39.     }  
  40.   
  41.     rgb_2_pix = (unsigned int *)av_malloc(3*768*sizeof(unsigned int));  
  42.   
  43.     r_2_pix = &rgb_2_pix[0*768];  
  44.     g_2_pix = &rgb_2_pix[1*768];  
  45.     b_2_pix = &rgb_2_pix[2*768];  
  46.   
  47.     for(i=0; i<256; i++)  
  48.     {  
  49.         r_2_pix[i] = 0;  
  50.         g_2_pix[i] = 0;  
  51.         b_2_pix[i] = 0;  
  52.     }  
  53.   
  54.     for(i=0; i<256; i++)  
  55.     {  
  56.         r_2_pix[i+256] = (i & 0xF8) << 8;  
  57.         g_2_pix[i+256] = (i & 0xFC) << 3;  
  58.         b_2_pix[i+256] = (i ) >> 3;  
  59.     }  
  60.   
  61.     for(i=0; i<256; i++)  
  62.     {  
  63.         r_2_pix[i+512] = 0xF8 << 8;  
  64.         g_2_pix[i+512] = 0xFC << 3;  
  65.         b_2_pix[i+512] = 0x1F;  
  66.     }  
  67.   
  68.     r_2_pix += 256;  
  69.     g_2_pix += 256;  
  70.     b_2_pix += 256;  
  71. }  
  72.   
  73. void CH264Decoder::displayYUV_16(unsigned int *pdst, unsigned char *y, unsigned char *u, unsigned char *v, int width, int height, int src_ystride, int src_uvstride, int dst_ystride)  
  74. {  
  75.     int i, j;  
  76.     int r, g, b, rgb;  
  77.   
  78.     int yy, ub, ug, vg, vr;  
  79.   
  80.     unsigned char* yoff;  
  81.     unsigned char* uoff;  
  82.     unsigned char* voff;  
  83.   
  84.     int width2 = width/2;  
  85.     int height2 = height/2;  
  86.   
  87.     for(j=0; j<height2; j++)  
  88.     {  
  89.         yoff = y + j * 2 * src_ystride;  
  90.         uoff = u + j * src_uvstride;  
  91.         voff = v + j * src_uvstride;  
  92.   
  93.         for(i=0; i<width2; i++)  
  94.         {  
  95.             yy  = *(yoff+(i<<1));  
  96.             ub = u_b_tab[*(uoff+i)];  
  97.             ug = u_g_tab[*(uoff+i)];  
  98.             vg = v_g_tab[*(voff+i)];  
  99.             vr = v_r_tab[*(voff+i)];  
  100.   
  101.             b = yy + ub;  
  102.             g = yy - ug - vg;  
  103.             r = yy + vr;  
  104.   
  105.             rgb = r_2_pix[r] + g_2_pix[g] + b_2_pix[b];  
  106.   
  107.             yy = *(yoff+(i<<1)+1);  
  108.             b = yy + ub;  
  109.             g = yy - ug - vg;  
  110.             r = yy + vr;  
  111.   
  112.             pdst[(j*dst_ystride+i)] = (rgb)+((r_2_pix[r] + g_2_pix[g] + b_2_pix[b])<<16);  
  113.   
  114.             yy = *(yoff+(i<<1)+src_ystride);  
  115.             b = yy + ub;  
  116.             g = yy - ug - vg;  
  117.             r = yy + vr;  
  118.   
  119.             rgb = r_2_pix[r] + g_2_pix[g] + b_2_pix[b];  
  120.   
  121.             yy = *(yoff+(i<<1)+src_ystride+1);  
  122.             b = yy + ub;  
  123.             g = yy - ug - vg;  
  124.             r = yy + vr;  
  125.   
  126.             pdst [((2*j+1)*dst_ystride+i*2)>>1] = (rgb)+((r_2_pix[r] + g_2_pix[g] + b_2_pix[b])<<16);  
  127.         }  
  128.     }  
  129. }  
  130. int CH264Decoder::initial()  
  131. {  
  132.     avcodec_register_all();  
  133.     av_init_packet(&packet);  
  134.   
  135.     codec = avcodec_find_decoder(AV_CODEC_ID_H264);  
  136.     if (!codec)  
  137.     {  
  138.         printf("avcodec_find_encoder failed");  
  139.         return -1;  
  140.     }  
  141.   
  142.     context = avcodec_alloc_context3(codec);  
  143.     if (!context)  
  144.     {  
  145.         printf("avcodec_alloc_context3 failed");  
  146.         return -2;  
  147.     }  
  148.   
  149.     context->codec_type = AVMEDIA_TYPE_VIDEO;  
  150.     context->pix_fmt = AV_PIX_FMT_YUV420P;  
  151.   
  152.     if (avcodec_open2(context, codec, NULL) < 0)  
  153.     {  
  154.         printf("avcodec_open2 failed");  
  155.         return -3;  
  156.     }  
  157.   
  158.     frame = av_frame_alloc();  
  159.     if (!frame)  
  160.     {  
  161.         return -4;  
  162.     }  
  163.   
  164.     return 0;  
  165. }  
  166.   
  167. void CH264Decoder::unInitial()  
  168. {  
  169.     avcodec_close(context);  
  170.     av_free(context);  
  171.     av_frame_free(&frame);  
  172. }  
  173.   
  174. int CH264Decoder::decode(uint8_t *pDataIn, int nInSize, uint8_t *pDataOut,int *nWidth, int *nHeight)  
  175. {  
  176.     av_init_packet(&packet);  
  177.     packet.size = nInSize;  
  178.     packet.data = pDataIn;  
  179.   
  180.     if (packet.size > 0)  
  181.     {  
  182.         int got_picture=0;  
  183.         int ret= avcodec_decode_video2(context, frame, &got_picture, &packet);  
  184.         if (ret < 0)  
  185.         {  
  186.             printf("avcodec_encode_video2 failed");  
  187.             return -2;  
  188.         }  
  189.   
  190.         if (got_picture)  
  191.         {  
  192.             *nWidth = context->width;  
  193.             *nHeight = context->height;  
  194.   
  195.              displayYUV_16((unsigned int*)pDataOut, frame->data[0], frame->data[1],frame->data[2],  
  196.                      *nWidth,*nHeight,frame->linesize[0],frame->linesize[2],*nWidth);  
  197.         }  
  198.     }  
  199.     else  
  200.     {  
  201.         printf("no data to decode");  
  202.         return -1;  
  203.     }  
  204.   
  205.     return 0;  
  206. }  

使用方法,先调用initial()进行初始化,然后读取本地H264文件,调用decode()函数进行解码,退出时调用unInitial()函数释放资源。

 

需要注意的是,解码后的数据是RGB16格式,转换为QImage时,最后一个参数要用QImage::Format_RGB16,例如QImage image= QImage(outBuf, width, height, QImage::Format_RGB16);

下图是播放效果:

技术分享

演示用的H264文件下载链接:http://download.csdn.net/detail/caoshangpa/9492803

源码下载链接:见http://blog.csdn.net/caoshangpa/article/details/51953208的评论

 

技术分享

Qt基于FFmpeg播放本地 H.264(H264)文件(灿哥哥的博客)

标签:

原文地址:http://www.cnblogs.com/findumars/p/5702198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!