[FFmpeg-trac] #1831(avformat:new): Seeking by byte returns success but does not seek

FFmpeg trac at avcodec.org
Thu Oct 18 21:47:50 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          |
-----------------------------------+------------------------------------

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 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
> }}}

New description:

 '''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
 }}}

--

Comment (by mbradshaw):

 Another typo fix, sorry.

-- 
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/1831#comment:2>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list