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

中国建设银行总行网站陕西省建设网官网住房和城乡厅官网

中国建设银行总行网站,陕西省建设网官网住房和城乡厅官网,网站分析怎么做,虚拟主机与网站建设学习课题#xff1a;逐步构建开发播放器【QT5 FFmpeg6 SDL2】 前言 根据第一章内容#xff0c;我们首先可以先把解复用和解码模块完成#xff0c;其中需要使用到多线程以及队列#xff0c;还需要使用FFmpeg进行解复用和解码动作的实现。 创建BaseQueue基类 BaseQueue.h…学习课题逐步构建开发播放器【QT5 FFmpeg6 SDL2】 前言 根据第一章内容我们首先可以先把解复用和解码模块完成其中需要使用到多线程以及队列还需要使用FFmpeg进行解复用和解码动作的实现。 创建BaseQueue基类 BaseQueue.h #include condition_variable #include mutex #include queueusing namespace std;templateclass T class BaseQueue { public:/*** 唤醒所有等待线程设置异常标识为1*/void abort() {m_abort 1;m_cond.notify_all();}/*** push进m_queue** param val 需要push的值* return 1是成功 or -1是m_abort1可能有异常*/int push(T val) {lock_guardmutex lock(m_mutex);if (m_abort 1) {return -1;}m_queue.push(val);m_cond.notify_one();return 0;}/*** 从基类 front 到 val 并执行基类std::queue.pop** param val 存放front值的地址引用* param timeout 持有锁的上限时间(ms)* return 1是成功 or -1是m_abort1可能有异常 or 是m_queue为空*/int pop(T val, int timeout 0) {unique_lockmutex lock(m_mutex);if (m_queue.empty()) {m_cond.wait_for(lock, chrono::microseconds(timeout), [this] {return !m_queue.empty() | m_abort;});}if (m_abort 1) {return -1;}if (m_queue.empty()) {return -2;}// there is address referenceval m_queue.front();m_queue.pop();return 0;}/*** 从基类std::queue.front 获取值保存到引用地址val** param val 存放front值的地址引用* return 1是成功 or -1是m_abort1可能有异常 or 是m_queue为空*/int front(T val) {lock_guardmutex lock(m_mutex);if (m_abort 1) {return -1;}if (m_queue.empty()) {return -2;}val m_queue.front();return 0;}int size() {lock_guardmutex lock(m_mutex);return m_queue.size();}private:int m_abort 0;// 是否中止mutex m_mutex; // 锁condition_variable m_cond;queueT m_queue; }; 创建AVPacketQueue包队列类和AVFrameQueue帧队列类 在AVPacketQueue和AVFrameQueue中分别实现模版BaseQueue基类并且可以添加一些错误的信息打印。 我们可以新建一个头文件FFmpegHeader.h用来存放导入ffmpeg的一些代码后面用的时候导入这个文件就可以了 FFmpegHeader.h extern C { #include libavcodec/avcodec.h #include libavfilter/avfilter.h #include libavformat/avformat.h #include libavutil/audio_fifo.h #include libavutil/avassert.h #include libavutil/ffversion.h #include libavutil/frame.h #include libavutil/imgutils.h #include libavutil/opt.h #include libavutil/pixdesc.h #include libavutil/time.h #include libswresample/swresample.h #include libswscale/swscale.h#ifdef ffmpegdevice #include libavdevice/avdevice.h #endif }#include qdatetime.h #pragma execution_character_set(utf-8)#define TIMEMS qPrintable(QTime::currentTime().toString(HH:mm:ss zzz)) #define TIME qPrintable(QTime::currentTime().toString(HH:mm:ss)) #define QDATE qPrintable(QDate::currentDate().toString(yyyy-MM-dd)) #define QTIME qPrintable(QTime::currentTime().toString(HH-mm-ss)) #define DATETIME qPrintable(QDateTime::currentDateTime().toString(yyyy-MM-dd HH:mm:ss)) #define STRDATETIME qPrintable(QDateTime::currentDateTime().toString(yyyy-MM-dd-HH-mm-ss)) #define STRDATETIMEMS qPrintable(QDateTime::currentDateTime().toString(yyyy-MM-dd-HH-mm-ss-zzz))AVPacketQueue //AVPacketQueue.h #include BaseQueue.h #include FFmpegHeader.h #include cstdioclass AVPacketQueue { public:~AVPacketQueue();int push(AVPacket *val);AVPacket *pop(int timeout);void release();int size();private:BaseQueueAVPacket * m_queue; };//AVPacketQueue.cpp #include AVPacketQueue.hAVPacketQueue::~AVPacketQueue() {release();m_queue.abort(); }int AVPacketQueue::push(AVPacket *val) {AVPacket *tmp_pkt av_packet_alloc();av_packet_move_ref(tmp_pkt, val);return m_queue.push(tmp_pkt); } AVPacket *AVPacketQueue::pop(int timeout) {AVPacket *tmp_pkt nullptr;int ret m_queue.pop(tmp_pkt, timeout);if (ret -1) {printf(AVPacketQueue::pop -- m_abort1可能有异常);}if (ret -2) {printf(AVPacketQueue::pop -- 队列为空);}return tmp_pkt; } void AVPacketQueue::release() {while (true) {AVPacket *pkt nullptr;int ret m_queue.pop(pkt, 1);if (ret 0) {break;} else {av_packet_free(pkt);continue;}} } int AVPacketQueue::size() {return m_queue.size(); } AVFrameQueue //AVFrameQueue.h #include BaseQueue.h #include FFmpegHeader.h #include cstdioclass AVFrameQueue { public:~AVFrameQueue();int push(AVFrame *val);AVFrame *pop(int timeout);void release();int size();private:BaseQueueAVFrame * m_queue; };//AVFrameQueue.cpp #include AVFrameQueue.h AVFrameQueue::~AVFrameQueue() {release();m_queue.abort(); }int AVFrameQueue::push(AVFrame *val) {AVFrame *tmp_frame av_frame_alloc();av_frame_move_ref(tmp_frame, val);return m_queue.push(tmp_frame); } AVFrame *AVFrameQueue::pop(int timeout) {AVFrame *tmp_frame nullptr;int ret m_queue.pop(tmp_frame, timeout);if (ret -1) {printf(AVFrameQueue::pop -- m_abort1可能有异常);}if (ret -2) {printf(AVFrameQueue::pop -- 队列为空);}return tmp_frame; } void AVFrameQueue::release() {while (true) {AVFrame *pkt nullptr;int ret m_queue.pop(pkt, 1);if (ret 0) {break;} else {av_frame_free(pkt);continue;}} } int AVFrameQueue::size() {return m_queue.size(); } 创建BaseThread抽象类 #include QThread/*** 因为我们后面可能需要用到qt信号传递是否暂停所以使用QThread*/ class BaseThread : public QThread {Q_OBJECT public:// 初始化virtual int init() 0;// 创建线程 开始run工作virtual int start() 0;// 停止线程 释放资源virtual void stop() {isStopped true;if (m_thread) {if (m_thread-isRunning()) {m_thread-wait(-1);}delete m_thread;m_thread nullptr;}};protected:bool isStopped true; // 是否已经停止 停止时退出线程bool isPlaying false;// 是否正在播放bool isPause false; // 是否暂停QThread *m_thread nullptr; }; 创建DemuxThread解复用线程模块和DecodeThread解码线程模块 DemuxThread解复用线程 1、打开视频文件解封装操作。 2、读取流信息并添加打印信息。 3、解复用(循环分离视频流和音频流)。 DemuxThread //DemuxThread.h enum class MediaType {Audio,Video };class DemuxThread : public BaseThread { private:QString m_url nullptr;AVFormatContext *ic nullptr;int m_videoStreamIndex -1;int m_audioStreamIndex -1;const AVCodec *m_videoCodec;const AVCodec *m_audioCodec;AVPacketQueue *m_audioQueue;AVPacketQueue *m_videoQueue;public:DemuxThread(AVPacketQueue *mAudioQueue, AVPacketQueue *mVideoQueue);DemuxThread(const QString url, AVPacketQueue *mAudioQueue, AVPacketQueue *mVideoQueue);~DemuxThread() override;// 打开视频文件读取信息int init() override;int start() override;void stop() override;void run() override;void setUrl(const QString url);AVCodecParameters *getCodecParameters(MediaType type);AVRational *getStreamTimeBase(MediaType type);const AVCodec *getCodec(MediaType type); };//DemuxThread.cpp #include DemuxThread.h DemuxThread::DemuxThread(AVPacketQueue *mAudioQueue, AVPacketQueue *mVideoQueue): m_audioQueue(mAudioQueue), m_videoQueue(mVideoQueue) { } DemuxThread::DemuxThread(const QString url, AVPacketQueue *mAudioQueue, AVPacketQueue *mVideoQueue): m_url(url), m_audioQueue(mAudioQueue), m_videoQueue(mVideoQueue) { }DemuxThread::~DemuxThread() {if (m_thread) {this-stop();} } int DemuxThread::init() {if (m_url nullptr) {qDebug() 没有设置文件链接;return -1;}ic avformat_alloc_context();int ret;ret avformat_open_input(ic, m_url.toUtf8(), nullptr, nullptr);if (ret 0) {qDebug() avformat_open_input 函数发送错误;return -1;}ret avformat_find_stream_info(ic, nullptr);if (ret 0) {qDebug() avformat_find_stream_info 函数发送错误;return -1;}m_videoStreamIndex av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, m_videoCodec, 0);if (m_videoStreamIndex 0) {qDebug() 没有找到视频流索引 av_find_best_stream error;return -1;}AVCodecParameters *codecParameters_video ic-streams[m_videoStreamIndex]-codecpar;QString codecNameVideo avcodec_get_name(codecParameters_video-codec_id);qDebug() 视频流 codecNameVideo;m_audioStreamIndex av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, m_audioCodec, 0);if (m_audioStreamIndex 0) {qDebug() 没有找到音频流索引 av_find_best_stream error;return -1;}AVCodecParameters *codecParameters_audio ic-streams[m_audioStreamIndex]-codecpar;QString codecNameAudio avcodec_get_name(codecParameters_audio-codec_id);qDebug() 音频流 codecNameAudio;return 1; } int DemuxThread::start() {if (init() ! 1) {qDebug() 打开文件失败停止创建线程;return -1;}isStopped false;isPlaying true;QThread::start();if (!currentThread()) {qDebug() 线程创建失败;return -1;}return 0; } void DemuxThread::stop() {BaseThread::stop();if (ic) {avformat_close_input(ic);ic nullptr;}if (m_videoCodec) {m_videoCodec nullptr;}if (m_audioCodec) {m_audioCodec nullptr;} } void DemuxThread::run() {int ret;AVPacket pkt;while (!isStopped) {//if (m_audioQueue-size() 10 || m_videoQueue-size() 10) {// qDebug()解复用线程等待 videoSize m_videoQueue-size()audioSize m_audioQueue-size();msleep(10);// std::this_thread::sleep_for(std::chrono::milliseconds(10));continue;}ret av_read_frame(ic, pkt);if (ret 0) {qDebug() 帧读完;break;}if (pkt.stream_index m_audioStreamIndex) {m_audioQueue-push(pkt);// qDebug() audio pkt queue size: m_audioQueue-size();} else if (pkt.stream_index m_videoStreamIndex) {m_videoQueue-push(pkt);// qDebug() video pkt queue size: m_videoQueue-size();} else {av_packet_unref(pkt);}} }void DemuxThread::setUrl(const QString url) {m_url url; } AVCodecParameters *DemuxThread::getCodecParameters(MediaType type) {switch (type) {case MediaType::Audio:if (m_audioStreamIndex ! -1) {return ic-streams[m_audioStreamIndex]-codecpar;} else {return nullptr;}case MediaType::Video:if (m_videoStreamIndex ! -1) {return ic-streams[m_videoStreamIndex]-codecpar;} else {return nullptr;}} } AVRational *DemuxThread::getStreamTimeBase(MediaType type) {switch (type) {case MediaType::Audio:if (m_audioStreamIndex ! -1) {return ic-streams[m_audioStreamIndex]-time_base;} else {return nullptr;}case MediaType::Video:if (m_videoStreamIndex ! -1) {return ic-streams[m_videoStreamIndex]-time_base;} else {return nullptr;}} } const AVCodec *DemuxThread::getCodec(MediaType type) {switch (type) {case MediaType::Audio:return m_audioCodec;case MediaType::Video:return m_videoCodec;} }DecodeThread //DecodeThread.h #include BaseThread.h #include FFmpegHeader.h #include queue/AVFrameQueue.h #include queue/AVPacketQueue.h #include QDebugclass DecodeThread : public BaseThread { private:const AVCodec *m_codec nullptr;AVCodecParameters *m_par nullptr;AVPacketQueue *m_packetQueue nullptr;AVFrameQueue *m_frameQueue nullptr;public:AVCodecContext *dec_ctx nullptr;DecodeThread(const AVCodec *mCodec, AVCodecParameters *mPar, AVPacketQueue *mPacketQueue, AVFrameQueue *mFrameQueue);~DecodeThread() override;int init() override;int start() override;void stop() override;void run() override; };//DecodeThread.cpp #include DecodeThread.h DecodeThread::DecodeThread(const AVCodec *mCodec, AVCodecParameters *mPar, AVPacketQueue *mPacketQueue, AVFrameQueue *mFrameQueue): m_codec(mCodec), m_par(mPar), m_packetQueue(mPacketQueue), m_frameQueue(mFrameQueue) { } DecodeThread::~DecodeThread() {stop(); } int DecodeThread::init() {if (!m_par) {qDebug() AVCodecParameters 为空;return -1;}dec_ctx avcodec_alloc_context3(nullptr);int ret avcodec_parameters_to_context(dec_ctx, m_par);if (ret 0) {qDebug() avcodec_parameters_to_context error;}ret avcodec_open2(dec_ctx, m_codec, nullptr);if (ret 0) {qDebug() avcodec_open2 error;}return 0; } void DecodeThread::run() {AVFrame *frame av_frame_alloc();while (!isStopped) {if (m_frameQueue-size() 10) {// qDebug()解码线程等待;msleep(10);// std::this_thread::sleep_for(std::chrono::milliseconds(10));continue;}AVPacket *pkt m_packetQueue-pop(5);if (pkt) {int ret avcodec_send_packet(dec_ctx, pkt);av_packet_free(pkt);if (ret 0) {qDebug() avcodec_send_packet error;break;}while (true) {ret avcodec_receive_frame(dec_ctx, frame);if (ret 0) {m_frameQueue-push(frame);// qDebug()m_frameQueue size:m_frameQueue-size();continue;} else if (AVERROR(EAGAIN) ret) {break;} else {isStopped true;qDebug() avcodec_receive_frame error;break;}}} else {break;}} } int DecodeThread::start() {isStopped false;isPlaying true;QThread::start();if (!currentThread()) {qDebug() 线程创建失败;return -1;}return 0; } void DecodeThread::stop() {BaseThread::stop();if (dec_ctx)avcodec_close(dec_ctx); }测试是否能够正常运行 现在解复用线程模块和解码线程模块都已经完成了测试一下是否正常运行 main.cpp #include QApplication #include QPushButton //----------- #include queue/AVFrameQueue.h #include queue/AVPacketQueue.h #include thread/DecodeThread.h #include thread/DemuxThread.hint main(int argc, char *argv[]) {QApplication a(argc, argv);QPushButton button(Hello world!, nullptr);button.resize(200, 100);button.show();// 解复用DemuxThread *demuxThread;DecodeThread *audioDecodeThread;DecodeThread *videoDecodeThread;// 解码-音频AVPacketQueue audioPacketQueue;AVFrameQueue audioFrameQueue;// 解码-视频AVPacketQueue videoPacketQueue;AVFrameQueue videoFrameQueue;demuxThread new DemuxThread(audioPacketQueue, videoPacketQueue);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();return QApplication::exec(); }测试完成运行正常
http://www.zqtcl.cn/news/271156/

相关文章:

  • 消费者联盟网站怎么做中山网站建设案例
  • 郑州市多商家网站制作公司网站建设要学多少课程
  • 现在网站开发模式淄博网站建设设计公司
  • 瑶海合肥网站建设东莞网站优化多少钱
  • pc蛋蛋游戏体验网站建设大型门户网站建设效果好吗
  • 昆明网站建设制作汽车之家官网网页版入口
  • 诸城建设局网站免费的创建个人网站
  • 网站建设工作下步打算上海搬家公司电话查询
  • 如何将自己做的网站推广出去大型网站方案
  • 深圳做网站排名哪家好贵阳景观设计公司
  • 做图片网站中英网站搭建报价表
  • 酒类网站该怎么做网站建设协议
  • 怎么打帮人 做网站开发的广告双语言网站模版
  • 企业网站建设的实验报告广告公司网站建设方案
  • 安徽茶叶商城网站建设贵阳市花溪区建设局网站
  • 广西网站建设制作推广普通话倡议书
  • 最新网站建设的模板下载小制作作文400字
  • 海南省城乡建设部网站首页央视新闻
  • 高端白酒品牌有哪些网站怎么做才能得到更好的优化
  • 北京安慧桥网站建设青之峰做网站
  • 免费制作网站的平台推广网站多少钱
  • 怎么增加网站的收录量广西建设厅网站地址
  • flash网站方案料神wordpress建站教程
  • 杭州 企业 建网站蚌埠网站优化
  • 网站建设的分类黄骅港最新招聘
  • 门户网站建设和检务公开自查搜索引擎排名优化价格
  • 湘阴网站建设如何建立自己的网站
  • 国外的ps网站网页源代码翻译器
  • 六安马昌友优化营商环境 助推高质量发展
  • wdcp 配置网站什么是搜索引擎营销?