利用ffmpeg将H264流 解码为RGB
利用H264解码分为几个步骤:
注意一点在添加头文件的时候要添加extern "C",不然会出现错误
- extern "C"
- {
- #include <avcodec.h>
- #include <avformat.h>
- #include <avutil.h>
- #include <swscale.h>
- };
这里申明了几个全局变量
- AVCodec *pCodec = NULL;
- AVCodecContext *pCodecCtx = NULL;
- SwsContext *img_convert_ctx = NULL;
- AVFrame *pFrame = NULL;
- AVFrame *pFrameRGB = NULL;
1. 初始化
- int H264_Init(void)
- {
- /* must be called before using avcodec lib*/
- avcodec_init();
- /* register all the codecs */
- avcodec_register_all();
- /* find the h264 video decoder */
- pCodec = avcodec_find_decoder(CODEC_ID_H264);
- if (!pCodec) {
- fprintf(stderr, "codec not found\n");
- }
- pCodecCtx = avcodec_alloc_context();
- /* open the coderc */
- if (avcodec_open(pCodecCtx, pCodec) < 0) {
- fprintf(stderr, "could not open codec\n");
- }
- // Allocate video frame
- pFrame = avcodec_alloc_frame();
- if(pFrame == NULL)
- return -1;
- // Allocate an AVFrame structure
- pFrameRGB=avcodec_alloc_frame();
- if(pFrameRGB == NULL)
- return -1;
- return 0;
- }
在最早使用的时候没有使用全局变量,初始化中也就只有init和regisger这两个函数,而这样做的下场是,非关键帧全部无法解码,只有关键帧才有办法解码。
2. 解码
解码的时候avcodec_decode_video函数是进行解码操作,在外部定义outputbuf的大小时,pixes*3,outsize是返回的outputbuf的size,值也是pixes*3。
在解码的时候这几句话的意义是将YUV420P的数据倒置。在原先使用中,发现解出来的图像居然是中心旋转图,后面在网上找了些办法,觉得这个比较实用。解码实时是很重要的,图像转化完之后也可以讲RGB图再次转化,那样也能成为一个正的图,但是那样效率就明显低了。
- pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height-1);
- pFrame->linesize[0] *= -1;
- pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height/2 - 1);;
- pFrame->linesize[1] *= -1;
- pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height/2 - 1);;
- pFrame->linesize[2] *= -1;
- int H264_2_RGB(unsigned char *inputbuf, int frame_size, unsigned char *outputbuf, unsigned int*outsize)
- {
- int decode_size;
- int numBytes;
- int av_result;
- uint8_t *buffer = NULL;
- printf("Video decoding\n");
- av_result = avcodec_decode_video(pCodecCtx, pFrame, &decode_size, inputbuf, frame_size);
- if (av_result < 0)
- {
- fprintf(stderr, "decode failed: inputbuf = 0x%x , input_framesize = %d\n", inputbuf, frame_size);
- return -1;
- }
- // Determine required buffer size and allocate buffer
- numBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,
- pCodecCtx->height);
- buffer = (uint8_t*)malloc(numBytes * sizeof(uint8_t));
- // Assign appropriate parts of buffer to image planes in pFrameRGB
- avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_BGR24,
- pCodecCtx->width, pCodecCtx->height);
- img_convert_ctx = sws_getCachedContext(img_convert_ctx,pCodecCtx->width,pCodecCtx->height,
- //PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,
- pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24 ,
- SWS_X ,NULL,NULL,NULL) ;
- if (img_convert_ctx == NULL)
- {
- printf("can't init convert context!\n") ;
- return -1;
- }
- pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height-1);
- pFrame->linesize[0] *= -1;
- pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height/2 - 1);;
- pFrame->linesize[1] *= -1;
- pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height/2 - 1);;
- pFrame->linesize[2] *= -1;
- sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
- 0, 0 - pCodecCtx->width, pFrameRGB->data, pFrameRGB->linesize);
- if (decode_size)
- {
- *outsize = pCodecCtx->width * pCodecCtx->height * 3;
- memcpy(outputbuf, pFrameRGB->data[0], *outsize);
- }
- free(buffer);
- return 0;
- }
//解码yuv 修改 PIX_FMT_YUV420P memcpy(outputbuf, pFrameRGB->data[2], 720*576/4); memcpy(outputbuf, pFrameRGB->data[1], 720*576/4); memcpy(outputbuf, pFrameRGB->data[0], 720*576);
3. 释放资源
资源的回收。
- void H264_Release(void)
- {
- avcodec_close(pCodecCtx);
- av_free(pCodecCtx);
- av_free(pFrame);
- av_free(pFrameRGB);
- }
利用ffmpeg将H264流 解码为RGB的更多相关文章
- FFMPEG实现H264的解码(从源代码角度)
农历2014年底了,将前段时间工作中研究的FFMPEG解码H264流程在此做一下整理,也算作年终技术总结了! H264解码原理: H264的原理参考另一篇博文 http://blog.csdn.net ...
- 利用ffmpeg将H264解码为RGB
因为公司买到了一个不提供解码器的设备,我不得已还要做解码的工作.在网上找了一圈,H264解码比較方便的也就是ffmpeg一系列的函数库了,原本设备中也是用这套函数库解码,但厂家不给提供,没办法,仅仅得 ...
- 用ffmpeg把H264数据流解码成YUV420P
在网上找了很久这方面的内容,发现网上的代码都太旧了,所使用的函数旧到连最新版本的ffmpeg都已经不包含了,所以对于我这个初学者来说太坑拉.不过经过多次查找ffmpeg的头文件和结合网上的内容,终于成 ...
- 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中
既然已经可以通过 RTSP 获取h264 裸流了.那么通过 FFmpeg 将其保存到文件中怎么做呢? 一.首先RTSP获取 h264 裸流 我们上面两篇文章主要讲的是通过 rtsp://Your ip ...
- [ffmpeg] h264并行解码
ffmpeg中的并行解码分为两种: Frame-level Parallelism Slice-level Parallelism Frame-level Parallelism 帧间依赖 我们之前讨 ...
- VS2015编译FFMPEG,修改FFmpeg缓冲区大小解决实时流解码丢包问题,FFmpeg错误rtsp流地址卡死的问题,设置超时
之前尝试过很多网上利用Windows编译FFmpeg的文章,都没有办法编译X64位的FFmpeg,有些教程中有专门提到编译64位的FFmpeg需要下载mingw-w64-install,但是编译的过程 ...
- ps流提取H264并解码播放
因为需要从海康ps流中提取H264数据并进行解码播放,才有了这篇文章.因为是视频编解码领域的纯入门新手,个别理解或者方法有误,需要自行判断,不过相关方法已经测试通过,对于 像我这样的新手还是有一定的借 ...
- ffmpeg H264 编解码配置
ffmpeg H264编解码前面有文章介绍下,本文主要介绍一些参数配置. 编码: int InitEncoderCodec( int iWidth, int iHeight) { AVCodec * ...
- 【VS开发】【视频开发】利用ffmpeg+opencv实现画中画
需求:把两路视频合成一路,即一个画面同时显示两路视频,其中一路缩小成小视频叠在大视频上面,和电视机的画中画效果类似. 思路:用h264编码的视频举例,文件中存储的es流是h264,经过解码成yuv,y ...
随机推荐
- 自己做的notepad++ FTP同步插件
平时修改FTP上的文件的时候,想先备份一下,没有合适的方法,尝试做了一个小插件. 差点忘了,下载地址 https://pan.baidu.com/s/1htdtT9E 下面是 具体的说明 Fa ...
- java中的二叉树排序问题
原创:转载请注明出处 目的:想用java实现二叉树排序算法 思想:利用java中面向对象的思想,即: Tree:类 树根Tree:root //static所属于每一个Tree 左节点Tree:lef ...
- SpringMVC环境搭建---xml版及注解版
一.建立 JavaWeb 项目(基于Intellij 14.0.3搭建) 1.建立一个 Java 项目,在项目下新建一个文件夹 webapp ,然后在该文件夹下新建一个 WEB-INF 文件夹: 2. ...
- elasticsearch的percolator操作
es的普通查询是通过某些条件来查询满足的文档,percolator则不同,先是注册一些条件,然后查询一条文档是否满足其中的某些条件. es的percolator特性在数据分类.数据路由.事件监控和预警 ...
- 【转】如何解决plsql查询oracle数据库语句where条件带有中文无法匹配结果
一.问题描述 之前使用PLSQL查询oracle数据库可以正常查询统计结果,由于换了个电脑,重新安装之后,同样的sql查询语句同一个数据库,无法正常查询结果,如下图所示 二.解决办法 1. 查询数据当 ...
- 使用scrapy爬取豆瓣上面《战狼2》影评
这几天一直在学习scrapy框架,刚好学到了CrawlSpider和Rule的搭配使用,就想着要搞点事情练练手!!! 信息提取 算了,由于爬虫运行了好几次,太过分了,被封IP了,就不具体分析了,附上& ...
- S5PV210中断处理
_start: 1.设置栈空间:防止之前的UBOOT代码被覆盖,应为c中需要栈空间 ldr sp, =0x40010000 2.设置CPSR的I,F位,A8打开IRQ,FIQ中断: mov r0, # ...
- [Python Study Notes]cpu信息
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...
- Kudu存储实战笔记
有人会问,为啥要用这个叫啥Kudu的,Kudu是啥? 就像官网所说,Kudu是一个针对Apache hadoop 平台而开发的列式存储管理器,在本菜鸟看来,它是一种介于hdfs与hbase的一种存储. ...
- centos7下安装apache服务器httpd的yum方式安装
转自Clement-Xu的csdn博客 http://blog.csdn.net/clementad/article/details/41620631 Apache在Linux系统中,其实叫&qu ...
