#include "ffmpeg.h"
#include <QDebug>
#include <QImage>
#include "AudioPlayer.h"
ffmpeg::ffmpeg()
{
}
ffmpeg::~ffmpeg()
{
avformat_free_context(m_avFormatContext);
}
void ffmpeg::initBase()
{
avcodec_register_all();//注册所有解码器
av_register_all();//注册所有格式
avformat_network_init();//初始化网络流格式,使用RTSP网络流时必须先执行
if(nullptr == m_avFormatContext)
m_avFormatContext = avformat_alloc_context();
m_yuvFrame = av_frame_alloc();
m_pcmFrame = av_frame_alloc();
}
bool ffmpeg::initFFmpeg(QString url)
{
deleteFFmpeg();
if(nullptr == m_avFormatContext)
initBase();
//打开视频流
int result=avformat_open_input(&m_avFormatContext, url.toStdString().c_str(),nullptr,nullptr);
if (result<0)
{
qDebug()<<"avformat_open_input error ---"<<result;
return false;
}
//获取视频流信息
result=avformat_find_stream_info(m_avFormatContext,nullptr);
if (result<0)
{
qDebug()<<"avformat_find_stream_info error ---"<<result;
return false;
}
if(!initAudio())
{
qDebug()<<"init audio error";
return false;
}
if(!initVideo())
{
qDebug()<<"init Video error";
return false;
}
return true;
}
bool ffmpeg::initAudio()
{
//获取音频流索引
for (uint i = 0; i < m_avFormatContext->nb_streams; i++)
{
if (AVMEDIA_TYPE_AUDIO == m_avFormatContext->streams[i]->codec->codec_type)
{
m_audioCodecContext = m_avFormatContext->streams[i]->codec;
m_audioStreamIndex = i;
break;
}
}
if (-1 == m_audioStreamIndex)
{
qDebug()<<"audioStreamIndex init error -----";
return false;
}
if(nullptr == m_audioCodecContext)
{
qDebug()<<"m_audioCidecContext error---";
return false;
}
//初始化一个视音频编解码器的AVCodecContext
AVCodec *codec = avcodec_find_decoder(m_audioCodecContext->codec_id);//查找解码器
if (avcodec_open2(m_audioCodecContext, codec, nullptr) < 0)
{
qDebug()<<"avcodec_open2 error---";
return false;
}
m_sampleRate = m_audioCodecContext->sample_rate;//样本率
m_channel = m_audioCodecContext->channels;//通道数
switch (m_audioCodecContext->sample_fmt)//样本大小
{
case AV_SAMPLE_FMT_S16:
this->m_sampleSize = 16;
break;
case AV_SAMPLE_FMT_S32:
this->m_sampleSize = 32;
default:
break;
}
//初始化音频的设备
AudioPlayer::Get()->m_sampleRate = m_sampleRate;
AudioPlayer::Get()->m_channel = m_channel;
AudioPlayer::Get()->m_sampleSize = m_sampleSize;
AudioPlayer::Get()->Start();
if (nullptr == m_audioSwrContext)
{
m_audioSwrContext = swr_alloc();//初始化
swr_alloc_set_opts(m_audioSwrContext,m_audioCodecContext->channel_layout,
AV_SAMPLE_FMT_S16,
m_audioCodecContext->sample_rate,
m_audioCodecContext->channels,
m_audioCodecContext->sample_fmt,
m_audioCodecContext->sample_rate,
0,0
);
swr_init(m_audioSwrContext);
}
return true;
}
bool ffmpeg::initVideo()
{
//获取视频流索引
for (uint i = 0; i < m_avFormatContext->nb_streams; i++)
{
if (AVMEDIA_TYPE_VIDEO == m_avFormatContext->streams[i]->codec->codec_type)
{
m_videoStreamIndex = i;
m_videoCodecContext = m_avFormatContext->streams[i]->codec;
break;
}
}
if(-1 == m_videoStreamIndex)
{
qDebug()<<"videoStreamIndex init error---";
return false;
}
if (m_videoCodecContext == nullptr)
{
qDebug()<<"videoCodecContext init error---";
return false;
}
//获取视频流解码器
AVCodec *pAVCodec = avcodec_find_decoder(m_videoCodecContext->codec_id);
//打开对应解码器
int result=avcodec_open2(m_videoCodecContext,pAVCodec,nullptr);
if (result<0)
{
qDebug()<<"avcodec_open2 video open error";
return false;
}
m_videoSwsContext = sws_getContext(m_videoCodecContext->width,m_videoCodecContext->height,
m_videoCodecContext->pix_fmt,
m_videoCodecContext->width,m_videoCodecContext->height,
AV_PIX_FMT_BGRA,SWS_BICUBIC,0,0,0);
avpicture_alloc(&pAVPicture,AV_PIX_FMT_BGRA,m_videoCodecContext->width,m_videoCodecContext->height);
return true;
}
AVPacket ffmpeg::getPacket()
{
AVPacket pkt;
memset(&pkt, 0, sizeof(AVPacket));
if (!m_avFormatContext)
{
return pkt;
}
int err = av_read_frame(m_avFormatContext, &pkt);//读取视频帧
if (err != 0)//读取失败
{
char errorbuff[1024];//错误信息
av_strerror(err, errorbuff, sizeof(errorbuff));
}
return pkt;
}
bool ffmpeg::decode(const AVPacket *pkt)
{
m_mutex.lock();
if (!m_avFormatContext)
{
m_mutex.unlock();
return false;
}
AVFrame *frame;
if (pkt->stream_index == m_audioStreamIndex)
{
frame = m_pcmFrame;//此时frame是解码后的音频流
}
else
{
frame = m_yuvFrame;
}
int re = avcodec_send_packet(m_avFormatContext->streams[pkt->stream_index]->codec, pkt);//发送之前读取的pkt
if (re != 0)
{
m_mutex.unlock();
qDebug()<<"avcodec_send_packet error---"<<re;
return NULL;
}
re = avcodec_receive_frame(m_avFormatContext->streams[pkt->stream_index]->codec, frame);//解码pkt后存入yuv中
if (re != 0)
{
m_mutex.unlock();
qDebug()<<"avcodec_receive_frame error---"<<re;
return NULL;
}
m_mutex.unlock();
return true;
}
int ffmpeg::getPCM(char *out)
{
m_mutex.lock();
uint8_t *data[1];
data[0] = (uint8_t *)out;
int len = swr_convert(m_audioSwrContext, data, 10000,
(const uint8_t **)m_pcmFrame->data,
m_pcmFrame->nb_samples
);
if (len <= 0)
{
m_mutex.unlock();
return 0;
}
int outsize = av_samples_get_buffer_size(nullptr, m_audioCodecContext->channels,
m_pcmFrame->nb_samples,
AV_SAMPLE_FMT_S16,
0);
m_mutex.unlock();
return outsize;
}
void ffmpeg::getRBG()
{
m_mutex.lock();
int result = sws_scale(m_videoSwsContext,m_yuvFrame->data,m_yuvFrame->linesize,
0,m_videoCodecContext->height,pAVPicture.data,pAVPicture.linesize);
if (result<0)
{
m_mutex.unlock();
return;
}
//发送获取一帧图像信号
QImage image(pAVPicture.data[0],m_videoCodecContext->width,m_videoCodecContext->height,QImage::Format_ARGB32);
emit GetImage(image);
m_mutex.unlock();
}
void ffmpeg::deleteFFmpeg()
{
m_mutex.lock();
avformat_close_input(&m_avFormatContext);
av_free(m_yuvFrame);
av_free(m_pcmFrame);
if (m_videoSwsContext)
{
sws_freeContext(m_videoSwsContext);
m_videoSwsContext = nullptr;
}
if (m_audioSwrContext)
{
swr_free(&m_audioSwrContext);
}
m_mutex.unlock();
}
没有合适的资源?快使用搜索试试~ 我知道了~
QtFFmpeg 音视频播放器 demo
共172个文件
h:116个
dll:14个
cpp:10个
需积分: 50 45 下载量 105 浏览量
2021-09-18
17:53:59
上传
评论 1
收藏 39.02MB ZIP 举报
温馨提示
使用FFmpeg库的音视频播放器,qt工程,支持本地文件和rtp流,该demo只是展示了ffmpeg的基本使用方式。适合初学者 qt5.12 vs2019 x86 ffmpeg3.4.8
资源详情
资源评论
资源推荐
收起资源包目录
QtFFmpeg 音视频播放器 demo (172个子文件)
ffmpeg.cpp 8KB
moc_VideoThread.cpp 4KB
moc_ffmpeg.cpp 4KB
moc_mainwindow.cpp 4KB
moc_OpenglWidget.cpp 4KB
AudioPlayer.cpp 2KB
VideoThread.cpp 1KB
mainwindow.cpp 1KB
OpenglWidget.cpp 660B
main.cpp 183B
Makefile.Debug 103KB
avcodec-57.dll 12.74MB
avcodec-57.dll 12.74MB
avformat-57.dll 2.76MB
avformat-57.dll 2.76MB
avfilter-6.dll 2.69MB
avfilter-6.dll 2.69MB
avutil-55.dll 1.1MB
avutil-55.dll 1.1MB
swscale-4.dll 979KB
swscale-4.dll 979KB
avdevice-57.dll 617KB
avdevice-57.dll 617KB
swresample-2.dll 558KB
swresample-2.dll 558KB
ffmpeg.exe 779KB
ffmpeg.exe 779KB
ffprobe.exe 594KB
ffprobe.exe 594KB
QtFFmpegPlayer.exe 44KB
avcodec.h 213KB
avformat.h 113KB
avfilter.h 42KB
opt.h 35KB
pixfmt.h 34KB
avio.h 31KB
frame.h 26KB
mem.h 23KB
hwcontext.h 22KB
swresample.h 21KB
intreadwrite.h 18KB
avdevice.h 17KB
common.h 15KB
pixdesc.h 15KB
avstring.h 14KB
swscale.h 12KB
log.h 11KB
imgutils.h 11KB
buffer.h 10KB
samplefmt.h 10KB
channel_layout.h 9KB
avutil.h 9KB
hash.h 8KB
dict.h 8KB
version.h 8KB
spherical.h 8KB
mathematics.h 8KB
vdpau.h 8KB
bprint.h 8KB
parseutils.h 7KB
buffersrc.h 6KB
buffersink.h 6KB
hwcontext_d3d11va.h 6KB
xvmc.h 6KB
vda.h 6KB
audio_fifo.h 6KB
fifo.h 6KB
rational.h 6KB
cpu.h 5KB
error.h 5KB
tree.h 5KB
timecode.h 5KB
eval.h 5KB
version.h 5KB
stereo3d.h 5KB
attributes.h 4KB
hwcontext_drm.h 4KB
vaapi.h 4KB
dirac.h 4KB
videotoolbox.h 4KB
mastering_display_metadata.h 4KB
version.h 4KB
hwcontext_vaapi.h 4KB
qsv.h 4KB
dv_profile.h 4KB
ui_mainwindow.h 4KB
threadmessage.h 4KB
display.h 3KB
murmur3.h 3KB
downmix_info.h 3KB
crc.h 3KB
avfft.h 3KB
hmac.h 3KB
bswap.h 3KB
d3d11va.h 3KB
xtea.h 3KB
mediacodec.h 3KB
version.h 3KB
timestamp.h 3KB
avdct.h 3KB
共 172 条
- 1
- 2
不要碧莲赵小二
- 粉丝: 3
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0