[FFmpeg-trac] #1831(avformat:new): Seeking by byte returns success but does not seek
FFmpeg
trac at avcodec.org
Thu Oct 18 21:42:45 CEST 2012
#1831: Seeking by byte returns success but does not seek
-----------------------------------+------------------------------------
Reporter: mbradshaw | Owner:
Type: defect | Status: new
Priority: normal | Component: avformat
Version: 1.0 | Resolution:
Keywords: | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-----------------------------------+------------------------------------
Changes (by mbradshaw):
* component: undetermined => avformat
Old description:
> '''Summary of the bug:'''
> When calling `av_seek_frame()` (or `avformat_seek_file()`) with
> `AVFMT_NO_BYTE_SEEK`, 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)
> {{{
> packetCount: 526 decodedFrameCount: 259
> formatContext->iformat->flags: 0 no byte seeking: 0
> av_seek_frame() returned: -1
> packetCount: 0 decodedFrameCount: 0
> }}}
New description:
'''Summary of the bug:'''
When calling `av_seek_frame()` (or `avformat_seek_file()`) with
`AVFMT_NO_BYTE_SEEK`, 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
}}}
--
Comment:
Reformatted the sample code (tabs to spaces), fixed a small typo, and set
compenent to avformat.
--
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/1831#comment:1>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list