[FFmpeg-trac] #11546(avcodec:new): mjpeg file call av_read_frame return EOF after seek
FFmpeg
trac at avcodec.org
Tue Apr 15 09:25:16 EEST 2025
#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
More information about the FFmpeg-trac
mailing list