Codificación de cuadros a video con ffmpeg

Estoy tratando de codificar un video en Unreal Engine 4 con C ++. Tengo acceso a los marcos separados. A continuación se muestra el código que leeviewport's muestra píxeles y almacena en el búfer.

//Safely get render target resource.
FRenderTarget* RenderTarget = TextureRenderTarget->GameThread_GetRenderTargetResource();
FIntPoint Size = RenderTarget->GetSizeXY();
auto ImageBytes = Size.X* Size.Y * static_cast<int32>(sizeof(FColor));
TArray<uint8> RawData;
RawData.AddUninitialized(ImageBytes);

//Get image raw data.
if (!RenderTarget->ReadPixelsPtr((FColor*)RawData.GetData()))
{
    RawData.Empty();
    UE_LOG(ExportRenderTargetBPFLibrary, Error, TEXT("ExportRenderTargetAsImage: Failed to get raw data."));
    return false;
}

Buffer::getInstance().add(RawData);

Unreal Engine tieneIImageWrapperModule con el que puede obtener una imagen del cuadro, pero observando la codificación de video. Lo que quiero es codificar cuadros en tiempo real para el servicio de transmisión en vivo.

Encontré esta publicaciónCodificación de una captura de pantalla en un video usando FFMPEG que es lo que quiero, pero tengo problemas para adaptar esta solución a mi caso. El código está desactualizado (por ejemploavcodec_encode_video cambiado aavcodec_encode_video2 con diferentes parámetros).

Abajo está el código del codificador.

void Compressor::DoWork()
{
AVCodec* codec;
AVCodecContext* c = NULL;
//uint8_t* outbuf;
//int /*i, out_size,*/ outbuf_size;

UE_LOG(LogTemp, Warning, TEXT("encoding"));

codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);            // finding the H264 encoder
if (!codec) {
    UE_LOG(LogTemp, Warning, TEXT("codec not found"));
    exit(1);
}
else UE_LOG(LogTemp, Warning, TEXT("codec found"));

c = avcodec_alloc_context3(codec);
c->bit_rate = 400000;
c->width = 1280;                                        // resolution must be a multiple of two (1280x720),(1900x1080),(720x480)
c->height = 720;
c->time_base.num = 1;                                   // framerate numerator
c->time_base.den = 25;                                  // framerate denominator
c->gop_size = 10;                                       // emit one intra frame every ten frames
c->max_b_frames = 1;                                    // maximum number of b-frames between non b-frames
c->keyint_min = 1;                                      // minimum GOP size
c->i_quant_factor = (float)0.71;                        // qscale factor between P and I frames
//c->b_frame_strategy = 20;                               ///// find out exactly what this does
c->qcompress = (float)0.6;                              ///// find out exactly what this does
c->qmin = 20;                                           // minimum quantizer
c->qmax = 51;                                           // maximum quantizer
c->max_qdiff = 4;                                       // maximum quantizer difference between frames
c->refs = 4;                                            // number of reference frames
c->trellis = 1;                                         // trellis RD Quantization
c->pix_fmt = AV_PIX_FMT_YUV420P;                           // universal pixel format for video encoding
c->codec_id = AV_CODEC_ID_MPEG1VIDEO;
c->codec_type = AVMEDIA_TYPE_VIDEO;

if (avcodec_open2(c, codec, NULL) < 0) {
    UE_LOG(LogTemp, Warning, TEXT("could not open codec"));         // opening the codec
    //exit(1);
}
else UE_LOG(LogTemp, Warning, TEXT("codec oppened"));

FString FinalFilename = FString("C:/Screen/sample.mpg");
auto &PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
auto FileHandle = PlatformFile.OpenWrite(*FinalFilename, true);

if (FileHandle)
{
    delete FileHandle; // remove when ready
    UE_LOG(LogTemp, Warning, TEXT("file opened"));
    while (true)
    {
        UE_LOG(LogTemp, Warning, TEXT("removing from buffer"));

        int nbytes = avpicture_get_size(AV_PIX_FMT_YUV420P, c->width, c->height);                                      // allocating outbuffer
        uint8_t* outbuffer = (uint8_t*)av_malloc(nbytes * sizeof(uint8_t));

        AVFrame* inpic = av_frame_alloc();
        AVFrame* outpic = av_frame_alloc();

        outpic->pts = (int64_t)((float)1 * (1000.0 / ((float)(c->time_base.den))) * 90);                              // setting frame pts
        avpicture_fill((AVPicture*)inpic, (uint8_t*)Buffer::getInstance().remove().GetData(),
            AV_PIX_FMT_PAL8, c->width, c->height); // fill image with input screenshot
        avpicture_fill((AVPicture*)outpic, outbuffer, AV_PIX_FMT_YUV420P, c->width, c->height);                        // clear output picture for buffer copy
        av_image_alloc(outpic->data, outpic->linesize, c->width, c->height, c->pix_fmt, 1);

        /* 
        inpic->data[0] += inpic->linesize[0]*(screenHeight-1);                                                      
        // flipping frame
        inpic->linesize[0] = -inpic->linesize[0];                                                                   
        // flipping frame

        struct SwsContext* fooContext = sws_getContext(screenWidth, screenHeight, PIX_FMT_RGB32, c->width, c->height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
        sws_scale(fooContext, inpic->data, inpic->linesize, 0, c->height, outpic->data, outpic->linesize);          // converting frame size and format

        out_size = avcodec_encode_video(c, outbuf, outbuf_size, outpic);                                            
        // save in file

        */

    }
    delete FileHandle;
}
else
{
    UE_LOG(LogTemp, Warning, TEXT("Can't open file"));
}
}

Alguien puede explicarvoltear marco parte (¿por qué está hecho?) y cómo usaravcodec_encode_video2 funcionar en lugar deavcodec_encode_video?

Respuestas a la pregunta(1)

Su respuesta a la pregunta