Recherche avancée

Médias (0)

Mot : - Tags -/xmlrpc

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (46)

  • Multilang : améliorer l’interface pour les blocs multilingues

    18 février 2011, par

    Multilang est un plugin supplémentaire qui n’est pas activé par défaut lors de l’initialisation de MediaSPIP.
    Après son activation, une préconfiguration est mise en place automatiquement par MediaSPIP init permettant à la nouvelle fonctionnalité d’être automatiquement opérationnelle. Il n’est donc pas obligatoire de passer par une étape de configuration pour cela.

  • Des sites réalisés avec MediaSPIP

    2 mai 2011, par

    Cette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
    Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page.

  • HTML5 audio and video support

    13 avril 2011, par

    MediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
    The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
    For older browsers the Flowplayer flash fallback is used.
    MediaSPIP allows for media playback on major mobile platforms with the above (...)

Sur d’autres sites (9596)

  • 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;

  • I want to take any Audio from a file and encode it as PCM_ALAW. My Example is a .m4a file to .wav file

    22 novembre 2023, par Clockman

    I have been working on this for a while now while am generally new to ffmpeg library, I have studied it a bit. The challenge I have that at the point of witting to file I get the following exception.

    &#xA;

    "Exception thrown at 0x00007FFACA8305B3 (avformat-60.dll) in FfmpegPractice.exe : 0xC0000005 : Access violation writing location 0x0000000000000000.". I understand this means am writing to an uninitialized buffer am unable to discover why this is happening. The exception call stack shows the following

    &#xA;

    avformat-60.dll!avformat_write_header() C&#xA;avformat-60.dll!ff_write_chained()  C&#xA;avformat-60.dll!ff_write_chained()  C&#xA;avformat-60.dll!av_write_frame()    C&#xA;FfmpegPractice.exe!main() Line 215  C&#x2B;&#x2B;&#xA;

    &#xA;

    Some things I have tried

    &#xA;

    This code is part of a larger project built with CMake but for some reason I could no step into ffmpeg library while debugging, So I recompiled ffmpeg ensured debugging was enabled so I could drill down to the root cause but I still could not step into the ffmpeg library.

    &#xA;

    I then created a minimal project using visual studio c++ console project and I still could not step into the code.

    &#xA;

    I have read through many ffmpeg docs and some I could find on the internet and I still could not solve it.

    &#xA;

    This is the code

    &#xA;

    #include <iostream>&#xA;&#xA;extern "C" {&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libswresample></libswresample>swresample.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>audio_fifo.h>&#xA;}&#xA;&#xA;using namespace std;&#xA;&#xA;//in audio file&#xA;string filename{ "rapid_caller_test.m4a" };&#xA;AVFormatContext* pFormatCtx{};&#xA;AVCodecContext* pCodecCtx{};&#xA;AVStream* pStream{};&#xA;&#xA;//out audio file&#xA;string outFilename{ "output.wav" };&#xA;AVFormatContext* pOutFormatCtx{ nullptr };&#xA;AVCodecContext* pOutCodecCtx{ nullptr };&#xA;AVIOContext* pOutIoContext{ nullptr };&#xA;const AVCodec* pOutCodec{ nullptr };&#xA;AVStream* pOutStream{ nullptr };&#xA;const int OUTPUT_CHANNELS = 1;&#xA;const int SAMPLE_RATE = 8000;&#xA;const int OUT_BIT_RATE = 64000;&#xA;uint8_t** convertedSamplesBuffer{ nullptr };&#xA;int64_t dstNmbrSamples{ 0 };&#xA;int dstLineSize{ 0 };&#xA;static int64_t pts{ 0 };&#xA;&#xA;//conversion context;&#xA;SwrContext* swr{};&#xA;&#xA;uint32_t i{ 0 };&#xA;int audiostream{ -1 };&#xA;&#xA;&#xA;void cleanUp() &#xA;{&#xA;  avcodec_free_context(&amp;pOutCodecCtx);;&#xA;  avio_closep(&amp;(pOutFormatCtx)->pb);&#xA;  avformat_free_context(pOutFormatCtx);&#xA;  pOutFormatCtx = nullptr;&#xA;}&#xA;&#xA;int main()&#xA;{&#xA;&#xA;/*&#xA;* section to setup input file&#xA;*/&#xA;if (avformat_open_input(&amp;pFormatCtx, filename.data(), nullptr, nullptr) != 0) {&#xA;  cout &lt;&lt; "could not open file " &lt;&lt; filename &lt;&lt; endl;&#xA;  return -1;&#xA;}&#xA;if (avformat_find_stream_info(pFormatCtx, nullptr) &lt; 0) {&#xA;  cout &lt;&lt; "Could not retrieve stream information from file " &lt;&lt; filename &lt;&lt; endl;&#xA;  return -1;&#xA;}&#xA;av_dump_format(pFormatCtx, 0, filename.c_str(), 0);&#xA;&#xA;for (i = 0; i &lt; pFormatCtx->nb_streams; i&#x2B;&#x2B;) {&#xA;  if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {&#xA;    audiostream = i;&#xA;    break;&#xA;  }&#xA;}&#xA;if (audiostream == -1) {&#xA;  cout &lt;&lt; "did not find audio stream" &lt;&lt; endl;&#xA;  return -1;&#xA;}&#xA;&#xA;pStream = pFormatCtx->streams[audiostream];&#xA;const AVCodec* pCodec{ avcodec_find_decoder(pStream->codecpar->codec_id) };&#xA;pCodecCtx = avcodec_alloc_context3(pCodec);&#xA;avcodec_parameters_to_context(pCodecCtx, pStream->codecpar);&#xA;if (avcodec_open2(pCodecCtx, pCodec, nullptr)) {&#xA;  cout &lt;&lt; "could not open codec" &lt;&lt; endl;&#xA;  return -1;&#xA;}&#xA;&#xA;/*&#xA;* section to set up output file which is a G711 audio&#xA;*/&#xA;if (avio_open(&amp;pOutIoContext, outFilename.data(), AVIO_FLAG_WRITE)) {&#xA;  cout &lt;&lt; "could not open out put file" &lt;&lt; endl;&#xA;  return -1;&#xA;}&#xA;if (!(pOutFormatCtx = avformat_alloc_context())) {&#xA;  cout &lt;&lt; "could not create format conext" &lt;&lt; endl;&#xA;  cleanUp();&#xA;  return -1;&#xA;}&#xA;pOutFormatCtx->pb = pOutIoContext;&#xA;if (!(pOutFormatCtx->oformat = av_guess_format(nullptr, outFilename.data(), nullptr))) {&#xA;  cout &lt;&lt; "could not find output file format" &lt;&lt; endl;&#xA;  cleanUp();&#xA;  return -1;&#xA;}&#xA;if (!(pOutFormatCtx->url = av_strdup(outFilename.data()))) {&#xA;  cout &lt;&lt; "could not allocate file name" &lt;&lt; endl;&#xA;  cleanUp();&#xA;  return -1;&#xA;}&#xA;if (!(pOutCodec = avcodec_find_encoder(AV_CODEC_ID_PCM_ALAW))) {&#xA;  cout &lt;&lt; "codec not found" &lt;&lt; endl;&#xA;  cleanUp();&#xA;  return -1;&#xA;}&#xA;if (!(pOutStream = avformat_new_stream(pOutFormatCtx, nullptr))) {&#xA;  cout &lt;&lt; "could not create new stream" &lt;&lt; endl;&#xA;  cleanUp();&#xA;  return -1;&#xA;}&#xA;if (!(pOutCodecCtx = avcodec_alloc_context3(pOutCodec))) {&#xA;  cout &lt;&lt; "could not allocate codec context" &lt;&lt; endl;&#xA;  return -1;&#xA;}&#xA;av_channel_layout_default(&amp;pOutCodecCtx->ch_layout, OUTPUT_CHANNELS);&#xA;pOutCodecCtx->sample_rate = SAMPLE_RATE;&#xA;pOutCodecCtx->sample_fmt = pOutCodec->sample_fmts[0];&#xA;pOutCodecCtx->bit_rate = OUT_BIT_RATE;&#xA;&#xA;//setting sample rate for the container&#xA;pOutStream->time_base.den = SAMPLE_RATE;&#xA;pOutStream->time_base.num = 1;&#xA;if (pOutFormatCtx->oformat->flags &amp; AVFMT_GLOBALHEADER)&#xA;  pOutCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;&#xA;&#xA;if (avcodec_open2(pOutCodecCtx, pOutCodec, nullptr)) {&#xA;  cout &lt;&lt; "could not open output codec" &lt;&lt; endl;&#xA;  cleanUp();&#xA;  return -1;&#xA;}&#xA;if ((avcodec_parameters_from_context(pOutStream->codecpar, pOutCodecCtx)) &lt; 0) {&#xA;  cout &lt;&lt; "could not initialize stream parameters" &lt;&lt; endl;&#xA;}   &#xA;&#xA;AVPacket* packet = av_packet_alloc();&#xA;&#xA;swr = swr_alloc();&#xA;swr_alloc_set_opts2(&amp;swr, &amp;pOutCodecCtx->ch_layout, pOutCodecCtx->sample_fmt, pOutCodecCtx->sample_rate,&amp;pCodecCtx->ch_layout, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0, nullptr);&#xA;swr_init(swr);&#xA;&#xA;int ret{};&#xA;int bSize{};&#xA;while (av_read_frame(pFormatCtx, packet) >= 0) {&#xA;  AVFrame* pFrame = av_frame_alloc();&#xA;  AVFrame* pOutFrame = av_frame_alloc();&#xA;  if (packet->stream_index == audiostream) {&#xA;    ret = avcodec_send_packet(pCodecCtx, packet);&#xA;    while (ret >= 0) {&#xA;    ret = avcodec_receive_frame(pCodecCtx, pFrame);&#xA;    if (ret == AVERROR(EAGAIN))&#xA;    continue;&#xA;    else if (ret == AVERROR_EOF)&#xA;    break;&#xA;    dstNmbrSamples = av_rescale_rnd(swr_get_delay(swr, pCodecCtx->sample_rate) &#x2B; pFrame->nb_samples, pOutCodecCtx->sample_rate, pCodecCtx->sample_rate, AV_ROUND_UP);&#xA;    if ((av_samples_alloc_array_and_samples(&amp;convertedSamplesBuffer, &amp;dstLineSize, pOutCodecCtx->ch_layout.nb_channels,dstNmbrSamples, pOutCodecCtx->sample_fmt, 0)) &lt; 0) {&#xA;    cout &lt;&lt; "coult not allocate samples array and buffer" &lt;&lt; endl;&#xA;    }&#xA;    int channel_samples_count{ 0 };&#xA;    channel_samples_count = swr_convert(swr, convertedSamplesBuffer, dstNmbrSamples, (const uint8_t**)pFrame->data, pFrame->nb_samples);&#xA;    bSize = av_samples_get_buffer_size(&amp;dstLineSize, pOutCodecCtx->ch_layout.nb_channels, channel_samples_count, pOutCodecCtx->sample_fmt, 0);&#xA;    cout &lt;&lt; "no of samples is " &lt;&lt; channel_samples_count &lt;&lt; " the buffer size " &lt;&lt; bSize &lt;&lt; endl;&#xA;    pOutFrame->nb_samples = channel_samples_count;&#xA;    av_channel_layout_copy(&amp;pOutFrame->ch_layout, &amp;pOutCodecCtx->ch_layout);&#xA;    pOutFrame->format = pOutCodecCtx->sample_fmt;&#xA;    pOutFrame->sample_rate = pOutCodecCtx->sample_rate;&#xA;    if ((av_frame_get_buffer(pOutFrame, 0)) &lt; 0) {&#xA;    cout &lt;&lt; "could not allocate output frame samples " &lt;&lt; endl;&#xA;    av_frame_free(&amp;pOutFrame);&#xA;  }&#xA;                &#xA;    //populate out frame buffer&#xA;    av_frame_make_writable(pOutFrame);&#xA;    for (int i{ 0 }; i &lt; bSize; i&#x2B;&#x2B;) {&#xA;    pOutFrame->data[0][i] = convertedSamplesBuffer[0][i];&#xA;    cout &lt;&lt; pOutFrame->data[0][i];&#xA;   }&#xA;   if (pOutFrame) {&#xA;   pOutFrame->pts = pts;&#xA;   pts &#x2B;= pOutFrame->nb_samples;&#xA;  }&#xA;   int res = avcodec_send_frame(pOutCodecCtx, pOutFrame);&#xA;    if (res &lt; 0) {&#xA;    cout &lt;&lt; "error sending frame to encoder" &lt;&lt; endl;&#xA;    cleanUp();&#xA;    return -1;&#xA;   }&#xA;   //int er = avformat_write_header(pOutFormatCtx,nullptr);&#xA;   AVPacket* pOutPacket = av_packet_alloc();&#xA;   pOutPacket->time_base.num = 1;&#xA;   pOutPacket->time_base.den = 8000;&#xA;   if (pOutPacket == nullptr) {&#xA;    cout &lt;&lt; "unable to allocate packet" &lt;&lt; endl;&#xA;  }&#xA;  while (res >= 0) {&#xA;   res = avcodec_receive_packet(pOutCodecCtx, pOutPacket);&#xA;   if (res == AVERROR(EAGAIN))&#xA;    continue;&#xA;   else if (ret == AVERROR_EOF)&#xA;    break;&#xA;   av_packet_rescale_ts(pOutPacket, pOutCodecCtx->time_base, pOutFormatCtx->streams[0]->time_base);&#xA;   //av_dump_format(pOutFormatCtx, 0, outFilename.c_str(), 1);&#xA;   if (av_write_frame(pOutFormatCtx, pOutPacket) &lt; 0) {&#xA;    cout &lt;&lt; "could not write frame" &lt;&lt; endl;&#xA;    }&#xA;   }&#xA;  }&#xA;}&#xA; av_frame_free(&amp;pFrame);&#xA; av_frame_free(&amp;pOutFrame);&#xA;}&#xA;if (av_write_trailer(pOutFormatCtx) &lt; 0) {&#xA; cout &lt;&lt; "could not write file trailer" &lt;&lt; endl;&#xA;}&#xA;swr_free(&amp;swr);&#xA;avcodec_free_context(&amp;pOutCodecCtx);&#xA;av_packet_free(&amp;packet);&#xA;}&#xA;</iostream>

    &#xA;

    Error/Exception

    &#xA;

    The exception is thrown when I call

    &#xA;

    if (av_write_frame(pOutFormatCtx, pOutPacket) &lt; 0)  {   cout &lt;&lt; "could not write frame" &lt;&lt; endl; } &#xA;I also called this line

    &#xA;

    //int er = avformat_write_header(pOutFormatCtx,nullptr);

    &#xA;

    to see if I will get an exception but it did not throw any exception.

    &#xA;

    I have spent weeks on this issue with no success.&#xA;My goal is to take any audio from a file an be able to resample it if need be, and transcode it to PCM_ALAW.&#xA;I will appreciate any help I can get.

    &#xA;

  • Bad src image ptrs converting YUV to RGB after H264 decoding with libav and c++

    31 octobre 2023, par Sebastian DELLING

    I am getting "bad src image ptrs" errors when trying to convert my frames to RGB with sws_scale after decoding frames from a H264 file and cannot figure out wht is going wrong.

    &#xA;

    I checked what is causing the error and found the check_image_pointers function in swscale.c which validates that the planes and line sizes needed for the pixel format (av_pix_fmt_desc_get) are present in the given data which seems not to be the case with my data.

    &#xA;

    The written pgm files look ok to me, also replaying the file works.

    &#xA;

    I printed the corresponding data of my frame. The problem seems that planes 1 and 2 have lines sizes of 0. All 3 of them seem to have data. Plane 0 line size is three times image width which is also confusing to me.

    &#xA;

    Here is my output :

    &#xA;

    Have videoStreamIndex 0 codec id: 27&#xA;saving frame 1 C:\\tmp\\output-frame-1.pgm colorspace 2 pix_fmt 0 w: 3840 h: 2160&#xA;Required:&#xA;plane 0 : 0&#xA;plane 1 : 1&#xA;plane 2 : 2&#xA;plane 3 : 0&#xA;Present:&#xA;Frame plane 0: 1 , 11520&#xA;Frame plane 1: 1 , 0&#xA;Frame plane 2: 1 , 0&#xA;Frame plane 3: 0 , 0&#xA;Frame plane 4: 0 , 0&#xA;Frame plane 5: 0 , 0&#xA;Frame plane 6: 0 , 0&#xA;Frame plane 7: 0 , 0&#xA;

    &#xA;

    Here the whole code of my application, the issues occurs in method decode :

    &#xA;

    #include <iostream>&#xA;#include <cstring>&#xA;#include <cstdio>&#xA;#include <cstdint>&#xA;#include <string>&#xA;#include <iostream>&#xA;#include <chrono>&#xA;&#xA;// #include <opencv2></opencv2>highgui.hpp>&#xA;// #include <opencv2></opencv2>opencv.hpp>&#xA;&#xA;extern "C"&#xA;{&#xA;&#xA;#include <libswscale></libswscale>swscale.h>&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavfilter></libavfilter>buffersink.h>&#xA;#include <libavfilter></libavfilter>buffersrc.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>pixdesc.h>&#xA;#include <libavutil></libavutil>display.h>&#xA;#include "libavutil/imgutils.h"&#xA;}&#xA;&#xA;#define INBUF_SIZE 4096&#xA;class H264Decoder&#xA;{&#xA;public:&#xA;    H264Decoder(const std::string &amp;inputFilename, const std::string &amp;outputFilenamePrefix)&#xA;    {&#xA;&#xA;        // Open input file&#xA;        if (avformat_open_input(&amp;formatContext, inputFilename.c_str(), nullptr, nullptr) != 0)&#xA;        {&#xA;            throw std::runtime_error("Could not open input file");&#xA;        }&#xA;&#xA;        if (avformat_find_stream_info(formatContext, nullptr) &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not find stream information");&#xA;        }&#xA;&#xA;        // Find H.264 video stream&#xA;        for (unsigned i = 0; i &lt; formatContext->nb_streams; i&#x2B;&#x2B;)&#xA;        {&#xA;            if (formatContext->streams[i]->codecpar->codec_id == AV_CODEC_ID_H264)&#xA;            {&#xA;                videoStreamIndex = i;&#xA;                std::cout &lt;&lt; "Have videoStreamIndex " &lt;&lt; videoStreamIndex &lt;&lt; " codec id: " &lt;&lt; formatContext->streams[i]->codecpar->codec_id &lt;&lt; std::endl;&#xA;                break;&#xA;            }&#xA;        }&#xA;&#xA;        if (videoStreamIndex == -1)&#xA;        {&#xA;            throw std::runtime_error("H.264 video stream not found");&#xA;        }&#xA;&#xA;        // Initialize codec and codec context&#xA;        const AVCodec *codec = avcodec_find_decoder(formatContext->streams[videoStreamIndex]->codecpar->codec_id);&#xA;        if (!codec)&#xA;        {&#xA;            throw std::runtime_error("Codec not found");&#xA;        }&#xA;&#xA;        parser = av_parser_init(codec->id);&#xA;        if (!parser)&#xA;        {&#xA;            throw std::runtime_error("parser not found");&#xA;        }&#xA;&#xA;        codecContext = avcodec_alloc_context3(codec);&#xA;        if (!codecContext)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate codec context");&#xA;        }&#xA;&#xA;        if (avcodec_open2(codecContext, codec, nullptr) &lt; 0)&#xA;        {&#xA;            throw std::runtime_error("Could not open codec");&#xA;        }&#xA;&#xA;        // Initialize frame&#xA;        frame = av_frame_alloc();&#xA;        frame->format = AV_PIX_FMT_YUV420P;&#xA;        if (!frame)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate frame");&#xA;        }&#xA;&#xA;        inputPacket = av_packet_alloc();&#xA;        if (!inputPacket)&#xA;        {&#xA;            throw std::runtime_error("Could not allocate packet");&#xA;        }&#xA;&#xA;        inputFilename_ = inputFilename;&#xA;        outputFilenamePrefix_ = outputFilenamePrefix;&#xA;    }&#xA;&#xA;    void decode()&#xA;    {&#xA;        char buf[1024];&#xA;        int ret;&#xA;&#xA;        ret = avcodec_send_packet(codecContext, inputPacket);&#xA;        if (ret &lt; 0)&#xA;        {&#xA;            fprintf(stderr, "Error sending a packet for decoding\n");&#xA;            exit(1);&#xA;        }&#xA;&#xA;        while (ret >= 0)&#xA;        {&#xA;            ret = avcodec_receive_frame(codecContext, frame);&#xA;            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;                return;&#xA;            else if (ret &lt; 0)&#xA;            {&#xA;                fprintf(stderr, "Error during decoding\n");&#xA;                exit(1);&#xA;            }&#xA;&#xA;            /* the picture is allocated by the decoder. no need to&#xA;               free it */&#xA;            snprintf(buf, sizeof(buf), "%s-%" PRId64 ".pgm", outputFilenamePrefix_.c_str(), codecContext->frame_num);&#xA;&#xA;            std::cout &lt;&lt; "saving frame " &lt;&lt; codecContext->frame_num &lt;&lt; " " &lt;&lt; buf &lt;&lt; " colorspace " &lt;&lt; frame->colorspace &lt;&lt; " pix_fmt " &lt;&lt; codecContext->pix_fmt &lt;&lt; " w: " &lt;&lt; frame->width &lt;&lt; " h: " &lt;&lt; frame->height &lt;&lt; std::endl;&#xA;&#xA;            SwsContext *sws_ctx = NULL;&#xA;&#xA;            sws_ctx = sws_getContext(codecContext->width,&#xA;                                     codecContext->height,&#xA;                                     codecContext->pix_fmt,&#xA;                                     codecContext->width,&#xA;                                     codecContext->height,&#xA;                                     AV_PIX_FMT_RGB24,&#xA;                                     SWS_BICUBIC,&#xA;                                     NULL,&#xA;                                     NULL,&#xA;                                     NULL);&#xA;&#xA;            AVFrame *frame2 = av_frame_alloc();&#xA;            int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codecContext->width, codecContext->height, 32);&#xA;            uint8_t *frame2_buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t));&#xA;            av_image_fill_arrays(frame2->data, frame->linesize, frame2_buffer, AV_PIX_FMT_RGB24, codecContext->width, codecContext->height, 32);&#xA;&#xA;            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(codecContext->pix_fmt);&#xA;            std::cout &lt;&lt; "Required:" &lt;&lt; std::endl;&#xA;            for (int i = 0; i &lt; 4; i&#x2B;&#x2B;)&#xA;            {&#xA;                int plane = desc->comp[i].plane;&#xA;                std::cout &lt;&lt; "plane " &lt;&lt; i &lt;&lt; " : " &lt;&lt; plane &lt;&lt; std::endl;&#xA;            }&#xA;            std::cout &lt;&lt; "Present:" &lt;&lt; std::endl;&#xA;            for (int i = 0; i &lt; AV_NUM_DATA_POINTERS; &#x2B;&#x2B;i)&#xA;            {&#xA;                std::cout &lt;&lt; "Frame plane " &lt;&lt; i &lt;&lt; ": " &lt;&lt; static_cast<bool>(frame->data[i]) &lt;&lt; " , " &lt;&lt; frame->linesize[i] &lt;&lt; std::endl;&#xA;            }&#xA;&#xA;            sws_scale(sws_ctx, frame->data,&#xA;                      frame->linesize, 0, codecContext->height,&#xA;                      frame2->data, frame2->linesize);&#xA;&#xA;            // cv::Mat img(frame2->height, frame2->width, CV_8UC3, frame2->data[0]);&#xA;            // cv::imshow("Image", img);&#xA;&#xA;            pgm_save(frame->data[0], frame->linesize[0],&#xA;                     frame->width, frame->height, buf);&#xA;        }&#xA;    }&#xA;&#xA;    ~H264Decoder()&#xA;    {&#xA;        avformat_close_input(&amp;formatContext);&#xA;        avformat_free_context(formatContext);&#xA;        avcodec_free_context(&amp;codecContext);&#xA;        av_frame_free(&amp;frame);&#xA;        av_packet_free(&amp;inputPacket);&#xA;    }&#xA;&#xA;    void readAndDecode()&#xA;    {&#xA;        FILE *f;&#xA;        uint8_t inbuf[INBUF_SIZE &#x2B; AV_INPUT_BUFFER_PADDING_SIZE];&#xA;        uint8_t *data;&#xA;        size_t data_size;&#xA;        int ret;&#xA;        int eof;&#xA;        f = fopen(inputFilename_.c_str(), "rb");&#xA;        auto start = std::chrono::high_resolution_clock::now();&#xA;        do&#xA;        {&#xA;            /* read raw data from the input file */&#xA;            data_size = fread(inbuf, 1, INBUF_SIZE, f);&#xA;            if (ferror(f))&#xA;                break;&#xA;            eof = !data_size;&#xA;&#xA;            /* use the parser to split the data into frames */&#xA;            data = inbuf;&#xA;            while (data_size > 0 || eof)&#xA;            {&#xA;                ret = av_parser_parse2(parser, codecContext, &amp;inputPacket->data, &amp;inputPacket->size,&#xA;                                       data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);&#xA;                if (ret &lt; 0)&#xA;                {&#xA;                    fprintf(stderr, "Error while parsing\n");&#xA;                    exit(1);&#xA;                }&#xA;                data &#x2B;= ret;&#xA;                data_size -= ret;&#xA;&#xA;                if (inputPacket->size)&#xA;                {&#xA;                    decode();&#xA;                }&#xA;                else if (eof)&#xA;                {&#xA;                    break;&#xA;                }&#xA;            }&#xA;        } while (!eof);&#xA;        auto diff = std::chrono::high_resolution_clock::now() - start;&#xA;        std::cout &lt;&lt; "Decoded " &lt;&lt; codecContext->frame_num &lt;&lt; " frames in " &lt;&lt; std::chrono::duration_cast(diff).count() &lt;&lt; " ms" &lt;&lt; std::endl;&#xA;    }&#xA;&#xA;private:&#xA;    AVFormatContext *formatContext = nullptr;&#xA;    AVCodecContext *codecContext = nullptr;&#xA;    AVCodecParserContext *parser;&#xA;    AVFrame *frame = nullptr;&#xA;    AVFrame *frameRgb = nullptr;&#xA;    AVPacket *inputPacket = nullptr;&#xA;    int videoStreamIndex = -1;&#xA;    std::string inputFilename_;&#xA;    std::string outputFilenamePrefix_;&#xA;&#xA;    static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, const char *filename)&#xA;    {&#xA;        FILE *f = fopen(filename, "wb");&#xA;        if (!f)&#xA;        {&#xA;            std::cout &lt;&lt; "Error opening file for saving PGM" &lt;&lt; std::endl;&#xA;            exit(1);&#xA;        }&#xA;&#xA;        fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);&#xA;        for (int i = 0; i &lt; ysize; i&#x2B;&#x2B;)&#xA;            fwrite(buf &#x2B; i * wrap, 1, xsize, f);&#xA;&#xA;        fclose(f);&#xA;    }&#xA;};&#xA;&#xA;int main(int argc, char *argv[])&#xA;{&#xA;    if (argc &lt; 2)&#xA;    {&#xA;        std::cout &lt;&lt; "Please provide input file name as parameter" &lt;&lt; std::endl;&#xA;    }&#xA;&#xA;    std::string inputFilename = argv[1];&#xA;    std::string outputFilenamePrefix = "C:\\tmp\\output-frame";&#xA;&#xA;    try&#xA;    {&#xA;&#xA;        H264Decoder decoder(inputFilename, outputFilenamePrefix);&#xA;        decoder.readAndDecode();&#xA;    }&#xA;    catch (const std::exception &amp;e)&#xA;    {&#xA;        std::cout &lt;&lt; "Error: " &lt;&lt; e.what() &lt;&lt; std::endl;&#xA;        return 1;&#xA;    }&#xA;&#xA;    return 0;&#xA;}&#xA;</bool></chrono></iostream></string></cstdint></cstdio></cstring></iostream>

    &#xA;