Guide technique : Implémentation d'un client RTSP avec Qt 6 et FFmpeg 5.0.1 sur Ubuntu 20.04

Configuration et développement d'un lecteur RTSP avec Qt et FFmpeg

Ce guide technique détaille la mise en place d'un environnement pour le traitement de flux vidéo RTSP sur Ubuntu 20.04, en utilisant le framework Qt 6 et la bibliothèque FFmpeg 5.0.1. Il couvre la compilation de FFmpeg, la configuration CMake avancée et l'implémentation des composants de décodage vidéo avec gestion multi-thread.

  1. Préparation de l'environnement de développement

1.1 Installation des dépendances système

Mettez à jour le système et installez les outils essentiels :

sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential nasm pkg-config cmake git

Pour Qt, utilisez l'installateur officiel en sélectionnant la version 6.2 ou supérieure avec le module CMake :

wget https://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run
chmod +x qt-unified-linux-x64-online.run
./qt-unified-linux-x64-online.run

1.2 Compilation de FFmpeg 5.0.1 depuis les sources

Clonez la version spécifique et configurez la compilation avec les options recommandées :

git clone --branch n5.0.1 https://git.ffmpeg.org/ffmpeg.git FFmpeg-5.0.1
cd FFmpeg-5.0.1
Option de configuration Description Valeur conseillée
--enable-shared Génération de bibliothèques partagées Indispensable
--disable-static Désactivation des bibliothèques statiques Recommandé
--enable-gpl Activation du code sous licence GPL Optionnel
--enable-libx264 Support de l'encodage H.264 Recommandé
--extra-cflags=-fPIC Code position-indépendant pour les bibliothèques Obligatoire
./configure --prefix="/opt/ffmpeg-5.0.1" \
            --enable-shared \
            --disable-static \
            --extra-cflags="-fPIC" \
            --enable-gpl \
            --enable-libx264
make -j$(nproc)
sudo make install
  1. Configuration du projet avec CMake

2.1 Fichier CMakeLists.txt pour Qt et FFmpeg

Exemple de configuration moderne intégrant les dépendances :

cmake_minimum_required(VERSION 3.16)
project(StreamRTSP LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 COMPONENTS Core Gui Multimedia REQUIRED)

# Recherche personnalisée de FFmpeg
find_path(FFMPEG_INCLUDE_PATH
    NAMES libavcodec/avcodec.h
    PATHS /opt/ffmpeg-5.0.1/include
    REQUIRED
)

find_library(VIDEO_CODEC_LIB avcodec PATHS /opt/ffmpeg-5.0.1/lib REQUIRED)
find_library(MULTIMEDIA_FORMAT_LIB avformat PATHS /opt/ffmpeg-5.0.1/lib REQUIRED)

add_executable(stream_reader
    src/main.cpp
    src/MediaDecoder.cpp
)

target_include_directories(stream_reader PRIVATE ${FFMPEG_INCLUDE_PATH})
target_link_libraries(stream_reader PRIVATE
    Qt6::Core
    Qt6::Gui
    ${VIDEO_CODEC_LIB}
    ${MULTIMEDIA_FORMAT_LIB}
)

2.2 Gestion des bibliothèques dynamiques

Pour éviter les erreurs d'exécution liées aux bibliothèques :

  1. Variable d'environnement (développement) : ``` export LD_LIBRARY_PATH=/opt/ffmpeg-5.0.1/lib:$LD_LIBRARY_PATH
  2. Intégration du rpath (déploiement) : ``` set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
  3. Installation globale (avec droits administrateur) : ``` sudo echo "/opt/ffmpeg-5.0.1/lib" > /etc/ld.so.conf.d/ffmpeg.conf sudo ldconfig
    
    
  4. Composants principaux pour le traitement RTSP

3.1 Gestion sécurisée du contexte multimédia

Initialisation avec gestion des erreurs et options réseau :

class MediaSession {
public:
    explicit MediaSession(const std::string& address) {
        avformat_network_init();
        context = avformat_alloc_context();
        
        AVDictionary* params = nullptr;
        av_dict_set(&params, "rtsp_transport", "tcp", 0);
        av_dict_set(&params, "stimeout", "3000000", 0); // Timeout de 3 secondes
        
        if(avformat_open_input(&context, address.c_str(), nullptr, &params) != 0) {
            throw std::runtime_error("Impossible de se connecter au flux");
        }
    }
    
    ~MediaSession() {
        if(context) avformat_close_input(&context);
        avformat_network_deinit();
    }
    
private:
    AVFormatContext* context = nullptr;
};

3.2 Architecture de décodage multi-thread

Implémentation d'un modèle producteur-consommateur pour le traitement des paquets :

class VideoDecoder : public QObject {
    Q_OBJECT
public:
    explicit VideoDecoder(QObject* parent = nullptr) : QObject(parent) {
        worker_thread.start();
        moveToThread(&worker_thread);
    }
    
public slots:
    void decodePacket(AVPacket* packet) {
        // Logique de décodage
        emit frameDecoded(decoded_frame);
    }

signals:
    void frameDecoded(AVFrame* frame);

private:
    QThread worker_thread;
};

Paramètres d'optimisation courants :

Paramètre Valeur type Rôle
probesize 51200 Taille initiale d'analyse du flux
max_analyze_duration 5*AV_TIME_BASE Durée maximale d'analyse des métadonnées
fps_probe_size 30 Nombre d'échantillons pour déterminer le débit d'images
  1. Débogage et optimisation des performances

4.1 Résolution des problèmes courants

  • Échec de connexion : Vérifiez la sortie d'avformat_open_input, testez la connectivité réseau avec telnet, et ajustez le timeout.
  • Artéfacts visuels ou coupures : Activez les options de basse latence : ``` av_dict_set(&params, "fflags", "nobuffer", 0); av_dict_set(&params, "flags", "low_delay", 0);
  • Détection de fuites mémoire : ``` valgrind --leak-check=full ./stream_reader
    
    

4.2 Mesure des performances en temps réel

Extraction des statistiques via FFmpeg :

AVFormatContext* session = ...;
std::cout << "Débit binaire: " << session->bit_rate/1000 << " kbps\n";
std::cout << "Débit d'images: " << av_q2d(session->streams[video_index]->avg_frame_rate) << " fps\n";

Pour le suivi de la charge processeur et mémoire :

auto start_time = std::chrono::high_resolution_clock::now();
// Code de traitement
auto end_time = std::chrono::high_resolution_clock::now();
metrics.processing_rate = 1e9 / (end_time - start_time).count();
watch -n 1 'ps -p $(pidof stream_reader) -o %mem,rss'

Pour les flux haute résolution, l'utilisation de threads séparés pour l'E/S et le décodage, combinée avec av_packet_ref pour une gestion mémoire efficace, améliore significativement les performances.

Étiquettes: Ubuntu Qt-6 FFmpeg-5.0.1 RTSP CMake

Publié le 6 juin à 23h54