北京做网站好的,网站推广软件信息,wordpress添加页头代码,如何查询企业联系方式面向对象开发的五大基本原则
单一职责 各个模块相对独立#xff0c;优点一#xff1a;在修改其中某个模块的时候不会对其他模块造成影响#xff1b;优点二#xff1a;可以对各个模块进行单独的测试#xff1b;例如解封装模块和解码模块相互独立设计。
开闭原则 对扩展…面向对象开发的五大基本原则
单一职责 各个模块相对独立优点一在修改其中某个模块的时候不会对其他模块造成影响优点二可以对各个模块进行单独的测试例如解封装模块和解码模块相互独立设计。
开闭原则 对扩展开发修改封闭。例如增加一个功能时对之前的业务逻辑不需要变更只需要添加新的方案。
替换原则 一个类的派生类可以直接替换基类的方法。保证基类接口功能不变子类去实现自己的接口方法。
接口隔离 内部对用户进行隔离使用户只使用我们提供的公共接口。
依赖倒置 尽量依靠抽象来编程外部变成全部是基于抽象接口来编程。
超级播放器UML整体架构 #pragma once
#include mutex
struct AVFormatContext;
struct AVPacket;
struct AVCodecParameters;
class XDemux
{
public://打开媒体文件或者流媒体 rtmp http rstpvirtual bool Open(const char *url);//空间需要调用者释放 释放AVPacket对象空间和数据空间 av_packet_freevirtual AVPacket *Read();virtual bool IsAudio(AVPacket *pkt);//获取视频参数 返回的空间需要清理 avcodec_parameters_freevirtual AVCodecParameters *CopyVPara();//获取音频参数 返回的空间需要清理 avcodec_parameters_freevirtual AVCodecParameters *CopyAPara();//seek 位置 pos 0.0 ~1.0virtual bool Seek(double pos);//清空读取缓存virtual void Clear();virtual void Close();XDemux();virtual ~XDemux();//媒体总时长毫秒int totalMs 0;int width 0;int height 0;int sampleRate 0;int channels 0;
protected:std::mutex mux;//解封装上下文AVFormatContext *FormatContext NULL;//音视频索引读取时区分音视频int videoStream 0;int audioStream 1;};
#include XDemux.h
#include iostream
using namespace std;
extern C {
#include libavformat/avformat.h
}static double r2d(AVRational r)
{return r.den 0 ? 0 : (double)r.num / (double)r.den;
}bool XDemux::Open(const char *url)
{//防止重复打开先进行关闭Close();//参数设置//AVDictionary *opts NULL;设置rtsp流已tcp协议打开//av_dict_set(opts, rtsp_transport, tcp, 0);网络延时时间//av_dict_set(opts, max_delay, 500, 0);//加锁防止多线程重复操作mux.lock();int re avformat_open_input(FormatContext,url,NULL, // 0表示自动选择解封器NULL //参数设置比如rtsp的延时时间);if (re ! 0){mux.unlock();char buf[1024] { 0 };av_strerror(re, buf, sizeof(buf) - 1);cout open url failed! : buf endl;return false;}cout open url success! endl;//获取流信息 re avformat_find_stream_info(FormatContext, 0);//总时长 毫秒int totalMs FormatContext-duration / (AV_TIME_BASE / 1000);cout totalMs totalMs endl;//打印视频流详细信息av_dump_format(FormatContext, 0, url, 0);//获取视频流videoStream av_find_best_stream(FormatContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);AVStream *as FormatContext-streams[videoStream];width as-codecpar-width;height as-codecpar-height;cout endl;cout videoStream 视频信息 endl;cout codec_id as-codecpar-codec_id endl;cout format as-codecpar-format endl;cout width as-codecpar-width endl;cout height as-codecpar-height endl;//帧率 fps 分数转换cout video fps r2d(as-avg_frame_rate) endl;cout endl;cout audioStream 音频信息 endl;//获取音频流audioStream av_find_best_stream(FormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);as FormatContext-streams[audioStream];sampleRate as-codecpar-sample_rate;channels as-codecpar-channels;cout codec_id as-codecpar-codec_id endl;cout format as-codecpar-format endl;cout sample_rate as-codecpar-sample_rate endl;//AVSampleFormat;cout channels as-codecpar-channels endl;//一帧数据 单通道样本数 cout frame_size as-codecpar-frame_size endl;//1024 * 2 * 2 4096 fps sample_rate/frame_sizemux.unlock();return true;
}
//清空读取缓存
void XDemux::Clear()
{mux.lock();if (!FormatContext){mux.unlock();return;}//清理读取缓冲avformat_flush(FormatContext);mux.unlock();
}
void XDemux::Close()
{mux.lock();if (!FormatContext){mux.unlock();return;}avformat_close_input(FormatContext);//媒体总时长毫秒totalMs 0;mux.unlock();
}//seek 位置 pos 0.0 ~1.0
bool XDemux::Seek(double pos)
{mux.lock();if (!FormatContext){mux.unlock();return false;}//清理读取缓冲防止网络流粘包avformat_flush(FormatContext);long long seekPos 0;seekPos FormatContext-streams[videoStream]-duration * pos;int re av_seek_frame(FormatContext, videoStream, seekPos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME);mux.unlock();if (re 0) return false;return true;
}
//获取视频参数 返回的空间需要清理 avcodec_parameters_free
AVCodecParameters *XDemux::CopyVPara()
{mux.lock();if (!FormatContext){mux.unlock();return NULL;}AVCodecParameters *pa avcodec_parameters_alloc();avcodec_parameters_copy(pa, FormatContext-streams[videoStream]-codecpar);mux.unlock();return pa;
}//获取音频参数 返回的空间需要清理 avcodec_parameters_free
AVCodecParameters *XDemux::CopyAPara()
{mux.lock();if (!FormatContext){mux.unlock();return NULL;}AVCodecParameters *pa avcodec_parameters_alloc();avcodec_parameters_copy(pa, FormatContext-streams[audioStream]-codecpar);mux.unlock();return pa;
}
bool XDemux::IsAudio(AVPacket *pkt)
{if (!pkt) return false;if (pkt-stream_index videoStream)return false;return true;}
//空间需要调用者释放 释放AVPacket对象空间和数据空间 av_packet_free
AVPacket *XDemux::Read()
{//防止Open被线程性关掉mux.lock();if (!FormatContext) //容错{mux.unlock();return 0;}//定义一个临时的AVPacket用于解码使用AVPacket *pkt av_packet_alloc();//读取一帧并分配空间int re av_read_frame(FormatContext, pkt);if (re ! 0){mux.unlock();av_packet_free(pkt);return 0;}//pts转换为毫秒pkt-pts pkt-pts*(1000 * (r2d(FormatContext-streams[pkt-stream_index]-time_base)));pkt-dts pkt-dts*(1000 * (r2d(FormatContext-streams[pkt-stream_index]-time_base)));mux.unlock();cout **********************************\n;cout PKT DTS: pkt-dts endl;cout PKT PTS: pkt-pts endl;/*cout pkt-pts flush;*/return pkt;}
XDemux::XDemux()
{//防止多线程访问不会出现问题static bool isFirst true;//每次只进一个线程,只内部知道 外部不需要知道static std::mutex dmux;dmux.lock();if (isFirst){//初始化封装库av_register_all();//初始化网络库 可以打开rtsp rtmp http 协议的流媒体视频avformat_network_init();isFirst false;}dmux.unlock();
}XDemux::~XDemux()
{
}本项目下载链接