rames @Raw H264 no contêiner mpegts usando libavcodec

Realmente gostaria de receber ajuda com o seguinte problema:

Eu tenho um gadget com uma câmera, produzindo quadros de vídeo compactados H264, esses quadros estão sendo enviados para o meu aplicativo. Esses quadros não estão em um contêiner, apenas dados brutos.

Eu quero usar as funções ffmpeg e libav para criar um arquivo de vídeo, que pode ser usado posteriorment

Se decodificar os quadros e depois codificá-los, tudo funcionará bem, recebo um arquivo de vídeo válido. (as etapas de decodificação / codificação são os comandos usuais do libav, nada sofisticado aqui, eu os tirei da Internet onipotente, eles são sólidos) ... No entanto, eu perco muito tempo decodificando e codificando, então eu gostaria de pule esta etapa e coloque diretamente os quadros no fluxo de saída. Agora, os problemas vêm.

Aqui está o código que criei para produzir a codificação:

AVFrame* picture;

avpicture_fill((AVPicture*) picture, (uint8_t*)frameData, 
                 codecContext->pix_fmt, codecContext->width,
                 codecContext->height);
int outSize = avcodec_encode_video(codecContext, videoOutBuf, 
                 sizeof(videoOutBuf), picture);
if (outSize > 0) 
{
    AVPacket packet;
    av_init_packet(&packet);
    packet.pts = av_rescale_q(codecContext->coded_frame->pts,
                  codecContext->time_base, videoStream->time_base);
    if (codecContext->coded_frame->key_frame) 
    {
        packet.flags |= PKT_FLAG_KEY;
    }
    packet.stream_index = videoStream->index;
    packet.data =  videoOutBuf;
    packet.size =  outSize;

    av_interleaved_write_frame(context, &packet);
    put_flush_packet(context->pb);
}

Onde as variáveis são como:

frameData são os dados do quadro decodificado que vieram da câmera, foram decodificados em uma etapa anterior evideoOutBuf é um buffer uint8_t simples para armazenar os dados

Modifiquei o aplicativo para não decodificar os quadros, mas simplesmente passe os dados como:

    AVPacket packet;
    av_init_packet(&packet);

    packet.stream_index = videoStream->index;
    packet.data = (uint8_t*)frameData;
    packet.size = currentFrameSize;

    av_interleaved_write_frame(context, &packet);
    put_flush_packet(context->pb);

Ond

frameData é o quadro H264 bruto ecurrentFrameSize é o tamanho do quadro H264 bruto, ou seja. o número de bytes que recebo do gadget para cada quadro.

E de repente o aplicativo não está mais funcionando corretamente, o vídeo produzido não pode ser reproduzido. Isso é óbvio, já que eu não estava definindo um PTS correto para o pacote. O que fiz foi o seguinte (estou desesperado, você pode vê-lo a partir desta abordagem :))

    packet.pts = timestamps[timestamp_counter ++];

Ondetimestamps é na verdade uma lista de PTSs produzidos pelo código de trabalho acima e gravados em um arquivo (sim, você leu corretamente, registrei todos os PTSs por uma sessão de 10 minutos e queria usá-los

O aplicativo ainda não funciona.

Agora, aqui estou eu sem nenhuma pista do que fazer, então aqui está a pergunta:

Gostaria de criar um fluxo de vídeo "mpegts" usando as funções libav, inserir no fluxo os quadros de vídeo já codificados e criar um arquivo de vídeo com ele. Como eu faço isso

Obrigado, f.

questionAnswers(2)

yourAnswerToTheQuestion