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.