Recherche avancée

Médias (3)

Mot : - Tags -/plugin

Autres articles (61)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

  • MediaSPIP en mode privé (Intranet)

    17 septembre 2013, par

    À partir de la version 0.3, un canal de MediaSPIP peut devenir privé, bloqué à toute personne non identifiée grâce au plugin "Intranet/extranet".
    Le plugin Intranet/extranet, lorsqu’il est activé, permet de bloquer l’accès au canal à tout visiteur non identifié, l’empêchant d’accéder au contenu en le redirigeant systématiquement vers le formulaire d’identification.
    Ce système peut être particulièrement utile pour certaines utilisations comme : Atelier de travail avec des enfants dont le contenu ne doit pas (...)

  • Librairies et binaires spécifiques au traitement vidéo et sonore

    31 janvier 2010, par

    Les logiciels et librairies suivantes sont utilisées par SPIPmotion d’une manière ou d’une autre.
    Binaires obligatoires FFMpeg : encodeur principal, permet de transcoder presque tous les types de fichiers vidéo et sonores dans les formats lisibles sur Internet. CF ce tutoriel pour son installation ; Oggz-tools : outils d’inspection de fichiers ogg ; Mediainfo : récupération d’informations depuis la plupart des formats vidéos et sonores ;
    Binaires complémentaires et facultatifs flvtool2 : (...)

Sur d’autres sites (9564)

  • Display real time frames from several RTSP streams

    13 février 2024, par Mrax

    I have this class, it uses ffmpeg library for rtsp live streaming :

    


    #include <iostream>&#xA;#include <string>&#xA;#include <vector>&#xA;#include <mutex>&#xA;&#xA;extern "C"&#xA;{&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavformat></libavformat>avio.h>&#xA;}&#xA;&#xA;class ryMediaSource&#xA;{&#xA;public:&#xA;    ryMediaSource() {}&#xA;    ryMediaSource(const ryMediaSource&amp; other);&#xA;    ~ryMediaSource();&#xA;&#xA;    bool ryOpenMediaSource(const std::string&amp;);&#xA;&#xA;private:&#xA;    mediaSource pMediaSource;&#xA;    AVFormatContext* pFormatCtx;&#xA;    mutable std::mutex pMutex;&#xA;};&#xA;</mutex></vector></string></iostream>

    &#xA;

    And inside my main file, I have these vector of ryMediaSource and four rstp urls :

    &#xA;

    std::vector<rymediasource> mediaSources;&#xA;std::vector streams =&#xA;{&#xA;    {"rtsp://1&#xA;    {"rtsp://2&#xA;    {"rtsp://3&#xA;    {"rtsp://4&#xA;};&#xA;</rymediasource>

    &#xA;

    Creating a instance for every vector :

    &#xA;

    for (const auto&amp; stream : streams)&#xA;{&#xA;    mediaSources.emplace_back(); // Create a new instance for each stream&#xA;}&#xA;

    &#xA;

    And opening all the streams (I need to have access to all the streams, all the time).

    &#xA;

    for (size_t s = 0; s &lt; streams.size(); s&#x2B;&#x2B;)&#xA;{&#xA;     mediaSources[s].ryOpenMediaSource(streams[s]);&#xA;}&#xA;

    &#xA;

    After all the streams are loaded, I start to display the videos all of the streams : av_read_frame(pFormatCtx, pPacket).&#xA;But I am having a gap from what is been displayed to what is really capturing from the source (IP Cameras).&#xA;From ryOpenMediaSource(streams[0]) is about 11 seconds, ryOpenMediaSource(streams[1]) about 7 seconds, ryOpenMediaSource(streams[2]) is about 4 seconds and ryOpenMediaSource(streams[3]) is real time.&#xA;I realized that the issue is on my ryOpenMediaSource code :

    &#xA;

    bool ryMediaSource::ryOpenMediaSource(const std::string&amp; url)&#xA;{&#xA;    int rc = -1;&#xA;&#xA;    pFormatCtx = avformat_alloc_context();&#xA;    if (!pFormatCtx)&#xA;        throw std::runtime_error("Failed to allocate AVFormatContext.");&#xA;    rc = avformat_open_input(&amp;pFormatCtx, url.c_str(), NULL, NULL);&#xA;    if (rc &lt; 0)&#xA;    {&#xA;        return false;&#xA;    }&#xA;}&#xA;

    &#xA;

    My question is, why this is happening ? Why can't all streams have the same (time stamp ?) , as the last inserted in my vector of ryMediaSource ?

    &#xA;

    Should I overwrite some variable of pFormatCtx to "force" the all vector to have the (time stamp ?) as the last one ? If so, can you give me some guidance ?

    &#xA;

    Tried setting some different values on pFormatCtx after loaded with avformat_open_input(&pFormatCtx, url.c_str(), NULL, &pDicts) ; but no luck at all.

    &#xA;

    I am expecting that all streams started at the same time, even if pre loading them, for later on, transform these frames into a cv::Mat for rendering.

    &#xA;

    MRE :

    &#xA;

    Header :&#xA;&#xA;#pragma once&#xA;&#xA;#include <iostream>&#xA;#include <string>&#xA;#include <vector>&#xA;#include <chrono>&#xA;#include <thread>&#xA;#include <mutex>&#xA;&#xA;&#xA;extern "C"&#xA;{&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavutil></libavutil>pixdesc.h>&#xA;#include <libavutil></libavutil>hwcontext.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>avassert.h>&#xA;#include <libavutil></libavutil>imgutils.h>&#xA;#include <libswscale></libswscale>swscale.h>&#xA;#include <libavdevice></libavdevice>avdevice.h>&#xA;#include <libavformat></libavformat>avio.h>&#xA;#include <libavutil></libavutil>time.h>&#xA;}&#xA;&#xA;class ryMediaSource&#xA;{&#xA;public:&#xA;    ryMediaSource() {}&#xA;    ryMediaSource(const ryMediaSource&amp; other);&#xA;    ~ryMediaSource();&#xA;&#xA;    struct mediaSourceParams&#xA;    {&#xA;        int sx;&#xA;        int sy;&#xA;        int lsize;&#xA;        double fps;&#xA;        unsigned char* frame;&#xA;    };&#xA;&#xA;    bool ryOpenMediaSource(const std::string&amp;);&#xA;    mediaSourceParams ryGetMediaSourceFrame();&#xA;    void ryCloseMediaSource();&#xA;&#xA;private:&#xA;    mediaSource pMediaSource;&#xA;    AVFormatContext* pFormatCtx;&#xA;    AVCodecContext* pCodecCtx;&#xA;    AVFrame* pFrame;&#xA;    SwsContext* pSwsCtx;&#xA;    AVPacket* pPacket;&#xA;    int pVideoStream;&#xA;    uint8_t* pBuffer;&#xA;    AVFrame* pPict;&#xA;    double pFPS;&#xA;    mutable std::mutex pMutex;&#xA;};&#xA;&#xA;C&#x2B;&#x2B; source code :&#xA;&#xA;#include "ryMediaSource.hpp"&#xA;&#xA;ryMediaSource::ryMediaSource(const ryMediaSource&amp; other)&#xA;:pFormatCtx(nullptr), &#xA;pCodecCtx(nullptr), &#xA;pFrame(nullptr), &#xA;pSwsCtx(nullptr), &#xA;pPacket(nullptr), &#xA;pBuffer(nullptr), &#xA;pPict(nullptr)&#xA;{&#xA;    std::lock_guard lock(other.pMutex);&#xA;    av_log_set_level(0);&#xA;    avformat_network_init();&#xA;}&#xA;&#xA;bool ryMediaSource::ryOpenMediaSource(const std::string&amp; url)&#xA;{&#xA;    int rc = -1;&#xA;&#xA;    try&#xA;    {&#xA;        AVDictionary* pDicts = nullptr;&#xA;&#xA;        pFormatCtx = avformat_alloc_context();&#xA;        if (!pFormatCtx)&#xA;            throw std::runtime_error("Failed to allocate AVFormatContext.");&#xA;        rc = av_dict_set(&amp;pDicts, "rtsp_transport", "tcp", 0);&#xA;        if (rc &lt; 0)&#xA;            throw std::runtime_error("av_dict_set failed.");&#xA;                rc = avformat_open_input(&amp;pFormatCtx, url.c_str(), NULL, &amp;pDicts);&#xA;        if (rc &lt; 0)&#xA;        {&#xA;            av_dict_free(&amp;pDicts);  // Free the dictionary in case of an error&#xA;            throw std::runtime_error("Could not open source.");&#xA;        }&#xA;    }&#xA;    catch (const std::exception&amp; e)&#xA;    {&#xA;        std::cerr &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        return false;&#xA;    }&#xA;&#xA;    try&#xA;    {&#xA;        rc = avformat_find_stream_info(pFormatCtx, NULL);&#xA;        if (rc &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not find stream information.");&#xA;        }&#xA;        pVideoStream = -1;&#xA;        for (size_t v = 0; v &lt; pFormatCtx->nb_streams; &#x2B;&#x2B;v)&#xA;        {&#xA;            if (pFormatCtx->streams[v]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)&#xA;            {&#xA;                pVideoStream = static_cast<int>(v);&#xA;                AVRational rational = pFormatCtx->streams[pVideoStream]->avg_frame_rate;&#xA;                pFPS = 1.0 / ((double)rational.num / (double)(rational.den));&#xA;                break;&#xA;            }&#xA;        }&#xA;        if (pVideoStream &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not find video stream.");&#xA;        }&#xA;&#xA;        const AVCodec* pCodec = avcodec_find_decoder(pFormatCtx->streams[pVideoStream]->codecpar->codec_id);&#xA;        if (!pCodec)&#xA;        {&#xA;            throw std::runtime_error("Unsupported codec!");&#xA;        }&#xA;        pCodecCtx = avcodec_alloc_context3(pCodec);&#xA;        if (!pCodecCtx)&#xA;        {&#xA;            throw std::runtime_error("Failed to allocate AVCodecContext.");&#xA;        }&#xA;        rc = avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[pVideoStream]->codecpar);&#xA;        if (rc != 0)&#xA;        {&#xA;            throw std::runtime_error("Could not copy codec context.");&#xA;        }&#xA;        rc = avcodec_open2(pCodecCtx, pCodec, NULL);&#xA;        if (rc &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not open codec.");&#xA;        }&#xA;        pFrame = av_frame_alloc();&#xA;        if (!pFrame)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate frame.");&#xA;        }&#xA;        pSwsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_BGR24, SWS_BILINEAR, NULL, NULL, NULL);&#xA;        if (!pSwsCtx)&#xA;        {&#xA;            throw std::runtime_error("Failed to allocate SwsContext.");&#xA;        }&#xA;        pPacket = av_packet_alloc();&#xA;        if (!pPacket)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate AVPacket.");&#xA;        }&#xA;        pBuffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height, 1));&#xA;        if (!pBuffer)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate buffer.");&#xA;        }&#xA;        pPict = av_frame_alloc();&#xA;        if (!pPict)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate frame.");&#xA;        }&#xA;        av_image_fill_arrays(pPict->data, pPict->linesize, pBuffer, AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height, 1);&#xA;    }&#xA;    catch (const std::exception&amp; e)&#xA;    {&#xA;        std::cerr &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        return false;&#xA;    }&#xA;&#xA;    return true;&#xA;}&#xA;&#xA;ryMediaSource::mediaSourceParams ryMediaSource::ryGetMediaSourceFrame()&#xA;{&#xA;    mediaSourceParams msp = { 0, 0, 0, 0.0, nullptr };&#xA;    char errbuf[AV_ERROR_MAX_STRING_SIZE];&#xA;&#xA;    std::lock_guard lock(pMutex);&#xA;    if (av_read_frame(pFormatCtx, pPacket) >= 0)&#xA;    {&#xA;        if (pPacket->stream_index == pVideoStream)&#xA;        {&#xA;            int ret = avcodec_send_packet(pCodecCtx, pPacket);&#xA;            if (ret &lt; 0)&#xA;            {&#xA;                av_strerror(ret, errbuf, sizeof(errbuf));&#xA;                std::cerr &lt;&lt; "Error sending packet for avcodec_send_packet: " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;&#xA;                std::cerr &lt;&lt; "avcodec_flush_buffers " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;                avcodec_flush_buffers(pCodecCtx);&#xA;                // Handle specific error cases&#xA;                if (ret == AVERROR(EAGAIN))&#xA;                {&#xA;                    std::cerr &lt;&lt; "EAGAIN indicates that more input is required" &lt;&lt; std::endl;&#xA;                }&#xA;                else if (ret == AVERROR_EOF)&#xA;                {&#xA;                    std::cerr &lt;&lt; "AVERROR_EOF indicates that the encoder has been fully flushed" &lt;&lt; std::endl;&#xA;                }&#xA;                else&#xA;                {&#xA;                    //std::cerr &lt;&lt; "avcodec_flush_buffers " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;                    // For other errors, you may choose to flush the codec context and continue decoding.&#xA;                    //avcodec_flush_buffers(pCodecCtx);&#xA;                }&#xA;            }&#xA;            ret = avcodec_receive_frame(pCodecCtx, pFrame);&#xA;            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;            {&#xA;                av_strerror(ret, errbuf, sizeof(errbuf));&#xA;&#xA;                std::cerr &lt;&lt; "Error receiving packet for avcodec_receive_frame: " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;&#xA;&#xA;                // EAGAIN indicates that more frames are needed or EOF is reached.&#xA;                // You may choose to break out of the loop or handle it based on your application&#x27;s logic.&#xA;&#xA;                return msp;&#xA;            }&#xA;            else if (ret &lt; 0)&#xA;            {&#xA;                av_strerror(ret, errbuf, sizeof(errbuf));&#xA;                std::cerr &lt;&lt; "Error receiving frame for avcodec_receive_frame: " &lt;&lt; errbuf &lt;&lt; std::endl;&#xA;                // Optionally, handle specific error cases&#xA;                if (ret == AVERROR(EINVAL))&#xA;                {&#xA;                    std::cerr &lt;&lt; "EINVAL indicates that more input is required" &lt;&lt; std::endl;&#xA;&#xA;                    //break;&#xA;                }&#xA;                else&#xA;                {&#xA;                    std::cerr &lt;&lt; "For other errors" &lt;&lt; std::endl;&#xA;&#xA;                    //break;&#xA;                }&#xA;            }&#xA;            // Move memory allocation outside the loop if frame size is constant&#xA;            size_t bufferSize = static_cast(pPict->linesize[0]) * pCodecCtx->height;&#xA;            msp.frame = new unsigned char[bufferSize];&#xA;            msp.lsize = pPict->linesize[0];&#xA;            msp.sx = pCodecCtx->width;&#xA;            msp.sy = pCodecCtx->height;&#xA;            msp.fps = pFPS;&#xA;            sws_scale(pSwsCtx, (uint8_t const* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pPict->data, pPict->linesize);&#xA;            std::memcpy(msp.frame, pBuffer, bufferSize);&#xA;            //delete[] msp.frame;&#xA;        }&#xA;&#xA;        // Unref packet for non-video streams&#xA;        av_packet_unref(pPacket);&#xA;    }&#xA;&#xA;    return msp;&#xA;}&#xA;&#xA;main.cpp&#xA;&#xA;std::vector streams =&#xA;{&#xA;    {"rtsp://1},&#xA;    {"rtsp://2},&#xA;    {"rtsp://3},&#xA;    {"rtsp://4},&#xA;};&#xA;&#xA;std::vector<rymediasource> mediaSources;&#xA;&#xA;void main()&#xA;{&#xA;    int key = 0;&#xA;    int channel = 0;&#xA;    std::vector streamFrame(streams.size());&#xA;    ryMediaSource::mediaSourceParams msp = { 0, 0, 0, 0.0, nullptr };&#xA;&#xA;    for (const auto&amp; stream : streams)&#xA;    {&#xA;        mediaSources.emplace_back(); // Create a new instance for each stream&#xA;    }&#xA;    for (size_t s = 0; s &lt; streams.size(); s&#x2B;&#x2B;)&#xA;    {&#xA;        try&#xA;        {&#xA;            mediaSources[s].ryOpenMediaSource(streams[s]);&#xA;        }&#xA;        catch (const std::exception&amp; e)&#xA;        {&#xA;            std::cerr &lt;&lt; "Error initializing stream " &lt;&lt; s &lt;&lt; ": " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        }&#xA;    }&#xA;&#xA;    cv::namedWindow("ryInferenceServer", cv::WINDOW_FREERATIO);&#xA;    cv::resizeWindow("ryInferenceServer", 640, 480);&#xA;    cv::moveWindow("ryInferenceServer", 0, 0);&#xA;    for (;;)&#xA;    {&#xA;        for (size_t st = 0; st &lt; mediaSources.size(); &#x2B;&#x2B;st)&#xA;        {&#xA;            msp = mediaSources[st].ryGetMediaSourceFrame();&#xA;            if (msp.frame != nullptr)&#xA;            {&#xA;                cv::Mat preview;&#xA;                cv::Mat frame(msp.sy, msp.sx, CV_8UC3, msp.frame, msp.lsize);&#xA;                cv::resize(frame, preview, cv::Size(640, 480));&#xA;                if (!frame.empty())&#xA;                {&#xA;                    try&#xA;                    {&#xA;                        streamFrame[st] = frame.clone();&#xA;                        if (channel == st)&#xA;                        {&#xA;                            cv::imshow("ryInferenceServer", preview);&#xA;                            key = cv::waitKeyEx(1);&#xA;                            if (key == LEFT_KEY)&#xA;                            {&#xA;                                channel--;&#xA;                                if (channel &lt; 0)&#xA;                                    channel = 0;&#xA;                            }&#xA;                            if (key == RIGHT_KEY)&#xA;                            {&#xA;                                channel&#x2B;&#x2B;;&#xA;                                if (channel >= mediaSources.size())&#xA;                                    channel = mediaSources.size() - 1;&#xA;                            }&#xA;                            if (key == 27)&#xA;                                break;&#xA;                        }&#xA;                        streamFrame[st].release();&#xA;                        delete[] msp.frame;&#xA;                    }&#xA;                    catch (const std::exception&amp; e)&#xA;                    {&#xA;                        std::cerr &lt;&lt; "Exception in processing frame for stream " &lt;&lt; st &lt;&lt; ": " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;                    }&#xA;                }&#xA;                frame.release();&#xA;            }&#xA;        }&#xA;    }&#xA;}&#xA;</rymediasource></int></mutex></thread></chrono></vector></string></iostream>

    &#xA;

  • avcodec/mlpenc : implement advanced stereo rematrix

    16 octobre 2023, par Paul B Mahol
    avcodec/mlpenc : implement advanced stereo rematrix
    
    • [DH] libavcodec/mlpenc.c
  • avfilter/avf_showcwt : add bar display support

    10 juillet 2023, par Paul B Mahol
    avfilter/avf_showcwt : add bar display support
    
    • [DH] libavfilter/avf_showcwt.c