[Libav-user] h264 Encoding problems

Matthew Einhorn moiein2000 at gmail.com
Fri Nov 4 17:16:27 CET 2011

On Fri, Nov 4, 2011 at 2:40 AM, Zac Shenker <zac at zacshenker.com> wrote:
> Hi,
> I have started working on some code based on the decoding_encoding.c sample
> file to encode the test pattern as h.264 video.
> The settings I am using on my AVCodecContext is as follows:
> c->width = 352;
> c->height = 288;
> c->time_base.num = 1;
> c->time_base.den = 25;
> c->pix_fmt = PIX_FMT_YUV420P;
> c->gop_size = 1;
> if(codec_id == CODEC_ID_H264)
> av_opt_set(c->priv_data, "preset", "slow", 0);
> I am having a number of issues:
> 1) Even when I set the AVFrame->pts to AVS_NOPTS_VALUE, I still get
> "non-strictly-monotonic PTS" warning messages. How should I be setting the
> PTS value?

See my code below. I don't set the pts or anything else in the frame
other than copying the image data to the picture.

> 2) For the first 13 frames my call to avcodec_encode_video returns a size of
> 0, should this be happening?
Yes, because it needs to buffer a couple of frames so it can calculate
best compression.

> 3) The output file that gets written does not seem to have a duration(using
> ffprobe or VLC to check)

Maybe you have to write the header and trailer before and after the
video is written. I.e. avformat_write_header(m_pFormatCtx, NULL) and

> So far to figure out how things work I have been searching through the
> ffmpeg & x264 source, is there any up-to-date examples of doing h264 video
> encoding (no audio) anywhere?

Look in ffmpeg.c and ffplay.c

Here's how my code looks:
if (m_pFormatCtx->oformat->flags & AVFMT_RAWPICTURE)
		/* raw video case. The API will change slightly in the near
		future for that. Latency won't happen here.  */
		AVPacket sPkt;

		sPkt.flags |= AV_PKT_FLAG_KEY;
		sPkt.stream_index= m_pAVStream->index;
		sPkt.data= (unsigned char *)m_pAVFrame;
		sPkt.size= sizeof(AVPicture);

		nRes = av_interleaved_write_frame(m_pFormatCtx, &sPkt);
	} else
		/* Encode the image, if flushing pass null frame. */
		nTemp = avcodec_encode_video(pCodecCtx, m_auchVideoOutBuf, m_nBuffer,
		/* If zero size, it means the image was buffered and will need to be
flushed later. */
		if (nTemp > 0)
			AVPacket sPkt;

			// Save pts of frame
			if (pCodecCtx->coded_frame && pCodecCtx->coded_frame->pts != AV_NOPTS_VALUE)
				sPkt.pts= av_rescale_q(pCodecCtx->coded_frame->pts,
pCodecCtx->time_base, m_pAVStream->time_base);
			if(sPkt.pts == AV_NOPTS_VALUE && sPkt.dts == AV_NOPTS_VALUE &&
!(m_pFormatCtx->oformat->flags & AVFMT_NOTIMESTAMPS))
				sPkt.dts= 0;

			// Is it a key frame?
			if(pCodecCtx->coded_frame && pCodecCtx->coded_frame->key_frame)
				sPkt.flags |= AV_PKT_FLAG_KEY;
			sPkt.stream_index= m_pAVStream->index;
			sPkt.data= m_auchVideoOutBuf;
			sPkt.size= nTemp;
			/* Write the compressed frame in the media file */
			nRes = av_interleaved_write_frame(m_pFormatCtx, &sPkt);
		} else
			nRes = nTemp;	// If zero it's ok, if none zero it means error.
			if (!auchBuffer)	// Either way, no more frames to flush, if flushing
				m_bDone= true;

More information about the Libav-user mailing list