[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
av_write_trailer(m_pFormatCtx);
> 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;
av_init_packet(&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,
auchBuffer?m_pAVFrame:NULL);
/* If zero size, it means the image was buffered and will need to be
flushed later. */
if (nTemp > 0)
{
AVPacket sPkt;
av_init_packet(&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