1 Star 1 Fork 1

Devin / XPlay3

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
XDemux.cpp 5.38 KB
一键复制 编辑 原始数据 按行查看 历史
伊兴龙 提交于 2022-09-14 16:29 . 增加了推流
#include "XDemux.h"
#include "Xffmepg.h"
XDemux::XDemux()
{
m_pxPushStream = new XPushStream();
}
XDemux::~XDemux()
{
}
static double r2d(AVRational r)
{
return r.den == 0 ? 0:(double)r.num/(double)r.den;
}
bool XDemux::Open(const QString &_qstrUrl)
{
Close();
//参数设置
AVDictionary *AVOption = nullptr;
int iResult = 0;
//设置rtsp流已tcp协议打开
iResult = av_dict_set(&AVOption, "rtsp_transport", "tcp", 0);
if(iResult < 0)
{
qDebug()<<"av_dict_set rtsp_transport error";
return false;
}
//设置网络延时时间
iResult = av_dict_set(&AVOption, "max_delay", "500", 0);
if(iResult < 0)
{
qDebug()<<"av_dict_set max_delay error";
return false;
}
m_qmutDemux.lock();
iResult = avformat_open_input(
&m_avfmtContext,
_qstrUrl.toUtf8().data(),
0, // 0表示自动选择解封器
&AVOption //参数设置,比如rtsp的延时时间
);
if(iResult != 0)
{
m_qmutDemux.unlock();
char buf[1024] = {0};
av_strerror(iResult, buf, sizeof(buf) - 1);
qDebug()<< "open" << _qstrUrl << "error:"<<buf;
return false;
}
else
{
qDebug()<< "open" << _qstrUrl << "success";
}
//获取流信息
iResult = avformat_find_stream_info(m_avfmtContext, 0);
qDebug()<<"iResult = "<<iResult;
//获取总时长
m_iTotalMs = m_avfmtContext->duration / (AV_TIME_BASE / 1000);
//打印视频流详细信息
av_dump_format(m_avfmtContext, 0, _qstrUrl.toUtf8().data(), 0);
//获取视频流
m_iVideoStream = av_find_best_stream(m_avfmtContext, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
AVStream *pAVStream = m_avfmtContext->streams[m_iVideoStream];
//获取视频的宽和高
m_iWidth = pAVStream->codecpar->width;
m_iHeight = pAVStream->codecpar->height;
qDebug()<<"m_iTotalMs == "<<m_iTotalMs;
qDebug()<<"m_iWidth == "<<m_iWidth;
qDebug()<<"m_iHeight == "<<m_iHeight;
//获取音频流
m_iAudioStream = av_find_best_stream(m_avfmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
pAVStream = m_avfmtContext->streams[m_iAudioStream];
//获取音频采样率和通道数
m_iSampleRate = pAVStream->codecpar->sample_rate;
m_iChannels = pAVStream->codecpar->channels;
qDebug()<<"m_iSampleRate == "<<m_iSampleRate;
qDebug()<<"m_iChannels == "<<m_iChannels;
m_qmutDemux.unlock();
return true;
}
void XDemux::Close()
{
m_qmutDemux.lock();
if(m_avfmtContext)
{
//关闭解封装上下文
avformat_close_input(&m_avfmtContext);
}
m_qmutDemux.unlock();
}
void XDemux::Clear()
{
m_qmutDemux.lock();
if(m_avfmtContext)
{
//清理解封装上下文
avformat_flush(m_avfmtContext);
}
if(m_pxPushStream)
{
m_pxPushStream->Clear();
delete m_pxPushStream;
m_pxPushStream = nullptr;
}
m_qmutDemux.unlock();
}
AVCodecParameters *XDemux::CopyVideoParam()
{
m_qmutDemux.lock();
if(!m_avfmtContext)
{
m_qmutDemux.unlock();
return nullptr;
}
AVCodecParameters *avCodecParam = avcodec_parameters_alloc();
avcodec_parameters_copy(avCodecParam, m_avfmtContext->streams[m_iVideoStream]->codecpar);
m_qmutDemux.unlock();
return avCodecParam;
}
AVCodecParameters *XDemux::CopyAudioParam()
{
m_qmutDemux.lock();
if(!m_avfmtContext)
{
m_qmutDemux.unlock();
return nullptr;
}
AVCodecParameters *avCodecParam = avcodec_parameters_alloc();
avcodec_parameters_copy(avCodecParam, m_avfmtContext->streams[m_iAudioStream]->codecpar);
m_qmutDemux.unlock();
return avCodecParam;
}
AVPacket *XDemux::ReadFramePacket()
{
m_qmutDemux.lock();
if(m_avfmtContext == nullptr)
{
qDebug()<<"m_avfmtContext == nullptr";
m_qmutDemux.unlock();
return nullptr;
}
AVPacket *pAVPacket = av_packet_alloc();
//读取一帧,并分配空间
int iResult = av_read_frame(m_avfmtContext, pAVPacket);
if(iResult)
{
qDebug()<<"iResult != 0";
m_qmutDemux.unlock();
av_packet_free(&pAVPacket);
return nullptr;
}
if(pAVPacket)
{
//qDebug()<<"pAVPacket->size:========"<<pAVPacket->size;
}
if(m_blIsPushStream)
{
m_pxPushStream->PushStream(pAVPacket);
}
//pts转换为毫秒
pAVPacket->pts = pAVPacket->pts*(1000 * (r2d(m_avfmtContext->streams[pAVPacket->stream_index]->time_base)));
pAVPacket->dts = pAVPacket->dts*(1000 * (r2d(m_avfmtContext->streams[pAVPacket->stream_index]->time_base)));
m_qmutDemux.unlock();
return pAVPacket;
}
int XDemux::GetAVPacketType(AVPacket *_pavPacket)
{
if(_pavPacket == nullptr)
{
qDebug()<<"_pavPacket == nullptr";
return AVPACKET_TYPE_ERROR;
}
m_qmutDemux.lock();
if(_pavPacket->stream_index == m_iVideoStream)
{
m_qmutDemux.unlock();
return AVPACKET_TYPE_VIDEO;
}
else if(_pavPacket->stream_index == m_iAudioStream)
{
m_qmutDemux.unlock();
return AVPACKET_TYPE_AUDIO;
}
m_qmutDemux.unlock();
return AVPACKET_TYPE_ERROR;
}
void XDemux::OpenPushStream(QString _qstrPushStreamUrl)
{
if(m_pxPushStream->Init(_qstrPushStreamUrl, "flv", m_avfmtContext))
{
m_blIsPushStream = true;
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/yixinglong/xplay3.git
git@gitee.com:yixinglong/xplay3.git
yixinglong
xplay3
XPlay3
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891