Search code examples
cvideoffmpegvideo-streamingvideo-capture

ffmpeg recording h264 live stream got error


I am trying to record a h.264 live stream using the following code:

   AVOutputFormat* fmt = av_guess_format(NULL, "test.mpeg", NULL);
   AVFormatContext* oc  = avformat_alloc_context();
   oc->oformat = fmt;
   avio_open2(&oc->pb, "test.mpeg", AVIO_FLAG_WRITE, NULL, NULL);
   AVStream* stream = NULL;
   ...
   while(!done)
   {

      // Read a frame
      if(av_read_frame(inputStreamFormatCtx, &packet)<0)
         return false;      

      if(packet.stream_index==correct_index)
      {
          ////////////////////////////////////////////////////////////////////////
         // Is this a packet from the video stream -> decode video frame
          if (stream == NULL){//create stream in file
              stream = avformat_new_stream(oc, pFormatCtx->streams[videoStream]->codec->codec);
              avcodec_copy_context(stream->codec, pFormatCtx->streams[videoStream]->codec);
              stream->sample_aspect_ratio = pFormatCtx->streams[videoStream]->codec->sample_aspect_ratio;

              stream->sample_aspect_ratio.num = pFormatCtx->streams[videoStream]->codec->sample_aspect_ratio.num;
              stream->sample_aspect_ratio.den = pFormatCtx->streams[videoStream]->codec->sample_aspect_ratio.den;

              // Assume r_frame_rate is accurate
              stream->r_frame_rate = pFormatCtx->streams[videoStream]->r_frame_rate;
              stream->avg_frame_rate = stream->r_frame_rate;
              stream->time_base = av_inv_q(stream->r_frame_rate);
              stream->codec->time_base = stream->time_base;

              avformat_write_header(oc, NULL);
          }
          av_write_frame(oc, &packet);
          ...
      }
    }

However, the ffmpeg says

encoder did not produce proper pts making some up

when the code runs to av_write_frame(); what's the problem here?


Solution

  • First make sure the inputStreamFormatCtx allocated and filled by right values (which is the cause of 90% of problem with demuxing/remuxing problems) - check some samples on internet to know how u should allocate and set its values.

    The error tells us what is happening and it seems it is just a warning. PTS (Presentation Time Stamp) is a number based on stream->time_base which tells us when we should show the decoded frame of this packet. when u get a live stream via network it's possible the server hasn't put a valid number for PTS of packet and when you receive the data it has a INVALID PTS (which you can find out by reading packet.pts and check if its a AV_NOPTS_VALUE). so then libav tries to generate the right pts based on frame rate and time_base of stream. It's a helpful attempt and if the recorded file can be played on a real motion (fps-wise) you should be happy. and if the recorded file will be played on a fast or slow motion (fps-wise) you got a problem and you can't rely on libav to correct the fps anymore. so then you should calculate the right fps by decoding the packets and then calculate the right pts based on the stream->time_base and set it to packet.pts.