[FFmpeg-user] Strange latency with some codecs

Simon Pickles pickles at thefoundry.co.uk
Tue Jul 22 18:20:28 CEST 2014


Hi

I've just upgraded from FFmpeg 1.0 to 2.1.4 and although it was pretty
painless, I am having a weird problem with a few codecs. So far I've found
this problem occurs with PNG, jpeg2000 and DNxHD.

Basically, in the old version a mov format with a png codec used to work
fine, with every call to avcodec_decode_video2 succeeding to decode the
frame, and got_packet_ptr returning 1.

In 2.1.4 I don't get 1 returned by got_packet_ptr. However, if I keep
trying to decode the frame, it eventually starts to decode after FIFTEEN
attempts! Yes, it is always 15!. I thought I must be doing something
strange so I pared it down to a simplest repro case, which follows.

Can anyone explain what I have missed.

Thanks

Simon

/////////////////////////////////////////////////////////
// main.cpp
/////////////////////////////////////////////////////////
#include <string>
#include <iostream>

#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif

extern "C" {
#include <errno.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavformat/avio.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
#include <libavutil/avutil.h>
#include <libavutil/error.h>
}


int main(int argc, char *argv[])
{
  std::string filename = "/tmp/pngMov.mov";

  av_register_all();

  AVInputFormat* format = NULL;
  AVFormatContext* context = NULL;

  int ret = 0;

  ret = avformat_open_input(&context, filename.c_str(), format, NULL);
  ret = avformat_find_stream_info(context, NULL);
  std::cout << context->nb_streams << " streams" << std::endl;

  AVStream* avstream = context->streams[0];
  std::cout << "Codec " << avstream->codec->codec_name << std::endl;

  AVCodec* videoCodec = avcodec_find_decoder(avstream->codec->codec_id);
  avcodec_open2(avstream->codec, videoCodec, NULL);

  // DECODE
  int framePts = 0;
  ret = av_seek_frame(context, 0, framePts, AVSEEK_FLAG_BACKWARD);

  AVPacket packet;
  av_init_packet(&packet);
  ret = av_read_frame(context, &packet);

  std::cout << "    PTS=" << packet.pts <<
          ", DTS=" << packet.dts <<
          ", Duration=" << packet.duration <<
          ", KeyFrame=" << ((packet.flags & AV_PKT_FLAG_KEY) ? 1 : 0) <<
          ", Corrupt=" << ((packet.flags & AV_PKT_FLAG_CORRUPT) ? 1 : 0) <<
          ", StreamIdx=" << packet.stream_index <<
          ", PktSize=" << packet.size << std::endl;

  int frameDecoded = 0;
  AVCodecContext* codecContext = avstream->codec;
  AVFrame* frame = avcodec_alloc_frame();
  for (int i = 0; i < 20; ++i) {
    ret = avcodec_decode_video2(codecContext, frame, &frameDecoded,
&packet);

    std::cout << "Decode " << ret << " frameDecoded " << frameDecoded <<
std::endl;
  }

  // mem leak here etc etc

  return 0;
}


More information about the ffmpeg-user mailing list