利用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 ...
随机推荐
- 已知有两个水杯,一个11L一个7L,水可以任意使用,求怎么得到2L 的详细解法
问题:有两个水杯,一个是11L一个是7L,水可以随便用,怎么得到2L 1.了解问题的本质 问题中给出了两个杯子,只有这两个杯子有量度,所以只能让杯中的水满进满出才能确定杯子中最后有多少水. 现在问题要 ...
- Java中获取本地某一个目录下的所有文件和文件夹
在从事web开发工作中,经常需要对本地某一个目录下的文件进行处理,而在这之前,我们需要做的就是获取到这个目录下的文件. String filepath = "D:\file";// ...
- python中的字符串格式化
Python中常见的字符串格式化方式包括两种:字符串插入(str%),format函数(str.format()) 1.字符串插入 字符串插入是设置字符串格式的简单方法,与C语言.Fortran语言差 ...
- BZOJ 2822: [AHOI2012]树屋阶梯 [Catalan数 高精度]
2822: [AHOI2012]树屋阶梯 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 779 Solved: 453[Submit][Status] ...
- HDU 4333 Revolving Digits [扩展KMP]【学习笔记】
题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...
- AI 学习新的开始
推荐入门学习 http://www.cnblogs.com/subconscious/p/6240151.html
- Properties工具类
/** * 加载Properties文件 * @param path Properties文件路径 * @return */ private static Properties getClasspat ...
- VS2015安装时问题汇总
安装VS2015遇到teamexplorer严重错误 在控制台管理员权限执行: fsutil behavior set SymlinkEvaluation L2L:1 L2R:1 R2L:1 R2R: ...
- Python中高阶函数sorted()用法
在Python中,有内置的排序方法:sorted(iterable, key, reverse). Sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序.key指定的函数 ...
- 腾讯云微计算实践:从Serverless说起,谈谈边缘计算的未来
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:黄文俊,腾讯云高级产品经理,曾经历过企业级存储.企业级容器平台等产品的架构与开发,对容器.微服务.无服务器.DevOps等都有浓厚兴趣. ...
