#11546: mjpeg file call av_read_frame return EOF after seek ------------------------------------+----------------------------------- Reporter: honglongyu | Owner: (none) Type: defect | Status: new Priority: normal | Component: avcodec Version: git-master | Resolution: Keywords: | Blocked By: Blocking: | Reproduced by developer: 0 Analyzed by developer: 0 | ------------------------------------+----------------------------------- Description changed by honglongyu:
Old description: > I'm working on a looped decoding scenario for MJPEG files, and I > encountered an issue when seeking back to the beginning of the file. > Specifically, after calling av_seek_frame(fmt_ctx, -1, 0, > AVSEEK_FLAG_BACKWARD), the first packet returned by av_read_frame() is > immediately an EOF. > > Below is a minimal demo of my decoding code: > > {{{ > #include <iostream> > extern "C" { > #include <libavformat/avformat.h> > #include <libavcodec/avcodec.h> > } > int main() { > const char* filename = > "D:\\dev\\8k_main\\8k\\example\\decode_pic\\test.jpg"; > AVFormatContext* formatContext = nullptr; > if (avformat_open_input(&formatContext, filename, nullptr, nullptr) > != 0) { > std::cerr << "Could not open file: " << filename << std::endl; > return -1; > } > if (avformat_find_stream_info(formatContext, nullptr) < 0) { > std::cerr << "FFmpeg failed to find stream info: " << filename > << std::endl; > return -1; > } > av_dump_format(formatContext, 0, filename, 0); > int ret_seek = av_seek_frame(formatContext, 0, 0, > AVSEEK_FLAG_BACKWARD); > if (ret_seek < 0) { > std::cerr << "Error seeking to frame" << std::endl; > avformat_close_input(&formatContext); > return -1; > } > // Read a frame from the file > AVPacket packet; > int ret = av_read_frame(formatContext, &packet); > if (ret < 0) { > char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0}; > av_strerror(ret, errbuf, sizeof(errbuf)); > std::cerr << "Error reading frame, err is " << errbuf << > std::endl; > av_packet_unref(&packet); > avformat_close_input(&formatContext); > return -1; > } > std::cout << "Frame read successfully" << std::endl; > return 0; > } > }}} > > > Here is the console output with seek: > > {{{ > Input #0, image2, from 'D:\dev\8k_main\8k\example\decode_pic\test.jpg': > Duration: 00:00:00.04, start: 0.000000, bitrate: 551200 kb/s > Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, > bt470bg/unknown/unknown), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, > 25 tbn > Error reading frame, err is End of file > }}} > > And here is the output without calling seek: > > {{{ > Input #0, image2, from 'D:\dev\8k_main\8k\example\decode_pic\test.jpg': > Duration: 00:00:00.04, start: 0.000000, bitrate: 551200 kb/s > Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, > bt470bg/unknown/unknown), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, > 25 tbn > Frame read successfully > }}} New description: I'm working on a looped decoding scenario for MJPEG files, and I encountered an issue when seeking back to the beginning of the file. Specifically, after calling av_seek_frame(fmt_ctx, -1, 0, AVSEEK_FLAG_BACKWARD), the first packet returned by av_read_frame() is immediately an EOF. Below is a minimal demo of my decoding code: {{{ #include <iostream> extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> } int main() { const char* filename = "D:\\dev\\8k_main\\8k\\example\\decode_pic\\test.jpg"; AVFormatContext* formatContext = nullptr; if (avformat_open_input(&formatContext, filename, nullptr, nullptr) != 0) { std::cerr << "Could not open file: " << filename << std::endl; return -1; } if (avformat_find_stream_info(formatContext, nullptr) < 0) { std::cerr << "FFmpeg failed to find stream info: " << filename << std::endl; return -1; } av_dump_format(formatContext, 0, filename, 0); int ret_seek = av_seek_frame(formatContext, 0, 0, AVSEEK_FLAG_BACKWARD); if (ret_seek < 0) { std::cerr << "Error seeking to frame" << std::endl; avformat_close_input(&formatContext); return -1; } // Read a frame from the file AVPacket packet; int ret = av_read_frame(formatContext, &packet); if (ret < 0) { char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0}; av_strerror(ret, errbuf, sizeof(errbuf)); std::cerr << "Error reading frame, err is " << errbuf << std::endl; av_packet_unref(&packet); avformat_close_input(&formatContext); return -1; } std::cout << "Frame read successfully" << std::endl; return 0; } }}} Here is the console output with seek: {{{ Input #0, image2, from 'D:\dev\8k_main\8k\example\decode_pic\test.jpg': Duration: 00:00:00.04, start: 0.000000, bitrate: 551200 kb/s Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 25 tbn Error reading frame, err is End of file }}} And here is the output without calling seek: {{{ Input #0, image2, from 'D:\dev\8k_main\8k\example\decode_pic\test.jpg': Duration: 00:00:00.04, start: 0.000000, bitrate: 551200 kb/s Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 25 tbn Frame read successfully }}} The original attachment was too large to upload, so I included a smaller image instead. The issue remains the same. -- -- Ticket URL: <https://trac.ffmpeg.org/ticket/11546#comment:1> FFmpeg <https://ffmpeg.org> FFmpeg issue tracker
_______________________________________________ FFmpeg-trac mailing list FFmpeg-trac@avcodec.org https://ffmpeg.org/mailman/listinfo/ffmpeg-trac To unsubscribe, visit link above, or email ffmpeg-trac-requ...@ffmpeg.org with subject "unsubscribe".