#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QDateTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
AVFormatContext* pFormatCtx = nullptr;
AVCodecContext* pCodecCtx = nullptr;
AVCodec* pCodec = nullptr; // 解码器
int iVideoIndex = 0, iaudioIndex = 0, iRet = 0;
AVFrame* pFrame = nullptr;
AVFrame* pFrameYUV = nullptr;
AVPacket* pPacket = nullptr;
unsigned char* out_buffer = nullptr;
SwsContext* pSwsCtx = nullptr;
FILE* fp_yuv = nullptr;
int got_picture = 0;
// sdl
int nScreen_w = 0, nScreen_h = 0;
SDL_Window* pScreen = nullptr; // 播放窗口
SDL_Renderer* pRender = nullptr; // 渲染器
SDL_Texture* pSDLTexture = nullptr; // 纹理
//char filepath[] = "rtmp://ns8.indexforce.com/home/mystream";
//char filepath[] = "rtsp://192.168.20.2/chn1";
char filepath[] = "11.mp4";
SDLHandle* m_pSDlHandle = nullptr;
qDebug()<<"FFMpeg version :"<<QString(av_version_info());
// ffmpeg
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if (!pFormatCtx)
{
printf("avformat_alloc_context error!\n");
goto exit;
}
// 该函数用于打开多媒体数据并且获得一些相关的信息
if (avformat_open_input(&pFormatCtx, filepath, nullptr, nullptr) < 0)
{
printf("avformat_open_input failed!\n");
goto exit;
}
// 该函数可以读取一部分视音频数据并且获得一些相关的信息
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0)
{
printf("avformat_find_stream_info error!\n");
goto exit;
}
iVideoIndex = -1;
for (int i=0; i< pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
iVideoIndex = i;
}
else if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
iaudioIndex = i;
}
}
if (iVideoIndex == -1)
{
printf("not find a video stream.\n");
goto exit;
}
if (iaudioIndex == -1)
{
printf("not find a audio stream.\n");
goto exit;
}
pCodecCtx = pFormatCtx->streams[iVideoIndex]->codec;
nScreen_w = pCodecCtx->width;
nScreen_h = pCodecCtx->height;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id); // 查找解码器
if (pCodec == nullptr)
{
printf("avcodec_find_decode error.\n");
goto exit;
}
if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0)
{
printf("avcodec_open2 failed!\n");
goto exit;
}
printf("--------------- File Information ----------------\n");
av_dump_format(pFormatCtx, 0, filepath, 0);
printf("-------------------------------------------------\n");
// 解码准备
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
pPacket = (AVPacket*)av_malloc(sizeof(AVPacket));
// 申请内存 w*h*1.5(Y:w*h U:w*h/4 V:w*h/4)
out_buffer = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1));
av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
pSwsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, nullptr, nullptr, nullptr);
m_pSDlHandle = new SDLHandle(pCodecCtx->width, pCodecCtx->height);//(1000,800);//pCodecCtx->width, pCodecCtx->height);
if (!m_pSDlHandle->CreateSDLWindow("SDL_TEXT", SDL_WINDOW_OPENGL))
{
printf("CreateSDLWindow error:%s\n", SDL_GetError());
goto exit;
}
// 解码
while (av_read_frame(pFormatCtx,pPacket) >= 0)
{
if (pPacket->stream_index == iVideoIndex) // 视频packet
{
iRet = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, pPacket);
if (iRet < 0)
{
printf("avcodec_decode_video2 error!\n");
goto exit;
}
if (got_picture)
{
sws_scale(pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
m_pSDlHandle->UpdateTexture(pFrame);
}
QImage output(pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB888); //构造一个QImage用作输出
int outputLineSize[3]; //构造AVFrame到QImage所需要的数据
av_image_fill_linesizes(outputLineSize,AV_PIX_FMT_RGB24,pCodecCtx->width);
uint8_t *outputDst[]={output.bits()};
sws_scale(pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, outputDst, outputLineSize);
QDateTime current_date_time = QDateTime::currentDateTime();
//获取当前时间
QString current_time = current_date_time.toString("hh_mm_ss_zzz");
qDebug() << "video::run :" << current_time;
output.save("./images/" + current_time+".jpg");
qDebug()<<"video avcodec_receive_frame success";
}
// else if(pPacket->stream_index == )
// {
// }
av_free_packet(pPacket);
}
// 解码器虽然读完了 但是还有一些帧缓存
while (true)
{
iRet = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, pPacket);
if (iRet < 0)
{
break;
}
if (!got_picture)
{
break;
}
sws_scale(pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
m_pSDlHandle->UpdateTexture(pFrame);
}
exit:
if (m_pSDlHandle)
{
delete m_pSDlHandle;
m_pSDlHandle = nullptr;
}
if (pSwsCtx)
{
sws_freeContext(pSwsCtx);
}
if (pFrame)
{
av_frame_free(&pFrame);
}
if (pFrameYUV)
{
av_frame_free(&pFrameYUV);
}
if (pCodecCtx)
{
avcodec_close(pCodecCtx);
}
if (pFormatCtx)
{
avformat_close_input(&pFormatCtx);
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
ubuntu下使用SDL和FFmpeg进行播放视频文件和实时流媒体
需积分: 9 2 下载量 10 浏览量
2022-10-27
15:37:18
上传
评论
收藏 94.94MB GZ 举报
温馨提示
共247个文件
h:189个
a:11个
pc:9个
ubuntu下使用SDL和FFmpeg进行播放视频文件和实时流媒体
资源推荐
资源详情
资源评论
收起资源包目录
ubuntu下使用SDL和FFmpeg进行播放视频文件和实时流媒体 (247个子文件)
libSDL2-2.0.so.0 7.39MB
libSDL2-2.0.so.0.12.0 7.39MB
libavcodec.so.58.18.100 57.08MB
libavformat.so.58.12.100 17.28MB
libavfilter.so.7.16.100 10.61MB
libswscale.so.5.1.100 2.44MB
libavutil.so.56.14.100 1.4MB
libavdevice.so.58.3.100 449KB
libpostproc.so.55.1.100 309KB
libswresample.so.3.1.100 294KB
libswresample.so.3 294KB
libswscale.so.5 2.44MB
libpostproc.so.55 309KB
libavutil.so.56 1.4MB
libavcodec.so.58 57.08MB
libavformat.so.58 17.28MB
libavdevice.so.58 449KB
libavfilter.so.7 10.61MB
libavcodec.a 142.85MB
libavformat.a 50.84MB
libavfilter.a 26.84MB
libSDL2.a 9.69MB
libswscale.a 5.63MB
libavutil.a 2.59MB
libavdevice.a 1.33MB
libSDL2_test.a 880KB
libpostproc.a 610KB
libswresample.a 572KB
libSDL2main.a 6KB
sdl2-config.cmake 2KB
sdl2-config-version.cmake 278B
mainwindow.cpp 6KB
sdlhandle.cpp 2KB
main.cpp 172B
SDL_opengl_glext.h 714KB
avcodec.h 207KB
avformat.h 115KB
SDL_opengles2_gl2ext.h 96KB
SDL_opengl.h 81KB
SDL_egl.h 72KB
SDL_hints.h 56KB
SDL_video.h 45KB
SDL_render.h 44KB
avfilter.h 41KB
SDL_haptic.h 38KB
opt.h 35KB
SDL_audio.h 35KB
pixfmt.h 32KB
SDL_opengles2_gl2.h 31KB
avio.h 31KB
SDL_events.h 30KB
frame.h 28KB
mem.h 23KB
hwcontext.h 22KB
SDL_stdinc.h 22KB
swresample.h 21KB
SDL_surface.h 20KB
intreadwrite.h 18KB
avdevice.h 17KB
SDL_pixels.h 17KB
common.h 16KB
pixdesc.h 15KB
SDL_keycode.h 15KB
SDL_scancode.h 15KB
SDL_gamecontroller.h 14KB
SDL_joystick.h 14KB
avstring.h 14KB
SDL_thread.h 13KB
SDL_test_fuzzer.h 13KB
SDL_config.h 12KB
swscale.h 12KB
imgutils.h 11KB
log.h 11KB
SDL_assert.h 11KB
SDL_mouse.h 11KB
SDL_atomic.h 11KB
SDL_vulkan.h 11KB
buffer.h 10KB
SDL_system.h 10KB
samplefmt.h 10KB
SDL_opengles2_khrplatform.h 10KB
channel_layout.h 9KB
avutil.h 9KB
SDL_syswm.h 9KB
SDL_rwops.h 9KB
SDL_cpuinfo.h 9KB
hash.h 8KB
dict.h 8KB
spherical.h 8KB
mathematics.h 8KB
bprint.h 8KB
parseutils.h 7KB
SDL_sensor.h 7KB
encryption_info.h 7KB
SDL_mutex.h 7KB
buffersrc.h 6KB
SDL_endian.h 6KB
SDL_log.h 6KB
SDL_keyboard.h 6KB
buffersink.h 6KB
共 247 条
- 1
- 2
- 3
资源评论
qq_40170041
- 粉丝: 1679
- 资源: 31
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功