Opened 12 years ago
Closed 12 years ago
#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 )
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 (1)
Change History (7)
by , 12 years ago
Attachment: | MP4-MC264-AAC.mp4 added |
---|
comment:1 by , 12 years ago
Component: | undetermined → avformat |
---|---|
Description: | modified (diff) |
follow-up: 4 comment:3 by , 12 years ago
Keywords: | seek added |
---|
Could you confirm that you see the same behaviour with current git head?
comment:4 by , 12 years ago
Replying to cehoyos:
Could you confirm that you see the same behaviour with current git head?
Yes, I can confirm this is reproducible with current git head. I just tried it with the latest code. Same thing.
comment:5 by , 12 years ago
Version: | 1.0 → git-master |
---|
comment:6 by , 12 years ago
Reproduced by developer: | set |
---|---|
Resolution: | → fixed |
Status: | new → closed |
Reproduced with ffplay instead
Reformatted the sample code (tabs to spaces), fixed a small typo, and set compenent to avformat.