[FFmpeg-cvslog] [ffmpeg-web] branch master updated. fb51859 web/index: add news entry for 4.3
The branch, master has been updated via fb51859289ee3409ec458af626caa70363f39734 (commit) from b442e762543ee063ca04e793f9bc830481397835 (commit) - Log - commit fb51859289ee3409ec458af626caa70363f39734 Author: Gyan Doshi AuthorDate: Wed Apr 7 11:16:04 2021 +0530 Commit: Gyan Doshi CommitDate: Wed Apr 7 11:18:21 2021 +0530 web/index: add news entry for 4.3 diff --git a/src/index b/src/index index fdde3d3..b0ca46c 100644 --- a/src/index +++ b/src/index @@ -35,6 +35,91 @@ News + June 15th, 2020, FFmpeg 4.3 "4:3" + +FFmpeg 4.3 "4:3", a new +major release, is now available! Some of the highlights: + + +v360 filter +Intel QSV-accelerated MJPEG decoding +Intel QSV-accelerated VP9 decoding +Support for TrueHD in mp4 +Support AMD AMF encoder on Linux (via Vulkan) +IMM5 video decoder +ZeroMQ protocol +support Sipro ACELP.KELVIN decoding +streamhash muxer +sierpinski video source +scroll video filter +photosensitivity filter +anlms filter +arnndn filter +bilateral filter +maskedmin and maskedmax filters +VDPAU VP9 hwaccel +median filter +QSV-accelerated VP9 encoding +AV1 encoding support via librav1e +AV1 frame merge bitstream filter +AV1 Annex B demuxer +axcorrelate filter +mvdv decoder +mvha decoder +MPEG-H 3D Audio support in mp4 +thistogram filter +freezeframes filter +Argonaut Games ADPCM decoder +Argonaut Games ASF demuxer +xfade video filter +xfade_opencl filter +afirsrc audio filter source +pad_opencl filter +Simon & Schuster Interactive ADPCM decoder +Real War KVAG demuxer +CDToons video decoder +siren audio decoder +Rayman 2 ADPCM decoder +Rayman 2 APM demuxer +cas video filter +High Voltage Software ADPCM decoder +LEGO Racers ALP (.tun & .pcm) demuxer +AMQP 0-9-1 protocol (RabbitMQ) +Vulkan support +avgblur_vulkan, overlay_vulkan, scale_vulkan and chromaber_vulkan filters +ADPCM IMA MTF decoder +FWSE demuxer +DERF DPCM decoder +DERF demuxer +CRI HCA decoder +CRI HCA demuxer +overlay_cuda filter +switch from AvxSynth to AviSynth+ on Linux +mv30 decoder +Expanded styling support for 3GPP Timed Text Subtitles (movtext) +WebP parser +tmedian filter +maskedthreshold filter +Support for muxing pcm and pgs in m2ts +Cunning Developments ADPCM decoder +asubboost filter +Pro Pinball Series Soundbank demuxer +pcm_rechunk bitstream filter +scdet filter +NotchLC decoder +gradients source video filter +MediaFoundation encoder wrapper +untile filter +Simon & Schuster Interactive ADPCM encoder +PFM decoder +dblur video filter +Real War KVAG muxer + + +We strongly recommend users, distributors, and system integrators to +upgrade unless they use current git master. + + October 5th, 2019, Bright Lights FFmpeg has added a realtime bright flash removal filter to libavfilter. --- Summary of changes: src/index | 85 +++ 1 file changed, 85 insertions(+) hooks/post-receive -- ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] [ffmpeg-web] branch master updated. c04853a web/documentation: shift external links to wiki page
The branch, master has been updated via c04853a37681d915ffb8590fb5095fceffa2347d (commit) from fb51859289ee3409ec458af626caa70363f39734 (commit) - Log - commit c04853a37681d915ffb8590fb5095fceffa2347d Author: Gyan Doshi AuthorDate: Wed Apr 7 14:09:05 2021 +0530 Commit: Gyan Doshi CommitDate: Wed Apr 7 14:09:05 2021 +0530 web/documentation: shift external links to wiki page diff --git a/src/documentation b/src/documentation index 060ef06..8ae5073 100644 --- a/src/documentation +++ b/src/documentation @@ -113,23 +113,7 @@ Community Contributed Documentation https://trac.ffmpeg.org/wiki";>Official FFmpeg Wiki -https://wiki.multimedia.cx/";>MultimediaWiki -http://dranger.com/ffmpeg/";>An FFmpeg and SDL Tutorial - by Stephen Dranger, explains how to write a video player based on FFmpeg. - - - - - - - - - Books about FFmpeg - -http://ffmpeg.tv";>FFmpeg Basics by Frantisek Korbel, - describes various FFmpeg features and common tasks. -http://book.chinaffmpeg.com";>FFmpeg Beginner's handbook Chinese Version by Steven Liu, -describes FFmpeg common use method in Chinese, from command line to API usage. +https://trac.ffmpeg.org/wiki/BooksAndOtherExternalResources";>Books and other external resources --- Summary of changes: src/documentation | 18 +- 1 file changed, 1 insertion(+), 17 deletions(-) hooks/post-receive -- ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] doc/muxers: fix alphabetical sorting of entries
ffmpeg | branch: master | Gyan Doshi | Wed Apr 7 14:59:44 2021 +0530| [c06465a70bd6e3a746f670e1d46d850d9233bfde] | committer: Gyan Doshi doc/muxers: fix alphabetical sorting of entries > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c06465a70bd6e3a746f670e1d46d850d9233bfde --- doc/muxers.texi | 348 1 file changed, 174 insertions(+), 174 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 4c6eac1f84..5826d7e986 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -178,37 +178,6 @@ and the input video converted to MPEG-2 video, use the command: ffmpeg -i INPUT -c:a pcm_u8 -c:v mpeg2video -f crc - @end example -@section flv - -Adobe Flash Video Format muxer. - -This muxer accepts the following options: - -@table @option - -@item flvflags @var{flags} -Possible values: - -@table @samp - -@item aac_seq_header_detect -Place AAC sequence header based on audio stream data. - -@item no_sequence_end -Disable sequence end tag. - -@item no_metadata -Disable metadata tag. - -@item no_duration_filesize -Disable duration and filesize in metadata when they are equal to zero -at the end of stream. (Be used to non-seekable living stream). - -@item add_keyframe_index -Used to facilitate seeking; particularly for HTTP pseudo streaming. -@end table -@end table - @anchor{dash} @section dash @@ -385,6 +354,137 @@ adjusting playback latency and buffer occupancy during normal playback by client @end table +@anchor{fifo} +@section fifo + +The fifo pseudo-muxer allows the separation of encoding and muxing by using +first-in-first-out queue and running the actual muxer in a separate thread. This +is especially useful in combination with the @ref{tee} muxer and can be used to +send data to several destinations with different reliability/writing speed/latency. + +API users should be aware that callback functions (interrupt_callback, +io_open and io_close) used within its AVFormatContext must be thread-safe. + +The behavior of the fifo muxer if the queue fills up or if the output fails is +selectable, + +@itemize @bullet + +@item +output can be transparently restarted with configurable delay between retries +based on real time or time of the processed stream. + +@item +encoding can be blocked during temporary failure, or continue transparently +dropping packets in case fifo queue fills up. + +@end itemize + +@table @option + +@item fifo_format +Specify the format name. Useful if it cannot be guessed from the +output name suffix. + +@item queue_size +Specify size of the queue (number of packets). Default value is 60. + +@item format_opts +Specify format options for the underlying muxer. Muxer options can be specified +as a list of @var{key}=@var{value} pairs separated by ':'. + +@item drop_pkts_on_overflow @var{bool} +If set to 1 (true), in case the fifo queue fills up, packets will be dropped +rather than blocking the encoder. This makes it possible to continue streaming without +delaying the input, at the cost of omitting part of the stream. By default +this option is set to 0 (false), so in such cases the encoder will be blocked +until the muxer processes some of the packets and none of them is lost. + +@item attempt_recovery @var{bool} +If failure occurs, attempt to recover the output. This is especially useful +when used with network output, since it makes it possible to restart streaming transparently. +By default this option is set to 0 (false). + +@item max_recovery_attempts +Sets maximum number of successive unsuccessful recovery attempts after which +the output fails permanently. By default this option is set to 0 (unlimited). + +@item recovery_wait_time @var{duration} +Waiting time before the next recovery attempt after previous unsuccessful +recovery attempt. Default value is 5 seconds. + +@item recovery_wait_streamtime @var{bool} +If set to 0 (false), the real time is used when waiting for the recovery +attempt (i.e. the recovery will be attempted after at least +recovery_wait_time seconds). +If set to 1 (true), the time of the processed stream is taken into account +instead (i.e. the recovery will be attempted after at least @var{recovery_wait_time} +seconds of the stream is omitted). +By default, this option is set to 0 (false). + +@item recover_any_error @var{bool} +If set to 1 (true), recovery will be attempted regardless of type of the error +causing the failure. By default this option is set to 0 (false) and in case of +certain (usually permanent) errors the recovery is not attempted even when +@var{attempt_recovery} is set to 1. + +@item restart_with_keyframe @var{bool} +Specify whether to wait for the keyframe after recovering from +queue overflow or failure. This option is set to 0 (false) by default. + +@item timeshift @var{duration} +Buffer the specified amount of packets and delay writing the output. Note that +@var{queue_size} must be big enough to store the packets for timeshift. At the +end of the in
[FFmpeg-cvslog] avformat/utils: add helper functions to retrieve index entries from an AVStream
ffmpeg | branch: master | James Almer | Tue Mar 23 15:36:22 2021 -0300| [557953a397dfdd9c7a3d8c2f60d1204599e3d3ac] | committer: James Almer avformat/utils: add helper functions to retrieve index entries from an AVStream Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=557953a397dfdd9c7a3d8c2f60d1204599e3d3ac --- doc/APIchanges | 4 libavformat/avformat.h | 39 +++ libavformat/utils.c| 27 +++ libavformat/version.h | 2 +- 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index b41dadee8d..9dfcc97d5c 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2017-10-21 API changes, most recent first: +2021-04-06 - xx - lavf 58.78.100 - avformat.h + Add avformat_index_get_entries_count(), avformat_index_get_entry(), + and avformat_index_get_entry_from_timestamp(). + 2021-03-21 - xx - lavu 56.72.100 - frame.h Deprecated av_get_colorspace_name(). Use av_color_space_name() instead. diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 765bc3b6f5..8600ee1bf7 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -2754,6 +2754,45 @@ int av_find_default_stream_index(AVFormatContext *s); */ int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); +/** + * Get the index entry count for the given AVStream. + * + * @param st stream + * @return the number of index entries in the stream + */ +int avformat_index_get_entries_count(const AVStream *st); + +/** + * Get the AVIndexEntry corresponding to the given index. + * + * @param st Stream containing the requested AVIndexEntry. + * @param idx The desired index. + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise. + * + * @note The pointer returned by this function is only guaranteed to be valid + * until any function that could alter the stream or the AVFormatContext + * that contains it is called. + */ +const AVIndexEntry *avformat_index_get_entry(const AVStream *st, int idx); + +/** + * Get the AVIndexEntry corresponding to the given timestamp. + * + * @param st Stream containing the requested AVIndexEntry. + * @param timestamp Timestamp to retrieve the index entry for. + * @param flags If AVSEEK_FLAG_BACKWARD then the returned entry will correspond + *to the timestamp which is <= the requested one, if backward + *is 0, then it will be >= + *if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise. + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise. + * + * @note The pointer returned by this function is only guaranteed to be valid + * until any function that could alter the stream or the AVFormatContext + * that contains it is called. + */ +const AVIndexEntry *avformat_index_get_entry_from_timestamp(const AVStream *st, +int64_t wanted_timestamp, +int flags); /** * Add an index entry into a sorted list. Update the entry if the list * already contains it. diff --git a/libavformat/utils.c b/libavformat/utils.c index 13b1bc7c78..b671fa75b3 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2164,6 +2164,33 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags) wanted_timestamp, flags); } +int avformat_index_get_entries_count(const AVStream *st) +{ +return st->internal->nb_index_entries; +} + +const AVIndexEntry *avformat_index_get_entry(const AVStream *st, int idx) +{ +if (idx < 0 || idx >= st->internal->nb_index_entries) +return NULL; + +return &st->internal->index_entries[idx]; +} + +const AVIndexEntry *avformat_index_get_entry_from_timestamp(const AVStream *st, +int64_t wanted_timestamp, +int flags) +{ +int idx = ff_index_search_timestamp(st->internal->index_entries, +st->internal->nb_index_entries, +wanted_timestamp, flags); + +if (idx < 0) +return NULL; + +return &st->internal->index_entries[idx]; +} + static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) { diff --git a/libavformat/version.h b/libavformat/version.h index ced5600034..b6023f9d2e 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Al
[FFmpeg-cvslog] avformat/url: fix ff_make_absolute_url with Windows file paths
ffmpeg | branch: master | Marton Balint | Fri Apr 2 17:07:54 2021 +0200| [5dc5f289cefe67457bd16f1950c56911e926385f] | committer: Marton Balint avformat/url: fix ff_make_absolute_url with Windows file paths Ugly, but a lot less broken than it was. Fixes ticket #9166. Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5dc5f289cefe67457bd16f1950c56911e926385f --- libavformat/url.c | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/libavformat/url.c b/libavformat/url.c index 77d610d95f..222d7d8a10 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -149,6 +149,18 @@ int ff_url_decompose(URLComponents *uc, const char *url, const char *end) return 0; } +static int is_fq_dos_path(const char *path) +{ +if ((path[0] >= 'a' && path[0] <= 'z' || path[0] >= 'A' && path[0] <= 'Z') && + path[1] == ':' && +(path[2] == '/' || path[2] == '\\')) +return 1; +if ((path[0] == '/' || path[0] == '\\') && +(path[1] == '/' || path[1] == '\\')) +return 1; +return 0; +} + static int append_path(char *root, char *out_end, char **rout, const char *in, const char *in_end) { @@ -185,6 +197,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base, char *out, *out_end, *path; const char *keep, *base_path_end; int use_base_path, simplify_path = 0, ret; +const char *base_separators = "/"; /* This is tricky. For HTTP, http://server/site/page + ../media/file @@ -211,6 +224,15 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (!base) base = ""; +if (HAVE_DOS_PATHS) { +if ((ret = ff_url_decompose(&ub, base, NULL)) < 0) +goto error; +if (is_fq_dos_path(base) || av_strstart(base, "file:", NULL) || ub.path == ub.url) { +base_separators = "/\\"; +if (is_fq_dos_path(rel)) +base = ""; +} +} if ((ret = ff_url_decompose(&ub, base, NULL)) < 0 || (ret = ff_url_decompose(&uc, rel, NULL)) < 0) goto error; @@ -249,7 +271,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (use_base_path) { base_path_end = ub.url_component_end_path; if (URL_COMPONENT_HAVE(uc, path)) -while (base_path_end > ub.path && base_path_end[-1] != '/') +while (base_path_end > ub.path && !strchr(base_separators, base_path_end[-1])) base_path_end--; } if (keep > ub.path) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/url: add ff_make_absolulte_url2 to be able to test windows path cases
ffmpeg | branch: master | Marton Balint | Tue Apr 6 01:10:30 2021 +0200| [fb4da90fecdefa2508618ca835cd0250be940e04] | committer: Marton Balint avformat/url: add ff_make_absolulte_url2 to be able to test windows path cases Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fb4da90fecdefa2508618ca835cd0250be940e04 --- libavformat/tests/url.c | 33 ++--- libavformat/url.c | 12 +--- libavformat/url.h | 10 ++ tests/ref/fate/url | 20 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c index 2eb597bb5e..8644a3e826 100644 --- a/libavformat/tests/url.c +++ b/libavformat/tests/url.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "libavformat/url.h" #include "libavformat/avformat.h" @@ -48,19 +49,30 @@ static void test_decompose(const char *url) static void test(const char *base, const char *rel) { -char buf[200], buf2[200]; +char buf[200], buf2[200], buf_dos[200], buf_native[200]; int ret; -ret = ff_make_absolute_url(buf, sizeof(buf), base, rel); +ret = ff_make_absolute_url2(buf, sizeof(buf), base, rel, 0); if (ret < 0) { printf("%50s %-20s => error %s\n", base, rel, av_err2str(ret)); return; } printf("%50s %-20s => %s\n", base, rel, buf); +ret = ff_make_absolute_url2(buf_dos, sizeof(buf_dos), base, rel, 1); +if (ret < 0) +snprintf(buf_dos, sizeof(buf_dos), "error %s", av_err2str(ret)); +ret = ff_make_absolute_url(buf_native, sizeof(buf_native), base, rel); +if (ret < 0) +snprintf(buf_native, sizeof(buf_native), "error %s", av_err2str(ret)); +if (strcmp(buf, buf_dos)) +printf("%50s %-20sDOS %s\n", base, rel, buf_dos); +if (HAVE_DOS_PATHS && strcmp(buf_dos, buf_native) || +!HAVE_DOS_PATHS && strcmp(buf, buf_native)) +printf("Native mismatch\n"); if (base) { /* Test in-buffer replacement */ snprintf(buf2, sizeof(buf2), "%s", base); -ff_make_absolute_url(buf2, sizeof(buf2), buf2, rel); +ff_make_absolute_url2(buf2, sizeof(buf2), buf2, rel, 0); if (strcmp(buf, buf2)) { printf("In-place handling of %s + %s failed\n", base, rel); exit(1); @@ -121,6 +133,21 @@ int main(void) test("http://server/foo/bar";, "..doubledotfile"); test("http://server/foo/bar";, "double..dotfile"); test("http://server/foo/bar";, "doubledotfile.."); +test("file1", "file2"); +test("dir/file1", "file2"); +test("dir/file1", "../file2"); +test("dir\\file1", "file2"); +test("srv\\shr\\file", "..\\..\\dummy"); +test("srv\\shr\\file", "dummy"); +test("srv\\shr\\file", "srv2\\shr2\\file2"); +test("srv\\shr\\file", "d:/file"); +test("C:\\dir\\a", "..\\file"); +test("C:\\dir\\a", "srv\\shr\\file"); +test("C:\\dir\\a", "d:\\file"); +test("http://a/b";, "srv\\shr\\file"); +test("http://a/b";, "//srv/shr/file"); +test("http://a/b";, "d:\\file"); +test("http://a/b";, "C:/file"); /* From https://tools.ietf.org/html/rfc3986#section-5.4 */ test("http://a/b/c/d;p?q";, "g:h"); // g:h diff --git a/libavformat/url.c b/libavformat/url.c index 222d7d8a10..f53fdf59d8 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -190,8 +190,8 @@ static int append_path(char *root, char *out_end, char **rout, return 0; } -int ff_make_absolute_url(char *buf, int size, const char *base, - const char *rel) +int ff_make_absolute_url2(char *buf, int size, const char *base, + const char *rel, int handle_dos_paths) { URLComponents ub, uc; char *out, *out_end, *path; @@ -224,7 +224,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (!base) base = ""; -if (HAVE_DOS_PATHS) { +if (handle_dos_paths) { if ((ret = ff_url_decompose(&ub, base, NULL)) < 0) goto error; if (is_fq_dos_path(base) || av_strstart(base, "file:", NULL) || ub.path == ub.url) { @@ -316,6 +316,12 @@ error: return ret; } +int ff_make_absolute_url(char *buf, int size, const char *base, + const char *rel) +{ +return ff_make_absolute_url2(buf, size, base, rel, HAVE_DOS_PATHS); +} + AVIODirEntry *ff_alloc_dir_entry(void) { AVIODirEntry *entry = av_mallocz(sizeof(AVIODirEntry)); diff --git a/libavformat/url.h b/libavformat/url.h index f13e851a14..3bb1cf89f7 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -308,6 +308,16 @@ int ff_url_join(char *str, int size, const char *proto, * @param size the size of buf * @param base the base url, may be equal to buf. * @param rel the new url, which is interpreted relative to base + * @para
[FFmpeg-cvslog] Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()"
ffmpeg | branch: master | Andreas Rheinhardt | Thu Dec 24 14:36:22 2020 +0100| [d4b9e117ceb6356cbcdc9ca81ec9c6c4b90efdae] | committer: Andreas Rheinhardt Revert "avcodec: add FF_CODEC_CAP_INIT_CLEANUP for all codecs which use ff_mpv_common_init()" This mostly reverts commit 4b2863ff01b1fe93d9a518523c9098d17a9d8c6f. Said commit removed the freeing code from ff_mpv_common_init(), ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use ff_mpv_common_init(). This introduced several bugs: a) Several decoders using ff_mpv_common_init() in their init function were forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as VC-1/WMV3. b) ff_mpv_common_init() is not only called from the init function of codecs, it is also called from AVCodec.decode functions. If an error happens after an allocation has succeeded, it can lead to memleaks; furthermore, it is now possible for the MpegEncContext to be marked as initialized even when ff_mpv_common_init() returns an error and this can lead to segfaults because decoders that call ff_mpv_common_init() when decoding a frame can mistakenly think that the MpegEncContext has been properly initialized. This can e.g. happen with H.261 or MPEG-4. c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't be called from any init function) can lead to segfaults because the check for whether it needs to allocate consists of checking whether the first of the buffers allocated there has been allocated. This part has already been fixed in 76cea1d2ce3f23e8131c8664086a1daf873ed694. d) ff_mpv_common_frame_size_change() can also not be reached from any AVCodec.init function; yet the changes can e.g. lead to segfaults with decoders using ff_h263_decode_frame() upon allocation failure, because the MpegEncContext will upon return be flagged as both initialized and not in need of reinitialization (granted, the fact that ff_h263_decode_frame() clears context_reinit before the context has been reinited is a bug in itself). With the earlier version, the context would be cleaned upon failure and it would be attempted to initialize the context again in the next call to ff_h263_decode_frame(). While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP, keeping the current approach would entail adding cleanup code to several other places because of b). Therefore ff_mpv_common_init() is again made to clean up after itself; the changes to the wmv2 decoder and the SVQ1 encoder have not been reverted: The former fixed a memleak, the latter allowed to remove cleanup code. Fixes: double free Fixes: ff_free_picture_tables.mp4 Fixes: ff_mpeg_update_thread_context.mp4 Fixes: decode_colskip.mp4 Fixes: memset.mp4 Reviewed-by: Michael Niedermayer Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d4b9e117ceb6356cbcdc9ca81ec9c6c4b90efdae --- libavcodec/h261dec.c | 2 +- libavcodec/h263dec.c | 4 ++-- libavcodec/mpeg12dec.c | 9 + libavcodec/mpeg4videodec.c | 3 +-- libavcodec/mpegvideo.c | 33 + libavcodec/msmpeg4dec.c| 8 libavcodec/rv10.c | 2 -- 7 files changed, 34 insertions(+), 27 deletions(-) diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 5c25aa9cb3..eb544e6046 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -678,6 +678,6 @@ AVCodec ff_h261_decoder = { .close = h261_decode_end, .decode = h261_decode_frame, .capabilities = AV_CODEC_CAP_DR1, -.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, +.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .max_lowres = 3, }; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index dafa54d8d4..e8b4d83e6e 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -771,7 +771,7 @@ AVCodec ff_h263_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, -.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, +.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, @@ -789,7 +789,7 @@ AVCodec ff_h263p_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, -.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, +.caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, diff --git a/libavcodec/mpeg12dec.c b/libavcod
[FFmpeg-cvslog] avcodec/mpegvideo: Fix memleak upon allocation error
ffmpeg | branch: master | Andreas Rheinhardt | Fri Dec 25 14:17:10 2020 +0100| [ff0706cde8b1a1f483e26c0ccac117c23b23d604] | committer: Andreas Rheinhardt avcodec/mpegvideo: Fix memleak upon allocation error When slice-threading is used, ff_mpv_common_init() duplicates the first MpegEncContext and allocates some buffers for each MpegEncContext (the first as well as the copies). But the count of allocated MpegEncContexts is not updated until after everything has been allocated and if an error happens after the first one has been allocated, only the first one is freed; the others leak. This commit fixes this: The count is now set before the copies are allocated. Furthermore, the copies are now created and initialized before the first MpegEncContext, so that the buffers exclusively owned by each MpegEncContext are still NULL in the src MpegEncContext so that no double-free happens upon allocation failure. Given that this effectively touches every line of the init code, it has also been factored out in a function of its own in order to remove code duplication with the same code in ff_mpv_common_frame_size_change() (which was never called when using more than one slice (and if it were, there would be potential double-frees)). Reviewed-by: Michael Niedermayer Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ff0706cde8b1a1f483e26c0ccac117c23b23d604 --- libavcodec/mpegvideo.c | 89 -- 1 file changed, 36 insertions(+), 53 deletions(-) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index e03f174024..7327204e99 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -366,13 +366,6 @@ static int init_duplicate_context(MpegEncContext *s) if (s->mb_height & 1) yc_size += 2*s->b8_stride + 2*s->mb_stride; -s->sc.edge_emu_buffer = -s->me.scratchpad = -s->me.temp = -s->sc.rd_scratchpad = -s->sc.b_scratchpad= -s->sc.obmc_scratchpad = NULL; - if (s->encoding) { if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) || !FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE)) @@ -413,6 +406,35 @@ static int init_duplicate_context(MpegEncContext *s) return 0; } +/** + * Initialize an MpegEncContext's thread contexts. Presumes that + * slice_context_count is already set and that all the fields + * that are freed/reset in free_duplicate_context() are NULL. + */ +static int init_duplicate_contexts(MpegEncContext *s) +{ +int nb_slices = s->slice_context_count, ret; + +/* We initialize the copies before the original so that + * fields allocated in init_duplicate_context are NULL after + * copying. This prevents double-frees upon allocation error. */ +for (int i = 1; i < nb_slices; i++) { +s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); +if (!s->thread_context[i]) +return AVERROR(ENOMEM); +if ((ret = init_duplicate_context(s->thread_context[i])) < 0) +return ret; +s->thread_context[i]->start_mb_y = +(s->mb_height * (i) + nb_slices / 2) / nb_slices; +s->thread_context[i]->end_mb_y = +(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; +} +s->start_mb_y = 0; +s->end_mb_y = nb_slices > 1 ? (s->mb_height + nb_slices / 2) / nb_slices + : s->mb_height; +return init_duplicate_context(s); +} + static void free_duplicate_context(MpegEncContext *s) { if (!s) @@ -949,29 +971,12 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) s->context_initialized = 1; memset(s->thread_context, 0, sizeof(s->thread_context)); s->thread_context[0] = s; +s->slice_context_count = nb_slices; // if (s->width && s->height) { -if (nb_slices > 1) { -for (i = 0; i < nb_slices; i++) { -if (i) { -s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); -if (!s->thread_context[i]) -goto fail_nomem; -} -if ((ret = init_duplicate_context(s->thread_context[i])) < 0) -goto fail; -s->thread_context[i]->start_mb_y = -(s->mb_height * (i) + nb_slices / 2) / nb_slices; -s->thread_context[i]->end_mb_y = -(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; -} -} else { -if ((ret = init_duplicate_context(s)) < 0) -goto fail; -s->start_mb_y = 0; -s->end_mb_y = s->mb_height; -} -s->slice_context_count = nb_slices; +ret = init_duplicate_contexts(s); +if (ret < 0) +goto fail; // } return 0; @@ -1088,31 +1093,9 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) s->thread_context[0] = s; if (s->width && s->height) { -int nb_slices = s->slice_context_count; -if (
[FFmpeg-cvslog] avcodec/rv10: Don't presume context to be initialized
ffmpeg | branch: master | Andreas Rheinhardt | Sun Apr 4 21:30:33 2021 +0200| [8ffd3ef9d94f33b411348c594a49d994b55c9550] | committer: Andreas Rheinhardt avcodec/rv10: Don't presume context to be initialized In case of resolution changes rv20_decode_picture_header() closes and reopens its MpegEncContext; it checks the latter for errors, yet when an error happens, it might happen that no new attempt at reinitialization is performed when decoding the next frame; this leads to crashes lateron. This commit fixes this by making sure that initialization will always be attempted if the context is currently not initialized. Reviewed-by: Michael Niedermayer Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8ffd3ef9d94f33b411348c594a49d994b55c9550 --- libavcodec/rv10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 89b838ad15..bd70689cab 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -226,7 +226,7 @@ static int rv20_decode_picture_header(RVDecContext *rv) new_w = rv->orig_width; new_h = rv->orig_height; } -if (new_w != s->width || new_h != s->height) { +if (new_w != s->width || new_h != s->height || !s->context_initialized) { AVRational old_aspect = s->avctx->sample_aspect_ratio; av_log(s->avctx, AV_LOG_DEBUG, "attempting to change resolution to %dx%d\n", new_w, new_h); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/mpegvideo: Factor common freeing code out
ffmpeg | branch: master | Andreas Rheinhardt | Fri Dec 25 14:57:38 2020 +0100| [9bab7de175d7c942a6ebddae6ba0cacdf360827e] | committer: Andreas Rheinhardt avcodec/mpegvideo: Factor common freeing code out Reviewed-by: Michael Niedermayer Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9bab7de175d7c942a6ebddae6ba0cacdf360827e --- libavcodec/mpegvideo.c | 36 +++- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 7327204e99..7eddbdcc37 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -457,6 +457,15 @@ static void free_duplicate_context(MpegEncContext *s) s->block = NULL; } +static void free_duplicate_contexts(MpegEncContext *s) +{ +for (int i = 1; i < s->slice_context_count; i++) { +free_duplicate_context(s->thread_context[i]); +av_freep(&s->thread_context[i]); +} +free_duplicate_context(s); +} + static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src) { #define COPY(a) bak->a = src->a @@ -988,7 +997,8 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) } /** - * Frees and resets MpegEncContext fields depending on the resolution. + * Frees and resets MpegEncContext fields depending on the resolution + * as well as the slice thread contexts. * Is used during resolution changes to avoid a full reinitialization of the * codec. */ @@ -996,6 +1006,8 @@ static void free_context_frame(MpegEncContext *s) { int i, j, k; +free_duplicate_contexts(s); + av_freep(&s->mb_type); av_freep(&s->p_mv_table_base); av_freep(&s->b_forw_mv_table_base); @@ -1048,16 +1060,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if (!s->context_initialized) return AVERROR(EINVAL); -if (s->slice_context_count > 1) { -for (i = 0; i < s->slice_context_count; i++) { -free_duplicate_context(s->thread_context[i]); -} -for (i = 1; i < s->slice_context_count; i++) { -av_freep(&s->thread_context[i]); -} -} else -free_duplicate_context(s); - free_context_frame(s); if (s->picture) @@ -1112,15 +1114,9 @@ void ff_mpv_common_end(MpegEncContext *s) if (!s) return; -if (s->slice_context_count > 1) { -for (i = 0; i < s->slice_context_count; i++) { -free_duplicate_context(s->thread_context[i]); -} -for (i = 1; i < s->slice_context_count; i++) { -av_freep(&s->thread_context[i]); -} +free_context_frame(s); +if (s->slice_context_count > 1) s->slice_context_count = 1; -} else free_duplicate_context(s); av_freep(&s->parse_context.buffer); s->parse_context.buffer_size = 0; @@ -1152,8 +1148,6 @@ void ff_mpv_common_end(MpegEncContext *s) ff_mpeg_unref_picture(s->avctx, &s->new_picture); av_frame_free(&s->new_picture.f); -free_context_frame(s); - s->context_initialized = 0; s->last_picture_ptr = s->next_picture_ptr = ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/rv34, mpegvideo: Fix segfault upon frame size change error
ffmpeg | branch: master | Andreas Rheinhardt | Mon Apr 5 02:05:58 2021 +0200| [9abda1365c5e2d827eb673b6d98245163c868bf1] | committer: Andreas Rheinhardt avcodec/rv34, mpegvideo: Fix segfault upon frame size change error The RealVideo 3.0 and 4.0 decoders call ff_mpv_common_init() only during their init function and not during decode_frame(); when the size of the frame changes, they call ff_mpv_common_frame_size_change(). Yet upon error, said function calls ff_mpv_common_end() which frees the whole MpegEncContext and not only those parts that ff_mpv_common_frame_size_change() reinits. As a result, the context will never be usable again; worse, because decode_frame() contains no check for whether the context is initialized or not, it is presumed that it is initialized, leading to segfaults. Basically the same happens if rv34_decoder_realloc() fails. This commit fixes this by only resetting the parts that ff_mpv_common_frame_size_change() changes upon error and by actually checking whether the context is in need of reinitialization in ff_rv34_decode_frame(). Reviewed-by: Michael Niedermayer Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9abda1365c5e2d827eb673b6d98245163c868bf1 --- libavcodec/mpegvideo.c | 6 -- libavcodec/rv34.c | 13 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 7eddbdcc37..5de0719f83 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -555,7 +555,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, } if (s->height != s1->height || s->width != s1->width || s->context_reinit) { -s->context_reinit = 0; s->height = s1->height; s->width = s1->width; if ((ret = ff_mpv_common_frame_size_change(s)) < 0) @@ -1099,10 +1098,12 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if (err < 0) goto fail; } +s->context_reinit = 0; return 0; fail: -ff_mpv_common_end(s); +free_context_frame(s); +s->context_reinit = 1; return err; } @@ -1149,6 +1150,7 @@ void ff_mpv_common_end(MpegEncContext *s) av_frame_free(&s->new_picture.f); s->context_initialized = 0; +s->context_reinit = 0; s->last_picture_ptr = s->next_picture_ptr = s->current_picture_ptr = NULL; diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 7e5bfe0e22..99e580a09a 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1383,6 +1383,7 @@ static int rv34_decoder_alloc(RV34DecContext *r) if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs && r->intra_types_hist && r->mb_type)) { +r->s.context_reinit = 1; rv34_decoder_free(r); return AVERROR(ENOMEM); } @@ -1530,7 +1531,7 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte if (dst == src || !s1->context_initialized) return 0; -if (s->height != s1->height || s->width != s1->width) { +if (s->height != s1->height || s->width != s1->width || s->context_reinit) { s->height = s1->height; s->width = s1->width; if ((err = ff_mpv_common_frame_size_change(s)) < 0) @@ -1667,11 +1668,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (s->mb_num_left > 0 && s->current_picture_ptr) { av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n", s->mb_num_left); -ff_er_frame_end(&s->er); +if (!s->context_reinit) +ff_er_frame_end(&s->er); ff_mpv_frame_end(s); } -if (s->width != si.width || s->height != si.height) { +if (s->width != si.width || s->height != si.height || s->context_reinit) { int err; av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n", @@ -1689,7 +1691,6 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, err = ff_set_dimensions(s->avctx, s->width, s->height); if (err < 0) return err; - if ((err = ff_mpv_common_frame_size_change(s)) < 0) return err; if ((err = rv34_decoder_realloc(r)) < 0) @@ -1744,6 +1745,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, } s->mb_x = s->mb_y = 0; ff_thread_finish_setup(s->avctx); +} else if (s->context_reinit) { +av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames to " + "reinitialize (start MB is %d).\n", si.start); +return AVERROR_INVALIDDATA; } else if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) { av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames in frame " ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mai
[FFmpeg-cvslog] avcodec/h261dec: Initialize IDCT context during init
ffmpeg | branch: master | Andreas Rheinhardt | Mon Apr 5 02:42:18 2021 +0200| [5106fe85f71459f0f293019e682edec0c3c26cee] | committer: Andreas Rheinhardt avcodec/h261dec: Initialize IDCT context during init Before 998c9f15d1ca8c7489775ebcca51623b915988f1, initializing an MpegEncContext's IDCT parts occured in ff_mpv_common_init() and this has been called in h261_decode_frame(), not h261_decode_init(). Yet said commit factored this out of ff_mpv_common_init() and therefore there is no reason any more not to set this during init as this commit does. Reviewed-by: Michael Niedermayer Signed-off-by: Andreas Rheinhardt > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5106fe85f71459f0f293019e682edec0c3c26cee --- libavcodec/h261dec.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index eb544e6046..0d8cd8c20d 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -79,6 +79,7 @@ static av_cold int h261_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV420P; h->gob_start_code_skipped = 0; +ff_mpv_idct_init(s); ff_thread_once(&init_static_once, h261_decode_init_static); @@ -595,10 +596,6 @@ static int h261_decode_frame(AVCodecContext *avctx, void *data, retry: init_get_bits(&s->gb, buf, buf_size * 8); -if (!s->context_initialized) -// we need the IDCT permutation for reading a custom matrix -ff_mpv_idct_init(s); - ret = h261_decode_picture_header(h); /* skip if the header was thrashed */ ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] lavfi/dnn_backend_openvino.c: only allow DFT_PROCESS_FRAME to get output dim
ffmpeg | branch: master | Guo, Yejun | Mon Mar 15 16:42:27 2021 +0800| [d2ccbc966b151f2500aa43e789288af188258ba3] | committer: Guo, Yejun lavfi/dnn_backend_openvino.c: only allow DFT_PROCESS_FRAME to get output dim > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d2ccbc966b151f2500aa43e789288af188258ba3 --- libavfilter/dnn/dnn_backend_openvino.c | 5 + 1 file changed, 5 insertions(+) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 9a47d74c15..66845fbd51 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -493,6 +493,11 @@ static DNNReturnType get_output_ov(void *model, const char *input_name, int inpu IEStatusCode status; input_shapes_t input_shapes; +if (ov_model->model->func_type != DFT_PROCESS_FRAME) { +av_log(ctx, AV_LOG_ERROR, "Get output dim only when processing frame.\n"); +return DNN_ERROR; +} + if (ctx->options.input_resizable) { status = ie_network_get_input_shapes(ov_model->network, &input_shapes); input_shapes.shapes->shape.dims[2] = input_height; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] lavfi/dnn: add post process for detection
ffmpeg | branch: master | Guo, Yejun | Tue Mar 9 14:51:42 2021 +0800| [13bf797ced0b527fa770d4b29884a5b0b8f19898] | committer: Guo, Yejun lavfi/dnn: add post process for detection > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=13bf797ced0b527fa770d4b29884a5b0b8f19898 --- libavfilter/dnn/dnn_backend_openvino.c | 30 +++--- libavfilter/dnn_filter_common.c| 6 ++ libavfilter/dnn_filter_common.h| 1 + libavfilter/dnn_interface.h| 3 +++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 3bea2d526a..0757727a9c 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -236,16 +236,32 @@ static void infer_completion_callback(void *args) av_assert0(request->task_count >= 1); for (int i = 0; i < request->task_count; ++i) { task = request->tasks[i]; -if (task->do_ioproc) { -if (task->ov_model->model->frame_post_proc != NULL) { -task->ov_model->model->frame_post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx); + +switch (task->ov_model->model->func_type) { +case DFT_PROCESS_FRAME: +if (task->do_ioproc) { +if (task->ov_model->model->frame_post_proc != NULL) { +task->ov_model->model->frame_post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx); +} else { +ff_proc_from_dnn_to_frame(task->out_frame, &output, ctx); +} } else { -ff_proc_from_dnn_to_frame(task->out_frame, &output, ctx); +task->out_frame->width = output.width; +task->out_frame->height = output.height; } -} else { -task->out_frame->width = output.width; -task->out_frame->height = output.height; +break; +case DFT_ANALYTICS_DETECT: +if (!task->ov_model->model->detect_post_proc) { +av_log(ctx, AV_LOG_ERROR, "detect filter needs to provide post proc\n"); +return; +} +task->ov_model->model->detect_post_proc(task->out_frame, &output, 1, task->ov_model->model->filter_ctx); +break; +default: +av_assert0(!"should not reach here"); +break; } + task->done = 1; output.data = (uint8_t *)output.data + output.width * output.height * output.channels * get_datatype_size(output.dt); diff --git a/libavfilter/dnn_filter_common.c b/libavfilter/dnn_filter_common.c index dc5966332a..1b922455a3 100644 --- a/libavfilter/dnn_filter_common.c +++ b/libavfilter/dnn_filter_common.c @@ -71,6 +71,12 @@ int ff_dnn_set_frame_proc(DnnContext *ctx, FramePrePostProc pre_proc, FramePrePo return 0; } +int ff_dnn_set_detect_post_proc(DnnContext *ctx, DetectPostProc post_proc) +{ +ctx->model->detect_post_proc = post_proc; +return 0; +} + DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input) { return ctx->model->get_input(ctx->model->model, input, ctx->model_inputname); diff --git a/libavfilter/dnn_filter_common.h b/libavfilter/dnn_filter_common.h index c611d594dc..8deb18b39a 100644 --- a/libavfilter/dnn_filter_common.h +++ b/libavfilter/dnn_filter_common.h @@ -49,6 +49,7 @@ typedef struct DnnContext { int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx); int ff_dnn_set_frame_proc(DnnContext *ctx, FramePrePostProc pre_proc, FramePrePostProc post_proc); +int ff_dnn_set_detect_post_proc(DnnContext *ctx, DetectPostProc post_proc); DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input); DNNReturnType ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height); DNNReturnType ff_dnn_execute_model(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame); diff --git a/libavfilter/dnn_interface.h b/libavfilter/dnn_interface.h index 3c7846f1a5..ae5a488341 100644 --- a/libavfilter/dnn_interface.h +++ b/libavfilter/dnn_interface.h @@ -64,6 +64,7 @@ typedef struct DNNData{ } DNNData; typedef int (*FramePrePostProc)(AVFrame *frame, DNNData *model, AVFilterContext *filter_ctx); +typedef int (*DetectPostProc)(AVFrame *frame, DNNData *output, uint32_t nb, AVFilterContext *filter_ctx); typedef struct DNNModel{ // Stores model that can be different for different backends. @@ -86,6 +87,8 @@ typedef struct DNNModel{ // set the post process to transfer data from DNNData to AVFrame // the default implementation within DNN is used if it is not provided by the filter FramePrePostProc frame_post_proc; +// set the post process to interpret detect result from DNNData +DetectPostProc detect_post_proc; } DNNModel; // Stores pointers to functions f
[FFmpeg-cvslog] lavfi/dnn: refine code for frame pre/proc processing
ffmpeg | branch: master | Guo, Yejun | Mon Mar 1 19:23:20 2021 +0800| [59021d79a24e28434f57376276625bc44eff340c] | committer: Guo, Yejun lavfi/dnn: refine code for frame pre/proc processing > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=59021d79a24e28434f57376276625bc44eff340c --- libavfilter/dnn/dnn_backend_native.c | 8 libavfilter/dnn/dnn_backend_openvino.c | 8 libavfilter/dnn/dnn_backend_tf.c | 8 libavfilter/dnn_filter_common.c| 7 +++ libavfilter/dnn_filter_common.h| 1 + libavfilter/dnn_interface.h| 6 -- 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_native.c b/libavfilter/dnn/dnn_backend_native.c index d8ae36c52d..d9762eeaf6 100644 --- a/libavfilter/dnn/dnn_backend_native.c +++ b/libavfilter/dnn/dnn_backend_native.c @@ -310,8 +310,8 @@ static DNNReturnType execute_model_native(const DNNModel *model, const char *inp input.data = oprd->data; input.dt = oprd->data_type; if (do_ioproc) { -if (native_model->model->pre_proc != NULL) { -native_model->model->pre_proc(in_frame, &input, native_model->model->filter_ctx); +if (native_model->model->frame_pre_proc != NULL) { +native_model->model->frame_pre_proc(in_frame, &input, native_model->model->filter_ctx); } else { ff_proc_from_frame_to_dnn(in_frame, &input, native_model->model->func_type, ctx); } @@ -358,8 +358,8 @@ static DNNReturnType execute_model_native(const DNNModel *model, const char *inp output.dt = oprd->data_type; if (do_ioproc) { -if (native_model->model->post_proc != NULL) { -native_model->model->post_proc(out_frame, &output, native_model->model->filter_ctx); +if (native_model->model->frame_post_proc != NULL) { +native_model->model->frame_post_proc(out_frame, &output, native_model->model->filter_ctx); } else { ff_proc_from_dnn_to_frame(out_frame, &output, ctx); } diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 66845fbd51..3bea2d526a 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -166,8 +166,8 @@ static DNNReturnType fill_model_input_ov(OVModel *ov_model, RequestItem *request for (int i = 0; i < request->task_count; ++i) { task = request->tasks[i]; if (task->do_ioproc) { -if (ov_model->model->pre_proc != NULL) { -ov_model->model->pre_proc(task->in_frame, &input, ov_model->model->filter_ctx); +if (ov_model->model->frame_pre_proc != NULL) { +ov_model->model->frame_pre_proc(task->in_frame, &input, ov_model->model->filter_ctx); } else { ff_proc_from_frame_to_dnn(task->in_frame, &input, ov_model->model->func_type, ctx); } @@ -237,8 +237,8 @@ static void infer_completion_callback(void *args) for (int i = 0; i < request->task_count; ++i) { task = request->tasks[i]; if (task->do_ioproc) { -if (task->ov_model->model->post_proc != NULL) { -task->ov_model->model->post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx); +if (task->ov_model->model->frame_post_proc != NULL) { +task->ov_model->model->frame_post_proc(task->out_frame, &output, task->ov_model->model->filter_ctx); } else { ff_proc_from_dnn_to_frame(task->out_frame, &output, ctx); } diff --git a/libavfilter/dnn/dnn_backend_tf.c b/libavfilter/dnn/dnn_backend_tf.c index c0aa510630..fb799d2b70 100644 --- a/libavfilter/dnn/dnn_backend_tf.c +++ b/libavfilter/dnn/dnn_backend_tf.c @@ -756,8 +756,8 @@ static DNNReturnType execute_model_tf(const DNNModel *model, const char *input_n input.data = (float *)TF_TensorData(input_tensor); if (do_ioproc) { -if (tf_model->model->pre_proc != NULL) { -tf_model->model->pre_proc(in_frame, &input, tf_model->model->filter_ctx); +if (tf_model->model->frame_pre_proc != NULL) { +tf_model->model->frame_pre_proc(in_frame, &input, tf_model->model->filter_ctx); } else { ff_proc_from_frame_to_dnn(in_frame, &input, tf_model->model->func_type, ctx); } @@ -818,8 +818,8 @@ static DNNReturnType execute_model_tf(const DNNModel *model, const char *input_n output.dt = TF_TensorType(output_tensors[i]); if (do_ioproc) { -if (tf_model->model->post_proc != NULL) { -tf_model->model->post_proc(out_frame, &output, tf_model->model->filter_ctx); +if (tf_model->model->frame_post_proc != NULL) { +tf_model->model->frame_post_proc(out_frame, &output, tf_model->model->filter_ctx); } else { ff_proc_f