Ticket #1831 (closed defect: fixed)
Seeking by byte returns success but does not seek
| Reported by: | mbradshaw | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | avformat |
| Version: | git-master | Keywords: | seek |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | yes | |
| Analyzed by developer: | no |
Description (last modified by mbradshaw) (diff)
Summary of the bug:
When calling av_seek_frame() (or avformat_seek_file()) with AVSEEK_FLAG_BYTE, it returns 0 indicating success, however, the seek is not performed. I have attached a file that exposes this failure, though I have many files for which this problem occurs.
How to reproduce:
I created the below quick sample code to show that seeking by byte does not work. If you change the seeking flag to AVSEEK_FLAG_BACKWARD then it works as expected. In both cases, however, av_seek_frame() returns 0, indicating success.
#include <iostream>
extern "C"
{
#include <avcodec.h>
#include <avformat.h>
#include <swscale.h>
};
int main()
{
av_register_all();
AVFrame* frame = avcodec_alloc_frame();
if (!frame)
{
std::cout << "Error allocating the frame" << std::endl;
return 1;
}
AVFormatContext* formatContext = NULL;
if (avformat_open_input(&formatContext, "C:/Users/mbradshaw/Desktop/b/MP4-MC264-AAC.mp4", NULL, NULL) != 0)
{
av_free(frame);
std::cout << "Error opening the file" << std::endl;
return 1;
}
if (avformat_find_stream_info(formatContext, NULL) < 0)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Error finding the stream info" << std::endl;
return 1;
}
AVStream* audioStream = NULL;
for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
{
if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = formatContext->streams[i];
break;
}
}
if (audioStream == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Could not find any audio stream in the file" << std::endl;
return 1;
}
AVCodecContext* codecContext = audioStream->codec;
codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
if (codecContext->codec == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Couldn't find a proper decoder" << std::endl;
return 1;
}
else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Couldn't open the context with the decoder" << std::endl;
return 1;
}
AVPacket packet;
av_init_packet(&packet);
int packetCount = 0;
int decodedFrameCount = 0;
while (av_read_frame(formatContext, &packet) == 0)
{
++packetCount;
if (packet.stream_index == audioStream->index)
{
int frameFinished = 0;
avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
if (frameFinished)
{
++decodedFrameCount;
}
}
av_free_packet(&packet);
}
std::cout << "packetCount: " << packetCount << "\tdecodedFrameCount: " << decodedFrameCount << std::endl;
std::cout << "formatContext->iformat->flags: " << formatContext->iformat->flags << "\tno byte seeking: " << (formatContext->iformat->flags & AVFMT_NO_BYTE_SEEK) << std::endl;
avcodec_flush_buffers(codecContext);
av_init_packet(&packet);
std::cout << "av_seek_frame() returned: " << av_seek_frame(formatContext, -1, 0, AVSEEK_FLAG_BYTE) << std::endl;
packetCount = 0;
decodedFrameCount = 0;
while (av_read_frame(formatContext, &packet) == 0)
{
++packetCount;
if (packet.stream_index == audioStream->index)
{
// Try to decode the packet into a frame
int frameFinished = 0;
avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
if (frameFinished)
{
++decodedFrameCount;
}
}
av_free_packet(&packet);
}
std::cout << "packetCount: " << packetCount << "\tdecodedFrameCount: " << decodedFrameCount << std::endl;
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
}
Actual results:
packetCount: 526 decodedFrameCount: 259 formatContext->iformat->flags: 0 no byte seeking: 0 av_seek_frame() returned: 0 packetCount: 0 decodedFrameCount: 0
Expected results: (if seeking really does succeed)
packetCount: 526 decodedFrameCount: 259 formatContext->iformat->flags: 0 no byte seeking: 0 av_seek_frame() returned: 0 packetCount: 526 decodedFrameCount: 259
Alternative expected results: (if seeking really does fail because byte seeking is not allowed)
packetCount: 526 decodedFrameCount: 259 formatContext->iformat->flags: 32768 no byte seeking: 32768 av_seek_frame() returned: -1 packetCount: 0 decodedFrameCount: 0
Attachments
Change History
comment:1 Changed 8 months ago by mbradshaw
- Component changed from undetermined to avformat
- Description modified (diff)
Reformatted the sample code (tabs to spaces), fixed a small typo, and set compenent to avformat.
comment:3 follow-up: ↓ 4 Changed 8 months ago by cehoyos
- Keywords seek added
Could you confirm that you see the same behaviour with current git head?



