(see also previous 2 commits)
Fixed according to [FFmpeg decode video example] - the parser needs
final call with zero long buffer to flush the frame.
\+ prefix eventual parser error with identifying prefix
[FFmpeg decode video example]:
https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/decode_video.c
This reverts commit d4be2d97b5.
The fix was not correct, because it just hided the root of the problem -
the av_parser_parse2 needs final call with buf_size == 0 to flush last
frame. Otherwise it will remain in the queue, effectivelly adding a
delay by one frame, because the particular frame will get flushed when
processing next frame.
See also:
<https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/decode_video.c>
removed skipping P frames after missing P frame in VP8
This doesn't seem to be needed anymore and removing it simplifies the
code a bit. Moreover, if frame drops was the case, now frames, that
have been skipped until now will be presented, potentially reducing
twitching.
Updated sync frame API to match updated tile API as defined by the
commit e9a407ad.
Note: none of 2 compression using this API currently need reading
additional frames.
There was a comment that the frame is no longer valid, which was a bit
misleading, because the the tiles hold reference to that frame but do
not modify it in any way.
Also removed assigning NUL altogether - it was not much functional,
since it will be released soon thereafter, anyways, so it is possibly
not much needed.
Modified the API in order to fetch additional frames from compression
with iterative passing NULL pointer (similarly as for audio).
This is particularly usefull when inter-frame compression outputs 2
frames at once, which can occur when B-frames would be enabled. It,
however sometimes happen even when B-frames are disbled, eg. with
h264/hevc_mf HW encoder on AMD (AMDh265Encoder; see commit d70e2fb3c).
Please note that semantic of passing NUL frame is different in this API
to that in async API, where it works as a poison pill.
In case that the encoder buffers frame for whatever reason (NVENC
with delay, hevc_mf sometimes batching 2 frames /returned frames count
0,1,2,0,1,2.../) so that output frame doesn't match the currently
enqueued onei, metadata would be incorrect (currently enqueued copied
to non-matching dequeued one).
use AVParser for the received compressed data
This is particularly useful when encoder produces frames glued together -
it shouldn't be the case most of the times, since UG programmatically
disables B-frames but there can be some not handled encoders, notably
currently problematic _hevc_mf_ on AMD (AMDh265Encoder).
The FFmpeg native H.264 and HEVC decoders are particuraly sensitive to
passing 2 encoded frames at once, breaking the picture with errors like:
[lavc hevc @ 0x61c590004d80] Two slices reporting being the first in the same frame.
[lavc hevc @ 0x61c590004d80] Could not find ref with POC 7
or
[lavc h264 @ 0x6ee80c004d80] Frame num change from 3 to 4
[lavc h264 @ 0x6ee80c004d80] decode_slice_header error
After this fix, decoding is correct. Excess frames are dismissed but
decoding works and more importantly, user is informed what is the
problem.
Moved reading eventual forced props at the beginning. Previously, it
must have been waited until first IDR, which is unecessary, because the
custom NAL unit is appended to every frame.
Also it is not needed to read it in all compressions since it is
codec-specific and thus as implemented now, it is only applicable to
H.264/HEVC.
Use rather defined function as mkdir(3p) is, even though there is needed
a compat for MSW.
+ removed some strtok_r undef, which should no longer be needed (see
also commit 6c6253c9)
Use ISO 8601 date/time for dump directory name instead of seconds since
epoch. Basic format is used because in the extended, the colons delimiting
the time interfere with _export_ options delimiter.
Since H.264 and HEVC uses different constants even for the same (named)
NAL type (eg. AUD has 9 in H.264 but 35 in HEVC), replace NAL_ prefix,
that were implilcitly meant or H.264 with NAL_H264.
removed explicit preset handling
Actually with current encoder set, having the preset is rather exceptional
- some codecs to not recognize the presets with any encoder, eg. MJPEG,
Other have a different keyword like "usage" (VP9). Even with eg. H.265
different encoders use different keywords ("scenario" for QSV and MF) etc.
So give up explicit handling of presets - those (or those under different
names) can be configure in codec specific configure callbacks.
There is also a change that the default preset is always set, previously
not if _preset_ was detected in cmdline params. This doesn't seem to be
a problem, however. The user-specified options are set after the
codec-specific configure callback so that it should override the default.
set default values
Seting hw_encoding=1 (force) - otherwise, the API seems to be using SW
encode. Moreover, using _hevc_mf_ fails to init (at least in some setups)
while the GPU supports that so that enforcing that makes it work.
When trying to init _any_ codec (for the further use with swscale), do not
try already tried pixfmts. Plus do not print that we will try with swscale
when there is no AV pixfmt left (it is a bit misleading in the UG output).
Do not enforce the file to be either included before stdlib.h or stdlib.h
to be using __STDC_WANT_LIB_EXT1__ = 1. The bound checking API is
currently nowhere implemented, anyways, and we may use system native secure
qsort implementation (qsort_r in *NIX, MS variant of qsort_s).
H264_mf encoder (Windows) produces single byte AUD unit prior to SPS
NALU. Because only first NALU was evaluated to assess whether to pass
the frame further, it took 10 frames (+ additional 10 for probe) before
decoding started before it surrendered the checks.
Also do not include malloc.h for Windows - it is already there but it is
not a good practice to include headers in the config_*.h files, anyways
(the actual functions are declared if any of malloc.h or stdlib.h is
included, while the second should be included explicitly if wanting
dynamic memory management, anyways).
Encounter using standard strerror_s() instead of home-grown
replacement. MSW already include C11-compatible strerror_s()
implementation (although it doesn't advertise __STDC_LIB_EXT1__).
XSI version of strerror_r() is mostly compatible (except of argument
order).
Using standard functions should be more convenient than custom workarounds
(even if there is needed a compat macro).