How to encode a video from several images generated in a C++ program without writing the separate frame images to disk?

后端 未结 4 744
北海茫月
北海茫月 2020-12-07 15:51

I am writing a C++ code where a sequence of N different frames is generated after performing some operations implemented therein. After each frame is completed, I write it o

4条回答
  •  囚心锁ツ
    2020-12-07 16:32

    Thanks to ksb496 I managed to do this task, but in my case I need to change some codes to work as expected. I thought maybe it could help others so I decided to share (with two years delay :D).

    I had an RGB buffer filled by directshow sample grabber that I needed to take a video from. RGB to YUV conversion from given answer didn't do the job for me. I did it like this :

    int stride = m_width * 3;
    int index = 0;
    for (int y = 0; y < m_height; y++) {
        for (int x = 0; x < stride; x++) {
            int j = (size - ((y + 1)*stride)) + x;
            m_rgbpic->data[0][j] = data[index];
            ++index;
        }
    }
    

    data variable here is my RGB buffer (simple BYTE*) and size is data buffer size in bytes. It's start filling RGB AVFrame from bottom left to top right.

    The other thing is that my version of FFMPEG didn't have av_packet_rescale_ts function. It's latest version but FFMPEG docs didn't say this function is deprecated anywhere, I guess this might be the case for windows only. Anyway I used av_rescale_q instead that does the same job. like this :

    AVPacket pkt;
    pkt.pts = av_rescale_q(pkt.pts, { 1, 25 }, m_stream->time_base);
    

    And the last thing, using this format conversion I needed to change my swsContext to BGR24 instead of RGB24 like this :

    m_convert_ctx = sws_getContext(width, height, AV_PIX_FMT_BGR24, width, height,
            AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
    

提交回复
热议问题