EasyDarwin接入ffmpeg实现264转图片快照功能
2016-06-29 14:30
471 查看
本文转自:http://blog.csdn.net/cai6811376/article/details/51774467
EasyDarwin一直坚持开源精神,所以我们着手把EasyDarwin中使用的非开源工具替换为开源项目。
我们将EasyCMS中使用的图片保存替换为FFmpeg。(这里说明Windows版)
首先到ffmpeg官网下载编译好的ffmpeg文件
下载页面:https://ffmpeg.zeranoe.com/builds/
![](http://img.blog.csdn.net/20160628111014033)
Shared包含.dll文件,Dev包含.h和.lib文件
将.h/.lib/.dll引入EasyDarwin工程
.h放入EasyDarwin/Include/FFmpeg下
.lib放入EasyDarwin/Lib/FFmpeg/x86下
.dll放入EasyDarwin/Bin/FFmpeg/x86下
编写DecoderHelper类
DecoderHelper.h
DecoderHelper.cpp
使用
WEB:www.EasyDarwin.org
QQ交流群:288214068
Copyright © EasyDarwin.org 2012-2015
EasyDarwin一直坚持开源精神,所以我们着手把EasyDarwin中使用的非开源工具替换为开源项目。
我们将EasyCMS中使用的图片保存替换为FFmpeg。(这里说明Windows版)
首先到ffmpeg官网下载编译好的ffmpeg文件
下载页面:https://ffmpeg.zeranoe.com/builds/
Shared包含.dll文件,Dev包含.h和.lib文件
将.h/.lib/.dll引入EasyDarwin工程
.h放入EasyDarwin/Include/FFmpeg下
.lib放入EasyDarwin/Lib/FFmpeg/x86下
.dll放入EasyDarwin/Bin/FFmpeg/x86下
编写DecoderHelper类
DecoderHelper.h
#ifndef _DECODER_HELPER_ #define _DECODER_HELPER_ #define __STDC_CONSTANT_MACROS extern "C" { #include <inttypes.h> #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/avutil.h" #include "libavutil/imgutils.h" #include "libswresample/swresample.h" #include "libswscale/swscale.h" } class DecoderHelper { public: DecoderHelper(); ~DecoderHelper(); int SetVideoDecoderParam(int width, int height, int codec, int format); int DecodeVideo(char *inBuff, int inBuffSize, void *yuvBuff, int width, int height); private: void releaseVideoDecoder(); private: AVFormatContext* _formatContext; AVCodecContext* _videoCodecContext; AVFrame* _videoFrame420; struct SwsContext* _swsContext; uint8_t* _buffYUV420; AVPacket _videoAVPacket; uint8_t* _buffYUV; AVFrame* _avframeYUV; AVFrame* _avframeSWS; int _codec; int _width; int _height; int _outputFormat; }; #endif //_DECODER_HELPER_
DecoderHelper.cpp
#include "DecoderHelper.h" DecoderHelper::DecoderHelper() : _formatContext(NULL), _videoCodecContext(NULL), _videoFrame420(NULL), _buffYUV420(NULL), _buffYUV(NULL), _avframeYUV(NULL), _avframeSWS(NULL), _swsContext(NULL), _codec(0), _width(0), _height(0), _outputFormat(0) { //Register all the codec avcodec_register_all(); //Register all types of decoding av_register_all(); } DecoderHelper::~DecoderHelper() { releaseVideoDecoder(); } int DecoderHelper::SetVideoDecoderParam(int width, int height, int codec, int format) { if (_width != width || _height != height || _codec != codec) { releaseVideoDecoder(); } if (NULL != _videoCodecContext) { return -1; } AVCodec *avcodec = avcodec_find_decoder((AVCodecID)codec); if (NULL == avcodec) { return -1; } _videoCodecContext = avcodec_alloc_context3(avcodec); _videoCodecContext->pix_fmt = AV_PIX_FMT_YUV420P; _videoCodecContext->width = width; _videoCodecContext->height = height; int ret = avcodec_open2(_videoCodecContext, avcodec, NULL); if (ret < 0) { goto $fail; } int numBytes = avpicture_get_size(AV_PIX_FMT_YUV420P, width, height); _buffYUV420 = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t)); _videoFrame420 = av_frame_alloc(); if (avpicture_fill((AVPicture *)_videoFrame420, _buffYUV420, AV_PIX_FMT_YUV420P, _width, _height) < 0) { } av_init_packet(&_videoAVPacket); _width = width; _height = height; _codec = codec; _outputFormat = format; return 0; $fail: { return -1; } } int DecoderHelper::DecodeVideo(char *inBuff, int inBuffSize, void *yuvBuff, int width, int height) { if (NULL == inBuff) return -1; if (1 > inBuffSize) return -1; if (NULL == yuvBuff) return -1; if (NULL == _videoCodecContext) return -2; _videoAVPacket.size = inBuffSize; _videoAVPacket.data = (uint8_t*)inBuff; int frameFinished = 0; int nDecode = avcodec_decode_video2(_videoCodecContext, _videoFrame420, &frameFinished, &_videoAVPacket);//(uint8_t*)pInBuffer, inputSize); if (nDecode < 0) return -3; if (!frameFinished) return -4; if (width != _width || height != _height) { if (NULL != _avframeYUV) { av_frame_free(&_avframeYUV); _avframeYUV = NULL; } if (NULL != _swsContext) { sws_freeContext(_swsContext); _swsContext = NULL; } _width = width; _height = height; } if (NULL == _avframeYUV) { int numBytes = avpicture_get_size((AVPixelFormat)_outputFormat, width, height); _avframeYUV = av_frame_alloc(); } if (NULL == _avframeYUV) return -5; if (avpicture_fill((AVPicture *)_avframeYUV, (uint8_t*)yuvBuff, (AVPixelFormat)_outputFormat, width, height) < 0) { return -1; } if (NULL == _swsContext) { _swsContext = sws_getCachedContext(_swsContext, _videoCodecContext->width, _videoCodecContext->height, (AVPixelFormat)AV_PIX_FMT_YUV420P, width, height, (AVPixelFormat)_outputFormat, SWS_BICUBIC, NULL, NULL, NULL); } if (NULL == _swsContext) return -1; int ret = sws_scale(_swsContext, _videoFrame420->data, _videoFrame420->linesize, 0, _videoCodecContext->height, _avframeYUV->data, _avframeYUV->linesize); return 0; } void DecoderHelper::releaseVideoDecoder() { if (NULL != _videoFrame420) { av_frame_free(&_videoFrame420); _videoFrame420 = NULL; } if (NULL != _buffYUV420) { av_free(_buffYUV420); _buffYUV420 = NULL; } if (NULL != _avframeSWS) { av_frame_free(&_avframeSWS); _avframeSWS = NULL; } if (NULL != _avframeYUV) { av_frame_free(&_avframeYUV); _avframeYUV = NULL; } if (NULL != _buffYUV) { av_free(_buffYUV); _buffYUV = NULL; } if (NULL != _swsContext) { sws_freeContext(_swsContext); _swsContext = NULL; } if (NULL != _videoCodecContext) { avcodec_close(_videoCodecContext); av_free(_videoCodecContext); _videoCodecContext = NULL; } }
使用
DecoderHelper decoderHelper; decoderHelper.SetVideoDecoderParam(); decoderHelper.DecodeVideo();
获取更多信息
邮件:support@easydarwin.orgWEB:www.EasyDarwin.org
QQ交流群:288214068
Copyright © EasyDarwin.org 2012-2015
![](http://www.easydarwin.org/skin/easydarwin/images/wx_qrcode.jpg)
相关文章推荐
- .net Framework 中的四种计时器
- EasyDarwin接入ffmpeg实现264转图片快照功能
- ASP.NET MVC 域名泛解析设置
- nvr向sip服务器注册失败(未携带摘要等类信息)
- Unity3D中移动物体位置的几种方法
- Java NIO Path
- 关于修改host的一点整理
- MYSQL双主架构搭建方法
- linux top命令
- tomcat,weblogic下配置问题
- IOS获取当前App的基本信息
- 关于Android中MD5加密算法
- Scala学习笔记(八)----类型问题
- [DUBBO] Decode rpc invocation failed: null, dubbo version: 2.8.4, current host: 127.0.0.1
- 侧滑(以Activity为页面)
- Spring3.1包详解与依赖关系
- Java实现MD5加密与解密
- mysql-批量修改表字段中的某一部分内容
- [Android]Android端ORM框架——RapidORM(v2.0)
- 用C#获取局域网内所有机器