您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
11. 封装FFDecode解码的Send和Recv接口~1
发布时间:2021-06-09 17:16:16编辑:雪饮阅读()
接收压缩包和发送压缩包,需要实现Send和Recv接口。cpp/IDecode.h:
#define XPLAY_IDECODE_H
#include "XParameter.h"
#include "IObserver.h"
//解码接口,支持硬解码
class IDecode:public IObserver
{
public:
//打开解码器
virtual bool Open(XParameter para) = 0;
//future模型发送数据到线程解码
virtual bool SendPacket(XData pkt) = 0;
//从线程中获取解码结果
virtual XData RecvFrame() = 0;
};
#endif //XPLAY_IDECODE_H
然后接下来就是这SendPacket、RecvFrame方法的具体实现:cpp/ FFDecode.cpp:
你会发现魅族16T仍旧可以执行成功。没有问题的。
#define XPLAY_FFDECODE_H
#include "XParameter.h"
#include "IDecode.h"
struct AVCodecContext;
struct AVFrame;
class FFDecode:public IDecode
{
public:
virtual bool Open(XParameter para);
//future模型发送数据到线程解码
virtual bool SendPacket(XData pkt);
//从线程中获取解码结果
virtual XData RecvFrame();
protected:
AVCodecContext *codec = 0;
AVFrame *frame = 0;
};
#endif //XPLAY_FFDECODE_H
{
#include <libavcodec/avcodec.h>
}
#include "FFDecode.h"
#include "XLog.h"
bool FFDecode::Open(XParameter para)
{
if(!para.para) return false;
AVCodecParameters *p = para.para;
//1 查找解码器
AVCodec *cd = avcodec_find_decoder(p->codec_id);
if(!cd)
{
XLOGE("avcodec_find_decoder %d failed!",p->codec_id);
return false;
}
XLOGI("avcodec_find_decoder success!");
//2 创建解码上下文,并复制参数
codec = avcodec_alloc_context3(cd);
avcodec_parameters_to_context(codec,p);
codec->thread_count = 8;
//3 打开解码器
int re = avcodec_open2(codec,0,0);
if(re != 0)
{
char buf[1024] = {0};
av_strerror(re,buf,sizeof(buf)-1);
XLOGE("%s",buf);
return false;
}
XLOGI("avcodec_open2 success!");
return true;
}
bool FFDecode::SendPacket(XData pkt)
{
if(pkt.size<=0 || !pkt.data)return false;
if(!codec)
{
return false;
}
int re = avcodec_send_packet(codec,(AVPacket*)pkt.data);
if(re != 0)
{
return false;
}
return true;
}
//从线程中获取解码结果
XData FFDecode::RecvFrame()
{
if(!codec)
{
return XData();
}
if(!frame)
{
frame = av_frame_alloc();
}
int re = avcodec_receive_frame(codec,frame);
if(re != 0)
{
return XData();
}
XData d;
d.data = (unsigned char *)frame;
if(codec->codec_type == AVMEDIA_TYPE_VIDEO){
//YUV分别对应0,1,2
d.size = (frame->linesize[0] + frame->linesize[1] + frame->linesize[2])*frame->height;
}
return d;
}
关键字词:Send