Monday, September 12, 2011

FFMPEG - av_interleaved_write_frame return error code -22 when passing in a H.264 frame

Actually, until now, I don't know what is error -22 means when av_interleaved_write_frame return me this error code. But, I am sure it is related to PTS value in your AVPacket that is going to pass into av_interleaved_write_frame.


AVPacket pkt;
av_init_packet(&pkt);
......
ret = av_interleaved_write_frame(oc, &pkt);


The above will return -22 if pkt is a H.264 encoded frame from avcodec_encode_video

Now, you need to figure out where to set this PTS value. If you are encoding raw image frame (YUV, RGB, etc...) into H.264, you have to set the PTS at the input frame for avcodec_encode_video.


AVFrame * picture;
picture = avcodec_alloc_frame();
picture->pts = video_pts;
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);

The line picture->pts = video_pts; is very important. It will solve not onlyyour error -22 issue but also non-strictly-monotonic pts generate when you call avcodec_encode_video.

Now, you will wonder how to compute PTS.

For H.264 frame, it will be 90000Hz for sample ratewith 30FPS. Therefore, the sequence for H.264 PTS will be

frame 0 ->  (1 / 30) * 90000 * 0 = 0
frame 1 ->  (1 / 30) * 90000 * 1 = 3000
frame 2 ->  (1 / 30) * 90000 * 2 = 6000
frame 3 ->  (1 / 30) * 90000 * 3 = 9000

So, the general formula is

(1 / FPS) * sample rate * frame number

Putting all the above together, it should solve all the issue.

If you want more concrete example, just give me a ping

11 comments:

  1. Thanks for this! Solved all my annoying non-strictly-monotonic PTS encoding warnings.

    ReplyDelete
  2. Any idea what would be the sample rate for 25 fps?

    ReplyDelete
  3. Well.. it depends on your encoding method. It has no relation to FPS.

    In general, H.264 and MPEG4 encoding use 90000 sample rate.

    ReplyDelete
    Replies
    1. Hi Thompson Ng,
      I developed code for recording video from ipcamera.
      which stores in AVI format.I am able to record both audio and video but there is no sync.I think this is problem with PTS.how to find PTS value in encoded H264 data.
      Thanks,
      Raghav.

      Delete
  4. This really depend on your source encoder whether it encode with PTS value.

    If there is and assume you are using ffmpeg, you can try getting PTS with avCodecCtx->getVideoCodecContext()->coded_frame->pts

    ReplyDelete
  5. I am still getting the error even after following your suggestion to the letter. However I am just getting an warning and I am not using av_interleaved_write_frame. I am just writing the encoded frames to a file using simple fwrite. Any suggestions why it might be happening.

    ReplyDelete
  6. So, where is the error appearing when you are not using av_interleaved_write_frame?

    ReplyDelete
  7. I am facing the same issue but since my stream is h264 I need to offset pts/dts according to the display time stamp I am recieving in the stream.

    generally the pts is not in order, please advice how to handle such streams.

    Thanks

    ReplyDelete
  8. What do you mean by pts not in order? Are involving B frames of H.264?

    ReplyDelete
  9. I am not sure about the B frames but the pts I am receiving from the decoder is in following order

    pts = (2002, 0, 1001, 5005, 3003...)

    and I am setting dts to (0, 1001, 2002, 3003...)

    ReplyDelete
  10. This works nut the time between frames is too extended. It takes three minutes to display 3 seconds worth of frames via rtmp. What is the issue?

    ReplyDelete

Facebook - Control privacy setting of liked page

By default, Facebook displayed your liked page to public. It is the user responsibility to adjust the privacy setting. And in my opinion, F...