[FFmpeg-cvslog] avcodec/get_bits: Document the return code of get_vlc2()
ffmpeg | branch: master | Michael Niedermayer| Sun Jan 28 02:29:01 2018 +0100| [4a94ff4ccd4f2329c599e37cabe4152dae60359e] | committer: Michael Niedermayer avcodec/get_bits: Document the return code of get_vlc2() Found-by: kierank Reviewed-by: Kieran Kunhya Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4a94ff4ccd4f2329c599e37cabe4152dae60359e --- libavcodec/get_bits.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index c530015169..0c7f5ff0c6 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -550,6 +550,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) * @param max_depth is the number of times bits bits must be read to completely * read the longest vlc code * = (max_vlc_length + bits - 1) / bits + * @returns the code parsed or -1 if no vlc matches */ static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/mpeg4videodec: Avoid possibly aliasing violating casts
ffmpeg | branch: master | Michael Niedermayer| Sun Jan 28 02:29:02 2018 +0100| [d4967c04e040b3b2f937cad88599af825147ec94] | committer: Michael Niedermayer avcodec/mpeg4videodec: Avoid possibly aliasing violating casts Found-by: kierank Reviewed-by: Kieran Kunhya Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d4967c04e040b3b2f937cad88599af825147ec94 --- libavcodec/mpeg4videodec.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index ba332de531..756753e2fc 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -1256,10 +1256,12 @@ not_coded: */ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) { -Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; +Mpeg4DecContext *ctx = s->avctx->priv_data; int cbp, mb_type; const int xy = s->mb_x + s->mb_y * s->mb_stride; +av_assert2(s == (void*)ctx); + mb_type = s->current_picture.mb_type[xy]; cbp = s->cbp_table[xy]; @@ -1341,12 +1343,13 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) { -Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; +Mpeg4DecContext *ctx = s->avctx->priv_data; int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; int16_t *mot_val; static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; const int xy = s->mb_x + s->mb_y * s->mb_stride; +av_assert2(s == (void*)ctx); av_assert2(s->h263_pred); if (s->pict_type == AV_PICTURE_TYPE_P || ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/mpeg4videodec: Check mb_num also against 0
ffmpeg | branch: master | Michael Niedermayer| Sun Jan 28 02:29:00 2018 +0100| [05f4703a168a336363750e32bcfdd6f303fbdbc3] | committer: Michael Niedermayer avcodec/mpeg4videodec: Check mb_num also against 0 The spec implies that 0 is invalid in addition to the existing checks Found-by: Reviewed-by: Kieran Kunhya Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=05f4703a168a336363750e32bcfdd6f303fbdbc3 --- libavcodec/mpeg4videodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 12755b5e8a..ba332de531 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -465,7 +465,7 @@ int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx) } mb_num = get_bits(>gb, mb_num_bits); -if (mb_num >= s->mb_num) { +if (mb_num >= s->mb_num || !mb_num) { av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); return -1; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] dashdec: Fix segfault on decoding segment timeline
ffmpeg | branch: master | Brendan McGrath| Mon Jan 29 10:46:50 2018 +0800| [4e3e8980b58fc22eb41c0e3cd3392bb4e6ca0184] | committer: Steven Liu dashdec: Fix segfault on decoding segment timeline If first_seq_no is not within the bounds of timelines then a segfault will occur. This patch removes the use of first_seq_no within the timelines array It also adds first_seq_no to the value returned by calc_next_seg_no_from_timelines (which allows for different values of 'startNumber') Signed-off-by: Brendan McGrath > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4e3e8980b58fc22eb41c0e3cd3392bb4e6ca0184 --- libavformat/dashdec.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index f4cbb065e9..f9dc033097 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1257,15 +1257,12 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls) if (pls->n_fragments) { num = pls->first_seq_no; } else if (pls->n_timelines) { -start_time_offset = get_segment_start_time_based_on_timeline(pls, 0x) - pls->timelines[pls->first_seq_no]->starttime; // total duration of playlist -if (start_time_offset < 60 * pls->fragment_timescale) -start_time_offset = 0; -else -start_time_offset = start_time_offset - 60 * pls->fragment_timescale; - -num = calc_next_seg_no_from_timelines(pls, pls->timelines[pls->first_seq_no]->starttime + start_time_offset); +start_time_offset = get_segment_start_time_based_on_timeline(pls, 0x) - 60 * pls->fragment_timescale; // 60 seconds before end +num = calc_next_seg_no_from_timelines(pls, start_time_offset); if (num == -1) num = pls->first_seq_no; +else +num += pls->first_seq_no; } else if (pls->fragment_duration){ if (pls->presentation_timeoffset) { num = pls->presentation_timeoffset * pls->fragment_timescale / pls->fragment_duration; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat: deprecate AVFormatContext filename field
ffmpeg | branch: master | Marton Balint| Fri Dec 29 01:19:37 2017 +0100| [fa8308d3d4f27d6fb38ac2069887a7b259f1c6ab] | committer: Marton Balint avformat: deprecate AVFormatContext filename field Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fa8308d3d4f27d6fb38ac2069887a7b259f1c6ab --- doc/APIchanges | 4 libavformat/avformat.h | 5 + libavformat/mux.c | 10 ++ libavformat/utils.c| 8 libavformat/version.h | 3 +++ 5 files changed, 30 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index 878429848d..6185545d56 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -16,6 +16,10 @@ libavutil: 2017-10-21 API changes, most recent first: 2018-01-xx - xxx - lavf 58.7.100 - avformat.h + Deprecate AVFormatContext filename field which had limited length, use the + new dynamically allocated url field instead. + +2018-01-xx - xxx - lavf 58.7.100 - avformat.h Add url field to AVFormatContext and add ff_format_set_url helper function. 2018-01-xx - xxx - lavf 58.6.100 - avformat.h diff --git a/libavformat/avformat.h b/libavformat/avformat.h index d1bd4902d0..82f9845337 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1394,13 +1394,18 @@ typedef struct AVFormatContext { */ AVStream **streams; +#if FF_API_FORMAT_FILENAME /** * input or output filename * * - demuxing: set by avformat_open_input() * - muxing: may be set by the caller before avformat_write_header() + * + * @deprecated Use url instead. */ +attribute_deprecated char filename[1024]; +#endif /** * input or output URL. Unlike the old filename field, this field has no diff --git a/libavformat/mux.c b/libavformat/mux.c index de63f2ca25..a13f0e3a1b 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -187,7 +187,11 @@ int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *ofor s->priv_data = NULL; if (filename) { +#if FF_API_FORMAT_FILENAME +FF_DISABLE_DEPRECATION_WARNINGS av_strlcpy(s->filename, filename, sizeof(s->filename)); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (!(s->url = av_strdup(filename))) goto nomem; @@ -255,7 +259,13 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) (ret = av_opt_set_dict2(s->priv_data, , AV_OPT_SEARCH_CHILDREN)) < 0) goto fail; +#if FF_API_FORMAT_FILENAME +FF_DISABLE_DEPRECATION_WARNINGS if (!s->url && !(s->url = av_strdup(s->filename))) { +FF_ENABLE_DEPRECATION_WARNINGS +#else +if (!s->url && !(s->url = av_strdup(""))) { +#endif ret = AVERROR(ENOMEM); goto fail; } diff --git a/libavformat/utils.c b/libavformat/utils.c index 0d722c69c8..28ea071409 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -560,7 +560,11 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, goto fail; } +#if FF_API_FORMAT_FILENAME +FF_DISABLE_DEPRECATION_WARNINGS av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename)); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if ((ret = init_input(s, filename, )) < 0) goto fail; s->probe_score = ret; @@ -5648,5 +5652,9 @@ void ff_format_set_url(AVFormatContext *s, char *url) av_assert0(url); av_freep(>url); s->url = url; +#if FF_API_FORMAT_FILENAME +FF_DISABLE_DEPRECATION_WARNINGS av_strlcpy(s->filename, url, sizeof(s->filename)); +FF_ENABLE_DEPRECATION_WARNINGS +#endif } diff --git a/libavformat/version.h b/libavformat/version.h index c375b0da15..897be0c2fe 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -85,6 +85,9 @@ #ifndef FF_API_LAVF_FFSERVER #define FF_API_LAVF_FFSERVER(LIBAVFORMAT_VERSION_MAJOR < 59) #endif +#ifndef FF_API_FORMAT_FILENAME +#define FF_API_FORMAT_FILENAME (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif #ifndef FF_API_R_FRAME_RATE ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat: add url field to AVFormatContext
ffmpeg | branch: master | Marton Balint| Fri Dec 29 01:01:37 2017 +0100| [ea3672b7d67c432724bdbc8de0221f869b6a04c6] | committer: Marton Balint avformat: add url field to AVFormatContext This will replace the 1024 character limited filename field. Compatiblity for output contexts are provided by copying filename field to URL if URL is unset and by providing an internal function for muxers to set both url and filename at once. Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ea3672b7d67c432724bdbc8de0221f869b6a04c6 --- doc/APIchanges | 3 +++ libavformat/avformat.h | 15 +++ libavformat/internal.h | 7 +++ libavformat/mux.c | 11 ++- libavformat/utils.c| 14 ++ libavformat/version.h | 2 +- 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 59e3b20c08..878429848d 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2017-10-21 API changes, most recent first: +2018-01-xx - xxx - lavf 58.7.100 - avformat.h + Add url field to AVFormatContext and add ff_format_set_url helper function. + 2018-01-xx - xxx - lavf 58.6.100 - avformat.h Add AVFMTCTX_UNSEEKABLE (for HLS demuxer). diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 60ab9fbc80..d1bd4902d0 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1403,6 +1403,21 @@ typedef struct AVFormatContext { char filename[1024]; /** + * input or output URL. Unlike the old filename field, this field has no + * length restriction. + * + * - demuxing: set by avformat_open_input(), initialized to an empty + * string if url parameter was NULL in avformat_open_input(). + * - muxing: may be set by the caller before calling avformat_write_header() + * (or avformat_init_output() if that is called first) to a string + * which is freeable by av_free(). Set to an empty string if it + * was NULL in avformat_init_output(). + * + * Freed by libavformat in avformat_free_context(). + */ +char *url; + +/** * Position of the first frame of the component, in * AV_TIME_BASE fractional seconds. NEVER set this value directly: * It is deduced from the AVStream values. diff --git a/libavformat/internal.h b/libavformat/internal.h index 0cd0556dc7..1e2a3e05a1 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -696,4 +696,11 @@ int ff_interleaved_peek(AVFormatContext *s, int stream, int ff_lock_avformat(void); int ff_unlock_avformat(void); +/** + * Set AVFormatContext url field to the provided pointer. The pointer must + * point to a valid string. The existing url field is freed if necessary. Also + * set the legacy filename field to the same string which was provided in url. + */ +void ff_format_set_url(AVFormatContext *s, char *url); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/mux.c b/libavformat/mux.c index ea9f13fdf5..de63f2ca25 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -186,8 +186,12 @@ int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *ofor } else s->priv_data = NULL; -if (filename) +if (filename) { av_strlcpy(s->filename, filename, sizeof(s->filename)); +if (!(s->url = av_strdup(filename))) +goto nomem; + +} *avctx = s; return 0; nomem: @@ -251,6 +255,11 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) (ret = av_opt_set_dict2(s->priv_data, , AV_OPT_SEARCH_CHILDREN)) < 0) goto fail; +if (!s->url && !(s->url = av_strdup(s->filename))) { +ret = AVERROR(ENOMEM); +goto fail; +} + #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) { diff --git a/libavformat/utils.c b/libavformat/utils.c index c15b8cc818..74e615f86e 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -555,6 +555,11 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, if ((ret = av_opt_set_dict(s, )) < 0) goto fail; +if (!(s->url = av_strdup(filename ? filename : ""))) { +ret = AVERROR(ENOMEM); +goto fail; +} + av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename)); if ((ret = init_input(s, filename, )) < 0) goto fail; @@ -4371,6 +4376,7 @@ void avformat_free_context(AVFormatContext *s) av_freep(>streams); flush_packet_queue(s); av_freep(>internal); +av_freep(>url); av_free(s); } @@ -5636,3 +5642,11 @@ FF_ENABLE_DEPRECATION_WARNINGS return st->internal->avctx->time_base; #endif } + +void ff_format_set_url(AVFormatContext *s, char *url) +{ +av_assert0(url); +av_freep(>url); +s->url = url; +
[FFmpeg-cvslog] avformat/hls: migrate to AVFormatContext->url
ffmpeg | branch: master | Marton Balint| Fri Dec 29 22:00:04 2017 +0100| [45ec2e44be911da073b02ae3a14e3cb08ce0a1f5] | committer: Marton Balint avformat/hls: migrate to AVFormatContext->url Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=45ec2e44be911da073b02ae3a14e3cb08ce0a1f5 --- libavformat/hls.c| 4 +- libavformat/hlsenc.c | 166 +-- 2 files changed, 96 insertions(+), 74 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 02e764f932..ba7eb94121 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1682,7 +1682,7 @@ static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url, av_log(s, AV_LOG_ERROR, "A HLS playlist item '%s' referred to an external file '%s'. " "Opening this file was forbidden for security reasons\n", - s->filename, url); + s->url, url); return AVERROR(EPERM); } @@ -1820,7 +1820,7 @@ static int hls_read_header(AVFormatContext *s) update_options(>http_proxy, "http_proxy", u); } -if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0) +if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0) goto fail; if ((ret = save_avio_options(s)) < 0) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index d7f8ab5037..cc13c94e97 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -292,7 +292,7 @@ static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c) { -int http_base_proto = ff_is_http_proto(s->filename); +int http_base_proto = ff_is_http_proto(s->url); if (c->method) { av_dict_set(options, "method", c->method, 0); @@ -467,7 +467,7 @@ static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, if (hls->segment_filename) { dirname = av_strdup(hls->segment_filename); } else { -dirname = av_strdup(vs->avf->filename); +dirname = av_strdup(vs->avf->url); } if (!dirname) { ret = AVERROR(ENOMEM); @@ -494,7 +494,7 @@ static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, av_strlcat(path, segment->filename, path_size); } -proto = avio_find_protocol_name(s->filename); +proto = avio_find_protocol_name(s->url); if (hls->method || (proto && !av_strcasecmp(proto, "http"))) { av_dict_set(, "method", "DELETE", 0); if ((ret = vs->avf->io_open(vs->avf, , path, AVIO_FLAG_WRITE, )) < 0) @@ -564,12 +564,12 @@ static int do_encrypt(AVFormatContext *s, VariantStream *vs) AVIOContext *pb; uint8_t key[KEYSIZE]; -len = strlen(s->filename) + 4 + 1; +len = strlen(s->url) + 4 + 1; hls->key_basename = av_mallocz(len); if (!hls->key_basename) return AVERROR(ENOMEM); -av_strlcpy(hls->key_basename, s->filename, len); +av_strlcpy(hls->key_basename, s->url, len); av_strlcat(hls->key_basename, ".key", len); if (hls->key_url) { @@ -699,7 +699,10 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs) return ret; oc = vs->avf; -oc->filename[0]= '\0'; +oc->url= av_strdup(""); +if (!oc->url) +return AVERROR(ENOMEM); + oc->oformat= vs->oformat; oc->interrupt_callback = s->interrupt_callback; oc->max_delay = s->max_delay; @@ -808,35 +811,38 @@ static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls { if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) && strlen(vs->current_segment_final_filename_fmt)) { -av_strlcpy(vs->avf->filename, vs->current_segment_final_filename_fmt, sizeof(vs->avf->filename)); +char * new_url = av_strdup(vs->current_segment_final_filename_fmt); +if (!new_url) { +av_free(en); +return AVERROR(ENOMEM); +} +ff_format_set_url(vs->avf, new_url); if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) { char *filename = NULL; -if (replace_int_data_in_filename(, vs->avf->filename, 's', pos + size) < 1) { +if (replace_int_data_in_filename(, vs->avf->url, 's', pos + size) < 1) { av_log(hls, AV_LOG_ERROR, "Invalid second level segment filename template '%s', " "you can try to remove second_level_segment_size flag\n", - filename); + vs->avf->url); av_free(filename); av_free(en); return AVERROR(EINVAL); } -av_strlcpy(vs->avf->filename, filename, sizeof(vs->avf->filename)); -
[FFmpeg-cvslog] avdevice: migrate to AVFormatContext->url
ffmpeg | branch: master | Marton Balint| Fri Dec 29 23:29:52 2017 +0100| [4bb04098204afadc8604af0113294f8ecc63a2de] | committer: Marton Balint avdevice: migrate to AVFormatContext->url Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4bb04098204afadc8604af0113294f8ecc63a2de --- libavdevice/alsa.c | 4 ++-- libavdevice/avfoundation.m | 2 +- libavdevice/bktr.c | 2 +- libavdevice/caca.c | 2 +- libavdevice/decklink_common.cpp | 2 +- libavdevice/decklink_dec.cpp| 4 ++-- libavdevice/decklink_enc.cpp| 4 ++-- libavdevice/dshow.c | 2 +- libavdevice/fbdev_dec.c | 4 ++-- libavdevice/fbdev_enc.c | 4 ++-- libavdevice/gdigrab.c | 2 +- libavdevice/iec61883.c | 8 libavdevice/jack.c | 6 +++--- libavdevice/lavfi.c | 2 +- libavdevice/libcdio.c | 6 +++--- libavdevice/libndi_newtek_dec.c | 2 +- libavdevice/libndi_newtek_enc.c | 4 ++-- libavdevice/openal-dec.c| 2 +- libavdevice/opengl_enc.c| 2 +- libavdevice/oss_dec.c | 2 +- libavdevice/oss_enc.c | 2 +- libavdevice/pulse_audio_dec.c | 4 ++-- libavdevice/pulse_audio_enc.c | 4 ++-- libavdevice/sdl2.c | 2 +- libavdevice/sndio_dec.c | 2 +- libavdevice/sndio_enc.c | 2 +- libavdevice/v4l2.c | 16 +--- libavdevice/v4l2enc.c | 4 ++-- libavdevice/vfwcap.c| 4 ++-- libavdevice/xcbgrab.c | 8 libavdevice/xv.c| 2 +- 31 files changed, 59 insertions(+), 57 deletions(-) diff --git a/libavdevice/alsa.c b/libavdevice/alsa.c index 1bbff30d5c..1b21beb6d5 100644 --- a/libavdevice/alsa.c +++ b/libavdevice/alsa.c @@ -177,8 +177,8 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, snd_pcm_uframes_t buffer_size, period_size; uint64_t layout = ctx->streams[0]->codecpar->channel_layout; -if (ctx->filename[0] == 0) audio_device = "default"; -else audio_device = ctx->filename; +if (ctx->url[0] == 0) audio_device = "default"; +else audio_device = ctx->url; if (*codec_id == AV_CODEC_ID_NONE) *codec_id = DEFAULT_CODEC_ID; diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m index e2ddf47dbe..a540f6a079 100644 --- a/libavdevice/avfoundation.m +++ b/libavdevice/avfoundation.m @@ -259,7 +259,7 @@ static void destroy_context(AVFContext* ctx) static void parse_device_name(AVFormatContext *s) { AVFContext *ctx = (AVFContext*)s->priv_data; -char *tmp = av_strdup(s->filename); +char *tmp = av_strdup(s->url); char *save; if (tmp[0] != ':') { diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c index 418247dc4e..993cc19ac7 100644 --- a/libavdevice/bktr.c +++ b/libavdevice/bktr.c @@ -294,7 +294,7 @@ static int grab_read_header(AVFormatContext *s1) st->codecpar->height = s->height; st->avg_frame_rate = framerate; -if (bktr_init(s1->filename, s->width, s->height, s->standard, +if (bktr_init(s1->url, s->width, s->height, s->standard, >video_fd, >tuner_fd, -1, 0.0) < 0) { ret = AVERROR(EIO); goto out; diff --git a/libavdevice/caca.c b/libavdevice/caca.c index 93cc0ffd25..47de8247dc 100644 --- a/libavdevice/caca.c +++ b/libavdevice/caca.c @@ -178,7 +178,7 @@ static int caca_write_header(AVFormatContext *s) } if (!c->window_title) -c->window_title = av_strdup(s->filename); +c->window_title = av_strdup(s->url); caca_set_display_title(c->display, c->window_title); caca_set_display_time(c->display, av_rescale_q(1, st->codec->time_base, AV_TIME_BASE_Q)); diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index d1576b8553..da414ed5f8 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -404,7 +404,7 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct } av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription", - avctx->filename); + avctx->url); while (itermode->Next() == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(_num, _den); diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index a69e28680b..5c116f2d13 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -951,7 +951,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) cctx->raw_format = MKBETAG('v','2','1','0'); } -strcpy (fname, avctx->filename); +av_strlcpy(fname, avctx->url, sizeof(fname)); tmp=strchr (fname, '@'); if (tmp != NULL) { av_log(avctx, AV_LOG_WARNING, "The @mode syntax is deprecated and will be
[FFmpeg-cvslog] fftools, tools, examples: migrate to AVFormatContext->url
ffmpeg | branch: master | Marton Balint| Fri Dec 29 23:29:27 2017 +0100| [25a2d269bdd919e633e202b67927c3c72f9f0dd5] | committer: Marton Balint fftools, tools, examples: migrate to AVFormatContext->url Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=25a2d269bdd919e633e202b67927c3c72f9f0dd5 --- doc/examples/transcode_aac.c | 7 +-- fftools/ffmpeg.c | 16 fftools/ffmpeg_opt.c | 8 fftools/ffplay.c | 6 +++--- fftools/ffprobe.c| 2 +- tools/uncoded_frame.c| 2 +- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c index 9fd5c00d60..3c7688cd33 100644 --- a/doc/examples/transcode_aac.c +++ b/doc/examples/transcode_aac.c @@ -171,8 +171,11 @@ static int open_output_file(const char *filename, goto cleanup; } -av_strlcpy((*output_format_context)->filename, filename, - sizeof((*output_format_context)->filename)); +if (!((*output_format_context)->url = av_strdup(filename))) { +fprintf(stderr, "Could not allocate url.\n"); +error = AVERROR(ENOMEM); +goto cleanup; +} /* Find the encoder to be used by its name. */ if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) { diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 918eb353aa..a37de2ff98 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1563,7 +1563,7 @@ static void print_final_stats(int64_t total_size) uint64_t total_packets = 0, total_size = 0; av_log(NULL, AV_LOG_VERBOSE, "Input file #%d (%s):\n", - i, f->ctx->filename); + i, f->ctx->url); for (j = 0; j < f->nb_streams; j++) { InputStream *ist = input_streams[f->ist_index + j]; @@ -1597,7 +1597,7 @@ static void print_final_stats(int64_t total_size) uint64_t total_packets = 0, total_size = 0; av_log(NULL, AV_LOG_VERBOSE, "Output file #%d (%s):\n", - i, of->ctx->filename); + i, of->ctx->url); for (j = 0; j < of->ctx->nb_streams; j++) { OutputStream *ost = output_streams[of->ost_index + j]; @@ -2105,7 +2105,7 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) if (exit_on_error && *got_output && ist) { if (ist->decoded_frame->decode_error_flags || (ist->decoded_frame->flags & AV_FRAME_FLAG_CORRUPT)) { -av_log(NULL, AV_LOG_FATAL, "%s: corrupt decoded frame in stream %d\n", input_files[ist->file_index]->ctx->filename, ist->st->index); +av_log(NULL, AV_LOG_FATAL, "%s: corrupt decoded frame in stream %d\n", input_files[ist->file_index]->ctx->url, ist->st->index); exit_program(1); } } @@ -2989,7 +2989,7 @@ static int check_init_output_file(OutputFile *of, int file_index) //assert_avoptions(of->opts); of->header_written = 1; -av_dump_format(of->ctx, file_index, of->ctx->filename, 1); +av_dump_format(of->ctx, file_index, of->ctx->url, 1); if (sdp_filename || want_sdp) print_sdp(); @@ -4252,7 +4252,7 @@ static int process_input(int file_index) } if (ret < 0) { if (ret != AVERROR_EOF) { -print_error(is->filename, ret); +print_error(is->url, ret); if (exit_on_error) exit_program(1); } @@ -4301,7 +4301,7 @@ static int process_input(int file_index) goto discard_packet; if (exit_on_error && (pkt.flags & AV_PKT_FLAG_CORRUPT)) { -av_log(NULL, AV_LOG_FATAL, "%s: corrupt input packet in stream %d\n", is->filename, pkt.stream_index); +av_log(NULL, AV_LOG_FATAL, "%s: corrupt input packet in stream %d\n", is->url, pkt.stream_index); exit_program(1); } @@ -4668,11 +4668,11 @@ static int transcode(void) av_log(NULL, AV_LOG_ERROR, "Nothing was written into output file %d (%s), because " "at least one of its streams received no packets.\n", - i, os->filename); + i, os->url); continue; } if ((ret = av_write_trailer(os)) < 0) { -av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", os->filename, av_err2str(ret)); +av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", os->url, av_err2str(ret)); if (exit_on_error) exit_program(1); } diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 92199b3ac2..997d538381 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -1271,7 +1271,7 @@ static int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *o if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
[FFmpeg-cvslog] avformat/hlsenc: use av_bprintf without buffer limit in replace_int_data_in_filename
ffmpeg | branch: master | Marton Balint| Sat Jan 6 18:41:27 2018 +0100| [dc5d1515681b57a257443ba72bb81fb3e6e6621b] | committer: Marton Balint avformat/hlsenc: use av_bprintf without buffer limit in replace_int_data_in_filename In preparation for the deprecation of AVFormatContext->filename. Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dc5d1515681b57a257443ba72bb81fb3e6e6621b --- libavformat/hlsenc.c | 113 ++- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index aab21f2f5e..d7f8ab5037 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -352,14 +352,17 @@ fail: return; } -static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number) +static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number) { const char *p; -char *q, buf1[20], c; -int nd, len, addchar_count; +char *new_filename; +char c; +int nd, addchar_count; int found_count = 0; +AVBPrint buf; + +av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED); -q = buf; p = filename; for (;;) { c = *p; @@ -376,13 +379,7 @@ static int replace_int_data_in_filename(char *buf, int buf_size, const char *fil } if (*(p + addchar_count) == placeholder) { -len = snprintf(buf1, sizeof(buf1), "%0*"PRId64, (number < 0) ? nd : nd++, number); -if (len < 1) // returned error or empty buf1 -goto fail; -if ((q - buf + len) > buf_size - 1) -goto fail; -memcpy(q, buf1, len); -q += len; +av_bprintf(, "%0*"PRId64, (number < 0) ? nd : nd++, number); p += (addchar_count + 1); addchar_count = 0; found_count++; @@ -391,17 +388,17 @@ static int replace_int_data_in_filename(char *buf, int buf_size, const char *fil } else addchar_count = 1; -while (addchar_count--) -if ((q - buf) < buf_size - 1) -*q++ = *p++; -else -goto fail; +av_bprint_append_data(, p, addchar_count); +p += addchar_count; } -*q = '\0'; +if (!av_bprint_is_complete()) { +av_bprint_finalize(, NULL); +return -1; +} +if (av_bprint_finalize(, _filename) < 0 || !new_filename) +return -1; +*s = new_filename; return found_count; -fail: -*q = '\0'; -return -1; } static void write_styp(AVIOContext *pb) @@ -813,13 +810,8 @@ static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls strlen(vs->current_segment_final_filename_fmt)) { av_strlcpy(vs->avf->filename, vs->current_segment_final_filename_fmt, sizeof(vs->avf->filename)); if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) { -char * filename = av_strdup(vs->avf->filename); // %%s will be %s after strftime -if (!filename) { -av_free(en); -return AVERROR(ENOMEM); -} -if (replace_int_data_in_filename(vs->avf->filename, sizeof(vs->avf->filename), -filename, 's', pos + size) < 1) { +char *filename = NULL; +if (replace_int_data_in_filename(, vs->avf->filename, 's', pos + size) < 1) { av_log(hls, AV_LOG_ERROR, "Invalid second level segment filename template '%s', " "you can try to remove second_level_segment_size flag\n", @@ -828,16 +820,13 @@ static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls av_free(en); return AVERROR(EINVAL); } +av_strlcpy(vs->avf->filename, filename, sizeof(vs->avf->filename)); av_free(filename); } if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) { -char * filename = av_strdup(vs->avf->filename); // %%t will be %t after strftime -if (!filename) { -av_free(en); -return AVERROR(ENOMEM); -} -if (replace_int_data_in_filename(vs->avf->filename, sizeof(vs->avf->filename), -filename, 't', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) { +char *filename = NULL; +if (replace_int_data_in_filename(, vs->avf->filename, +'t', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) { av_log(hls, AV_LOG_ERROR, "Invalid second level segment filename template '%s', " "you can try to remove second_level_segment_time flag\n", @@ -846,6 +835,7 @@ static int
[FFmpeg-cvslog] avformat: migrate to AVFormatContext->url
ffmpeg | branch: master | Marton Balint| Fri Dec 29 23:30:14 2017 +0100| [18ac64235939c4c5c7656546a9545f68339affbe] | committer: Marton Balint avformat: migrate to AVFormatContext->url Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=18ac64235939c4c5c7656546a9545f68339affbe --- libavformat/concatdec.c | 4 ++-- libavformat/dashenc.c| 16 libavformat/fifo.c | 8 libavformat/flvenc.c | 4 ++-- libavformat/gxfenc.c | 4 ++-- libavformat/hdsenc.c | 24 libavformat/img2dec.c| 4 ++-- libavformat/img2enc.c| 4 ++-- libavformat/matroskadec.c| 4 ++-- libavformat/mlvdec.c | 4 ++-- libavformat/mov.c| 2 +- libavformat/movenc.c | 10 +- libavformat/mpeg.c | 4 ++-- libavformat/mpegtsenc.c | 2 +- libavformat/options.c| 2 +- libavformat/rtsp.c | 18 -- libavformat/rtspdec.c| 4 ++-- libavformat/rtspenc.c| 4 +++- libavformat/sapdec.c | 2 +- libavformat/sapenc.c | 10 -- libavformat/sdp.c| 4 ++-- libavformat/segment.c| 36 +--- libavformat/smoothstreamingenc.c | 12 ++-- libavformat/tee.c| 4 ++-- libavformat/utils.c | 2 +- libavformat/webm_chunk.c | 10 +- 26 files changed, 111 insertions(+), 91 deletions(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index bd5174ada2..178fac86cb 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -126,10 +126,10 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, url = filename; filename = NULL; } else { -url_len = strlen(avf->filename) + strlen(filename) + 16; +url_len = strlen(avf->url) + strlen(filename) + 16; if (!(url = av_malloc(url_len))) FAIL(AVERROR(ENOMEM)); -ff_make_absolute_url(url, url_len, avf->filename, filename); +ff_make_absolute_url(url, url_len, avf->url, filename); av_freep(); } diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index d1e4d7466a..0f6f4f22fa 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -692,7 +692,7 @@ static int write_manifest(AVFormatContext *s, int final) AVIOContext *out; char temp_filename[1024]; int ret, i; -const char *proto = avio_find_protocol_name(s->filename); +const char *proto = avio_find_protocol_name(s->url); int use_rename = proto && !strcmp(proto, "file"); static unsigned int warned_non_file = 0; AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); @@ -701,7 +701,7 @@ static int write_manifest(AVFormatContext *s, int final) if (!use_rename && !warned_non_file++) av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n"); -snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename); +snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->url); set_http_options(, c); ret = dashenc_io_open(s, >mpd_out, temp_filename, ); if (ret < 0) { @@ -778,7 +778,7 @@ static int write_manifest(AVFormatContext *s, int final) dashenc_io_close(s, >mpd_out, temp_filename); if (use_rename) { -if ((ret = avpriv_io_move(temp_filename, s->filename)) < 0) +if ((ret = avpriv_io_move(temp_filename, s->url)) < 0) return ret; } @@ -859,14 +859,14 @@ static int dash_init(AVFormatContext *s) if (c->single_file) c->use_template = 0; -av_strlcpy(c->dirname, s->filename, sizeof(c->dirname)); +av_strlcpy(c->dirname, s->url, sizeof(c->dirname)); ptr = strrchr(c->dirname, '/'); if (ptr) { av_strlcpy(basename, [1], sizeof(basename)); ptr[1] = '\0'; } else { c->dirname[0] = '\0'; -av_strlcpy(basename, s->filename, sizeof(basename)); +av_strlcpy(basename, s->url, sizeof(basename)); } ptr = strrchr(basename, '.'); @@ -1025,7 +1025,7 @@ static int dash_write_header(AVFormatContext *s) } ret = write_manifest(s, 0); if (!ret) -av_log(s, AV_LOG_VERBOSE, "Manifest written to: %s\n", s->filename); +av_log(s, AV_LOG_VERBOSE, "Manifest written to: %s\n", s->url); return ret; } @@ -1124,7 +1124,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) DASHContext *c = s->priv_data; int i, ret = 0; -const char *proto = avio_find_protocol_name(s->filename); +const char *proto = avio_find_protocol_name(s->url); int use_rename = proto &&
[FFmpeg-cvslog] avcodec/utvideoenc : add SIMD (avx) for sub_left_prediction
ffmpeg | branch: master | Martin Vignali| Sun Jan 14 14:23:05 2018 +0100| [8f9c38b19629838066def1207703cfcdc19fcbc9] | committer: Martin Vignali avcodec/utvideoenc : add SIMD (avx) for sub_left_prediction asm code by Henrik Gramner > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8f9c38b19629838066def1207703cfcdc19fcbc9 --- libavcodec/lossless_videoencdsp.c | 15 +++ libavcodec/lossless_videoencdsp.h | 5 libavcodec/utvideoenc.c| 20 +- libavcodec/x86/lossless_videoencdsp.asm| 43 ++ libavcodec/x86/lossless_videoencdsp_init.c | 7 + 5 files changed, 71 insertions(+), 19 deletions(-) diff --git a/libavcodec/lossless_videoencdsp.c b/libavcodec/lossless_videoencdsp.c index 5cc4934c0e..ed70329628 100644 --- a/libavcodec/lossless_videoencdsp.c +++ b/libavcodec/lossless_videoencdsp.c @@ -74,10 +74,25 @@ static void sub_median_pred_c(uint8_t *dst, const uint8_t *src1, *left_top = lt; } +static void sub_left_predict_c(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, ptrdiff_t width, int height) +{ +int i, j; +uint8_t prev = 0x80; /* Set the initial value */ +for (j = 0; j < height; j++) { +for (i = 0; i < width; i++) { +*dst++ = src[i] - prev; +prev = src[i]; +} +src += stride; +} +} + av_cold void ff_llvidencdsp_init(LLVidEncDSPContext *c) { c->diff_bytes = diff_bytes_c; c->sub_median_pred = sub_median_pred_c; +c->sub_left_predict = sub_left_predict_c; if (ARCH_X86) ff_llvidencdsp_init_x86(c); diff --git a/libavcodec/lossless_videoencdsp.h b/libavcodec/lossless_videoencdsp.h index 3d645b159a..faa6c32551 100644 --- a/libavcodec/lossless_videoencdsp.h +++ b/libavcodec/lossless_videoencdsp.h @@ -21,6 +21,8 @@ #include +#include "avcodec.h" + typedef struct LLVidEncDSPContext { void (*diff_bytes)(uint8_t *dst /* align 16 */, const uint8_t *src1 /* align 16 */, @@ -33,6 +35,9 @@ typedef struct LLVidEncDSPContext { void (*sub_median_pred)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, intptr_t w, int *left, int *left_top); + +void (*sub_left_predict)(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, ptrdiff_t width, int height); } LLVidEncDSPContext; void ff_llvidencdsp_init(LLVidEncDSPContext *c); diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index a829b7aaac..db00e1eff5 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -283,23 +283,6 @@ static void mangle_rgb_planes(uint8_t *dst[4], ptrdiff_t dst_stride, } } -/* Write data to a plane with left prediction */ -static void left_predict(uint8_t *src, uint8_t *dst, ptrdiff_t stride, - int width, int height) -{ -int i, j; -uint8_t prev; - -prev = 0x80; /* Set the initial value */ -for (j = 0; j < height; j++) { -for (i = 0; i < width; i++) { -*dst++ = src[i] - prev; -prev = src[i]; -} -src += stride; -} -} - #undef A #undef B @@ -436,8 +419,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, for (i = 0; i < c->slices; i++) { sstart = send; send = height * (i + 1) / c->slices & cmask; -left_predict(src + sstart * stride, dst + sstart * width, - stride, width, send - sstart); +c->llvidencdsp.sub_left_predict(dst + sstart * width, src + sstart * stride, stride, width, send - sstart); } break; case PRED_MEDIAN: diff --git a/libavcodec/x86/lossless_videoencdsp.asm b/libavcodec/x86/lossless_videoencdsp.asm index 4d79eee36b..fb1204f0f1 100644 --- a/libavcodec/x86/lossless_videoencdsp.asm +++ b/libavcodec/x86/lossless_videoencdsp.asm @@ -25,6 +25,8 @@ %include "libavutil/x86/x86util.asm" +cextern pb_80 + SECTION .text ; void ff_diff_bytes(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, @@ -149,3 +151,44 @@ DIFF_BYTES_PROLOGUE DIFF_BYTES_BODYu, u %undef i %endif + + +;-- +;void sub_left_predict(uint8_t *dst, uint8_t *src, ptrdiff_t stride, ptrdiff_t width, int height) +;-- + +INIT_XMM avx +cglobal sub_left_predict, 5,6,5, dst, src, stride, width, height, x +mova m1, [pb_80] ; prev initial +adddstq, widthq +addsrcq, widthq +lea xd, [widthq-1] +neg widthq +and xd, 15 +pinsrb m4, m1, xd, 15 +mov xq, widthq + +.loop: +movu m0,
[FFmpeg-cvslog] checkasm : add test for losslessvideoencdsp for diff bytes and sub_left_pred
ffmpeg | branch: master | Martin Vignali| Sun Jan 14 14:23:42 2018 +0100| [78b982d3b9f11877a5e4408146cc3cb82908862c] | committer: Martin Vignali checkasm : add test for losslessvideoencdsp for diff bytes and sub_left_pred > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=78b982d3b9f11877a5e4408146cc3cb82908862c --- tests/checkasm/Makefile | 1 + tests/checkasm/checkasm.c| 3 ++ tests/checkasm/checkasm.h| 1 + tests/checkasm/llviddspenc.c | 114 +++ tests/fate/checkasm.mak | 1 + 5 files changed, 120 insertions(+) diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 3525094545..afbd09b940 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -10,6 +10,7 @@ AVCODECOBJS-$(CONFIG_H264DSP) += h264dsp.o AVCODECOBJS-$(CONFIG_H264PRED) += h264pred.o AVCODECOBJS-$(CONFIG_H264QPEL) += h264qpel.o AVCODECOBJS-$(CONFIG_LLVIDDSP) += llviddsp.o +AVCODECOBJS-$(CONFIG_LLVIDENCDSP) += llviddspenc.o AVCODECOBJS-$(CONFIG_VP8DSP)+= vp8dsp.o AVCODECOBJS-$(CONFIG_VIDEODSP) += videodsp.o diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index ff0ca5b68d..a4b8aff984 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -126,6 +126,9 @@ static const struct { #if CONFIG_HUFFYUVDSP { "llviddsp", checkasm_check_llviddsp }, #endif +#if CONFIG_LLVIDENCDSP +{ "llviddspenc", checkasm_check_llviddspenc }, +#endif #if CONFIG_PIXBLOCKDSP { "pixblockdsp", checkasm_check_pixblockdsp }, #endif diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index cfe9bfb355..3de38e6717 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -60,6 +60,7 @@ void checkasm_check_hevc_idct(void); void checkasm_check_huffyuvdsp(void); void checkasm_check_jpeg2000dsp(void); void checkasm_check_llviddsp(void); +void checkasm_check_llviddspenc(void); void checkasm_check_pixblockdsp(void); void checkasm_check_sbrdsp(void); void checkasm_check_synth_filter(void); diff --git a/tests/checkasm/llviddspenc.c b/tests/checkasm/llviddspenc.c new file mode 100644 index 00..31eafd5526 --- /dev/null +++ b/tests/checkasm/llviddspenc.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" + +#include "libavcodec/lossless_videoencdsp.h" + +#include "checkasm.h" + +#define randomize_buffers(buf, size) \ +do { \ +int j;\ +for (j = 0; j < size; j+=4) \ +AV_WN32(buf + j, rnd()); \ +} while (0) + +static const struct {uint8_t w, h, s;} planes[] = { +{16,16,16}, {21,23,25}, {32,17,48}, {15,128,16}, {128,127,128} +}; + +#define MAX_STRIDE 128 +#define MAX_HEIGHT 127 + +static void check_diff_bytes(LLVidEncDSPContext *c) +{ +int i; +LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE]); +LOCAL_ALIGNED_32(uint8_t, dst1, [MAX_STRIDE]); +LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE]); +LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE]); +LOCAL_ALIGNED_32(uint8_t, src2, [MAX_STRIDE]); +LOCAL_ALIGNED_32(uint8_t, src3, [MAX_STRIDE]); + +declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src1, + const uint8_t *src2, intptr_t w); + +memset(dst0, 0, MAX_STRIDE); +memset(dst1, 0, MAX_STRIDE); +randomize_buffers(src0, MAX_STRIDE); +memcpy(src1, src0, MAX_STRIDE); +randomize_buffers(src2, MAX_STRIDE); +memcpy(src3, src2, MAX_STRIDE); + +if (check_func(c->diff_bytes, "diff_bytes")) { +for (i = 0; i < 5; i ++) { +call_ref(dst0, src0, src2, planes[i].w); +call_new(dst1, src1, src3, planes[i].w); +if (memcmp(dst0, dst1, planes[i].w)) +fail(); +} +bench_new(dst1, src0, src2, planes[4].w); +} +} + +static void check_sub_left_pred(LLVidEncDSPContext *c) +{ +int i; +LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE *
[FFmpeg-cvslog] avfilter/x86/vf_blend : avfilter/x86/vf_blend : add AVX2 version for each func except divide
ffmpeg | branch: master | Martin Vignali| Wed Jan 17 20:59:58 2018 +0100| [3a230ce5fa10b21312236b362df9eeddd99e7ac2] | committer: Martin Vignali avfilter/x86/vf_blend : avfilter/x86/vf_blend : add AVX2 version for each func except divide and optimize average, grainextract, multiply, screen, grain merge > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3a230ce5fa10b21312236b362df9eeddd99e7ac2 --- libavfilter/x86/vf_blend.asm| 229 +--- libavfilter/x86/vf_blend_init.c | 39 +++ 2 files changed, 184 insertions(+), 84 deletions(-) diff --git a/libavfilter/x86/vf_blend.asm b/libavfilter/x86/vf_blend.asm index 4916aaf251..680e266348 100644 --- a/libavfilter/x86/vf_blend.asm +++ b/libavfilter/x86/vf_blend.asm @@ -2,6 +2,8 @@ ;* x86-optimized functions for blend filter ;* ;* Copyright (C) 2015 Paul B Mahol +;* Copyright (C) 2018 Henrik Gramner +;* Copyright (C) 2018 Jokyo Images ;* ;* This file is part of FFmpeg. ;* @@ -74,39 +76,36 @@ BLEND_INIT %1, 2 BLEND_END %endmacro -INIT_XMM sse2 -BLEND_SIMPLE xor, xor -BLEND_SIMPLE or, or -BLEND_SIMPLE and, and -BLEND_SIMPLE addition, addusb -BLEND_SIMPLE subtract, subusb -BLEND_SIMPLE darken, minub -BLEND_SIMPLE lighten, maxub - -BLEND_INIT grainextract, 4 -pxor m2, m2 -mova m3, [pw_128] +%macro GRAINEXTRACT 0 +BLEND_INIT grainextract, 6 +pxor m4, m4 +VBROADCASTI128 m5, [pw_128] .nextrow: movxq, widthq - .loop: -movhm0, [topq + xq] -movhm1, [bottomq + xq] -punpcklbw m0, m2 -punpcklbw m1, m2 -paddw m0, m3 -psubw m0, m1 -packuswbm0, m0 -movh [dstq + xq], m0 -add xq, mmsize / 2 +movu m1, [topq + xq] +movu m3, [bottomq + xq] +punpcklbw m0, m1, m4 +punpckhbw m1, m4 +punpcklbw m2, m3, m4 +punpckhbw m3, m4 + +paddw m0, m5 +paddw m1, m5 +psubw m0, m2 +psubw m1, m3 + +packuswb m0, m1 +mova [dstq + xq], m0 +addxq, mmsize jl .loop BLEND_END +%endmacro %macro MULTIPLY 3 ; a, b, pw_1 pmullw %1, %2 ; a * b paddw %1, %3 -mova%2, %1 -psrlw %2, 8 +psrlw %2, %1, 8 paddw %1, %2 psrlw %1, 8; 00xx00xx a * b / 255 %endmacro @@ -118,92 +117,112 @@ BLEND_END pxor%1, %4 ; 00xx00xx 255 - x / 255 %endmacro -BLEND_INIT multiply, 4 -pxor m2, m2 -mova m3, [pw_1] +%macro BLEND_MULTIPLY 0 +BLEND_INIT multiply, 6 +pxor m4, m4 +VBROADCASTI128 m5, [pw_1] .nextrow: movxq, widthq .loop: - ; word - ; |--| -movhm0, [topq + xq] ; -movhm1, [bottomq + xq] -punpcklbw m0, m2 ; 00xx00xx -punpcklbw m1, m2 - -MULTIPLYm0, m1, m3 - -packuswbm0, m0 ; -movh [dstq + xq], m0 -add xq, mmsize / 2 - +movu m1, [topq + xq] +movu m3, [bottomq + xq] +punpcklbw m0, m1, m4 +punpckhbw m1, m4 +punpcklbw m2, m3, m4 +punpckhbw m3, m4 + +MULTIPLYm0, m2, m5 +MULTIPLYm1, m3, m5 + +packuswb m0, m1 +mova [dstq + xq], m0 +addxq, mmsize jl .loop BLEND_END +%endmacro -BLEND_INIT screen, 5 -pxor m2, m2 -mova m3, [pw_1] -mova m4, [pw_255] +%macro BLEND_SCREEN 0 +BLEND_INIT screen, 7 +pxor m4, m4 + +VBROADCASTI128 m5, [pw_1] +VBROADCASTI128 m6, [pw_255] .nextrow: movxq, widthq .loop: -movhm0, [topq + xq] ; -movhm1, [bottomq + xq] -punpcklbw m0, m2 ; 00xx00xx -punpcklbw m1, m2 - -SCREEN m0, m1, m3, m4 - -packuswbm0, m0 ; -movh [dstq + xq], m0 -add xq, mmsize / 2 - +movu m1, [topq + xq] +movu m3, [bottomq + xq] +punpcklbw m0, m1, m4 +punpckhbw m1, m4 +punpcklbw m2, m3, m4 +punpckhbw m3, m4 + +SCREEN m0, m2, m5, m6 +SCREEN m1, m3, m5, m6 + +packuswb m0, m1 +mova [dstq + xq], m0 +addxq, mmsize jl .loop BLEND_END +%endmacro
[FFmpeg-cvslog] avfilter/vf_framerate: add SIMD functions for frame blending
ffmpeg | branch: master | Marton Balint| Mon Jan 8 01:05:45 2018 +0100| [4d95c6d5d7d8d79b5acafcf526a1b7c1797a1060] | committer: Marton Balint avfilter/vf_framerate: add SIMD functions for frame blending Blend function speedups on x86_64 Core i5 4460: ffmpeg -f lavfi -i allyuv -vf framerate=60:threads=1 -f null none C: 447548411 decicycles in Blend,2048 runs, 0 skips SSSE3: 130020087 decicycles in Blend,2048 runs, 0 skips AVX2: 128508221 decicycles in Blend,2048 runs, 0 skips ffmpeg -f lavfi -i allyuv -vf format=yuv420p12,framerate=60:threads=1 -f null none C: 228932745 decicycles in Blend,2048 runs, 0 skips SSE4: 123357781 decicycles in Blend,2048 runs, 0 skips AVX2: 121215353 decicycles in Blend,2048 runs, 0 skips Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4d95c6d5d7d8d79b5acafcf526a1b7c1797a1060 --- libavfilter/framerate.h | 74 libavfilter/vf_framerate.c | 70 +-- libavfilter/x86/Makefile| 2 + libavfilter/x86/vf_framerate.asm| 134 libavfilter/x86/vf_framerate_init.c | 42 +++ 5 files changed, 268 insertions(+), 54 deletions(-) diff --git a/libavfilter/framerate.h b/libavfilter/framerate.h new file mode 100644 index 00..a42d5af68a --- /dev/null +++ b/libavfilter/framerate.h @@ -0,0 +1,74 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_FRAMERATE_H +#define AVFILTER_FRAMERATE_H + +#include "libavutil/pixelutils.h" +#include "avfilter.h" + +#define BLEND_FUNC_PARAMS const uint8_t *src1, ptrdiff_t src1_linesize, \ + const uint8_t *src2, ptrdiff_t src2_linesize, \ + uint8_t *dst, ptrdiff_t dst_linesize, \ + ptrdiff_t width, ptrdiff_t height, \ + int factor1, int factor2, int half + +#define BLEND_FACTOR_DEPTH8 7 +#define BLEND_FACTOR_DEPTH16 15 + +typedef void (*blend_func)(BLEND_FUNC_PARAMS); + +typedef struct FrameRateContext { +const AVClass *class; +// parameters +AVRational dest_frame_rate; ///< output frames per second +int flags; ///< flags affecting frame rate conversion algorithm +double scene_score; ///< score that denotes a scene change has happened +int interp_start; ///< start of range to apply linear interpolation +int interp_end; ///< end of range to apply linear interpolation + +int line_size[4]; ///< bytes of pixel data per line for each plane +int vsub; + +AVRational srce_time_base; ///< timebase of source +AVRational dest_time_base; ///< timebase of destination + +av_pixelutils_sad_fn sad; ///< Sum of the absolute difference function (scene detect only) +double prev_mafd; ///< previous MAFD (scene detect only) + +int blend_factor_max; +int bitdepth; +AVFrame *work; + +AVFrame *f0;///< last frame +AVFrame *f1;///< current frame +int64_t pts0; ///< last frame pts in dest_time_base +int64_t pts1; ///< current frame pts in dest_time_base +int64_t delta; ///< pts1 to pts0 delta +double score; ///< scene change score (f0 to f1) +int flush; ///< 1 if the filter is being flushed +int64_t start_pts; ///< pts of the first output frame +int64_t n; ///< output frame counter + +blend_func blend; +} FrameRateContext; + +void ff_framerate_init(FrameRateContext *s); +void ff_framerate_init_x86(FrameRateContext *s); + +#endif /* AVFILTER_FRAMERATE_H */ diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 8119fe2bfd..3e2615be5e 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -38,52 +38,7 @@ #include "avfilter.h" #include "internal.h" #include
[FFmpeg-cvslog] avfilter/vf_framerate: unify luma and chroma blending
ffmpeg | branch: master | Marton Balint| Mon Jan 8 21:01:09 2018 +0100| [5bf774a4a448418c6977c744fbf1ec74659eb0d3] | committer: Marton Balint avfilter/vf_framerate: unify luma and chroma blending The expressions were mathematically equvivalent... Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5bf774a4a448418c6977c744fbf1ec74659eb0d3 --- libavfilter/vf_framerate.c | 60 -- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index a5ae6ddb71..583c96e02c 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -196,32 +196,16 @@ static int filter_slice8(AVFilterContext *ctx, void *arg, int job, int nb_jobs) cpy_src2_data += start * cpy_src2_line_size; cpy_dst_data += start * cpy_dst_line_size; -if (plane <1 || plane >2) { -// luma or alpha -for (line = start; line < end; line++) { -for (pixel = 0; pixel < cpy_line_width; pixel++) { -// integer version of (src1 * src1_factor) + (src2 + src2_factor) + 0.5 -// 0.5 is for rounding -// 128 is the integer representation of 0.5 << 8 -cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + 128) >> 8; -} -cpy_src1_data += cpy_src1_line_size; -cpy_src2_data += cpy_src2_line_size; -cpy_dst_data += cpy_dst_line_size; -} -} else { -// chroma -for (line = start; line < end; line++) { -for (pixel = 0; pixel < cpy_line_width; pixel++) { -// as above -// because U and V are based around 128 we have to subtract 128 from the components. -// 32896 is the integer representation of 128.5 << 8 -cpy_dst_data[pixel] = (((cpy_src1_data[pixel] - 128) * src1_factor) + ((cpy_src2_data[pixel] - 128) * src2_factor) + 32896) >> 8; -} -cpy_src1_data += cpy_src1_line_size; -cpy_src2_data += cpy_src2_line_size; -cpy_dst_data += cpy_dst_line_size; +for (line = start; line < end; line++) { +for (pixel = 0; pixel < cpy_line_width; pixel++) { +// integer version of (src1 * src1_factor) + (src2 + src2_factor) + 0.5 +// 0.5 is for rounding +// 128 is the integer representation of 0.5 << 8 +cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + 128) >> 8; } +cpy_src1_data += cpy_src1_line_size; +cpy_src2_data += cpy_src2_line_size; +cpy_dst_data += cpy_dst_line_size; } } @@ -235,7 +219,6 @@ static int filter_slice16(AVFilterContext *ctx, void *arg, int job, int nb_jobs) uint16_t src1_factor = td->src1_factor; uint16_t src2_factor = td->src2_factor; const int half = s->max / 2; -const int uv = (s->max + 1) * half; const int shift = s->bitdepth; int plane, line, pixel; @@ -254,25 +237,12 @@ static int filter_slice16(AVFilterContext *ctx, void *arg, int job, int nb_jobs) cpy_src2_data += start * cpy_src2_line_size; cpy_dst_data += start * cpy_dst_line_size; -if (plane <1 || plane >2) { -// luma or alpha -for (line = start; line < end; line++) { -for (pixel = 0; pixel < cpy_line_width; pixel++) -cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + half) >> shift; -cpy_src1_data += cpy_src1_line_size; -cpy_src2_data += cpy_src2_line_size; -cpy_dst_data += cpy_dst_line_size; -} -} else { -// chroma -for (line = start; line < end; line++) { -for (pixel = 0; pixel < cpy_line_width; pixel++) { -cpy_dst_data[pixel] = (((cpy_src1_data[pixel] - half) * src1_factor) + ((cpy_src2_data[pixel] - half) * src2_factor) + uv) >> shift; -} -cpy_src1_data += cpy_src1_line_size; -cpy_src2_data += cpy_src2_line_size; -cpy_dst_data += cpy_dst_line_size; -} +for (line = start; line < end; line++) { +for (pixel = 0; pixel < cpy_line_width; pixel++) +cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + half) >> shift; +cpy_src1_data += cpy_src1_line_size; +cpy_src2_data += cpy_src2_line_size; +cpy_dst_data += cpy_dst_line_size; } }
[FFmpeg-cvslog] avfilter/vf_framerate: factorize blend functions and unify filter_slice
ffmpeg | branch: master | Marton Balint| Mon Jan 8 21:44:42 2018 +0100| [1b6ffe9aca1bdcc0bf2249c8c1314faa1ab0dae6] | committer: Marton Balint avfilter/vf_framerate: factorize blend functions and unify filter_slice Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1b6ffe9aca1bdcc0bf2249c8c1314faa1ab0dae6 --- libavfilter/vf_framerate.c | 108 - 1 file changed, 57 insertions(+), 51 deletions(-) diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 583c96e02c..2a6d692eb0 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -39,6 +39,14 @@ #include "internal.h" #include "video.h" +#define BLEND_FUNC_PARAMS const uint8_t *src1, ptrdiff_t src1_linesize, \ + const uint8_t *src2, ptrdiff_t src2_linesize, \ + uint8_t *dst, ptrdiff_t dst_linesize, \ + ptrdiff_t width, ptrdiff_t height, \ + int factor1, int factor2, int half, int shift + +typedef void (*blend_func)(BLEND_FUNC_PARAMS); + typedef struct FrameRateContext { const AVClass *class; // parameters @@ -72,6 +80,8 @@ typedef struct FrameRateContext { int flush; ///< 1 if the filter is being flushed int64_t start_pts; ///< pts of the first output frame int64_t n; ///< output frame counter + +blend_func blend; } FrameRateContext; #define OFFSET(x) offsetof(FrameRateContext, x) @@ -173,13 +183,13 @@ typedef struct ThreadData { uint16_t src1_factor, src2_factor; } ThreadData; -static int filter_slice8(AVFilterContext *ctx, void *arg, int job, int nb_jobs) +static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) { FrameRateContext *s = ctx->priv; ThreadData *td = arg; uint16_t src1_factor = td->src1_factor; uint16_t src2_factor = td->src2_factor; -int plane, line, pixel; +int plane; for (plane = 0; plane < 4 && td->copy_src1->data[plane] && td->copy_src2->data[plane]; plane++) { int cpy_line_width = s->line_size[plane]; @@ -196,54 +206,11 @@ static int filter_slice8(AVFilterContext *ctx, void *arg, int job, int nb_jobs) cpy_src2_data += start * cpy_src2_line_size; cpy_dst_data += start * cpy_dst_line_size; -for (line = start; line < end; line++) { -for (pixel = 0; pixel < cpy_line_width; pixel++) { -// integer version of (src1 * src1_factor) + (src2 + src2_factor) + 0.5 -// 0.5 is for rounding -// 128 is the integer representation of 0.5 << 8 -cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + 128) >> 8; -} -cpy_src1_data += cpy_src1_line_size; -cpy_src2_data += cpy_src2_line_size; -cpy_dst_data += cpy_dst_line_size; -} -} - -return 0; -} - -static int filter_slice16(AVFilterContext *ctx, void *arg, int job, int nb_jobs) -{ -FrameRateContext *s = ctx->priv; -ThreadData *td = arg; -uint16_t src1_factor = td->src1_factor; -uint16_t src2_factor = td->src2_factor; -const int half = s->max / 2; -const int shift = s->bitdepth; -int plane, line, pixel; - -for (plane = 0; plane < 4 && td->copy_src1->data[plane] && td->copy_src2->data[plane]; plane++) { -int cpy_line_width = s->line_size[plane]; -const uint16_t *cpy_src1_data = (const uint16_t *)td->copy_src1->data[plane]; -int cpy_src1_line_size = td->copy_src1->linesize[plane] / 2; -const uint16_t *cpy_src2_data = (const uint16_t *)td->copy_src2->data[plane]; -int cpy_src2_line_size = td->copy_src2->linesize[plane] / 2; -int cpy_src_h = (plane > 0 && plane < 3) ? (td->copy_src1->height >> s->vsub) : (td->copy_src1->height); -uint16_t *cpy_dst_data = (uint16_t *)s->work->data[plane]; -int cpy_dst_line_size = s->work->linesize[plane] / 2; -const int start = (cpy_src_h * job ) / nb_jobs; -const int end = (cpy_src_h * (job+1)) / nb_jobs; -cpy_src1_data += start * cpy_src1_line_size; -cpy_src2_data += start * cpy_src2_line_size; -cpy_dst_data += start * cpy_dst_line_size; - -for (line = start; line < end; line++) { -for (pixel = 0; pixel < cpy_line_width; pixel++) -cpy_dst_data[pixel] = ((cpy_src1_data[pixel] * src1_factor) + (cpy_src2_data[pixel] * src2_factor) + half) >> shift; -cpy_src1_data += cpy_src1_line_size; -cpy_src2_data += cpy_src2_line_size; -cpy_dst_data += cpy_dst_line_size; -} +s->blend(cpy_src1_data, cpy_src1_line_size, + cpy_src2_data, cpy_src2_line_size, + cpy_dst_data,
[FFmpeg-cvslog] avfilter/vf_framerate: change blend factor precision
ffmpeg | branch: master | Marton Balint| Mon Jan 15 22:19:46 2018 +0100| [2cbe6bac0337939f023bd1c37a9c455e6d535f3a] | committer: Marton Balint avfilter/vf_framerate: change blend factor precision This is done mainly in preparation for the SIMD patches. - for the 8-bit input, decrease the blend factor precision to 7-bit. - for the 16-bit input, increase the blend factor precision to 15-bit. - make sure the blend functions are not called with 0 or maximum blending factors, because we don't want the signed factor integers to overflow. Fate test changes are due to different rounding. Signed-off-by: Marton Balint > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2cbe6bac0337939f023bd1c37a9c455e6d535f3a --- libavfilter/vf_framerate.c | 54 ++-- tests/ref/fate/filter-framerate-12bit-down | 80 +++--- tests/ref/fate/filter-framerate-12bit-up | 78 ++--- tests/ref/fate/filter-framerate-up | 8 +-- 4 files changed, 109 insertions(+), 111 deletions(-) diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 2a6d692eb0..8119fe2bfd 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -43,7 +43,10 @@ const uint8_t *src2, ptrdiff_t src2_linesize, \ uint8_t *dst, ptrdiff_t dst_linesize, \ ptrdiff_t width, ptrdiff_t height, \ - int factor1, int factor2, int half, int shift + int factor1, int factor2, int half + +#define BLEND_FACTOR_DEPTH8 7 +#define BLEND_FACTOR_DEPTH16 15 typedef void (*blend_func)(BLEND_FUNC_PARAMS); @@ -53,10 +56,8 @@ typedef struct FrameRateContext { AVRational dest_frame_rate; ///< output frames per second int flags; ///< flags affecting frame rate conversion algorithm double scene_score; ///< score that denotes a scene change has happened -int interp_start; ///< start of range to apply linear interpolation (same bitdepth as input) -int interp_end; ///< end of range to apply linear interpolation (same bitdepth as input) -int interp_start_param; ///< start of range to apply linear interpolation -int interp_end_param; ///< end of range to apply linear interpolation +int interp_start; ///< start of range to apply linear interpolation +int interp_end; ///< end of range to apply linear interpolation int line_size[4]; ///< bytes of pixel data per line for each plane int vsub; @@ -67,7 +68,7 @@ typedef struct FrameRateContext { av_pixelutils_sad_fn sad; ///< Sum of the absolute difference function (scene detect only) double prev_mafd; ///< previous MAFD (scene detect only) -int max; +int blend_factor_max; int bitdepth; AVFrame *work; @@ -92,8 +93,8 @@ typedef struct FrameRateContext { static const AVOption framerate_options[] = { {"fps", "required output frames per second rate", OFFSET(dest_frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="50"}, 0, INT_MAX, V|F }, -{"interp_start","point to start linear interpolation", OFFSET(interp_start_param),AV_OPT_TYPE_INT,{.i64=15}, 0, 255, V|F }, -{"interp_end", "point to end linear interpolation", OFFSET(interp_end_param), AV_OPT_TYPE_INT,{.i64=240},0, 255, V|F }, +{"interp_start","point to start linear interpolation", OFFSET(interp_start),AV_OPT_TYPE_INT, {.i64=15}, 0, 255, V|F }, +{"interp_end", "point to end linear interpolation", OFFSET(interp_end), AV_OPT_TYPE_INT, {.i64=240},0, 255, V|F }, {"scene", "scene change level", OFFSET(scene_score), AV_OPT_TYPE_DOUBLE, {.dbl=8.2},0, INT_MAX, V|F }, {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS,{.i64=1}, 0, INT_MAX, V|F, "flags" }, @@ -210,7 +211,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) cpy_src2_data, cpy_src2_line_size, cpy_dst_data, cpy_dst_line_size, cpy_line_width, end - start, - src1_factor, src2_factor, s->max / 2, s->bitdepth); + src1_factor, src2_factor, s->blend_factor_max >> 1); } return 0; @@ -235,7 +236,7 @@ static int blend_frames(AVFilterContext *ctx, int interpolate) td.copy_src1 = s->f0; td.copy_src2 =
[FFmpeg-cvslog] avfilter/vf_transpose: Fix regression with packed pixel formats
ffmpeg | branch: master | Michael Niedermayer| Sun Jan 28 02:46:56 2018 +0100| [3f621455d62e46745453568d915badd5b1e5bcd5] | committer: Michael Niedermayer avfilter/vf_transpose: Fix regression with packed pixel formats Regression since: c6939f65a116b1ffed345d29d8621ee4ffb32235 Found-by: Paul B Mahol Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3f621455d62e46745453568d915badd5b1e5bcd5 --- libavfilter/vf_transpose.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index 1e1a5c4b89..3ff4cb4249 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -217,7 +217,7 @@ static int config_props_output(AVFilterLink *outlink) s->hsub = desc_in->log2_chroma_w; s->vsub = desc_in->log2_chroma_h; -s->planes = desc_in->nb_components; +s->planes = av_pix_fmt_count_planes(outlink->format); av_assert0(desc_in->nb_components == desc_out->nb_components); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] fate: test the transpose filter more fully
ffmpeg | branch: master | Michael Niedermayer| Sun Jan 28 13:34:07 2018 +0100| [293f24b42c5d116172510768802d85de3d7d0d62] | committer: Michael Niedermayer fate: test the transpose filter more fully Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=293f24b42c5d116172510768802d85de3d7d0d62 --- tests/fate/filter-video.mak | 3 + tests/ref/fate/filter-pixfmts-transpose | 108 2 files changed, 111 insertions(+) diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index bf6e2c6f84..221ae81fdc 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -684,6 +684,9 @@ fate-filter-pixfmts-tinterlace_pad: CMD = pixfmts "pad" FATE_FILTER_PIXFMTS-$(CONFIG_TINTERLACE_FILTER) += fate-filter-pixfmts-tinterlace_vlpf fate-filter-pixfmts-tinterlace_vlpf: CMD = pixfmts "interleave_top:vlpf" +FATE_FILTER_PIXFMTS-$(CONFIG_TRANSPOSE_FILTER) += fate-filter-pixfmts-transpose +fate-filter-pixfmts-transpose: CMD = pixfmts "dir=cclock_flip" + FATE_FILTER_PIXFMTS-$(CONFIG_VFLIP_FILTER) += fate-filter-pixfmts-vflip fate-filter-pixfmts-vflip: CMD = pixfmts diff --git a/tests/ref/fate/filter-pixfmts-transpose b/tests/ref/fate/filter-pixfmts-transpose new file mode 100644 index 00..6f25f3dd27 --- /dev/null +++ b/tests/ref/fate/filter-pixfmts-transpose @@ -0,0 +1,108 @@ +0bgr6929c1e308d2f4f941d002627047d262 +0rgbcf1bedd0784a3efd3ab00c4e44005c37 +abgr6d6f896f853a6c6f93ee70dba9af3d17 +argb87bbd23debb94d486ac3a6b6c0b005f9 +ayuv64lee4c07e0d5b333b3bc9eb4f3ce6af3a2c +bgr0df3a6eedd4939ce09a357b655ac2962a +bgr24 f9a08135e5d58c0b2a5509c369a88414 +bgr444bedd9e990a327649ec0b2b81a8ee4d8f49 +bgr444lebee1d9fae8733d0c0669bca2ac4dfaf6 +bgr48be 39f48f6353dfc772af36cbb41e6126a4 +bgr48le 9a61d9531b1f6de44b27f6bb9b4dfc79 +bgr4_byte ddff9da461afce90e3122a41d79b287d +bgr555be24e5c6502a6d927f8ba88f3320ebf619 +bgr555le5201d098979ea86a66d8df1ef41c79ad +bgr565be59afe17b455e921daf428ba05a40bab9 +bgr565leb2709790684abbd2133906b637f2b4b8 +bgr8b6ee15f70989d2f52f184e32b3af2c18 +bgraf2fe61e08446900ad209f2c586997e15 +bgra64be8d01994c8c32e628fcf9749851f1ffe8 +bgra64lefaaef6d280f92e7e8abdd9fa4a61f7b5 +gbrap 0899b3af50d35a63bfecb419a5b29968 +gbrap10be 3e3be2d8f9aa5f449a1df404e27d0054 +gbrap10le db4e4861010cbbf726492fad282d5813 +gbrap12be 1518c9a565d1ba1a45dd369acc1aa75e +gbrap12le 714fe318af81a46f83655c6e7e13351e +gbrap16be 39d488528aacff466aac7539c9b948a8 +gbrap16le 5426ac9457289927bfe2ec03038a8780 +gbrp7b4b6a2f1cdc51455b25515c3ecea944 +gbrp10bed7401725699b2ddf954caa16a0878a1e +gbrp10le6036711969eae1979be6358f688bd9c8 +gbrp12beec7d6e69fc579619b53d57a76c20480d +gbrp12lebf7478185274486c3f7dd4db1da8f7d0 +gbrp14be9b66f22e4315aaa878a430ae3f44ab57 +gbrp14le16f30349b42dca007b37b8522d3018df +gbrp16be0d003b88d4f446ae9ba12cab1cbb359a +gbrp16lea1c09038fa4636c9843ab8dd2b7601ea +gbrp9be df381b4b27be25d172fa556434478807 +gbrp9le a5301e978f68b29bfc613b2462ec4888 +grayc5f8bc6636fd15dbc57deb4bba1e7379 +gray10be48b421da79c195fd91dffb8fca79a8a2 +gray10le7774e3296916b896afa46f626334a280 +gray12be89f1c4b7821b771f6d967f9db871f8ef +gray12le43d392c3dcbd79b47cce31f2006c5050 +gray16be4aef307021a91b1de67f1d4381a39132 +gray16le76f2afe156edca7ae05cfa4e5867126e +gray9be 2c425fa532c940d226822da8b3592310 +gray9le bcc575942910b3c72eaa72e8794f3acd +nv12aca847644e5dc0e942419183014981a4 +nv21098884e968d27286c8cf0d2fb1557dcd +p010be 5ff62dffa5dfdf823978c4f563f69c94 +p010le 20131abe34e084b04f1d169c66447825 +rgb031ea5da7fe779c6ea0a33f1d28aad918 +rgb24 47654cabaaad79170b90afd5a02161dd +rgb444be3cac1f0c43a74d2a95eb02e187070845 +rgb444le46d602468bd9e5a430622e3d4b7c8f40 +rgb48be 400932419bbb780614254253ef5591c3 +rgb48le 6a99c40f21629cb0655e8772d7190374 +rgb4_byte d3990da196266305a3f2e5b1d72401a5 +rgb555be79e4503ff0d5cf52d3a7901397499a28 +rgb555lec65f2594c0b3107a322f7aeb81aa8a16 +rgb565be0c746b5063d02d6cb98e9e9a59ad3b99 +rgb565le63b02db11c3d20be54d218c7c44f8ddb +rgb8c90feb30c3c9391ef5f470209d7b7a15 +rgba4d76a9542143752a4ac30f82f88f68f1 +rgba64bea60041217f4c0cd796d19d3940a12a41 +rgba64le
[FFmpeg-cvslog] avcodec/nvenc: also clear data pointer after unregistering a resource
ffmpeg | branch: release/3.3 | Timo Rothenpieler| Sun Jan 28 13:05:09 2018 +0100| [dfd2f4ee265e8027bf425424145396e6dc5e184e] | committer: Timo Rothenpieler avcodec/nvenc: also clear data pointer after unregistering a resource Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dfd2f4ee265e8027bf425424145396e6dc5e184e --- libavcodec/nvenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 5bc97835d6..5185342a7f 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1424,6 +1424,7 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); if (nv_status != NV_ENC_SUCCESS) return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource"); +ctx->registered_frames[i].ptr = 0; ctx->registered_frames[i].regptr = NULL; } return i; @@ -1682,6 +1683,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur res = nvenc_print_error(avctx, nv_status, "Failed unregistering input resource"); goto error; } +ctx->registered_frames[tmpoutsurf->reg_idx].ptr = 0; ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: refcount input frame mappings
ffmpeg | branch: release/3.3 | Timo Rothenpieler| Fri Jan 26 20:16:53 2018 +0100| [802ebfae3b5b95a8e12c4a182923745823ac703f] | committer: Timo Rothenpieler avcodec/nvenc: refcount input frame mappings If some logic like vsync in ffmpeg.c duplicates frames, it might pass the same frame twice, which will result in a crash due it being effectively mapped and unmapped twice. Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=802ebfae3b5b95a8e12c4a182923745823ac703f --- libavcodec/nvenc.c | 39 +++ libavcodec/nvenc.h | 2 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index e4f6f0f927..c357a6f46a 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1281,12 +1281,9 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_fifo_freep(>output_surface_queue); if (ctx->surfaces && avctx->pix_fmt == AV_PIX_FMT_CUDA) { -for (i = 0; i < ctx->nb_surfaces; ++i) { -if (ctx->surfaces[i].input_surface) { - p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->surfaces[i].in_map.mappedResource); -} -} for (i = 0; i < ctx->nb_registered_frames; i++) { +if (ctx->registered_frames[i].mapped) +p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[i].in_map.mappedResource); if (ctx->registered_frames[i].regptr) p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); } @@ -1503,19 +1500,23 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, if (res < 0) return res; -nvenc_frame->in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER; -nvenc_frame->in_map.registeredResource = ctx->registered_frames[reg_idx].regptr; -nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, _frame->in_map); -if (nv_status != NV_ENC_SUCCESS) { -av_frame_unref(nvenc_frame->in_ref); -return nvenc_print_error(avctx, nv_status, "Error mapping an input resource"); +if (!ctx->registered_frames[reg_idx].mapped) { +ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER; +ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr; +nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, >registered_frames[reg_idx].in_map); +if (nv_status != NV_ENC_SUCCESS) { +av_frame_unref(nvenc_frame->in_ref); +return nvenc_print_error(avctx, nv_status, "Error mapping an input resource"); +} } -ctx->registered_frames[reg_idx].mapped = 1; +ctx->registered_frames[reg_idx].mapped += 1; + nvenc_frame->reg_idx = reg_idx; -nvenc_frame->input_surface = nvenc_frame->in_map.mappedResource; -nvenc_frame->format= nvenc_frame->in_map.mappedBufferFmt; +nvenc_frame->input_surface = ctx->registered_frames[reg_idx].in_map.mappedResource; +nvenc_frame->format= ctx->registered_frames[reg_idx].in_map.mappedBufferFmt; nvenc_frame->pitch = frame->linesize[0]; + return 0; } else { NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 }; @@ -1665,9 +1666,15 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { -p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, tmpoutsurf->in_map.mappedResource); +ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; +if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { +p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +} else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { +res = AVERROR_BUG; +goto error; +} + av_frame_unref(tmpoutsurf->in_ref); -ctx->registered_frames[tmpoutsurf->reg_idx].mapped = 0; tmpoutsurf->input_surface = NULL; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 7dec5cc685..e7bb14b4da 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -35,7 +35,6 @@ typedef struct NvencSurface { NV_ENC_INPUT_PTR input_surface; AVFrame *in_ref; -NV_ENC_MAP_INPUT_RESOURCE in_map; int reg_idx; int width; int height; @@ -118,6 +117,7 @@ typedef struct NvencContext CUdeviceptr ptr; NV_ENC_REGISTERED_PTR regptr; int mapped; +NV_ENC_MAP_INPUT_RESOURCE in_map; } registered_frames[MAX_REGISTERED_FRAMES]; int nb_registered_frames;
[FFmpeg-cvslog] configure: add support for libnpp* from cuda sdk 9
ffmpeg | branch: release/3.3 | Timo Rothenpieler| Tue Aug 29 13:30:29 2017 +0200| [09419de21620f1ef3af91e2c591a08c36b8c7ba3] | committer: Timo Rothenpieler configure: add support for libnpp* from cuda sdk 9 Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=09419de21620f1ef3af91e2c591a08c36b8c7ba3 --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 23823e3b70..97aab62990 100755 --- a/configure +++ b/configure @@ -5797,7 +5797,9 @@ enabled libmfx&& require_pkg_config libmfx "mfx/mfxvideo.h" MFXInit enabled libmodplug&& require_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load enabled libmp3lame&& require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libnut&& require libnut libnut.h nut_demuxer_init -lnut -enabled libnpp&& require libnpp npp.h nppGetLibVersion -lnppi -lnppc +enabled libnpp&& { check_lib npp.h nppGetLibVersion -lnppig -lnppicc -lnppc || + check_lib npp.h nppGetLibVersion -lnppi -lnppc || + die "ERROR: libnpp not found"; } enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb enabled libopencv && { check_header opencv2/core/core_c.h && ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: add some more error case checks
ffmpeg | branch: release/3.3 | Timo Rothenpieler| Sun Jan 28 12:51:20 2018 +0100| [d68d537f0a782b10f34023aca987a47f4c872fd8] | committer: Timo Rothenpieler avcodec/nvenc: add some more error case checks Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d68d537f0a782b10f34023aca987a47f4c872fd8 --- libavcodec/nvenc.c | 24 ++-- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index bb059a2726..5bc97835d6 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1413,6 +1413,7 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = >nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = _fn->nvenc_funcs; +NVENCSTATUS nv_status; int i; @@ -1420,8 +1421,9 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) for (i = 0; i < ctx->nb_registered_frames; i++) { if (!ctx->registered_frames[i].mapped) { if (ctx->registered_frames[i].regptr) { -p_nvenc->nvEncUnregisterResource(ctx->nvencoder, - ctx->registered_frames[i].regptr); +nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); +if (nv_status != NV_ENC_SUCCESS) +return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource"); ctx->registered_frames[i].regptr = NULL; } return i; @@ -1661,15 +1663,25 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes); nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); -if (nv_status != NV_ENC_SUCCESS) -nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open"); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open"); +goto error; +} if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { -p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); -p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource"); +goto error; +} +nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unregistering input resource"); +goto error; +} ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: unregister input resource when unmapping
ffmpeg | branch: release/3.3 | Timo Rothenpieler| Sun Jan 28 12:39:03 2018 +0100| [4bb40c32ee09c5f08f56b2715177c3707c7e8ec5] | committer: Timo Rothenpieler avcodec/nvenc: unregister input resource when unmapping Currently the resource is only ever unregistered when the registered_frames array is fully in use and an unmapped entry is re-used and cleaned up. I'm pretty sure the frame will have been cleaned up before that happens, so I'm kinda surprised this never blew up. Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4bb40c32ee09c5f08f56b2715177c3707c7e8ec5 --- libavcodec/nvenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index c357a6f46a..bb059a2726 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1669,6 +1669,8 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; goto error; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: also clear data pointer after unregistering a resource
ffmpeg | branch: release/3.4 | Timo Rothenpieler| Sun Jan 28 13:05:09 2018 +0100| [93c8720b914e7027d0e6401e6f64a9a4ce531d0c] | committer: Timo Rothenpieler avcodec/nvenc: also clear data pointer after unregistering a resource Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=93c8720b914e7027d0e6401e6f64a9a4ce531d0c --- libavcodec/nvenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 43d2549fb5..d36fa2951b 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1493,6 +1493,7 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); if (nv_status != NV_ENC_SUCCESS) return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource"); +ctx->registered_frames[i].ptr = 0; ctx->registered_frames[i].regptr = NULL; } return i; @@ -1751,6 +1752,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur res = nvenc_print_error(avctx, nv_status, "Failed unregistering input resource"); goto error; } +ctx->registered_frames[tmpoutsurf->reg_idx].ptr = 0; ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: unregister input resource when unmapping
ffmpeg | branch: release/3.4 | Timo Rothenpieler| Sun Jan 28 12:39:03 2018 +0100| [a7c60c5b7bc51289773a7e64ebeeeccb53943bdb] | committer: Timo Rothenpieler avcodec/nvenc: unregister input resource when unmapping Currently the resource is only ever unregistered when the registered_frames array is fully in use and an unmapped entry is re-used and cleaned up. I'm pretty sure the frame will have been cleaned up before that happens, so I'm kinda surprised this never blew up. Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a7c60c5b7bc51289773a7e64ebeeeccb53943bdb --- libavcodec/nvenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 661da486f6..ed36b582f8 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1738,6 +1738,8 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; goto error; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: add some more error case checks
ffmpeg | branch: release/3.4 | Timo Rothenpieler| Sun Jan 28 12:51:20 2018 +0100| [d36714f727026ffcdf84c21c5498ceaef862ee75] | committer: Timo Rothenpieler avcodec/nvenc: add some more error case checks Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d36714f727026ffcdf84c21c5498ceaef862ee75 --- libavcodec/nvenc.c | 24 ++-- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index ed36b582f8..43d2549fb5 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1482,6 +1482,7 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = >nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = _fn->nvenc_funcs; +NVENCSTATUS nv_status; int i; @@ -1489,8 +1490,9 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) for (i = 0; i < ctx->nb_registered_frames; i++) { if (!ctx->registered_frames[i].mapped) { if (ctx->registered_frames[i].regptr) { -p_nvenc->nvEncUnregisterResource(ctx->nvencoder, - ctx->registered_frames[i].regptr); +nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); +if (nv_status != NV_ENC_SUCCESS) +return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource"); ctx->registered_frames[i].regptr = NULL; } return i; @@ -1730,15 +1732,25 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes); nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); -if (nv_status != NV_ENC_SUCCESS) -nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open"); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open"); +goto error; +} if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { -p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); -p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource"); +goto error; +} +nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unregistering input resource"); +goto error; +} ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: refcount input frame mappings
ffmpeg | branch: release/3.4 | Timo Rothenpieler| Fri Jan 26 20:16:53 2018 +0100| [fbb27e2911839aaac7b460112eddfafe55b36d75] | committer: Timo Rothenpieler avcodec/nvenc: refcount input frame mappings If some logic like vsync in ffmpeg.c duplicates frames, it might pass the same frame twice, which will result in a crash due it being effectively mapped and unmapped twice. Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fbb27e2911839aaac7b460112eddfafe55b36d75 --- libavcodec/nvenc.c | 39 +++ libavcodec/nvenc.h | 2 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index e1d3316de3..661da486f6 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1352,12 +1352,9 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_fifo_freep(>unused_surface_queue); if (ctx->surfaces && avctx->pix_fmt == AV_PIX_FMT_CUDA) { -for (i = 0; i < ctx->nb_surfaces; ++i) { -if (ctx->surfaces[i].input_surface) { - p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->surfaces[i].in_map.mappedResource); -} -} for (i = 0; i < ctx->nb_registered_frames; i++) { +if (ctx->registered_frames[i].mapped) +p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[i].in_map.mappedResource); if (ctx->registered_frames[i].regptr) p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); } @@ -1572,19 +1569,23 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, if (res < 0) return res; -nvenc_frame->in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER; -nvenc_frame->in_map.registeredResource = ctx->registered_frames[reg_idx].regptr; -nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, _frame->in_map); -if (nv_status != NV_ENC_SUCCESS) { -av_frame_unref(nvenc_frame->in_ref); -return nvenc_print_error(avctx, nv_status, "Error mapping an input resource"); +if (!ctx->registered_frames[reg_idx].mapped) { +ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER; +ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr; +nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, >registered_frames[reg_idx].in_map); +if (nv_status != NV_ENC_SUCCESS) { +av_frame_unref(nvenc_frame->in_ref); +return nvenc_print_error(avctx, nv_status, "Error mapping an input resource"); +} } -ctx->registered_frames[reg_idx].mapped = 1; +ctx->registered_frames[reg_idx].mapped += 1; + nvenc_frame->reg_idx = reg_idx; -nvenc_frame->input_surface = nvenc_frame->in_map.mappedResource; -nvenc_frame->format= nvenc_frame->in_map.mappedBufferFmt; +nvenc_frame->input_surface = ctx->registered_frames[reg_idx].in_map.mappedResource; +nvenc_frame->format= ctx->registered_frames[reg_idx].in_map.mappedBufferFmt; nvenc_frame->pitch = frame->linesize[0]; + return 0; } else { NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 }; @@ -1734,9 +1735,15 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { -p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, tmpoutsurf->in_map.mappedResource); +ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; +if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { +p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +} else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { +res = AVERROR_BUG; +goto error; +} + av_frame_unref(tmpoutsurf->in_ref); -ctx->registered_frames[tmpoutsurf->reg_idx].mapped = 0; tmpoutsurf->input_surface = NULL; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index afb93cc22c..d8e23d0ccb 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -37,7 +37,6 @@ typedef struct NvencSurface { NV_ENC_INPUT_PTR input_surface; AVFrame *in_ref; -NV_ENC_MAP_INPUT_RESOURCE in_map; int reg_idx; int width; int height; @@ -122,6 +121,7 @@ typedef struct NvencContext CUdeviceptr ptr; NV_ENC_REGISTERED_PTR regptr; int mapped; +NV_ENC_MAP_INPUT_RESOURCE in_map; } registered_frames[MAX_REGISTERED_FRAMES]; int nb_registered_frames;
[FFmpeg-cvslog] avcodec/nvenc: also clear data pointer after unregistering a resource
ffmpeg | branch: master | Timo Rothenpieler| Sun Jan 28 13:05:09 2018 +0100| [932037c6bb6b41a24e75b031426844a2e6472a74] | committer: Timo Rothenpieler avcodec/nvenc: also clear data pointer after unregistering a resource Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=932037c6bb6b41a24e75b031426844a2e6472a74 --- libavcodec/nvenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 7038a49d90..39c3aa1fbb 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1540,6 +1540,7 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); if (nv_status != NV_ENC_SUCCESS) return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource"); +ctx->registered_frames[i].ptr = NULL; ctx->registered_frames[i].regptr = NULL; } return i; @@ -1810,6 +1811,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur res = nvenc_print_error(avctx, nv_status, "Failed unregistering input resource"); goto error; } +ctx->registered_frames[tmpoutsurf->reg_idx].ptr = NULL; ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: add some more error case checks
ffmpeg | branch: master | Timo Rothenpieler| Sun Jan 28 12:51:20 2018 +0100| [48e52e4edd12adbc36eee0eebe1b97ffe0255be3] | committer: Timo Rothenpieler avcodec/nvenc: add some more error case checks Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=48e52e4edd12adbc36eee0eebe1b97ffe0255be3 --- libavcodec/nvenc.c | 24 ++-- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index a8194231ae..7038a49d90 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1529,6 +1529,7 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = >nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = _fn->nvenc_funcs; +NVENCSTATUS nv_status; int i; @@ -1536,8 +1537,9 @@ static int nvenc_find_free_reg_resource(AVCodecContext *avctx) for (i = 0; i < ctx->nb_registered_frames; i++) { if (!ctx->registered_frames[i].mapped) { if (ctx->registered_frames[i].regptr) { -p_nvenc->nvEncUnregisterResource(ctx->nvencoder, - ctx->registered_frames[i].regptr); +nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); +if (nv_status != NV_ENC_SUCCESS) +return nvenc_print_error(avctx, nv_status, "Failed unregistering unused input resource"); ctx->registered_frames[i].regptr = NULL; } return i; @@ -1789,15 +1791,25 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur memcpy(pkt->data, lock_params.bitstreamBufferPtr, lock_params.bitstreamSizeInBytes); nv_status = p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); -if (nv_status != NV_ENC_SUCCESS) -nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open"); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unlocking bitstream buffer, expect the gates of mordor to open"); +goto error; +} if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) { ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { -p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); -p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +nv_status = p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unmapping input resource"); +goto error; +} +nv_status = p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +if (nv_status != NV_ENC_SUCCESS) { +res = nvenc_print_error(avctx, nv_status, "Failed unregistering input resource"); +goto error; +} ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: unregister input resource when unmapping
ffmpeg | branch: master | Timo Rothenpieler| Sun Jan 28 12:39:03 2018 +0100| [32bc4e77f61a5483c83a360b9ccbfc2840daba1e] | committer: Timo Rothenpieler avcodec/nvenc: unregister input resource when unmapping Currently the resource is only ever unregistered when the registered_frames array is fully in use and an unmapped entry is re-used and cleaned up. I'm pretty sure the frame will have been cleaned up before that happens, so I'm kinda surprised this never blew up. Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=32bc4e77f61a5483c83a360b9ccbfc2840daba1e --- libavcodec/nvenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 0ecaa15162..a8194231ae 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1797,6 +1797,8 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].regptr); +ctx->registered_frames[tmpoutsurf->reg_idx].regptr = NULL; } else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { res = AVERROR_BUG; goto error; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avcodec/nvenc: refcount input frame mappings
ffmpeg | branch: master | Timo Rothenpieler| Fri Jan 26 20:16:53 2018 +0100| [bbe1b21022e4872bc64066d46a4567dc1b655f7a] | committer: Timo Rothenpieler avcodec/nvenc: refcount input frame mappings If some logic like vsync in ffmpeg.c duplicates frames, it might pass the same frame twice, which will result in a crash due it being effectively mapped and unmapped twice. Signed-off-by: Timo Rothenpieler > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=bbe1b21022e4872bc64066d46a4567dc1b655f7a --- libavcodec/nvenc.c | 39 +++ libavcodec/nvenc.h | 2 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 4a91d99720..0ecaa15162 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1389,12 +1389,9 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_fifo_freep(>unused_surface_queue); if (ctx->surfaces && (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11)) { -for (i = 0; i < ctx->nb_surfaces; ++i) { -if (ctx->surfaces[i].input_surface) { - p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->surfaces[i].in_map.mappedResource); -} -} for (i = 0; i < ctx->nb_registered_frames; i++) { +if (ctx->registered_frames[i].mapped) +p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[i].in_map.mappedResource); if (ctx->registered_frames[i].regptr) p_nvenc->nvEncUnregisterResource(ctx->nvencoder, ctx->registered_frames[i].regptr); } @@ -1629,19 +1626,23 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, if (res < 0) return res; -nvenc_frame->in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER; -nvenc_frame->in_map.registeredResource = ctx->registered_frames[reg_idx].regptr; -nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, _frame->in_map); -if (nv_status != NV_ENC_SUCCESS) { -av_frame_unref(nvenc_frame->in_ref); -return nvenc_print_error(avctx, nv_status, "Error mapping an input resource"); +if (!ctx->registered_frames[reg_idx].mapped) { +ctx->registered_frames[reg_idx].in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER; +ctx->registered_frames[reg_idx].in_map.registeredResource = ctx->registered_frames[reg_idx].regptr; +nv_status = p_nvenc->nvEncMapInputResource(ctx->nvencoder, >registered_frames[reg_idx].in_map); +if (nv_status != NV_ENC_SUCCESS) { +av_frame_unref(nvenc_frame->in_ref); +return nvenc_print_error(avctx, nv_status, "Error mapping an input resource"); +} } -ctx->registered_frames[reg_idx].mapped = 1; +ctx->registered_frames[reg_idx].mapped += 1; + nvenc_frame->reg_idx = reg_idx; -nvenc_frame->input_surface = nvenc_frame->in_map.mappedResource; -nvenc_frame->format= nvenc_frame->in_map.mappedBufferFmt; +nvenc_frame->input_surface = ctx->registered_frames[reg_idx].in_map.mappedResource; +nvenc_frame->format= ctx->registered_frames[reg_idx].in_map.mappedBufferFmt; nvenc_frame->pitch = frame->linesize[0]; + return 0; } else { NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 }; @@ -1793,9 +1794,15 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11) { -p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, tmpoutsurf->in_map.mappedResource); +ctx->registered_frames[tmpoutsurf->reg_idx].mapped -= 1; +if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped == 0) { +p_nvenc->nvEncUnmapInputResource(ctx->nvencoder, ctx->registered_frames[tmpoutsurf->reg_idx].in_map.mappedResource); +} else if (ctx->registered_frames[tmpoutsurf->reg_idx].mapped < 0) { +res = AVERROR_BUG; +goto error; +} + av_frame_unref(tmpoutsurf->in_ref); -ctx->registered_frames[tmpoutsurf->reg_idx].mapped = 0; tmpoutsurf->input_surface = NULL; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 2e51f1e946..ab6825f633 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -44,7 +44,6 @@ typedef struct NvencSurface { NV_ENC_INPUT_PTR input_surface; AVFrame *in_ref; -NV_ENC_MAP_INPUT_RESOURCE in_map; int reg_idx; int width; int height; @@ -131,6 +130,7 @@ typedef struct NvencContext int ptr_index; NV_ENC_REGISTERED_PTR regptr; int mapped; +NV_ENC_MAP_INPUT_RESOURCE in_map; }