#include "ScreenVideo.h"
ScreenVideo::ScreenVideo(QWidget *parent)
: QMainWindow(parent)
, m_bPlay(false)
, m_pInputContext(nullptr)
, m_lVideoIndex(-1)
, m_lLastReadTime(0)
, m_pSwsScale(nullptr)
{
ui.setupUi(this);
connect(ui.m_pBtnBegin, SIGNAL(clicked()), this, SLOT(sloBeginVideo()));
connect(ui.m_pBtnStop, SIGNAL(clicked()), this, SLOT(sloStopVideo()));
connect(ui.m_pRBtnRtsp, SIGNAL(clicked(bool)), this, SLOT(sloRtspPath(bool)));
connect(ui.m_pRBtnRtmp, SIGNAL(clicked(bool)), this, SLOT(sloRtmpPath(bool)));
connect(ui.m_pRBtnUdp, SIGNAL(clicked(bool)), this, SLOT(sloUdpPath(bool)));
ui.m_pBtnStop->setEnabled(false);
long l = avformat_version();
//初始化所有复用器,封装器
//av_register_all();
avfilter_register_all();
//初始化所有输入输出设备
avdevice_register_all();
//初始化网络
avformat_network_init();
av_log_set_level(AV_LOG_INFO);
//自适应DPI设置,windows专用
#ifdef Q_OS_WINDOWS
SetProcessDPIAware();
#endif
}
ScreenVideo::~ScreenVideo()
{
m_bPlay = false;
}
static int interrupt(void *p)
{
ScreenVideo *pThis = (ScreenVideo*)p;
int64_t timeOut = 5;
int64_t timeNow = av_gettime() - pThis->m_lLastReadTime;
if (timeNow >= timeOut * 1000 * 1000)
return -1;
return 0;
}
long ScreenVideo::OpenInput(const char *pUrl)
{
m_pInputContext = avformat_alloc_context();
m_lLastReadTime = av_gettime();
m_pInputContext->interrupt_callback.opaque = this;
m_pInputContext->interrupt_callback.callback = interrupt;
AVDictionary *pOptions = NULL;
av_dict_set(&pOptions, "probesize", "4096", 0);
av_dict_set(&pOptions, "max_delay", "100", 0);
av_dict_set_int(&pOptions, "max_analyze_duration", 5 * AV_TIME_BASE, 0);
if (ui.m_pRBtnRtsp->isChecked())
{
av_dict_set(&pOptions, "rtsp_transport", "tcp", 0);
av_dict_set(&pOptions, "buffer_size", "1024000", 0);
}
long ret = avformat_open_input(&m_pInputContext, pUrl, nullptr, &pOptions);
if (ret >= 0)
{
av_log(NULL, AV_LOG_INFO, "Open input success!\n");
}
else {
av_log(NULL, AV_LOG_INFO, "Open input error!(%d)\n", ret);
return ret;
}
//m_pInputContext->flags |= AVFMT_FLAG_NOBUFFER;
ret = avformat_find_stream_info(m_pInputContext, nullptr);
if (ret >= 0)
{
av_log(NULL, AV_LOG_INFO, "Find stream success!\n");
}
else {
av_log(NULL, AV_LOG_INFO, "Find stream error!(%d)\n", ret);
return ret;
}
for (size_t s = 0;s < m_pInputContext->nb_streams; s++)
{
if (m_pInputContext->streams[s]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
m_lVideoIndex = s;
break;
}
}
if (m_lVideoIndex < 0)
return -1;
return 0;
}
void ScreenVideo::CloseInput()
{
if (m_pInputContext != nullptr)
avformat_close_input(&m_pInputContext);
}
long ScreenVideo::InitDecode()
{
AVCodecContext *pCodecContext = m_pInputContext->streams[m_lVideoIndex]->codec;
AVCodec *pCodec= avcodec_find_decoder(pCodecContext->codec_id);
long ret = avcodec_open2(pCodecContext, pCodec, nullptr);
if (ret >= 0)
{
av_log(NULL, AV_LOG_INFO, "decoder open success!\n");
}
else {
av_log(NULL, AV_LOG_ERROR, "decoder open error!(%d)\n", ret);
return ret;
}
return ret;
}
void ScreenVideo::UnInitDecode()
{
if (m_pInputContext != nullptr && m_lVideoIndex >= 0)
avcodec_close(m_pInputContext->streams[m_lVideoIndex]->codec);
}
long ScreenVideo::DecodePacket(AVFrame *pDstFrame, AVPacket *pPktSrc)
{
int got_picture = 0;
AVCodecContext *pCodecContext = m_pInputContext->streams[m_lVideoIndex]->codec;
long ret = avcodec_decode_video2(pCodecContext, pDstFrame, &got_picture, pPktSrc);
if (ret >= 0 && got_picture != 0)
return 0;
return -1;
}
long ScreenVideo::InitSwsScale(long lSrcW, long lSrcH, AVPixelFormat sSrcPix, long lDstW, long lDstH, AVPixelFormat sDstPix)
{
m_pSwsScale = sws_getContext(
lSrcW, lSrcH, sSrcPix,
lDstW, lDstH, sDstPix,
SWS_BICUBIC, NULL, NULL, NULL);
if (m_pSwsScale == nullptr)
return -1;
return 0;
}
std::shared_ptr<AVPacket> ScreenVideo::ReadPacketFromStream()
{
std::shared_ptr<AVPacket> packet(static_cast<AVPacket *>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) {av_packet_free(&p); av_freep(&p); });
av_init_packet(packet.get());
packet->data = NULL;
packet->size = 0;
m_lLastReadTime = av_gettime();
long ret = av_read_frame(m_pInputContext, packet.get());
if (ret >= 0)
return packet;
av_log(NULL, AV_LOG_ERROR, "read packet error!(%d)", ret);
return nullptr;
}
void ScreenVideo::sloBeginVideo()
{
QString qsPath = ui.m_pEdtUrlPath->text();
long ret = OpenInput(qsPath.toLocal8Bit().data());
if (ret >= 0)
ret = InitDecode();
if (ret >= 0) {
long lW = m_pInputContext->streams[m_lVideoIndex]->codec->width;
long lH = m_pInputContext->streams[m_lVideoIndex]->codec->height;
AVPixelFormat sPix = m_pInputContext->streams[m_lVideoIndex]->codec->pix_fmt;
ret = InitSwsScale(lW, lH, sPix, lW, lH, AV_PIX_FMT_RGB32);
}
if (ret >= 0)
{
AVFrame *pFrame = av_frame_alloc();
AVFrame *pRGBFrame = av_frame_alloc();
long lW = m_pInputContext->streams[m_lVideoIndex]->codec->width;
long lH = m_pInputContext->streams[m_lVideoIndex]->codec->height;
long lSize = av_image_get_buffer_size(AV_PIX_FMT_RGB32, lW, lH, 1);
uint8_t *pBuff = static_cast<uint8_t *>(av_malloc(sizeof(uint8_t) * lSize));
av_image_fill_arrays(pRGBFrame->data, pRGBFrame->linesize, pBuff, AV_PIX_FMT_RGB32, lW, lH, 1);
m_bPlay = true;
ui.m_pBtnBegin->setEnabled(false);
ui.m_pBtnStop->setEnabled(true);
long lTemp = AV_PICTURE_TYPE_I;
long lCount = 0;
bool bReConnect = false;
while (m_bPlay)
{
QApplication::processEvents();
std::shared_ptr<AVPacket> pktRead = ReadPacketFromStream();
if (pktRead == nullptr)
{
bReConnect = true;
break;
}
if (pktRead->stream_index == m_lVideoIndex)
{
int64_t lBeginTime = av_gettime();
long dec = DecodePacket(pFrame, pktRead.get());
if (lTemp != pFrame->pict_type)
{
av_log(NULL, AV_LOG_INFO, "Frame is %d pic!(%d)\n", lTemp, lCount);
lTemp = pFrame->pict_type;
lCount = 0;
}
lCount++;
int64_t lDecodeTime = av_gettime() - lBeginTime;
if (dec >= 0)
{
sws_scale(m_pSwsScale, (const UCHAR * const *)pFrame->data, pFrame->linesize, 0, lH, pRGBFrame->data, pRGBFrame->linesize);
QImage img((uchar *)pRGBFrame->data[0], lW, lH, QImage::Format_RGB32);
QPixmap pixmap = QPixmap::fromImage(img);
QPixmap fitpixmap = pixmap.scaled(ui.m_pLblVideo->width(), ui.m_pLblVideo->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); // 饱满填充
ui.m_pLblVideo->setPixmap(fitpixmap);
}
int64_t lEndTime = av_gettime() - lDecodeTime;
}
}
av_free(pBuff);
av_frame_free(&pRGBFrame);
av_frame_free(&pFrame);
UnInitDecode();
CloseInput();
if (bReConnect)
{
sloBeginVideo();
}
}
return;
/*
//long lScreenW = ui.m_pEdtWidth->text().toLong();
//long lScreenH = ui.m_pEdtHeight->text().toLong();
//QString qsVideoSize = QString("%1x%2").arg(lScreenW).arg(lScreenH);
////解码用来显示
//AVFormatContext *pdeFormatCtx = NULL;
//pdeFormatCtx = avformat_alloc_context();
//AVInputFormat *ifmt = av_find_input_format("gdigrab");
//AVDictionary* options = NULL;
//av_dict_set(&options, "framerate", "30", 0);//帧率调整
//av_dict_set(&options, "video_size", qsVideoSize.toLocal8Bit().data(), 0);
//if (avformat_open_input(&pdeFormatCtx,"desktop", ifmt, &options))
//{
// QMessageBox::information(NULL, "说明", "打开输入设备错误!avformat_open_input");
// avformat_close_input(&pdeFormatCtx);
// return ;
//}
//if (avformat_find_stream_info(pdeFormatCtx,NULL) < 0)
//{
// QMessageBox::information(NULL, "说明", "无法找到流!avformat_find_stream_info");
// return;
//}
//AVPacket *pPacketEx = (AVPacket *)av_malloc(sizeof(AVPacket));
//av_read_frame(pdeFormat
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
QT + ffmpeg 播放 rtsp,rtmp,udp视频流 (270个子文件)
新建位图图像.bmp 0B
ScreenVideo.cpp 14KB
main.cpp 10KB
ScreenVideo - 副本.cpp 8KB
moc_ScreenVideo.cpp 4KB
moc_ScreenVideo.cpp 4KB
moc_QtTimeTest.cpp 4KB
moc_QtTimeTest.cpp 4KB
QtTimeTest.cpp 3KB
qrc_ScreenVideo.cpp 1KB
qrc_ScreenVideo.cpp 1KB
qrc_QtTimeTest.cpp 1KB
qrc_QtTimeTest.cpp 1KB
main.cpp 179B
avcodec-58.dll 32.66MB
avcodec-58.dll 32.66MB
avformat-58.dll 9.45MB
avformat-58.dll 9.45MB
avfilter-7.dll 7.02MB
avfilter-7.dll 7.02MB
avdevice-58.dll 1.37MB
avdevice-58.dll 1.37MB
avutil-56.dll 763KB
avutil-56.dll 763KB
swscale-5.dll 507KB
swscale-5.dll 507KB
swresample-3.dll 310KB
swresample-3.dll 310KB
postproc-55.dll 122KB
postproc-55.dll 122KB
QtTimeTest.exe 122KB
ScreenVideo.exe 91KB
ScreenVideo.exe 39KB
QtTimeTest.exe 32KB
ScreenVideo.vcxproj.filters 2KB
QtTimeTest.vcxproj.filters 2KB
avcodec.h 209KB
avformat.h 116KB
avfilter.h 41KB
opt.h 35KB
pixfmt.h 33KB
frame.h 32KB
avio.h 31KB
mem.h 23KB
hwcontext.h 22KB
swresample.h 21KB
intreadwrite.h 18KB
avdevice.h 17KB
common.h 16KB
pixdesc.h 16KB
avstring.h 14KB
hdr_dynamic_metadata.h 12KB
swscale.h 12KB
imgutils.h 11KB
log.h 11KB
buffer.h 10KB
samplefmt.h 10KB
channel_layout.h 9KB
avutil.h 9KB
hash.h 8KB
dict.h 8KB
spherical.h 8KB
mathematics.h 8KB
bprint.h 8KB
parseutils.h 7KB
encryption_info.h 7KB
buffersrc.h 6KB
buffersink.h 6KB
hwcontext_d3d11va.h 6KB
xvmc.h 6KB
audio_fifo.h 6KB
fifo.h 6KB
ui_ScreenVideo.h 6KB
rational.h 6KB
ui_ScreenVideo.h 6KB
vdpau.h 6KB
cpu.h 6KB
error.h 5KB
tree.h 5KB
timecode.h 5KB
eval.h 5KB
stereo3d.h 5KB
version.h 5KB
attributes.h 5KB
hwcontext_drm.h 5KB
version.h 5KB
version.h 4KB
ui_QtTimeTest.h 4KB
ui_QtTimeTest.h 4KB
dirac.h 4KB
videotoolbox.h 4KB
mastering_display_metadata.h 4KB
threadmessage.h 4KB
hwcontext_vaapi.h 4KB
qsv.h 4KB
dv_profile.h 4KB
murmur3.h 4KB
display.h 3KB
mediacodec.h 3KB
downmix_info.h 3KB
共 270 条
- 1
- 2
- 3
资源评论
- 阿里尼2022-04-08编译不过去
llomtff
- 粉丝: 2
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Jurassic Pack Vol. II Dinosaurs 侏罗纪包卷恐龙二号Unity游戏模型资源unitypackage
- Jurassic Pack Vol. III Dinosaurs 侏罗纪包卷恐龙三号Unity游戏模型资源unitypackag
- Ultimate Seating Controller 终极座椅控制器Unity游戏开发插件资源unitypackage
- 什么是人工智能-关于人工智能的相关介绍说明
- Figma Converter for Unity适用Unity的Figma转换器Unity游戏开发插件unitypackage
- Creepy Animatronic Anims 令人毛骨悚然的电子动画Unity游戏动画插件资源unitypackage
- Rankings & Leaderboards 排名和排行榜Unity游戏开发插件资源unitypackage
- Semantic Color Palette 语义调色板Unity游戏开发插件资源unitypackage
- Low Poly Nature:Lush and Diverse Environments低聚自然郁郁Unity低多边形模型资源
- voc数据集是什么-我们如何使用voc数据集
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功