FFMPEG :Adjusting PTS and DTS of encoded packets with real timestamps information

Viewed 1339

I am trying to record a video of activities in desktop using muxing in FFMPEG Library. I referred following link for my implementation. https://ffmpeg.org/doxygen/trunk/muxing_8c_source.html

I observe that the encoded video plays too fast. Below is the code of encoding the frame and then writing it to output file.

static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
                        AVStream *st, AVFrame *frame)
{
    int ret;
 
    // send the frame to the encoder
    ret = avcodec_send_frame(c, frame);
    if (ret < 0) {
    fprintf(stderr, "Error sending a frame to the encoder: %s\n",av_err2str(ret));
    exit(1);
    }
    while (ret >= 0) {
        AVPacket pkt = { 0 };

        ret = avcodec_receive_packet(c, &pkt);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
           break;
        else if (ret < 0) {
           fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret));
           exit(1);
        }

        /* rescale output packet timestamp values from codec to stream timebase(from 25 to 90000 this case) */
        av_packet_rescale_ts(&pkt, c->time_base, st->time_base);
        pkt.stream_index = st->index;

        /* Write the compressed frame to the media file. */
        log_packet(fmt_ctx, &pkt);
        ret = av_interleaved_write_frame(fmt_ctx, &pkt);
        av_packet_unref(&pkt);
        if (ret < 0) {
              fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret));
              exit(1);
        }
    }
  
    return ret == AVERROR_EOF ? 1 : 0;
  }

-> I am rescaling output packet timestamp values from codec to stream timebase (25 -> 90,000) before writing. -> Since encoded video does plays very fast, so I have added temporary fix to multiply stream timebase by some factor just before av_packet_rescale_ts (in my case it is 5 -> 5*st->time_base.den which becomes 4,50,000) so that output video duration increases. This may not be the accurate solution as this would not give the real time shift between the frames.

/**  rescale output packet timestamp values from codec to stream timebase  **/
st->time_base.den = 5*st->time_base.den;
av_packet_rescale_ts(pkt, *time_base, st->time_base);
pkt->stream_index = st->index;
/**  Write the compressed frame to the media file.  **/
return av_interleaved_write_frame(fmt_ctx, pkt);

-> I want that output video duration should be similar to the input. I have heard of things like giving real timestamps to the PTS and DTS of frame and packets and encoding at variable or unknown frame rate. Can we use these , If yes then How to implement? any suggestions or pseudo code of the approach would really help.

Thanks

0 Answers
Related