Recherche avancée

Médias (91)

Autres articles (25)

  • Selection of projects using MediaSPIP

    2 mai 2011, par

    The examples below are representative elements of MediaSPIP specific uses for specific projects.
    MediaSPIP farm @ Infini
    The non profit organizationInfini develops hospitality activities, internet access point, training, realizing innovative projects in the field of information and communication technologies and Communication, and hosting of websites. It plays a unique and prominent role in the Brest (France) area, at the national level, among the half-dozen such association. Its members (...)

  • Keeping control of your media in your hands

    13 avril 2011, par

    The vocabulary used on this site and around MediaSPIP in general, aims to avoid reference to Web 2.0 and the companies that profit from media-sharing.
    While using MediaSPIP, you are invited to avoid using words like "Brand", "Cloud" and "Market".
    MediaSPIP is designed to facilitate the sharing of creative media online, while allowing authors to retain complete control of their work.
    MediaSPIP aims to be accessible to as many people as possible and development is based on expanding the (...)

  • Sélection de projets utilisant MediaSPIP

    29 avril 2011, par

    Les exemples cités ci-dessous sont des éléments représentatifs d’usages spécifiques de MediaSPIP pour certains projets.
    Vous pensez avoir un site "remarquable" réalisé avec MediaSPIP ? Faites le nous savoir ici.
    Ferme MediaSPIP @ Infini
    L’Association Infini développe des activités d’accueil, de point d’accès internet, de formation, de conduite de projets innovants dans le domaine des Technologies de l’Information et de la Communication, et l’hébergement de sites. Elle joue en la matière un rôle unique (...)

Sur d’autres sites (4428)

  • Getting green screen in ffplay : Streaming desktop (DirectX surface) as H264 video over RTP stream using Live555

    7 novembre 2019, par Ram

    I’m trying to stream the desktop(DirectX surface in NV12 format) as H264 video over RTP stream using Live555 & Windows media foundation’s hardware encoder on Windows10, and expecting it to be rendered by ffplay (ffmpeg 4.2). But only getting a green screen like below,

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    I referred MFWebCamToRTP mediafoundation-sample & Encoding DirectX surface using hardware MFT for implementing live555’s FramedSource and changing the input source to DirectX surface instead of webCam.

    Here is an excerpt of my implementation for Live555’s doGetNextFrame callback to feed input samples from directX surface :

    virtual void doGetNextFrame()
    {
       if (!_isInitialised)
       {
           if (!initialise()) {
               printf("Video device initialisation failed, stopping.");
               return;
           }
           else {
               _isInitialised = true;
           }
       }

       //if (!isCurrentlyAwaitingData()) return;

       DWORD processOutputStatus = 0;
       HRESULT mftProcessOutput = S_OK;
       MFT_OUTPUT_STREAM_INFO StreamInfo;
       IMFMediaBuffer *pBuffer = NULL;
       IMFSample *mftOutSample = NULL;
       DWORD mftOutFlags;
       bool frameSent = false;
       bool bTimeout = false;

       // Create sample
       CComPtr<imfsample> videoSample = NULL;

       // Create buffer
       CComPtr<imfmediabuffer> inputBuffer;
       // Get next event
       CComPtr<imfmediaevent> event;
       HRESULT hr = eventGen->GetEvent(0, &amp;event);
       CHECK_HR(hr, "Failed to get next event");

       MediaEventType eventType;
       hr = event->GetType(&amp;eventType);
       CHECK_HR(hr, "Failed to get event type");


       switch (eventType)
       {
       case METransformNeedInput:
           {
               hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), surface, 0, FALSE, &amp;inputBuffer);
               CHECK_HR(hr, "Failed to create IMFMediaBuffer");

               hr = MFCreateSample(&amp;videoSample);
               CHECK_HR(hr, "Failed to create IMFSample");
               hr = videoSample->AddBuffer(inputBuffer);
               CHECK_HR(hr, "Failed to add buffer to IMFSample");

               if (videoSample)
               {
                   _frameCount++;

                   CHECK_HR(videoSample->SetSampleTime(mTimeStamp), "Error setting the video sample time.\n");
                   CHECK_HR(videoSample->SetSampleDuration(VIDEO_FRAME_DURATION), "Error getting video sample duration.\n");

                   // Pass the video sample to the H.264 transform.

                   hr = _pTransform->ProcessInput(inputStreamID, videoSample, 0);
                   CHECK_HR(hr, "The resampler H264 ProcessInput call failed.\n");

                   mTimeStamp += VIDEO_FRAME_DURATION;
               }
           }

           break;

       case METransformHaveOutput:

           {
               CHECK_HR(_pTransform->GetOutputStatus(&amp;mftOutFlags), "H264 MFT GetOutputStatus failed.\n");

               if (mftOutFlags == MFT_OUTPUT_STATUS_SAMPLE_READY)
               {
                   MFT_OUTPUT_DATA_BUFFER _outputDataBuffer;
                   memset(&amp;_outputDataBuffer, 0, sizeof _outputDataBuffer);
                   _outputDataBuffer.dwStreamID = outputStreamID;
                   _outputDataBuffer.dwStatus = 0;
                   _outputDataBuffer.pEvents = NULL;
                   _outputDataBuffer.pSample = nullptr;

                   mftProcessOutput = _pTransform->ProcessOutput(0, 1, &amp;_outputDataBuffer, &amp;processOutputStatus);

                   if (mftProcessOutput != MF_E_TRANSFORM_NEED_MORE_INPUT)
                   {
                       if (_outputDataBuffer.pSample) {

                           //CHECK_HR(_outputDataBuffer.pSample->SetSampleTime(mTimeStamp), "Error setting MFT sample time.\n");
                           //CHECK_HR(_outputDataBuffer.pSample->SetSampleDuration(VIDEO_FRAME_DURATION), "Error setting MFT sample duration.\n");

                           IMFMediaBuffer *buf = NULL;
                           DWORD bufLength;
                           CHECK_HR(_outputDataBuffer.pSample->ConvertToContiguousBuffer(&amp;buf), "ConvertToContiguousBuffer failed.\n");
                           CHECK_HR(buf->GetCurrentLength(&amp;bufLength), "Get buffer length failed.\n");
                           BYTE * rawBuffer = NULL;

                           fFrameSize = bufLength;
                           fDurationInMicroseconds = 0;
                           gettimeofday(&amp;fPresentationTime, NULL);

                           buf->Lock(&amp;rawBuffer, NULL, NULL);
                           memmove(fTo, rawBuffer, fFrameSize);

                           FramedSource::afterGetting(this);

                           buf->Unlock();
                           SafeRelease(&amp;buf);

                           frameSent = true;
                           _lastSendAt = GetTickCount();

                           _outputDataBuffer.pSample->Release();
                       }

                       if (_outputDataBuffer.pEvents)
                           _outputDataBuffer.pEvents->Release();
                   }

                   //SafeRelease(&amp;pBuffer);
                   //SafeRelease(&amp;mftOutSample);

                   break;
               }
           }

           break;
       }

       if (!frameSent)
       {
           envir().taskScheduler().triggerEvent(eventTriggerId, this);
       }

       return;

    done:

       printf("MediaFoundationH264LiveSource doGetNextFrame failed.\n");
       envir().taskScheduler().triggerEvent(eventTriggerId, this);
    }
    </imfmediaevent></imfmediabuffer></imfsample>

    Initialise method :

    bool initialise()
    {
       HRESULT hr;
       D3D11_TEXTURE2D_DESC desc = { 0 };

       HDESK CurrentDesktop = nullptr;
       CurrentDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL);
       if (!CurrentDesktop)
       {
           // We do not have access to the desktop so request a retry
           return false;
       }

       // Attach desktop to this thread
       bool DesktopAttached = SetThreadDesktop(CurrentDesktop) != 0;
       CloseDesktop(CurrentDesktop);
       CurrentDesktop = nullptr;
       if (!DesktopAttached)
       {
           printf("SetThreadDesktop failed\n");
       }

       UINT32 activateCount = 0;

       // h264 output
       MFT_REGISTER_TYPE_INFO info = { MFMediaType_Video, MFVideoFormat_H264 };

       UINT32 flags =
           MFT_ENUM_FLAG_HARDWARE |
           MFT_ENUM_FLAG_SORTANDFILTER;

       // ------------------------------------------------------------------------
       // Initialize D3D11
       // ------------------------------------------------------------------------

       // Driver types supported
       D3D_DRIVER_TYPE DriverTypes[] =
       {
           D3D_DRIVER_TYPE_HARDWARE,
           D3D_DRIVER_TYPE_WARP,
           D3D_DRIVER_TYPE_REFERENCE,
       };
       UINT NumDriverTypes = ARRAYSIZE(DriverTypes);

       // Feature levels supported
       D3D_FEATURE_LEVEL FeatureLevels[] =
       {
           D3D_FEATURE_LEVEL_11_0,
           D3D_FEATURE_LEVEL_10_1,
           D3D_FEATURE_LEVEL_10_0,
           D3D_FEATURE_LEVEL_9_1
       };
       UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);

       D3D_FEATURE_LEVEL FeatureLevel;

       // Create device
       for (UINT DriverTypeIndex = 0; DriverTypeIndex &lt; NumDriverTypes; ++DriverTypeIndex)
       {
           hr = D3D11CreateDevice(nullptr, DriverTypes[DriverTypeIndex], nullptr,
               D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
               FeatureLevels, NumFeatureLevels, D3D11_SDK_VERSION, &amp;device, &amp;FeatureLevel, &amp;context);
           if (SUCCEEDED(hr))
           {
               // Device creation success, no need to loop anymore
               break;
           }
       }

       CHECK_HR(hr, "Failed to create device");

       // Create device manager
       UINT resetToken;
       hr = MFCreateDXGIDeviceManager(&amp;resetToken, &amp;deviceManager);
       CHECK_HR(hr, "Failed to create DXGIDeviceManager");

       hr = deviceManager->ResetDevice(device, resetToken);
       CHECK_HR(hr, "Failed to assign D3D device to device manager");


       // ------------------------------------------------------------------------
       // Create surface
       // ------------------------------------------------------------------------
       desc.Format = DXGI_FORMAT_NV12;
       desc.Width = surfaceWidth;
       desc.Height = surfaceHeight;
       desc.MipLevels = 1;
       desc.ArraySize = 1;
       desc.SampleDesc.Count = 1;

       hr = device->CreateTexture2D(&amp;desc, NULL, &amp;surface);
       CHECK_HR(hr, "Could not create surface");

       hr = MFTEnumEx(
           MFT_CATEGORY_VIDEO_ENCODER,
           flags,
           NULL,
           &amp;info,
           &amp;activateRaw,
           &amp;activateCount
       );
       CHECK_HR(hr, "Failed to enumerate MFTs");

       CHECK(activateCount, "No MFTs found");

       // Choose the first available encoder
       activate = activateRaw[0];

       for (UINT32 i = 0; i &lt; activateCount; i++)
           activateRaw[i]->Release();

       // Activate
       hr = activate->ActivateObject(IID_PPV_ARGS(&amp;_pTransform));
       CHECK_HR(hr, "Failed to activate MFT");

       // Get attributes
       hr = _pTransform->GetAttributes(&amp;attributes);
       CHECK_HR(hr, "Failed to get MFT attributes");

       // Unlock the transform for async use and get event generator
       hr = attributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
       CHECK_HR(hr, "Failed to unlock MFT");

       eventGen = _pTransform;
       CHECK(eventGen, "Failed to QI for event generator");

       // Get stream IDs (expect 1 input and 1 output stream)
       hr = _pTransform->GetStreamIDs(1, &amp;inputStreamID, 1, &amp;outputStreamID);
       if (hr == E_NOTIMPL)
       {
           inputStreamID = 0;
           outputStreamID = 0;
           hr = S_OK;
       }
       CHECK_HR(hr, "Failed to get stream IDs");

        // ------------------------------------------------------------------------
       // Configure hardware encoder MFT
      // ------------------------------------------------------------------------
       CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, reinterpret_cast(deviceManager.p)), "Failed to set device manager.\n");

       // Set low latency hint
       hr = attributes->SetUINT32(MF_LOW_LATENCY, TRUE);
       CHECK_HR(hr, "Failed to set MF_LOW_LATENCY");

       hr = MFCreateMediaType(&amp;outputType);
       CHECK_HR(hr, "Failed to create media type");

       hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
       CHECK_HR(hr, "Failed to set MF_MT_MAJOR_TYPE on H264 output media type");

       hr = outputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
       CHECK_HR(hr, "Failed to set MF_MT_SUBTYPE on H264 output media type");

       hr = outputType->SetUINT32(MF_MT_AVG_BITRATE, TARGET_AVERAGE_BIT_RATE);
       CHECK_HR(hr, "Failed to set average bit rate on H264 output media type");

       hr = MFSetAttributeSize(outputType, MF_MT_FRAME_SIZE, desc.Width, desc.Height);
       CHECK_HR(hr, "Failed to set frame size on H264 MFT out type");

       hr = MFSetAttributeRatio(outputType, MF_MT_FRAME_RATE, TARGET_FRAME_RATE, 1);
       CHECK_HR(hr, "Failed to set frame rate on H264 MFT out type");

       hr = outputType->SetUINT32(MF_MT_INTERLACE_MODE, 2);
       CHECK_HR(hr, "Failed to set MF_MT_INTERLACE_MODE on H.264 encoder MFT");

       hr = outputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
       CHECK_HR(hr, "Failed to set MF_MT_ALL_SAMPLES_INDEPENDENT on H.264 encoder MFT");

       hr = _pTransform->SetOutputType(outputStreamID, outputType, 0);
       CHECK_HR(hr, "Failed to set output media type on H.264 encoder MFT");

       hr = MFCreateMediaType(&amp;inputType);
       CHECK_HR(hr, "Failed to create media type");

       for (DWORD i = 0;; i++)
       {
           inputType = nullptr;
           hr = _pTransform->GetInputAvailableType(inputStreamID, i, &amp;inputType);
           CHECK_HR(hr, "Failed to get input type");

           hr = inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
           CHECK_HR(hr, "Failed to set MF_MT_MAJOR_TYPE on H264 MFT input type");

           hr = inputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
           CHECK_HR(hr, "Failed to set MF_MT_SUBTYPE on H264 MFT input type");

           hr = MFSetAttributeSize(inputType, MF_MT_FRAME_SIZE, desc.Width, desc.Height);
           CHECK_HR(hr, "Failed to set MF_MT_FRAME_SIZE on H264 MFT input type");

           hr = MFSetAttributeRatio(inputType, MF_MT_FRAME_RATE, TARGET_FRAME_RATE, 1);
           CHECK_HR(hr, "Failed to set MF_MT_FRAME_RATE on H264 MFT input type");

           hr = _pTransform->SetInputType(inputStreamID, inputType, 0);
           CHECK_HR(hr, "Failed to set input type");

           break;
       }

       CheckHardwareSupport();

       CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, NULL), "Failed to process FLUSH command on H.264 MFT.\n");
       CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL), "Failed to process BEGIN_STREAMING command on H.264 MFT.\n");
       CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL), "Failed to process START_OF_STREAM command on H.264 MFT.\n");

       return true;

    done:

       printf("MediaFoundationH264LiveSource initialisation failed.\n");
       return false;
    }


       HRESULT CheckHardwareSupport()
       {
           IMFAttributes *attributes;
           HRESULT hr = _pTransform->GetAttributes(&amp;attributes);
           UINT32 dxva = 0;

           if (SUCCEEDED(hr))
           {
               hr = attributes->GetUINT32(MF_SA_D3D11_AWARE, &amp;dxva);
           }

           if (SUCCEEDED(hr))
           {
               hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE);
           }

    #if defined(CODECAPI_AVLowLatencyMode) // Win8 only

           hr = _pTransform->QueryInterface(IID_PPV_ARGS(&amp;mpCodecAPI));

           if (SUCCEEDED(hr))
           {
               VARIANT var = { 0 };

               // FIXME: encoder only
               var.vt = VT_UI4;
               var.ulVal = 0;

               hr = mpCodecAPI->SetValue(&amp;CODECAPI_AVEncMPVDefaultBPictureCount, &amp;var);

               var.vt = VT_BOOL;
               var.boolVal = VARIANT_TRUE;
               hr = mpCodecAPI->SetValue(&amp;CODECAPI_AVEncCommonLowLatency, &amp;var);
               hr = mpCodecAPI->SetValue(&amp;CODECAPI_AVEncCommonRealTime, &amp;var);

               hr = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);

               if (SUCCEEDED(hr))
               {
                   var.vt = VT_UI4;
                   var.ulVal = eAVEncCommonRateControlMode_Quality;
                   hr = mpCodecAPI->SetValue(&amp;CODECAPI_AVEncCommonRateControlMode, &amp;var);

                   // This property controls the quality level when the encoder is not using a constrained bit rate. The AVEncCommonRateControlMode property determines whether the bit rate is constrained.
                   VARIANT quality;
                   InitVariantFromUInt32(50, &amp;quality);
                   hr = mpCodecAPI->SetValue(&amp;CODECAPI_AVEncCommonQuality, &amp;quality);
               }
           }
    #endif

           return hr;
       }

    ffplay command :

    ffplay -protocol_whitelist file,udp,rtp -i test.sdp -x 800 -y 600 -profile:v baseline

    SDP :

    v=0
    o=- 0 0 IN IP4 127.0.0.1
    s=No Name
    t=0 0
    c=IN IP4 127.0.0.1
    m=video 1234 RTP/AVP 96
    a=rtpmap:96 H264/90000
    a=fmtp:96 packetization-mode=1

    I don’t know what am I missing, I have been trying to fix this for almost a week without any progress, and tried almost everything I could. Also, the online resources for encoding a DirectX surface as video are very limited.

    Any help would be appreciated.

  • increasing memory occupancy while recording screen save to disk with ffmpeg [on hold]

    19 mai 2016, par vbtang

    wonder if there are any resoures i didn’t free ?or do i need to do something special so that i can free these momery ?

    ps. run the demo step by step, and found it has the same problem, until it quit the main function, it still have 40MB memory occupancy. And i found the memory increase obviously in the screen capture thread,but when it increased to about 150MB, it won’t increase, until i quit the program, it will have 40MB memory left. i feel confused.

    pss. i download ffmpeg dev and shared version form here https://ffmpeg.zeranoe.com/builds/,it seems a dll of debug version ? do i need a release version ?
    here is my demo code.

       #include "stdafx.h"

    #ifdef  __cplusplus
    extern "C"
    {
    #endif
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libswscale/swscale.h"
    #include "libavdevice/avdevice.h"
    #include "libavutil/audio_fifo.h"

    #pragma comment(lib, "avcodec.lib")
    #pragma comment(lib, "avformat.lib")
    #pragma comment(lib, "avutil.lib")
    #pragma comment(lib, "avdevice.lib")
    #pragma comment(lib, "avfilter.lib")

    //#pragma comment(lib, "avfilter.lib")
    //#pragma comment(lib, "postproc.lib")
    //#pragma comment(lib, "swresample.lib")
    #pragma comment(lib, "swscale.lib")
    #ifdef __cplusplus
    };
    #endif

    AVFormatContext *pFormatCtx_Video = NULL, *pFormatCtx_Audio = NULL, *pFormatCtx_Out = NULL;
    AVCodecContext  *pCodecCtx_Video;
    AVCodec         *pCodec_Video;
    AVFifoBuffer    *fifo_video = NULL;
    AVAudioFifo     *fifo_audio = NULL;
    int VideoIndex, AudioIndex;

    CRITICAL_SECTION AudioSection, VideoSection;



    SwsContext *img_convert_ctx;
    int frame_size = 0;

    uint8_t *picture_buf = NULL, *frame_buf = NULL;

    bool bCap = true;

    DWORD WINAPI ScreenCapThreadProc( LPVOID lpParam );
    DWORD WINAPI AudioCapThreadProc( LPVOID lpParam );

    int OpenVideoCapture()
    {
       AVInputFormat *ifmt=av_find_input_format("gdigrab");
       //
       AVDictionary *options = NULL;
       av_dict_set(&amp;options, "framerate", "15", NULL);
       //av_dict_set(&amp;options,"offset_x","20",0);
       //The distance from the top edge of the screen or desktop
       //av_dict_set(&amp;options,"offset_y","40",0);
       //Video frame size. The default is to capture the full screen
       //av_dict_set(&amp;options,"video_size","320x240",0);
       if(avformat_open_input(&amp;pFormatCtx_Video, "desktop", ifmt, &amp;options)!=0)
       {
           printf("Couldn't open input stream.(无法打开视频输入流)\n");
           return -1;
       }
       if(avformat_find_stream_info(pFormatCtx_Video,NULL)&lt;0)
       {
           printf("Couldn't find stream information.(无法获取视频流信息)\n");
           return -1;
       }
       if (pFormatCtx_Video->streams[0]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
       {
           printf("Couldn't find video stream information.(无法获取视频流信息)\n");
           return -1;
       }
       pCodecCtx_Video = pFormatCtx_Video->streams[0]->codec;
       pCodec_Video = avcodec_find_decoder(pCodecCtx_Video->codec_id);
       if(pCodec_Video == NULL)
       {
           printf("Codec not found.(没有找到解码器)\n");
           return -1;
       }
       if(avcodec_open2(pCodecCtx_Video, pCodec_Video, NULL) &lt; 0)
       {
           printf("Could not open codec.(无法打开解码器)\n");
           return -1;
       }



       img_convert_ctx = sws_getContext(pCodecCtx_Video->width, pCodecCtx_Video->height, pCodecCtx_Video->pix_fmt,
           pCodecCtx_Video->width, pCodecCtx_Video->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

       frame_size = avpicture_get_size(pCodecCtx_Video->pix_fmt, pCodecCtx_Video->width, pCodecCtx_Video->height);
       //
       fifo_video = av_fifo_alloc(30 * avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx_Video->width, pCodecCtx_Video->height));

       return 0;
    }

    static char *dup_wchar_to_utf8(wchar_t *w)
    {
       char *s = NULL;
       int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
       s = (char *) av_malloc(l);
       if (s)
           WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
       return s;
    }

    int OpenAudioCapture()
    {
       //
       AVInputFormat *pAudioInputFmt = av_find_input_format("dshow");

       //
       char * psDevName = dup_wchar_to_utf8(L"audio=virtual-audio-capturer");

       if (avformat_open_input(&amp;pFormatCtx_Audio, psDevName, pAudioInputFmt,NULL) &lt; 0)
       {
           printf("Couldn't open input stream.(无法打开音频输入流)\n");
           return -1;
       }

       if(avformat_find_stream_info(pFormatCtx_Audio,NULL)&lt;0)  
           return -1;

       if(pFormatCtx_Audio->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
       {
           printf("Couldn't find video stream information.(无法获取音频流信息)\n");
           return -1;
       }

       AVCodec *tmpCodec = avcodec_find_decoder(pFormatCtx_Audio->streams[0]->codec->codec_id);
       if(0 > avcodec_open2(pFormatCtx_Audio->streams[0]->codec, tmpCodec, NULL))
       {
           printf("can not find or open audio decoder!\n");
       }



       return 0;
    }

    int OpenOutPut()
    {
       AVStream *pVideoStream = NULL, *pAudioStream = NULL;
       const char *outFileName = "test.mp4";
       avformat_alloc_output_context2(&amp;pFormatCtx_Out, NULL, NULL, outFileName);

       if (pFormatCtx_Video->streams[0]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
       {
           VideoIndex = 0;
           pVideoStream = avformat_new_stream(pFormatCtx_Out, NULL);

           if (!pVideoStream)
           {
               printf("can not new stream for output!\n");
               return -1;
           }

           //set codec context param
           pVideoStream->codec->codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
           pVideoStream->codec->height = pFormatCtx_Video->streams[0]->codec->height;
           pVideoStream->codec->width = pFormatCtx_Video->streams[0]->codec->width;

           pVideoStream->codec->time_base = pFormatCtx_Video->streams[0]->codec->time_base;
           pVideoStream->codec->sample_aspect_ratio = pFormatCtx_Video->streams[0]->codec->sample_aspect_ratio;
           // take first format from list of supported formats
           pVideoStream->codec->pix_fmt = pFormatCtx_Out->streams[VideoIndex]->codec->codec->pix_fmts[0];

           //open encoder
           if (!pVideoStream->codec->codec)
           {
               printf("can not find the encoder!\n");
               return -1;
           }

           if (pFormatCtx_Out->oformat->flags &amp; AVFMT_GLOBALHEADER)
               pVideoStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

           if ((avcodec_open2(pVideoStream->codec, pVideoStream->codec->codec, NULL)) &lt; 0)
           {
               printf("can not open the encoder\n");
               return -1;
           }
       }

       if(pFormatCtx_Audio->streams[0]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
       {
           AVCodecContext *pOutputCodecCtx;
           AudioIndex = 1;
           pAudioStream = avformat_new_stream(pFormatCtx_Out, NULL);

           pAudioStream->codec->codec = avcodec_find_encoder(pFormatCtx_Out->oformat->audio_codec);

           pOutputCodecCtx = pAudioStream->codec;

           pOutputCodecCtx->sample_rate = pFormatCtx_Audio->streams[0]->codec->sample_rate;
           pOutputCodecCtx->channel_layout = pFormatCtx_Out->streams[0]->codec->channel_layout;
           pOutputCodecCtx->channels = av_get_channel_layout_nb_channels(pAudioStream->codec->channel_layout);
           if(pOutputCodecCtx->channel_layout == 0)
           {
               pOutputCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;
               pOutputCodecCtx->channels = av_get_channel_layout_nb_channels(pOutputCodecCtx->channel_layout);

           }
           pOutputCodecCtx->sample_fmt = pAudioStream->codec->codec->sample_fmts[0];
           AVRational time_base={1, pAudioStream->codec->sample_rate};
           pAudioStream->time_base = time_base;
           //audioCodecCtx->time_base = time_base;

           pOutputCodecCtx->codec_tag = 0;  
           if (pFormatCtx_Out->oformat->flags &amp; AVFMT_GLOBALHEADER)  
               pOutputCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;

           if (avcodec_open2(pOutputCodecCtx, pOutputCodecCtx->codec, 0) &lt; 0)
           {
               //
               return -1;
           }
       }

       if (!(pFormatCtx_Out->oformat->flags &amp; AVFMT_NOFILE))
       {
           if(avio_open(&amp;pFormatCtx_Out->pb, outFileName, AVIO_FLAG_WRITE) &lt; 0)
           {
               printf("can not open output file handle!\n");
               return -1;
           }
       }

       if(avformat_write_header(pFormatCtx_Out, NULL) &lt; 0)
       {
           printf("can not write the header of the output file!\n");
           return -1;
       }

       return 0;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
       av_register_all();
       avdevice_register_all();
       if (OpenVideoCapture() &lt; 0)
       {
           return -1;
       }
       if (OpenAudioCapture() &lt; 0)
       {
           return -1;
       }
       if (OpenOutPut() &lt; 0)
       {
           return -1;
       }

       InitializeCriticalSection(&amp;VideoSection);
       InitializeCriticalSection(&amp;AudioSection);

       AVFrame *picture = av_frame_alloc();
       int size = avpicture_get_size(pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt,
           pFormatCtx_Out->streams[VideoIndex]->codec->width, pFormatCtx_Out->streams[VideoIndex]->codec->height);
       picture_buf = new uint8_t[size];

       avpicture_fill((AVPicture *)picture, picture_buf,
           pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt,
           pFormatCtx_Out->streams[VideoIndex]->codec->width,
           pFormatCtx_Out->streams[VideoIndex]->codec->height);



       //star cap screen thread
       CreateThread( NULL, 0, ScreenCapThreadProc, 0, 0, NULL);
       //star cap audio thread
       CreateThread( NULL, 0, AudioCapThreadProc, 0, 0, NULL);
       int64_t cur_pts_v=0,cur_pts_a=0;
       int VideoFrameIndex = 0, AudioFrameIndex = 0;

       while(1)
       {
           if (_kbhit() != 0 &amp;&amp; bCap)
           {
               bCap = false;
               Sleep(2000);//
           }
           if (fifo_audio &amp;&amp; fifo_video)
           {
               int sizeAudio = av_audio_fifo_size(fifo_audio);
               int sizeVideo = av_fifo_size(fifo_video);
               //
               if (av_audio_fifo_size(fifo_audio) &lt;= pFormatCtx_Out->streams[AudioIndex]->codec->frame_size &amp;&amp;
                   av_fifo_size(fifo_video) &lt;= frame_size &amp;&amp; !bCap)
               {
                   break;
               }
           }

           if(av_compare_ts(cur_pts_v, pFormatCtx_Out->streams[VideoIndex]->time_base,
               cur_pts_a,pFormatCtx_Out->streams[AudioIndex]->time_base) &lt;= 0)
           {
               //read data from fifo
               if (av_fifo_size(fifo_video) &lt; frame_size &amp;&amp; !bCap)
               {
                   cur_pts_v = 0x7fffffffffffffff;
               }
               if(av_fifo_size(fifo_video) >= size)
               {
                   EnterCriticalSection(&amp;VideoSection);
                   av_fifo_generic_read(fifo_video, picture_buf, size, NULL);
                   LeaveCriticalSection(&amp;VideoSection);

                   avpicture_fill((AVPicture *)picture, picture_buf,
                       pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt,
                       pFormatCtx_Out->streams[VideoIndex]->codec->width,
                       pFormatCtx_Out->streams[VideoIndex]->codec->height);

                   //pts = n * ((1 / timbase)/ fps);
                   picture->pts = VideoFrameIndex * ((pFormatCtx_Video->streams[0]->time_base.den / pFormatCtx_Video->streams[0]->time_base.num) / 15);

                   int got_picture = 0;
                   AVPacket pkt;
                   av_init_packet(&amp;pkt);

                   pkt.data = NULL;
                   pkt.size = 0;
                   int ret = avcodec_encode_video2(pFormatCtx_Out->streams[VideoIndex]->codec, &amp;pkt, picture, &amp;got_picture);
                   if(ret &lt; 0)
                   {
                       //
                       continue;
                   }

                   if (got_picture==1)
                   {
                       pkt.stream_index = VideoIndex;
                       pkt.pts = av_rescale_q_rnd(pkt.pts, pFormatCtx_Video->streams[0]->time_base,
                           pFormatCtx_Out->streams[VideoIndex]->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));  
                       pkt.dts = av_rescale_q_rnd(pkt.dts,  pFormatCtx_Video->streams[0]->time_base,
                           pFormatCtx_Out->streams[VideoIndex]->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));  

                       pkt.duration = ((pFormatCtx_Out->streams[0]->time_base.den / pFormatCtx_Out->streams[0]->time_base.num) / 15);

                       cur_pts_v = pkt.pts;

                       ret = av_interleaved_write_frame(pFormatCtx_Out, &amp;pkt);
                       //delete[] pkt.data;
                       av_free_packet(&amp;pkt);
                   }
                   VideoFrameIndex++;
               }
           }
           else
           {
               if (NULL == fifo_audio)
               {
                   continue;//
               }
               if (av_audio_fifo_size(fifo_audio) &lt; pFormatCtx_Out->streams[AudioIndex]->codec->frame_size &amp;&amp; !bCap)
               {
                   cur_pts_a = 0x7fffffffffffffff;
               }
               if(av_audio_fifo_size(fifo_audio) >=
                   (pFormatCtx_Out->streams[AudioIndex]->codec->frame_size > 0 ? pFormatCtx_Out->streams[AudioIndex]->codec->frame_size : 1024))
               {
                   AVFrame *frame;
                   frame = av_frame_alloc();
                   frame->nb_samples = pFormatCtx_Out->streams[AudioIndex]->codec->frame_size>0 ? pFormatCtx_Out->streams[AudioIndex]->codec->frame_size: 1024;
                   frame->channel_layout = pFormatCtx_Out->streams[AudioIndex]->codec->channel_layout;
                   frame->format = pFormatCtx_Out->streams[AudioIndex]->codec->sample_fmt;
                   frame->sample_rate = pFormatCtx_Out->streams[AudioIndex]->codec->sample_rate;
                   av_frame_get_buffer(frame, 0);

                   EnterCriticalSection(&amp;AudioSection);
                   av_audio_fifo_read(fifo_audio, (void **)frame->data,
                       (pFormatCtx_Out->streams[AudioIndex]->codec->frame_size > 0 ? pFormatCtx_Out->streams[AudioIndex]->codec->frame_size : 1024));
                   LeaveCriticalSection(&amp;AudioSection);

                   if (pFormatCtx_Out->streams[0]->codec->sample_fmt != pFormatCtx_Audio->streams[AudioIndex]->codec->sample_fmt
                       || pFormatCtx_Out->streams[0]->codec->channels != pFormatCtx_Audio->streams[AudioIndex]->codec->channels
                       || pFormatCtx_Out->streams[0]->codec->sample_rate != pFormatCtx_Audio->streams[AudioIndex]->codec->sample_rate)
                   {
                       //
                   }

                   AVPacket pkt_out;
                   av_init_packet(&amp;pkt_out);
                   int got_picture = -1;
                   pkt_out.data = NULL;
                   pkt_out.size = 0;

                   frame->pts = AudioFrameIndex * pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;
                   if (avcodec_encode_audio2(pFormatCtx_Out->streams[AudioIndex]->codec, &amp;pkt_out, frame, &amp;got_picture) &lt; 0)
                   {
                       printf("can not decoder a frame");
                   }
                   av_frame_free(&amp;frame);
                   if (got_picture)
                   {
                       pkt_out.stream_index = AudioIndex;
                       pkt_out.pts = AudioFrameIndex * pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;
                       pkt_out.dts = AudioFrameIndex * pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;
                       pkt_out.duration = pFormatCtx_Out->streams[AudioIndex]->codec->frame_size;

                       cur_pts_a = pkt_out.pts;

                       int ret = av_interleaved_write_frame(pFormatCtx_Out, &amp;pkt_out);
                       av_free_packet(&amp;pkt_out);
                   }
                   AudioFrameIndex++;
               }
           }
       }

       delete[] picture_buf;

       delete[]frame_buf;
       av_fifo_free(fifo_video);
       av_audio_fifo_free(fifo_audio);

       av_write_trailer(pFormatCtx_Out);

       avio_close(pFormatCtx_Out->pb);
       avformat_free_context(pFormatCtx_Out);

       if (pFormatCtx_Video != NULL)
       {
           avformat_close_input(&amp;pFormatCtx_Video);
           pFormatCtx_Video = NULL;
       }
       if (pFormatCtx_Audio != NULL)
       {
           avformat_close_input(&amp;pFormatCtx_Audio);
           pFormatCtx_Audio = NULL;
       }
       if (NULL != img_convert_ctx)
       {
           sws_freeContext(img_convert_ctx);
           img_convert_ctx = NULL;
       }

       return 0;
    }

    DWORD WINAPI ScreenCapThreadProc( LPVOID lpParam )
    {
       AVPacket packet;/* = (AVPacket *)av_malloc(sizeof(AVPacket))*/;
       int got_picture;
       AVFrame *pFrame;
       pFrame= av_frame_alloc();

       AVFrame *picture = av_frame_alloc();
       int size = avpicture_get_size(pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt,
           pFormatCtx_Out->streams[VideoIndex]->codec->width, pFormatCtx_Out->streams[VideoIndex]->codec->height);
       //picture_buf = new uint8_t[size];

       avpicture_fill((AVPicture *)picture, picture_buf,
           pFormatCtx_Out->streams[VideoIndex]->codec->pix_fmt,
           pFormatCtx_Out->streams[VideoIndex]->codec->width,
           pFormatCtx_Out->streams[VideoIndex]->codec->height);

    //  FILE *p = NULL;
    //  p = fopen("proc_test.yuv", "wb+");
       av_init_packet(&amp;packet);
       int height = pFormatCtx_Out->streams[VideoIndex]->codec->height;
       int width = pFormatCtx_Out->streams[VideoIndex]->codec->width;
       int y_size=height*width;
       while(bCap)
       {
           packet.data = NULL;
           packet.size = 0;
           if (av_read_frame(pFormatCtx_Video, &amp;packet) &lt; 0)
           {
               av_free_packet(&amp;packet);
               continue;
           }
           if(packet.stream_index == 0)
           {
               if (avcodec_decode_video2(pCodecCtx_Video, pFrame, &amp;got_picture, &amp;packet) &lt; 0)
               {
                   printf("Decode Error.(解码错误)\n");
                   continue;
               }
               if (got_picture)
               {
                   sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0,
                       pFormatCtx_Out->streams[VideoIndex]->codec->height, picture->data, picture->linesize);

                   if (av_fifo_space(fifo_video) >= size)
                   {
                       EnterCriticalSection(&amp;VideoSection);                    
                       av_fifo_generic_write(fifo_video, picture->data[0], y_size, NULL);
                       av_fifo_generic_write(fifo_video, picture->data[1], y_size/4, NULL);
                       av_fifo_generic_write(fifo_video, picture->data[2], y_size/4, NULL);
                       LeaveCriticalSection(&amp;VideoSection);
                   }
               }
           }
           av_free_packet(&amp;packet);
           //Sleep(50);
       }
       av_frame_free(&amp;pFrame);
       av_frame_free(&amp;picture);
       //delete[] picture_buf;
       return 0;
    }

    DWORD WINAPI AudioCapThreadProc( LPVOID lpParam )
    {
       AVPacket pkt;
       AVFrame *frame;
       frame = av_frame_alloc();
       int gotframe;
       while(bCap)
       {
           pkt.data = NULL;
           pkt.size = 0;
           if(av_read_frame(pFormatCtx_Audio,&amp;pkt) &lt; 0)
           {
               av_free_packet(&amp;pkt);
               continue;
           }

           if (avcodec_decode_audio4(pFormatCtx_Audio->streams[0]->codec, frame, &amp;gotframe, &amp;pkt) &lt; 0)
           {
               av_frame_free(&amp;frame);
               printf("can not decoder a frame");
               break;
           }
           av_free_packet(&amp;pkt);

           if (!gotframe)
           {
               continue;//
           }

           if (NULL == fifo_audio)
           {
               fifo_audio = av_audio_fifo_alloc(pFormatCtx_Audio->streams[0]->codec->sample_fmt,
                   pFormatCtx_Audio->streams[0]->codec->channels, 30 * frame->nb_samples);
           }

           int buf_space = av_audio_fifo_space(fifo_audio);
           if (av_audio_fifo_space(fifo_audio) >= frame->nb_samples)
           {
               EnterCriticalSection(&amp;AudioSection);
               av_audio_fifo_write(fifo_audio, (void **)frame->data, frame->nb_samples);
               LeaveCriticalSection(&amp;AudioSection);
           }
       }
       av_frame_free(&amp;frame);
       return 0;
    }
  • C++ FFmpeg encode stream to mp4 wrong fps and kbs

    22 mars 2024, par elmomoJacky

    i'm new to FFmpeg, i'm trying to learn how to encode images to an mp4 using a stream.&#xA;But even tough i can generate a playable file, my file is "broken", it does does past 1sec, and if i check it's data with ffmpeg i can see that it's duration is accordly wrong with the kb/s fps value

    &#xA;

    &#xA;

    Duration : 00:00:00.01 .... 2635232 kb/s, 15463.09 fps.

    &#xA;

    &#xA;

    ffmpeg -i 25_5.mp4 -f ffmetadata 25_5.txt

    &#xA;

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from &#x27;25_5.mp4&#x27;:&#xA;  Metadata:&#xA;    major_brand     : isom&#xA;    minor_version   : 512&#xA;    compatible_brands: isomiso2mp41&#xA;    title           : Your Title Here&#xA;    encoder         : Lavf60.16.100&#xA;    comment         : Your Comment Here&#xA;    copyright       : Copyright Information&#xA;  Duration: 00:00:00.01, start: 0.000000, bitrate: 2557680 kb/s&#xA;  Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 2635232 kb/s, 15463.09 fps, 15360 tbr, 15360 tbn, 30 tbc (default)&#xA;    Metadata:&#xA;      handler_name    : VideoHandler&#xA;      vendor_id       : [0][0][0][0]&#xA;File &#x27;25_5.txt&#x27; already exists. Overwrite? [y/N] y&#xA;Output #0, ffmetadata, to &#x27;25_5.txt&#x27;:&#xA;  Metadata:&#xA;    major_brand     : isom&#xA;    minor_version   : 512&#xA;    compatible_brands: isomiso2mp41&#xA;    title           : Your Title Here&#xA;    copyright       : Copyright Information&#xA;    comment         : Your Comment Here&#xA;    encoder         : Lavf58.76.100&#xA;

    &#xA;

    Here is my cpp and header code (using visual studio and vcpkg install ffmpeg)&#xA;file ffmpeg_example.cpp

    &#xA;

    &#xA;#include "ffmpeg_example.h"&#xA;&#xA;#include &#xA;#include &#xA;#include &#xA;#include <iostream>&#xA;#include <map>&#xA;&#xA;extern "C" {&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavutil></libavutil>imgutils.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libswscale></libswscale>swscale.h>&#xA;&#xA;}&#xA;&#xA;#define COMMON_AV_FRAME_FORMAT AV_PIX_FMT_YUV420P &#xA;&#xA;ffmpeg_example::ffmpeg_example()&#xA;{&#xA;&#xA;}&#xA;&#xA;ffmpeg_example::~ffmpeg_example()&#xA;{&#xA;&#xA;}&#xA;&#xA;void ffmpeg_example::set_codec_params(AVFormatContext*&amp; fctx, AVCodecContext*&amp; codec_ctx, double width, double height, int fps, int bitrate) {&#xA;    std::cout &lt;&lt; "encoding video for width:" &lt;&lt; width &lt;&lt; ", height:" &lt;&lt; height &lt;&lt; ", fps:" &lt;&lt; fps &lt;&lt; ", bitrate:" &lt;&lt; bitrate &lt;&lt; std::endl;&#xA;    codec_ctx->codec_id = fctx->oformat->video_codec;&#xA;    codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;    codec_ctx->width = width;&#xA;    codec_ctx->height = height;&#xA;    codec_ctx->gop_size = 12;&#xA;    codec_ctx->pix_fmt = COMMON_AV_FRAME_FORMAT;&#xA;    codec_ctx->framerate = AVRational{ fps, 1 };&#xA;    codec_ctx->time_base = AVRational{ 1, fps };&#xA;    if (bitrate) codec_ctx->bit_rate = bitrate;&#xA;    if (fctx->oformat->flags &amp; AVFMT_GLOBALHEADER) {&#xA;        codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;&#xA;    }&#xA;}&#xA;&#xA;AVStream* ffmpeg_example::create_stream(AVFormatContext*&amp; fctx, AVCodecContext*&amp; codec_ctx) {&#xA;    AVStream* stream = avformat_new_stream(fctx, nullptr);&#xA;    avcodec_parameters_from_context(stream->codecpar, codec_ctx);&#xA;    stream->time_base = codec_ctx->time_base;&#xA;    //stream->r_frame_rate = codec_ctx->framerate;&#xA;    //stream->avg_frame_rate = stream->r_frame_rate;&#xA;    return stream;&#xA;}&#xA;&#xA;AVFrame* ffmpeg_example::create_frame(int width, int height) {&#xA;    AVFrame* frame = av_frame_alloc();&#xA;    frame->format = COMMON_AV_FRAME_FORMAT;&#xA;    frame->width = width;&#xA;    frame->height = height;&#xA;    av_frame_get_buffer(frame, 0);&#xA;    return frame;&#xA;}&#xA;&#xA;void ffmpeg_example::fill_fake_yuv_image(AVFrame* frame, int frame_index, int width, int height) {&#xA;    /* Ensure the data buffers are writable */&#xA;    av_frame_make_writable(frame);&#xA;&#xA;    // This is where you could load actual image data into the frame.&#xA;    // For demonstration, we fill the frame with a color.&#xA;    // Y&#xA;    for (int y = 0; y &lt; height; y&#x2B;&#x2B;) {&#xA;        for (int x = 0; x &lt; width; x&#x2B;&#x2B;) {&#xA;            frame->data[0][y * frame->linesize[0] &#x2B; x] = x &#x2B; y &#x2B; frame_index * 3;&#xA;        }&#xA;    }&#xA;&#xA;    // Cb and Cr&#xA;    for (int y = 0; y &lt; height / 2; y&#x2B;&#x2B;) {&#xA;        for (int x = 0; x &lt; width / 2; x&#x2B;&#x2B;) {&#xA;            frame->data[1][y * frame->linesize[1] &#x2B; x] = 128 &#x2B; y &#x2B; frame_index * 2;&#xA;            frame->data[2][y * frame->linesize[2] &#x2B; x] = 64 &#x2B; x &#x2B; frame_index * 5;&#xA;        }&#xA;    }&#xA;}&#xA;&#xA;int ffmpeg_example::initFfmpegcontext()&#xA;{&#xA;    int ret;&#xA;&#xA;&#xA;    // Initialize the AVFormatContext&#xA;    if (avformat_alloc_output_context2(&amp;output_format_context, nullptr, _ouput_format, nullptr) &lt; 0 || !output_format_context) {&#xA;        std::cout &lt;&lt; "Could not allocat output context." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;&#xA;    // Find the encoder&#xA;    encoder = avcodec_find_encoder(output_format_context->oformat->video_codec);&#xA;    if (!encoder) {&#xA;        std::cout &lt;&lt; "Could not find encoder." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Create a new codec context&#xA;    codec_context = avcodec_alloc_context3(encoder);&#xA;    if (!codec_context) {&#xA;        std::cout &lt;&lt; "Could not allocate codec context." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Set codec parameters&#xA;    set_codec_params(output_format_context, codec_context, 1920, 1080, video_fps, 0);&#xA;&#xA;    // Open the codec&#xA;    ret = avcodec_open2(codec_context, encoder, nullptr);&#xA;    if (ret &lt; 0) {&#xA;        std::cout &lt;&lt; "Could not open encoder with context." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Create a new video stream&#xA;    video_stream = create_stream(output_format_context, codec_context);&#xA;    if (!video_stream) {&#xA;        std::cout &lt;&lt; "Could not create stream." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Initialize the IO context&#xA;    if (!(output_format_context->oformat->flags &amp; AVFMT_NOFILE)) {&#xA;        std::cout &lt;&lt; "Init IO, AVFMT_NOFILE not detected." &lt;&lt; std::endl;&#xA;        if (avio_open(&amp;output_format_context->pb, output, AVIO_FLAG_WRITE) &lt; 0) {&#xA;            std::cout &lt;&lt; "Could not open output file." &lt;&lt; std::endl;&#xA;            return -1;&#xA;        }&#xA;    }&#xA;&#xA;    // Write the file header&#xA;    ret = avformat_write_header(output_format_context, nullptr);&#xA;    if (ret &lt; 0) {&#xA;        std::cout &lt;&lt; "Could not write file header." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Create a new frame&#xA;    frame = create_frame(codec_context->width, codec_context->height);&#xA;    if (!frame) {&#xA;        std::cout &lt;&lt; "Could not create frame." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    // Create a new packet&#xA;    pkt = av_packet_alloc();&#xA;    if (!pkt) {&#xA;        std::cout &lt;&lt; "Could not allocate packet." &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;    return 0;&#xA;}&#xA;&#xA;&#xA;void ffmpeg_example::set_metadata() {&#xA;    // Ensure the format context exists&#xA;    if (!output_format_context) return;&#xA;    std::cout &lt;&lt; "Setting metadata." &lt;&lt; std::endl;&#xA;&#xA;    // Create or get the existing metadata dictionary&#xA;    AVDictionary** metadata = &amp;output_format_context->metadata;&#xA;&#xA;    // Set various metadata fields&#xA;    av_dict_set(metadata, "title", "Your Title Here", 0);&#xA;    av_dict_set(metadata, "author", "Author Name", 0);&#xA;    av_dict_set(metadata, "copyright", "Copyright Information", 0);&#xA;    av_dict_set(metadata, "comment", "Your Comment Here", 0);&#xA;    av_dict_set(metadata, "rating", "5", 0); // Assuming rating is a simple numeric value&#xA;&#xA;    // Note: The last parameter of av_dict_set is a flag; 0 means the entry will be added to the dictionary&#xA;    // if it doesn&#x27;t exist, or the existing entry will be updated if it does exist.&#xA;}&#xA;&#xA;int ffmpeg_example::start()&#xA;{&#xA;    int ret;&#xA;    if (initFfmpegcontext() &lt; 0) {&#xA;        std::cout &lt;&lt; "quitting" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    set_metadata();&#xA;    std::cout &lt;&lt; "filling stream with frames data." &lt;&lt; std::endl;&#xA;    // Write frames&#xA;    for (int i = 0; i &lt; video_fps * 4; i&#x2B;&#x2B;) { // 5 seconds at video_fps fps&#xA;        frame->pts = i;&#xA;        fill_fake_yuv_image(frame, i, codec_context->width, codec_context->height);&#xA;&#xA;        // Encode the image&#xA;        ret = avcodec_send_frame(codec_context, frame);&#xA;        while (ret >= 0) {&#xA;            ret = avcodec_receive_packet(codec_context, pkt);&#xA;            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {&#xA;                break;&#xA;            }&#xA;            pkt->stream_index = video_stream->index;&#xA;            av_interleaved_write_frame(output_format_context, pkt);&#xA;            av_packet_unref(pkt);&#xA;        }&#xA;    }&#xA;&#xA;    std::cout &lt;&lt; "closing." &lt;&lt; std::endl;&#xA;    // Send a null frame to the encoder to flush it&#xA;    avcodec_send_frame(codec_context, NULL);&#xA;    while (ret >= 0) {&#xA;        ret = avcodec_receive_packet(codec_context, pkt);&#xA;        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {&#xA;            break;&#xA;        }&#xA;        pkt->stream_index = video_stream->index;&#xA;        av_interleaved_write_frame(output_format_context, pkt);&#xA;        av_packet_unref(pkt);&#xA;    }&#xA;&#xA;    // Write the file trailer&#xA;    av_write_trailer(output_format_context);&#xA;&#xA;    cleanup();&#xA;    std::cout &lt;&lt; "done." &lt;&lt; std::endl;&#xA;&#xA;    return 0;&#xA;}&#xA;&#xA;void ffmpeg_example::cleanup() {&#xA;    // Clean up&#xA;    avcodec_free_context(&amp;codec_context);&#xA;    av_frame_free(&amp;frame);&#xA;    av_packet_free(&amp;pkt);&#xA;    avio_closep(&amp;output_format_context->pb);&#xA;    avformat_free_context(output_format_context);&#xA;}&#xA;</map></iostream>

    &#xA;

    Header file :

    &#xA;

    #pragma once&#xA;&#xA;class AVFormatContext;&#xA;class AVCodecContext;&#xA;class AVStream;&#xA;class AVCodec;&#xA;class AVFrame;&#xA;class AVPacket;&#xA;class AVOutputFormat;&#xA;&#xA;class ffmpeg_example {&#xA;private:&#xA;    const AVCodec* encoder = nullptr;&#xA;    AVFormatContext* output_format_context = nullptr;&#xA;    AVCodecContext* codec_context = nullptr;&#xA;    AVStream* video_stream = nullptr;&#xA;    AVFrame* frame = nullptr;&#xA;    AVPacket* pkt = nullptr;&#xA;&#xA;    const char* output = "output.mp4";&#xA;    const char* _ouput_format = "mp4";&#xA;&#xA;    int video_fps = 30;&#xA;public:&#xA;&#xA;    ffmpeg_example();&#xA;    virtual ~ffmpeg_example();&#xA;&#xA;    int start();&#xA;private:&#xA;    int initFfmpegcontext();&#xA;    AVFrame* create_frame(int width, int height);&#xA;    void fill_fake_yuv_image(AVFrame* frame, int frame_index, int width, int height);&#xA;    void set_codec_params(AVFormatContext*&amp; fctx, AVCodecContext*&amp; codec_ctx, double width, double height, int fps, int bitrate);&#xA;    AVStream* create_stream(AVFormatContext*&amp; fctx, AVCodecContext*&amp; codec_ctx);&#xA;&#xA;    void cleanup();&#xA;    void set_metadata();&#xA;};&#xA;

    &#xA;

    You just have to call the start() function to make it work.

    &#xA;

    I understand that the problem come surely from a flag disabling my fps setting, or it's an incorrect param while generating the header, but i can't find which one.&#xA;I searched other similar examples (ffmpeg example like encode_video.c or stackoverflow post : video-too-fast, speed-encoding-problem, ffmpeg-create-mp4 )&#xA;But whatever change i make i cannot make it work (and chatgpt is as lost as me).

    &#xA;

    — edit

    &#xA;

    The only way i find to impact the fps of the ouputed video is to inverscodec_ctx->framerate = AVRational{ 1, fps }; but even with that, my video is marked 30sec (should be 5) and doesn't past 1sec.&#xA;I'M LOST, i can count the number of packet -> 150

    &#xA;

    &#xA;

    ffprobe -v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 output.mp4&#xA;150

    &#xA;

    &#xA;

    Each frame has the correct pts so that it know in which order to play, my stream has the same avg_frame_rate as my codec framerate.

    &#xA;

    I don't know what i do wrong

    &#xA;