Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix invalid starting PTS value (blank 1st frame) #695

Merged
merged 7 commits into from Jul 3, 2021

Conversation

jonoomph
Copy link
Member

Fix invalid starting PTS value, preventing blank 1st frames on some thumbnailing and video players. Turns out, we were incrementing the starting timestamp before writing a packet at position 0. I did some tests, and now ffprobe reports a start time of 0.0000000, instead of 0.033008.

@codecov
Copy link

codecov bot commented Jun 25, 2021

Codecov Report

Merging #695 (9ca63b3) into develop (09eb807) will increase coverage by 0.00%.
The diff coverage is 61.53%.

Impacted file tree graph

@@           Coverage Diff            @@
##           develop     #695   +/-   ##
========================================
  Coverage    50.41%   50.42%           
========================================
  Files          155      155           
  Lines        13315    13297   -18     
========================================
- Hits          6713     6705    -8     
+ Misses        6602     6592   -10     
Impacted Files Coverage Δ
src/FFmpegWriter.h 25.00% <ø> (ø)
src/QtPlayer.cpp 0.00% <ø> (ø)
src/FFmpegReader.cpp 68.35% <50.00%> (ø)
src/FFmpegWriter.cpp 59.70% <62.16%> (+0.03%) ⬆️
src/FFmpegUtilities.h 100.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 09eb807...9ca63b3. Read the comment docs.

@JacksonRG
Copy link
Collaborator

So from testing with ffprobe, I found that video files are now starting at time:0.00000; but audio only exports are still starting a fraction of a second after 0.

@JacksonRG
Copy link
Collaborator

The change I made to write_audio_packets reduced the start time of my audio only tests from 0.042 to 0.021.

And I verified that the audio file I was using had an original start time of 0.

src/FFmpegWriter.cpp Outdated Show resolved Hide resolved
src/FFmpegWriter.cpp Outdated Show resolved Hide resolved
if (pkt.dts != AV_NOPTS_VALUE)
pkt.dts = av_rescale_q(pkt.dts, audio_codec_ctx->time_base, audio_st->time_base);
if (pkt.duration > 0)
pkt.duration = av_rescale_q(pkt.duration, audio_codec_ctx->time_base, audio_st->time_base);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have a pkt.duration, seems like that could be used to increment write_video_count. As the documentation says, AVPacket::duration "Equals next_pts - this_pts in presentation order." (Also, pretty sure av_packet_rescale_ts() is a better choice than av_rescale_q() here, too.)

…escale_ts() method. I'm just not sure the backwards compatibility of this approach with older FFmpeg versions.
@jonoomph
Copy link
Member Author

I'm curious if the switch to av_packet_rescale_ts() will cause builder failures on older versions of FFmpeg. Testing this now.

@ferdnyc
Copy link
Contributor

ferdnyc commented Jun 26, 2021

I'm curious if the switch to av_packet_rescale_ts() will cause builder failures on older versions of FFmpeg. Testing this now.

It's existed since at least FFmpeg 2.4, possibly earlier. (That's as far back as I checked.)

@ferdnyc
Copy link
Contributor

ferdnyc commented Jun 27, 2021

I just pushed a commit that adds --output-on-failure to the unit test run, so that we'll have a better idea of why tests fail when they do.

For the record, for the Webm unit test, this is the why:

-------------------------------------------------------------------------------
Webm
-------------------------------------------------------------------------------
/home/ferd/rpmbuild/REPOS/libopenshot/worktrees/pr695/tests/FFmpegWriter.cpp:45
...............................................................................

/home/ferd/rpmbuild/REPOS/libopenshot/worktrees/pr695/tests/FFmpegWriter.cpp:75: FAILED:
  CHECK( r1.info.fps.num == 24 )
with expansion:
  30 == 24

/home/ferd/rpmbuild/REPOS/libopenshot/worktrees/pr695/tests/FFmpegWriter.cpp:86: FAILED:
  CHECK( (int)pixels[pixel_index] == Approx(23).margin(5) )
with expansion:
  11 == Approx( 23.0 )

/home/ferd/rpmbuild/REPOS/libopenshot/worktrees/pr695/tests/FFmpegWriter.cpp:87: FAILED:
  CHECK( (int)pixels[pixel_index + 1] == Approx(23).margin(5) )
with expansion:
  11 == Approx( 23.0 )

/home/ferd/rpmbuild/REPOS/libopenshot/worktrees/pr695/tests/FFmpegWriter.cpp:88: FAILED:
  CHECK( (int)pixels[pixel_index + 2] == Approx(23).margin(5) )
with expansion:
  11 == Approx( 23.0 )

===============================================================================
test cases: 1 | 1 failed
assertions: 7 | 3 passed | 4 failed

But equally worrying is the output that comes before it, while the test is running:

Folded because it's frickin' Y000000GE...

ZmqLogger::Connection - Error binding to tcp://*:5556. Switching to an available port.
[libvpx @ 0x1dd4280] v1.9.0
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvorbis @ 0x1eb1200] Queue input is backward in time
[libvpx @ 0x1dd4280] Ignoring attempt to flush encoder that doesn't support it

@ferdnyc
Copy link
Contributor

ferdnyc commented Jun 27, 2021

P.S> It's also always possible to configure CMake with -DVERBOSE_TESTS=1, which will turn on output for all tests including the passing ones.

Doing so reveals that the next test — test 54, "FFmpegWriter:Options_Overloads" — also shows strange output, though it passes (because it's not testing the output, only the API):

54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [aac @ 0x207ae00] Queue input is backward in time
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [libx264 @ 0x2053740] non-strictly-monotonic PTS
54: [aac @ 0x207ae00] Queue input is backward in time
54: [libx264 @ 0x2053740] Ignoring attempt to flush encoder that doesn't support it
54: ===============================================================================
54: All tests passed (8 assertions in 1 test case)
54: 
  4/145 Test  #54: FFmpegWriter:Options_Overloads .....................   Passed    2.41 sec

...But those are the only two.

@ferdnyc
Copy link
Contributor

ferdnyc commented Jun 27, 2021

Here are the results of ffprobe -report on both files, output1.webm (test 53) and output1.mp4 (test 54):

ffprobe-mp4.log
ffprobe-webm.log

They both show the same basic thing:

matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 2 with DTS 0, packet 3 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 3 with DTS 0, packet 4 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 4 with DTS 0, packet 5 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 5 with DTS 0, packet 6 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 6 with DTS 0, packet 7 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 7 with DTS 0, packet 8 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 8 with DTS 0, packet 9 with DTS 0
[matroska,webm @ 0x56466ff4ed40] Non-increasing DTS in stream 0: packet 9 with DTS 0, packet 10 with DTS 0

...and so on for every frame except the first.

@ferdnyc ferdnyc added the ffmpeg Issues or PRs involving the a/v processing code label Jul 3, 2021
… some codecs (such as vp8), this approach breaks due to differences in the timebase vs the framerate. For example, if the timebase is an inverse of the FPS, everything works. But if the timebase is not, for example 1/1000000, this approach breaks.
@jonoomph
Copy link
Member Author

jonoomph commented Jul 3, 2021

Thanks @ferdnyc, however I could not get any output from CTest without the following:
CTEST_OUTPUT_ON_FAILURE=1 make test

I'm probably missing something simple, but I got your changes/commit, cleared the CMake temp files, and re-ran cmake (with and without the -DVERBOSE_TESTS=1 flag), but no additional output. Strange.

@jonoomph
Copy link
Member Author

jonoomph commented Jul 3, 2021

I ended up reverting a couple uses of the pkt.duration, due to failures in the unit tests. Best I could tell, it appears that if a codec uses a non-FPS related timebase (i.e. 1/1000000 vs 1/24), the pkt.duration does not correctly increment the timestamp. Feel free to play around with that theory if you wish, lol. But for now, I feel like this PR is a big improvement on readability/variable naming, and solves the general issue of incrementing timestamps before our first packet. 👍

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 3, 2021

@jonoomph

Sorry, that's my fault, I was unclear.

--output-on-failure is automatically added to the run, you don't need to do anything for that ­— but only if you use one of my coverage targets. (Which don't actually collect coverage, unless it's enabled.) There's no way (that I'm aware of) to customize the default test target that CMake creates, so I had to create other targets to supply custom arguments. Since I was already creating coverage targets to run the Codecov scripts if enabled, I just used those, though I'm open to other suggestions. test is off limits, though, when using CTest.

There's both the general coverage target, which runs all the tests, but each test also has a TestName_coverage target which will build and run only that test, which is much quicker when debugging a certain class.

So both cmake --build build --target FFmpegWriter_coverage (from the root dir) and make FFmpegWriter_coverage (from the build dir) will run just the FFmpegWriter tests, with output-on-failure automatically enabled. cmake --build build --target coverage and make coverage will similarly run all the tests.

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 3, 2021

To get complete test output, with the coverage targets, you can add -DVERBOSE_TESTS=1 to the cmake command line when you configure the build. But you don't need to do anything for output-on-failure, with the coverage targets, that's now the default.

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 3, 2021

(On the plus side, by default the coverage target will also run the tests in parallel, using the processor count detected by CMake. Which makes the tests run much faster. ...Except on Windows. I had to disable it there, because it seemed to be the cause of those build failures we were seeing due to test timeouts. The parallel test runs can also be disabled, if necessary, by adding -DENABLE_PARALLEL_CTEST=0 to the cmake command line when configuring the project.)

@jonoomph
Copy link
Member Author

jonoomph commented Jul 3, 2021

@ferdnyc On a side note, I've been playing more with Sentry.io, and added/assigned a few strange ones to your user, if you are curious or interested. 👍 Thx!

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 3, 2021

@jonoomph Sure, I'll take a look, thanks!

@jonoomph jonoomph merged commit 27c1f9d into develop Jul 3, 2021
@jonoomph jonoomph deleted the fix-invalid-starting-pts-timestamp branch July 3, 2021 22:48
@jeffski
Copy link
Contributor

jeffski commented Jul 5, 2021

Great to see this fixed, will give it a try soon. Thanks guys.

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 6, 2021

@jonoomph

I ended up reverting a couple uses of the pkt.duration, due to failures in the unit tests. Best I could tell, it appears that if a codec uses a non-FPS related timebase (i.e. 1/1000000 vs 1/24), the pkt.duration does not correctly increment the timestamp. Feel free to play around with that theory if you wish, lol. But for now, I feel like this PR is a big improvement on readability/variable naming, and solves the general issue of incrementing timestamps before our first packet.

Yeah, agreed. What I found is that it does increment — but only when the frame sent results in the creation of an output AVFrame. Buffered frames and partial frames (for audio) don't create new frames, so the packets have no duration.

That especially happens in the beginning of encoding, because the encoder buffers a bunch of frames for predictive motion estimation before it starts sending back packets. When looping through with some debug print()s in place, I'd see things like:

pkt.duration = 0
pkt.duration = 0
[... like 5 more frames ...]
pkt.duration = 0
pkt.duration = (some non-zero number)

from the video encoder.

(I guess that fits with the documentation line about duration being equal to next_pts - this_pts, if you interpret it as meaning that "the next pts will still be the same pts" for small frames — but it makes it useless for setting packet timestamps.)

Going through the calls like that did reveal another issue, though. I now know where all of those "ignoring attempt to flush an encoder..." messages on stderr are coming from. (To be continued...)

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 6, 2021

@jonoomph

Our current encoding code is still too locked into the old idea of "Send a frame, receive a packet." And it proceeds based on that assumption. But encoding isn't that strictly ordered, there isn't a 1:1 relationship between frames sent and packets received.

IOW, we're not following the official API guide for decoding/encoding:

The API is very similar for encoding/decoding and audio/video, and works as follows:

  • Set up and open the AVCodecContext as usual.

  • Send valid input:

    • For decoding, call avcodec_send_packet() to give the decoder raw compressed data in an AVPacket.
    • For encoding, call avcodec_send_frame() to give the encoder an AVFrame containing uncompressed audio or video.

    In both cases, it is recommended that AVPackets and AVFrames are refcounted, or libavcodec might have to copy the input data. (libavformat always returns refcounted AVPackets, and av_frame_get_buffer() allocates refcounted AVFrames.)

  • Receive output in a loop. Periodically call one of the avcodec_receive_*() functions and process their output:

    • For decoding, call avcodec_receive_frame(). On success, it will return an AVFrame containing uncompressed audio or video data.
    • For encoding, call avcodec_receive_packet(). On success, it will return an AVPacket with a compressed frame.

    Repeat this call until it returns AVERROR(EAGAIN) or an error. The AVERROR(EAGAIN) return value means that new input data is required to return new output. In this case, continue with sending input. For each input frame/packet, the codec will typically return 1 output frame/packet, but it can also be 0 or more than 1.

At the beginning of decoding or encoding, the codec might accept multiple input frames/packets without returning a frame, until its internal buffers are filled. This situation is handled transparently if you follow the steps outlined above.

In FFmpegWriter::write_video_packet, it does an avcodec_send_frame(), then calls avcodec_receive_packet() once. (It's inside a while loop, for some reason, but will break out of that loop the moment it receives a packet, defeating the point.) Worse, when it receives AVERROR(EAGAIN) as a result of the avcodec_receive_packet(), it goes into flush mode — even though there's nothing to flush, and getting no packet back from the early calls is perfectly normal due to codec buffering.

So what we're doing (in the FFmpeg 3.2+ branches) is:

ret = avcodec_send_frame();
while (ret >= 0) {
    ret = avcodec_receive_packet();
    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
        avcodec_flush_buffers();
        break;
    }
    if (ret == 0) {
       got_packet = 1;
       break;
    }
if (got_packet) {
     av_interleaved_write_frame();
}

and that's one call to that function. No more receives will be attempted until the next call.

What we need to be doing, instead, is something more like:

ret = avcodec_send_frame();
while (ret >= 0) {
    ret = avcodec_receive_packet();
    if (ret < 0) {
        if (ret != AVERROR(EAGAIN)) {
            // error-handling code
        }
        break;
    }
    av_interleaved_write_frame();
}

So that, if no packet is received, that's OK and will be ignored — it won't trigger an unnecessary flush attempt. And if more than one packet is waiting on the interface, we'll retrieve and write them all to the file immediately.

(I also get the impression that the receive loop will receive both audio and video data, regardless which one was last sent, and probably should be done separate from the send-audio/send-video code.)

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 6, 2021

Another possible reason the pkt.duration-consuming code was an issue, in fact, was because it came after the av_interleaved_write_frame() call. That may be forbidden by the API:

int av_interleaved_write_frame(AVFormatContext* s, AVPacket* pkt)

  • pkt: The packet containing the data to be written.If the packet is reference-counted, this function will take ownership of this reference and unreference it later when it sees fit. The caller must not access the data through this reference after this function returns.

(I say "may be" because it's not 100% clear to me whether "the data" in that statement means just the packet data buffer (pkt.data) itself, or any of the structure members like pkt.duration. But probably best to err on the side of assuming it means the entire packet.)

@ferdnyc
Copy link
Contributor

ferdnyc commented Jul 6, 2021

I also get the impression that the receive loop will receive both audio and video data, regardless which one was last sent

Nope! That's wrong, because it avcodec_receive_packet() receives from a specific encoder context. So a packet is always of a certain type, and it'll always be known what type of packet it is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ffmpeg Issues or PRs involving the a/v processing code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants