当前位置: 首页 > news >正文

现在做网站建设挣钱吗当前主流的网站开发语言

现在做网站建设挣钱吗,当前主流的网站开发语言,漂亮的蓝色网站,深圳施工目录 学习课题:逐步构建开发播放器【QT5 FFmpeg6 SDL2】 步骤 VideoOutPut模块 1、初始化【分配缓存、读取信息】 2、开始线程工作【从队列读帧->缩放->发送渲染信号到窗口】 VideoWidget自定义Widget类 1、定义内部变量 2、如果使用SDL,需要进…

目录

学习课题:逐步构建开发播放器【QT5 + FFmpeg6 + SDL2】

步骤

VideoOutPut模块

1、初始化【分配缓存、读取信息】

2、开始线程工作【从队列读帧->缩放->发送渲染信号到窗口】

VideoWidget自定义Widget类

1、定义内部变量

2、如果使用SDL,需要进行初始化

3、接收到信号后需要执行槽函数进行渲染

主要代码

分配缓存

    // 根据格式和视频宽高获取一张图像的字节数据大小int byte = av_image_get_buffer_size(AV_PIX_FMT_RGB32, videoWidth, videoHeight, 1);// 分配缓存空间buffer = (uint8_t *) av_malloc(byte * sizeof(uint8_t));// 类似于格式化已经申请的内存av_image_fill_arrays(playFrame->data, playFrame->linesize, buffer, AV_PIX_FMT_RGB32, videoWidth, videoHeight, 1);// 初始化分配并返回SwsContextswsContext = sws_getContext(decCtx->width, decCtx->height, pixelFormat, videoWidth, videoHeight, AV_PIX_FMT_RGB32, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);

执行缩放

sws_scale(swsContext, (const uint8_t *const *) frame->data, frame->linesize, 0, decCtx->height, playFrame->data, playFrame->linesize);

创建SDL窗口纹理渲染器

// 这里必须要先SDL_CreateWindowFrom,然后在设置父类为this,否则会直接把父类当成参数作为背景sdlWindow = SDL_CreateWindowFrom((void *) winId());//渲染器sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);//纹理 大小是视频大小sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, 1920, 1080);SDL_SetTextureScaleMode(sdlTexture, SDL_ScaleModeLinear);

SDL渲染

    int ret = 1;ret = SDL_RenderClear(sdlRenderer);if (ret != 0) {qDebug() << "SDL_RenderClear error";}// 帧数据更新到纹理ret = SDL_UpdateTexture(sdlTexture, &m_originalSDLRect, frame->data[0], frame->linesize[0]);// 如果这里的帧数据已经是YUV则需要使用下面的//    ret = SDL_UpdateYUVTexture(sdlTexture, &sdlRect2, frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1], frame->data[2], frame->linesize[2]);if (ret != 0) {qDebug() << "SDL_UpdateYUVTexture error:" << SDL_GetError();}// 将纹理绘制到渲染器上ret = SDL_RenderCopy(sdlRenderer, sdlTexture, &m_originalSDLRect, nullptr);if (ret != 0) {qDebug() << "SDL_RenderCopy error";}//     刷新渲染器,将内容显示到窗口上SDL_RenderPresent(sdlRenderer);

SDL窗口渲染在mac系统上好像有点问题,缩放的时候图像会很模糊,暂时不知道是什么情况。望知道的朋友告知原因。

QPainter渲染

使用Qt的QPainter进行渲染可以原画像显示,不会有模糊的情况。

// 注意这里需要使用RGB格式
QImage image((uchar *) frame->data[0], 1920, 1080, QImage::Format_RGB32);
QPainter painter(this);
painter.drawImage(this->rect(), image);

完整模块

VideoOutPut

1、run函数实现内为什么需要av_usleep(39999):
        在run函数中是进行循环读取帧,然后缩放,最后发送信号进行渲染,如果我们不进行sleep,哪么就会在极短的时间内循环读取完所有的帧,渲染过快导致无法看清图像,因此我们需要进行sleep,这个时间对于单个视频流来说,一般是FPS,就是画面每秒传输帧数,通俗来讲就是指动画或视频的画面数。这个值一般是可以通过视频流的一些参数计算出来的,我们放到同步部分在说。

// VideoOutPut.h
#include "FFmpegHeader.h"
#include "SDL.h"
#include "queue/AVFrameQueue.h"
#include <QDebug>
#include <QObject>
#include <QtGui>
#include <QtWidgets>
#include <thread>class VideoOutPut : public QObject {Q_OBJECT
private:std::thread *m_thread;bool isStopped = true; // 是否已经停止 停止时退出线程bool isPlaying = false;// 是否正在播放bool isPause = false;  // 是否暂停uint8_t *buffer;//存储解码后图片buffer//图像缩放、颜色空间转换上下文SwsContext *swsContext;AVFrame *playFrame;      //转换后的帧对象AVFrameQueue *frameQueue;//解码后的帧队列// 解码器上下文AVCodecContext *decCtx;// 音频解码器上下文
public:VideoOutPut(AVCodecContext *dec_ctx, AVFrameQueue *frame_queue);int init();int start();void run();int videoWidth; //视频宽度int videoHeight;//视频高度
Q_SIGNALS:void refreshImage(const SDL_Rect &sdlRect, AVFrame *frame);
};// VideoOutPut.cpp
#include "VideoOutPut.h"
VideoOutPut::VideoOutPut(AVCodecContext *dec_ctx, AVFrameQueue *frame_queue): decCtx(dec_ctx), frameQueue(frame_queue) {
}
int VideoOutPut::init() {//获取分辨率大小videoWidth = decCtx->width;videoHeight = decCtx->height;playFrame = av_frame_alloc();AVPixelFormat pixelFormat = decCtx->pix_fmt;qDebug() << av_get_pix_fmt_name(pixelFormat);int byte = av_image_get_buffer_size(AV_PIX_FMT_RGB32, videoWidth, videoHeight, 1);buffer = (uint8_t *) av_malloc(byte * sizeof(uint8_t));av_image_fill_arrays(playFrame->data, playFrame->linesize, buffer, AV_PIX_FMT_RGB32, videoWidth, videoHeight, 1);swsContext = sws_getContext(decCtx->width, decCtx->height, pixelFormat, videoWidth, videoHeight, AV_PIX_FMT_RGB32, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);return 1;
}
int VideoOutPut::start() {m_thread = new std::thread(&VideoOutPut::run, this);if (!m_thread->joinable()) {qDebug() << "VideoOutPut视频帧处理线程创建失败";return -1;}isStopped = false;isPlaying = true;return 0;
}void VideoOutPut::run() {AVFrame *frame;while (!isStopped) {frame = frameQueue->pop(10);if (frame) {//图像缩放、颜色空间转换sws_scale(swsContext, (const uint8_t *const *) frame->data, frame->linesize, 0, decCtx->height, playFrame->data, playFrame->linesize);av_frame_unref(frame);//视频区域SDL_Rect sdlRect;sdlRect.x = 0;sdlRect.y = 0;sdlRect.w = decCtx->width;sdlRect.h = decCtx->height;//渲染到sdl窗口emit refreshImage(sdlRect, playFrame);av_usleep(39999);}}
}

VideoWidget

我们这里使用到QWidget,直接把SDL封装进去,做一个自定义类,之后使用qt creator 提升一下就行了。


注意:在使用时,如果要把VideoWidget嵌入到某个widget内部,需要在new 之后在单独setParent,不然会把整个父类主窗口当作sdl窗口。

//VideoWidget.h
#include "FFmpegHeader.h"
#include "SDL.h"
#include <QApplication>
#include <QDebug>
#include <QMetaType>
#include <QWidget>
#include <QtGui>class VideoWidget : public QWidget {Q_OBJECT
private:SDL_Rect m_originalSDLRect;AVFrame *frame = nullptr;SDL_Window *sdlWindow = nullptr;SDL_Renderer *sdlRenderer = nullptr;SDL_Texture *sdlTexture = nullptr;protected:void paintEvent(QPaintEvent *event) override;public:VideoWidget(QWidget *parent = 0);~VideoWidget();void initSDL();
public slots:void updateImage(const SDL_Rect &sdl_rect, AVFrame *frame);
};//VideoWidget.cpp
#include "VideoWidget.h"
VideoWidget::VideoWidget(QWidget *parent): QWidget(parent) {// 注册SDL类qRegisterMetaType<SDL_Rect>("SDL_Rect");
}
VideoWidget::~VideoWidget() {if (frame)av_frame_free(&frame);if (sdlTexture)SDL_DestroyTexture(sdlTexture);if (sdlRenderer)SDL_DestroyRenderer(sdlRenderer);if (sdlWindow)SDL_DestroyWindow(sdlWindow);SDL_Quit();
}
void VideoWidget::initSDL() {// SDL initif (SDL_Init(SDL_INIT_VIDEO) != 0) {qDebug() << "SDL_INIT_VIDEO error";return;}// 这里必须要先SDL_CreateWindowFrom,然后在设置父类为this,否则会直接把父类当成参数作为背景sdlWindow = SDL_CreateWindowFrom((void *) winId());//渲染器sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);//纹理 大小是视频大小sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, 1920, 1080);SDL_SetTextureScaleMode(sdlTexture, SDL_ScaleModeLinear);
}
void VideoWidget::updateImage(const SDL_Rect &sdl_rect, AVFrame *frame) {this->m_originalSDLRect = sdl_rect;this->frame = frame;this->update();
}
void VideoWidget::paintEvent(QPaintEvent *event) {if (!frame) {return;}
#if 0//QPainter渲染QImage image((uchar *) frame->data[0], 1920, 1080, QImage::Format_RGB32);QPainter painter(this);painter.drawImage(this->rect(), image);
#endif#if 1//SDL渲染int ret = 1;ret = SDL_RenderClear(sdlRenderer);if (ret != 0) {qDebug() << "SDL_RenderClear error";}// 创建SDL纹理并从表面创建ret = SDL_UpdateTexture(sdlTexture, &m_originalSDLRect, frame->data[0], frame->linesize[0]);//    ret = SDL_UpdateYUVTexture(sdlTexture, &sdlRect2, frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1], frame->data[2], frame->linesize[2]);if (ret != 0) {qDebug() << "SDL_UpdateYUVTexture error:" << SDL_GetError();}// 将纹理绘制到渲染器上ret = SDL_RenderCopy(sdlRenderer, sdlTexture, &m_originalSDLRect, nullptr);if (ret != 0) {qDebug() << "SDL_RenderCopy error";}//     刷新渲染器,将内容显示到窗口上SDL_RenderPresent(sdlRenderer);
#endif
}

PlayerMain

因为我们使用到了QT,所以先简单创建一个qt的ui,并且在内调用播放视频的函数,测试是否能够看见画面

//PlayerMain.h
#include <QWidget>
#include <QtCore>
//-----------
#include "queue/AVFrameQueue.h"
#include "queue/AVPacketQueue.h"
#include "thread/DecodeThread.h"
#include "thread/DemuxThread.h"
#include "widget/VideoWidget.h"
#include "output/VideoOutPut.h"QT_BEGIN_NAMESPACE
namespace Ui {class PlayerMain;
}
QT_END_NAMESPACEclass PlayerMain : public QWidget {Q_OBJECTpublic:explicit PlayerMain(QWidget *parent = nullptr);~PlayerMain() override;private:Ui::PlayerMain *ui;// 解复用DemuxThread *demuxThread;DecodeThread *audioDecodeThread;DecodeThread *videoDecodeThread;// 解码-音频AVPacketQueue audioPacketQueue;AVFrameQueue audioFrameQueue;// 解码-视频AVPacketQueue videoPacketQueue;AVFrameQueue videoFrameQueue;VideoOutPut *videoOutPut;
};//PlayerMain.cpp
#include "PlayerMain.h"
#include "ui_PlayerMain.h"PlayerMain::PlayerMain(QWidget *parent): QWidget(parent), ui(new Ui::PlayerMain) {ui->setupUi(this);// 解复用demuxThread = new DemuxThread(&audioPacketQueue, &videoPacketQueue);demuxThread->setUrl("/Users/mac/Downloads/0911超前派对:于文文孟佳爆笑猜词 王源欧阳靖脑洞大开.mp4");//    demuxThread->setUrl("/Users/mac/Downloads/23.mp4");demuxThread->start();int ret;// 解码-音频audioDecodeThread = new DecodeThread(demuxThread->getCodec(MediaType::Audio),demuxThread->getCodecParameters(MediaType::Audio),&audioPacketQueue,&audioFrameQueue);audioDecodeThread->init();audioDecodeThread->start();// 解码-视频videoDecodeThread = new DecodeThread(demuxThread->getCodec(MediaType::Video),demuxThread->getCodecParameters(MediaType::Video),&videoPacketQueue,&videoFrameQueue);videoDecodeThread->init();videoDecodeThread->start();// video outputthis->resize(1920/2,1080/2);videoOutPut = new VideoOutPut(videoDecodeThread->dec_ctx, &videoFrameQueue);videoOutPut->init();VideoWidget *videoWidget = new VideoWidget(this);connect(videoOutPut, &VideoOutPut::refreshImage, videoWidget, &VideoWidget::updateImage);videoWidget->show();videoWidget->initSDL();videoOutPut->start();
//    videoWidget->setParent(this);
}PlayerMain::~PlayerMain() {delete ui;
}

测试运行结果

播放器开发(五):视频帧处理并用SDL渲染播放 结果

http://www.yayakq.cn/news/969310/

相关文章:

  • 外贸品牌网站建设wordpress 中文
  • 百度网站域名费一年多少钱长沙旅游攻略美食
  • 做网站图片什么软件百度下载安装2022最新版
  • 网站建设中 怎么办阿里云个人域名备案
  • 网站申请域名站点创建成功有影响吗
  • 免费网站大全推荐做网站运营需要学什么软件
  • 建设简易电子商务网站流程图制作网线的步骤
  • 自助公益网站建设wordpress动静分离oss
  • 网站建设销售一个月营业额室内设计师接私活的平台
  • 简易网站的html代码电子商务网站的建设要求
  • 第一模板网站怎么卸载2345网址导航
  • 南沙开发区建设和交通局网站男女做床上网站
  • 网站建设公司.程序员做一个网站多少钱
  • 给宝宝做辅食的网站公司网站如何被百度收录
  • 网站前台功能模块设计网站建设源程序清单
  • 金沙县建设局网站wordpress 归档
  • 深圳招聘网站有哪些分销商城系统源码
  • 自己建网站怎么推广福州seo按天收费
  • 网站开发服务费属于哪种进项网站的ftp账号和密码是什么
  • wordpress 目录布局aso应用商店优化
  • 手机自己怎么建电影网站汽车网络营销的方式有哪些
  • 协会建设网站的必要性教育app开发
  • 专业设计网站效果深圳网站制作建站
  • python做网站php新洲网站建设
  • 免费建站网站大全网站站建设建技设术技术
  • 做网站的软件m开头如何改进网站
  • 深圳o2o网站建设湖州建设培训入口网站
  • mvc5网站开发实战详解vs做网站链接sql
  • 上海网站建设千元漂亮做调研用到的大数据网站
  • 网站发展中国域名是