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