<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 10, 2022 at 10:01 PM John Regan via Libav-user <<a href="mailto:libav-user@ffmpeg.org">libav-user@ffmpeg.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, 10 Feb 2022 06:19:47 +0100<br>
Strahinja Radman <<a href="mailto:dr.strashni@gmail.com" target="_blank">dr.strashni@gmail.com</a>> wrote:<br>
<br>
> On Thu, Feb 10, 2022 at 1:14 AM John Regan via Libav-user <<br>
> <a href="mailto:libav-user@ffmpeg.org" target="_blank">libav-user@ffmpeg.org</a>> wrote:<br>
> <br>
> > Hi there, I was hoping somebody could offer advice on how to loop a<br>
> > video with libavformat/libavcodec.<br>
> ><br>
> > I have a filter graph created, so my core decoding code is<br>
> > basically:<br>
> ><br>
> > if( (err = av_read_frame(inputCtx, packet)) < 0) {<br>
> >     if(err != AVERROR_EOF) {<br>
> >         /* handle errors, return */<br>
> >     }<br>
> >     avformat_seek_file(inputCtx,videoStreamIndex, 0, 0, 0, 0));<br>
> >     avcodec_flush_buffers(codecCtx);<br>
> > }<br>
> ><br>
> > if(packet.stream_index == videoStreamIndex) {<br>
> >     avcodec_send_packet(codecCtx,packet);<br>
> >     avcodec_receive_frame(codecCtx,tmpFrame);<br>
> >     av_buffersrc_write_frame(bufferSrcCtx,tmpFrame);<br>
> >     if(av_buffersink_get_frame(bufferSinkCrx,frame) >= 0) {<br>
> >         /* we have a frame */<br>
> >     }<br>
> > }<br>
> ><br>
> > I'm not sure if there's steps that need to be taken to reset the<br>
> > filter graph? Like is there a timestamp discontinuity?<br>
> ><br>
> > It seems like this should work - but I'm missing something, it seems<br>
> > like the buffersink_get_frame stops producing frames after I reset.<br>
> ><br>
> > Thank you in advance,<br>
> > -John<br>
> > _______________________________________________<br>
> > Libav-user mailing list<br>
> > <a href="mailto:Libav-user@ffmpeg.org" target="_blank">Libav-user@ffmpeg.org</a><br>
> > <a href="https://ffmpeg.org/mailman/listinfo/libav-user" rel="noreferrer" target="_blank">https://ffmpeg.org/mailman/listinfo/libav-user</a><br>
> ><br>
> > To unsubscribe, visit link above, or email<br>
> > <a href="mailto:libav-user-request@ffmpeg.org" target="_blank">libav-user-request@ffmpeg.org</a> with subject "unsubscribe".<br>
> >  <br>
> <br>
> Hello,<br>
> <br>
> I dont think you need to reset the filter graph, in the end it simply<br>
> takes in AVFrame* and does some processing. Timestamps in filters are<br>
> only changed if you specify a different timebase for the filters (as<br>
> far as I am aware). But timestamp discontinuity is something you have<br>
> to take care of. For example you could generate them by using this<br>
> formula<br>
> <br>
> frame_timestamp = iteration_count * max_timestamp +<br>
> current_frame_timestamp<br>
> <br>
> max_timestamp is the last timestamp of the video stream.<br>
> This should enable you to get a looped sequence of frames that can be<br>
> properly played. On the other hand, check if you are actually getting<br>
> a frame from your decoder by saving it to a PGM file. Here is the code<br>
> <br>
> static void pgm_save(unsigned char* buf, int wrap, int xsize, int<br>
> ysize, const char* filename)<br>
> {<br>
> <br>
> FILE* f;<br>
> int i;<br>
> <br>
> <br>
> f = fopen(filename, "w");<br>
> fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);<br>
> for (i = 0; i < ysize; i++)<br>
> <br>
> fwrite(buf + i * wrap, 1, xsize, f);<br>
> <br>
> fclose(f);<br>
> <br>
> }<br>
> <br>
<br>
That tip about timestamps was a huge help, thank you!<br>
<br>
I figured out the issue was non-sequential timestamps with the "fps"<br>
filter.<br>
<br>
What I'm doing now is saving the "pts offset" variable and a "last<br>
pts" variable, and "pts offset" is initialized to zero. When I receive<br>
a packet, I save its original PTS to the "last pts" variable, and add<br>
the offset to the packet's PTS. Then, when av_read_frame returns EOF, I<br>
add that last_pts to the offset.<br>
<br>
Question, is it more appropriate to meddle with the packet PTS I get<br>
from the demuxer, or the frame PTS I get from the decoder? Or does it<br>
not really matter?<br>
<br>
_______________________________________________<br>
Libav-user mailing list<br>
<a href="mailto:Libav-user@ffmpeg.org" target="_blank">Libav-user@ffmpeg.org</a><br>
<a href="https://ffmpeg.org/mailman/listinfo/libav-user" rel="noreferrer" target="_blank">https://ffmpeg.org/mailman/listinfo/libav-user</a><br>
<br>
To unsubscribe, visit link above, or email<br>
<a href="mailto:libav-user-request@ffmpeg.org" target="_blank">libav-user-request@ffmpeg.org</a> with subject "unsubscribe".<br>
</blockquote></div><div><br></div><br clear="all"><div>Well as AVPacket has pkt_pts and pkt_dts which the decoder uses, I would rather change AVFrame's PTS value.</div>-- <br><div dir="ltr" class="gmail_signature"><br>Regards<br>Strahinja Radman</div></div>