91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Qt如何實現視頻流播放ffmpeg內核

發布時間:2021-12-15 11:05:54 來源:億速云 閱讀:389 作者:小新 欄目:互聯網科技

這篇文章主要為大家展示了“Qt如何實現視頻流播放ffmpeg內核”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Qt如何實現視頻流播放ffmpeg內核”這篇文章吧。

一、前言

好久以前就寫過這個工具,后來因為Qt版本的不斷升級以及ffmpeg也經歷過好多次的迭代,可能從官網下載的ffmpeg搭配原來的代碼不能正確編譯,因為很多api已經變了,所以這次特意抽空全部整理重寫一遍,只求最精簡最好用,同時兼容了ffmpeg3和ffmpeg4,并且同時支持32位的庫和64位的庫,這樣任何小白拿過去直接編譯就能用。

二、代碼思路

第一步:引入ffmpeg的頭文件

//必須加以下內容,否則編譯不能通過,為了兼容C和C99標準
#ifndef INT64_C
#define INT64_C
#define UINT64_C
#endif

//引入ffmpeg頭文件
extern "C" {
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "libavutil/frame.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/ffversion.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"

#ifdef ffmpegdevice
#include "libavdevice/avdevice.h"
#endif

#ifndef gcc45
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_qsv.h"
#endif
}

第二步:注冊ffmpeg的庫 這里發現很多人每個類都注冊一次,搞得內存每次增加很多,不是不可以,而是沒有必要,其實ffmpeg的庫和解碼器等,在一個程序中只需要注冊一次即可,沒必要每個視頻類都注冊一次。

//一個軟件中只需要初始化一次就行
void FFmpegThread::initlib()
{
    static QMutex mutex;
    QMutexLocker locker(&mutex);
    static bool isInit = false;
    if (!isInit) {
        //注冊庫中所有可用的文件格式和解碼器
        av_register_all();
        //注冊所有設備,主要用于本地攝像機播放支持
#ifdef ffmpegdevice
        avdevice_register_all();
#endif
        //初始化網絡流格式,使用網絡流時必須先執行
        avformat_network_init();

        isInit = true;
        qDebug() << TIMEMS << "init ffmpeg lib ok" << " version:" << FFMPEG_VERSION;
#if 0
        //輸出所有支持的解碼器名稱
        QStringList listCodeName;
        AVCodec *code = av_codec_next(NULL);
        while (code != NULL) {
            listCodeName << code->name;
            code = code->next;
        }

        qDebug() << TIMEMS << listCodeName;
#endif
    }
}

第三步:設置參數

//在打開碼流前指定各種參數比如:探測時間/超時時間/最大延時等
//設置緩存大小,1080p可將值調大
av_dict_set(&options, "buffer_size", "8192000", 0);
//以tcp方式打開,如果以udp方式打開將tcp替換為udp
av_dict_set(&options, "rtsp_transport", "tcp", 0);
//設置超時斷開連接時間,單位微秒,3000000表示3秒
av_dict_set(&options, "stimeout", "3000000", 0);
//設置最大時延,單位微秒,1000000表示1秒
av_dict_set(&options, "max_delay", "1000000", 0);
//自動開啟線程數
av_dict_set(&options, "threads", "auto", 0);

第四步:打開視頻流 具體代碼比較多,詳細代碼請自行開源主頁下載。

第五步:解碼圖像

void FFmpegThread::run()
{
    //計時
    QTime time;
    while (!stopped) {
        //根據標志位執行初始化操作
        if (isPlay) {
            this->init();
            isPlay = false;
            continue;
        }

        time.restart();
        if (av_read_frame(avFormatContext, avPacket) >= 0) {
            //判斷當前包是視頻還是音頻
            int packetSize = avPacket->size;
            int index = avPacket->stream_index;
            if (index == videoStreamIndex) {
                //解碼視頻流
                avcodec_decode_video2(videoCodec, avFrame2, &frameFinish, avPacket);

                if (frameFinish) {
                    //將數據轉成一張圖片
                    sws_scale(swsContext, (const uint8_t *const *)avFrame2->data, avFrame2->linesize, 0, videoHeight, avFrame3->data, avFrame3->linesize);

                    //以下兩種方法都可以
                    //QImage image(avFrame3->data[0], videoWidth, videoHeight, QImage::Format_RGB32);
                    QImage image((uchar *)buffer, videoWidth, videoHeight, QImage::Format_RGB32);
                    if (!image.isNull()) {
                        emit receiveImage(image);
                    }

                    msleep(1);
                }
            } else if (index == audioStreamIndex) {
                //解碼音頻流,這里暫不處理,以后交給sdl播放
            }
        }

        av_packet_unref(avPacket);
        av_freep(avPacket);
        msleep(1);
    }

    //線程結束后釋放資源
    free();
    stopped = false;
    isPlay = false;
    qDebug() << TIMEMS << "stop ffmpeg thread";
}

三、效果圖

Qt如何實現視頻流播放ffmpeg內核

以上是“Qt如何實現視頻流播放ffmpeg內核”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

qt
AI

湖口县| 沅陵县| 三原县| 琼结县| 兴安盟| 瓦房店市| 苏州市| 晋城| 延长县| 云安县| 衡南县| 阿巴嘎旗| 贡觉县| 丰城市| 兴隆县| 绥宁县| 镇安县| 时尚| 万荣县| 东莞市| 吴忠市| 清远市| 宝兴县| 从江县| 安龙县| 稻城县| 鄢陵县| 尉氏县| 灌云县| 张家川| 浙江省| 安丘市| 偃师市| 临城县| 聂荣县| 桐乡市| 怀柔区| 夏津县| 屯门区| 阳新县| 西安市|