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