EasyDarwin接入ffmpeg实现264转图片快照功能

来源:互联网 发布:小学生网络道德教育 编辑:程序博客网 时间:2024/05/18 01:02

本文转自:http://blog.csdn.net/cai6811376/article/details/51774467

EasyDarwin一直坚持开源精神,所以我们着手把EasyDarwin中使用的非开源工具替换为开源项目。

我们将EasyCMS中使用的图片保存替换为FFmpeg。(这里说明Windows版)

  • 首先到ffmpeg官网下载编译好的ffmpeg文件

下载页面:https://ffmpeg.zeranoe.com/builds/

ffmpeg

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_MACROSextern "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.org

WEB:www.EasyDarwin.org

QQ交流群:288214068

Copyright © EasyDarwin.org 2012-2015

EasyDarwin

0 0
原创粉丝点击