How to flush buffer while encoding H264 using FFMPEG?

I use the C ++ library to write images captured from a webcam to an mp4 file encoded in libx264. The encoding works correctly, but when it starts, it writes 40 frames to the buffer. When I close the file, these frames are not reset, so for about 6 seconds the video remains unwritten (the camera is about 6 frames per second).

So I'm calling:

out_size = libffmpeg::avcodec_encode_video( codecContext, data->VideoOutputBuffer,data->VideoOutputBufferSize, data->VideoFrame ); // if zero size, it means the image was buffered if ( out_size > 0 ) { //... write to file } 

I do not see a way to access images left in the buffer. Any ideas?

+4
source share
2 answers

This works for me, using the following code to flush the buffer. It seems that I was looking for the wrong term - there should have been "delayed frames" ...

 void VideoFileWriter::Flush(void) { if ( data != nullptr ) { int out_size = 0; int ret = 0; libffmpeg::AVCodecContext* c = data->VideoStream->codec; /* get the delayed frames */ while (1) { libffmpeg::AVPacket packet; libffmpeg::av_init_packet(&packet); out_size = libffmpeg::avcodec_encode_video(c, data->VideoOutputBuffer, data->VideoOutputBufferSize, NULL); if (out_size < 0) { //fprintf(stderr, "Error encoding delayed frame %d\n", out_size); break; } if (out_size == 0) { break; } if (c->coded_frame->pts != AV_NOPTS_VALUE) { packet.pts = av_rescale_q(c->coded_frame->pts, c->time_base, data->VideoStream->time_base); //fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts); } else { //fprintf(stderr, "Video Frame PTS: not set\n"); } if (c->coded_frame->key_frame) { packet.flags |= AV_PKT_FLAG_KEY; } packet.stream_index = data->VideoStream->index; packet.data = data->VideoOutputBuffer; packet.size = out_size; ret = libffmpeg::av_interleaved_write_frame( data->FormatContext, &packet ); if (ret != 0) { //fprintf(stderr, "Error writing delayed frame %d\n", ret); break; } } libffmpeg::avcodec_flush_buffers(data->VideoStream->codec); } } 
+6
source

Here 's a ffmpeg manual with avcodec that says avcodec uses some internal buffers that need to be flushed. There is also some code showing how to flush these buffers ("Flush our buffers").

+1
source

Source: https://habr.com/ru/post/1386490/


All Articles