[FFmpeg-devel] [PATCH] Fixed nvenc release dump
Signed-off-by: GOOR, Jean-Noël --- libavcodec/nvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 3c68ed3930..1f8c7e8c0e 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1860,7 +1860,7 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_fifo_freep2(&ctx->unused_surface_queue); if (ctx->frame_data_array) { -for (i = 0; i < ctx->nb_surfaces; i++) + for (i = 0; i < ctx->frame_data_array_nb; i++) av_buffer_unref(&ctx->frame_data_array[i].frame_opaque_ref); av_freep(&ctx->frame_data_array); } -- 2.37.3.windows.1 Jean-Noël GOOR - Senior Software Architect T. +32 4 361.58.70 jn.g...@evs.com EVS Broadcast Equipment - Rue Bois Saint Jean, 13 - 4102 Seraing - BELGIUM EVS Broadcast Equipment is a commercial name which is used for all legal entities of our group. At EVS we give utmost importance to your data's privacy. If you wish to know more on how we manage your data and on your rights, please consult our Privacy Statement. This message may contain confidential information and is intended solely for the use of the addressee. Please do not use or publish the contained information without the agreement of the sender. If you are not the intended recipient of this message, please notify the sender and do not disclose, use, disseminate or copy this message. Please consider the environment before printing this email. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] tools/general_assembly: restore printing HEAD
--- tools/general_assembly.pl | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/general_assembly.pl b/tools/general_assembly.pl index 3bf65f3405..13c13bb28f 100755 --- a/tools/general_assembly.pl +++ b/tools/general_assembly.pl @@ -139,5 +139,7 @@ foreach my $name (sort keys %assembly) { my $out_str = join("\n", @out_lines) . "\n"; utf8::encode($out_str); -printf("# GA for $since/$until; %d people; SHA256:%s\n%s", - scalar @out_lines, Digest::SHA::sha256_hex($out_str), $out_str); +printf("# GA for $since/$until; %d people; SHA256:%s; HEAD:%s%s", + scalar @out_lines, Digest::SHA::sha256_hex($out_str), + decode('UTF-8', `git rev-parse HEAD`, Encode::FB_CROAK), + $out_str); -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] tools/general_assembly: implement extra GA members
--- tools/general_assembly.pl | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tools/general_assembly.pl b/tools/general_assembly.pl index 4c3208ccac..3bf65f3405 100755 --- a/tools/general_assembly.pl +++ b/tools/general_assembly.pl @@ -13,6 +13,12 @@ use utf8; use DateTime; use DateTime::Format::ISO8601; +my @extra_members = ( +# entries should be of the format +# [ , , ], +# ['Foo Bar', 'foo@bar', DateTime->new(year => 8613, month => 5, day => 22)], +); + sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s }; sub print_help { @@ -29,7 +35,7 @@ sub print_help { my $print_full = 1; my $print_names = 0; my $print_emails = 0; -my $date = DateTime->now()->iso8601; +my $date_str = DateTime->now()->iso8601; my $help = 0; GetOptions( @@ -37,7 +43,7 @@ GetOptions( "names" => \$print_names, "emails" => \$print_emails, "help" => \$help, -"date=s" => \$date, +"date=s" => \$date_str, "h" => \$help, ); @@ -76,7 +82,8 @@ sub get_date_range { return ($date_since, $date_until); } -my ($since, $until) = get_date_range(DateTime::Format::ISO8601->parse_datetime($date)); +my $date = DateTime::Format::ISO8601->parse_datetime($date_str); +my ($since, $until) = get_date_range($date); my @shortlog = split /\n/, decode('UTF-8', `git log --pretty=format:"%aN <%aE>" --since="$since" --until="$until" | sort | uniq -c | sort -r`, @@ -108,6 +115,13 @@ foreach my $line (@shortlog) { $assembly{$name} = $email; } +foreach my $entry (@extra_members) { +my $elected = $entry->[2]; +if ($date->is_between($elected, $elected->clone()->set_year($elected->year + 2))) { +$assembly{$entry->[0]} = $entry->[1]; +} +} + # generate the output string my @out_lines; foreach my $name (sort keys %assembly) { -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2] avcodec/amfenc: add smart access video option
This commit adds option for enabling SmartAccess Video (SAV) in AMF encoders. SAV is an AMD hardware-specific feature which enables the parallelization of encode and decode streams across multiple Video Codec Engine (VCN) hardware instances. Signed-off-by: Evgeny Pavlov --- libavcodec/amfenc.h | 1 + libavcodec/amfenc_av1.c | 18 ++ libavcodec/amfenc_h264.c | 18 ++ libavcodec/amfenc_hevc.c | 18 ++ 4 files changed, 55 insertions(+) diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h index 2dbd378ef8..e8d66164ed 100644 --- a/libavcodec/amfenc.h +++ b/libavcodec/amfenc.h @@ -89,6 +89,7 @@ typedef struct AmfContext { int quality; int b_frame_delta_qp; int ref_b_frame_delta_qp; +int smart_access_video; // Dynamic options, can be set after Init() call diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c index 3f164ccc59..912d6bf020 100644 --- a/libavcodec/amfenc_av1.c +++ b/libavcodec/amfenc_av1.c @@ -104,6 +104,8 @@ static const AVOption options[] = { { "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{.i64 = 0 }, 0, 1, VE }, +{ "smart_access_video", "Enable Smart Access Video", OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE}, + //Pre Analysis options { "preanalysis","Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE }, @@ -243,6 +245,22 @@ FF_ENABLE_DEPRECATION_WARNINGS } } +if (ctx->smart_access_video != -1) { +AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0); +if (res != AMF_OK) { +av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF.\n"); +if (ctx->smart_access_video != 0) +return AVERROR(ENOSYS); +} else { +av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video); +// Set low latency mode if Smart Access Video is enabled +if (ctx->smart_access_video != 0) { +AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY); +av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode.\n"); +} +} +} + // Pre-Pass, Pre-Analysis, Two-Pass if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP) { AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_PREENCODE, 0); diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c index bd544d12df..b0b47645fc 100644 --- a/libavcodec/amfenc_h264.c +++ b/libavcodec/amfenc_h264.c @@ -136,6 +136,8 @@ static const AVOption options[] = { { "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, +{ "smart_access_video", "Enable Smart Access Video", OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE}, + //Pre Analysis options { "preanalysis","Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE }, @@ -353,6 +355,22 @@ FF_ENABLE_DEPRECATION_WARNINGS av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n"); } +if (ctx->smart_access_video != -1) { +AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0); +if (res != AMF_OK) { +av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF.\n"); +if (ctx->smart_access_video != 0) +return AVERROR(ENOSYS); +} else { +av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video); +// Set low latency mode if Smart Access Video is enabled +if (ctx->smart_access_video != 0) { +AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_LOWLATENCY_MODE, true); +av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode.\n"); +} +} +} + if (ctx->preanalysis != -1) { AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE, !!((ctx->preanalysis == 0) ? false : true)); } diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c index 352564a301..a5b6b15ef7 100644 --- a/libavcodec/amfenc_hevc
[FFmpeg-devel] [PATCH v6 2/7] avcodec/webp: remove unused definitions
--- libavcodec/webp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 4994781a64..286e7c8b73 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -60,8 +60,6 @@ #define VP8X_FLAG_ALPHA 0x10 #define VP8X_FLAG_ICC 0x20 -#define MAX_PALETTE_SIZE256 -#define MAX_CACHE_BITS 11 #define NUM_CODE_LENGTH_CODES 19 #define HUFFMAN_CODES_PER_META_CODE 5 #define NUM_LITERAL_CODES 256 -- 2.37.1 (Apple Git-137.1) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 3/7] avcodec/webp_parser: parse each frame into one packet
--- libavcodec/webp_parser.c | 130 +++ 1 file changed, 89 insertions(+), 41 deletions(-) diff --git a/libavcodec/webp_parser.c b/libavcodec/webp_parser.c index bd5f94dac5..da853bb1f5 100644 --- a/libavcodec/webp_parser.c +++ b/libavcodec/webp_parser.c @@ -25,13 +25,17 @@ #include "libavutil/bswap.h" #include "libavutil/common.h" +#include "libavutil/intreadwrite.h" #include "parser.h" typedef struct WebPParseContext { ParseContext pc; +int frame; +int first_frame; uint32_t fsize; -uint32_t remaining_size; +uint32_t remaining_file_size; +uint32_t remaining_tag_size; } WebPParseContext; static int webp_parse(AVCodecParserContext *s, AVCodecContext *avctx, @@ -41,62 +45,106 @@ static int webp_parse(AVCodecParserContext *s, AVCodecContext *avctx, WebPParseContext *ctx = s->priv_data; uint64_t state = ctx->pc.state64; int next = END_NOT_FOUND; -int i = 0; +int i, len; -*poutbuf = NULL; -*poutbuf_size = 0; - -restart: -if (ctx->pc.frame_start_found <= 8) { -for (; i < buf_size; i++) { +for (i = 0; i < buf_size;) { +if (ctx->remaining_tag_size) { +/* consuming tag */ +len = FFMIN(ctx->remaining_tag_size, buf_size - i); +i += len; +ctx->remaining_tag_size -= len; +ctx->remaining_file_size -= len; +} else { +/* scan for the next tag or file */ state = (state << 8) | buf[i]; -if (ctx->pc.frame_start_found == 0) { -if ((state >> 32) == MKBETAG('R', 'I', 'F', 'F')) { -ctx->fsize = av_bswap32(state); -if (ctx->fsize > 15 && ctx->fsize <= UINT32_MAX - 10) { -ctx->pc.frame_start_found = 1; -ctx->fsize += 8; +i++; + +if (!ctx->remaining_file_size) { +/* scan for the next file */ +if (ctx->pc.frame_start_found == 4) { +ctx->pc.frame_start_found = 0; +if ((uint32_t) state == MKBETAG('W', 'E', 'B', 'P')) { +if (ctx->frame || i != 12) { +ctx->frame = 0; +next = i - 12; +state = 0; +ctx->pc.frame_start_found = 0; +break; +} +ctx->remaining_file_size = ctx->fsize - 4; +ctx->first_frame = 1; +continue; } } -} else if (ctx->pc.frame_start_found == 8) { -if ((state >> 32) != MKBETAG('W', 'E', 'B', 'P')) { +if (ctx->pc.frame_start_found == 0) { +if ((state >> 32) == MKBETAG('R', 'I', 'F', 'F')) { +ctx->fsize = av_bswap32(state); +if (ctx->fsize > 15 && ctx->fsize <= UINT32_MAX - 10) { +ctx->fsize += (ctx->fsize & 1); +ctx->pc.frame_start_found = 1; +} +} +} else +ctx->pc.frame_start_found++; +} else { +/* read the next tag */ +ctx->remaining_file_size--; +if (ctx->remaining_file_size == 0) { ctx->pc.frame_start_found = 0; continue; } ctx->pc.frame_start_found++; -ctx->remaining_size = ctx->fsize + i - 15; -if (ctx->pc.index + i > 15) { -next = i - 15; -state = 0; +if (ctx->pc.frame_start_found < 8) +continue; + +switch (state >> 32) { +case MKBETAG('A', 'N', 'M', 'F'): +case MKBETAG('V', 'P', '8', ' '): +case MKBETAG('V', 'P', '8', 'L'): +if (ctx->frame) { +ctx->frame = 0; +next = i - 8; +state = 0; +ctx->pc.frame_start_found = 0; +goto flush; +} +ctx->frame = 1; +break; +default: break; -} else { -ctx->pc.state64 = 0; -goto restart; } -} else if (ctx->pc.frame_start_found) -ctx->pc.frame_start_found++; -} -ctx->pc.state64 = state; -} else { -if (ctx->remaining_size) { -i = FFMIN(ctx->remaining_size, buf_size); -ctx->remaining_size -= i; -if (ctx->remaining_size) -goto flush; -ctx->pc.frame_start_found = 0; -goto res
[FFmpeg-devel] [PATCH v6 1/7] avcodec/webp: move definitions into header
--- libavcodec/webp.c | 1 + libavcodec/webp.h | 38 ++ 2 files changed, 39 insertions(+) create mode 100644 libavcodec/webp.h diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 54b3fde6dc..4994781a64 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -52,6 +52,7 @@ #include "thread.h" #include "tiff_common.h" #include "vp8.h" +#include "webp.h" #define VP8X_FLAG_ANIMATION 0x02 #define VP8X_FLAG_XMP_METADATA 0x04 diff --git a/libavcodec/webp.h b/libavcodec/webp.h new file mode 100644 index 00..53bf59e7cd --- /dev/null +++ b/libavcodec/webp.h @@ -0,0 +1,38 @@ +/* + * WebP image format definitions + * Copyright (c) 2020 Pexeso Inc. + * + * 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 + */ + +/** + * @file + * WebP image format definitions. + */ + +#ifndef AVCODEC_WEBP_H +#define AVCODEC_WEBP_H + +#define ANMF_DISPOSAL_METHOD0x01 +#define ANMF_DISPOSAL_METHOD_UNCHANGED 0x00 +#define ANMF_DISPOSAL_METHOD_BACKGROUND 0x01 + +#define ANMF_BLENDING_METHOD0x02 +#define ANMF_BLENDING_METHOD_ALPHA 0x00 +#define ANMF_BLENDING_METHOD_OVERWRITE 0x02 + +#endif /* AVCODEC_WEBP_H */ -- 2.37.1 (Apple Git-137.1) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 0/7] webp: add support for animated WebP decoding
Still images fixed, includes FATE tests, VP8 decoder decoupled so there are no more data races, fixed more asserts. Patch 5/7 is still there for making changes in lavc/webp reviewable but shall be stashed when pushing. -Thilo Josef Zlomek (2): libavcodec/webp: add support for animated WebP decoding libavformat/webp: add WebP demuxer Thilo Borgmann (5): avcodec/webp: move definitions into header avcodec/webp: remove unused definitions avcodec/webp_parser: parse each frame into one packet avcodec/webp: make init_canvas_frame static fate: add test for animated WebP Changelog | 2 + doc/demuxers.texi | 28 + libavcodec/codec_desc.c | 3 +- libavcodec/version.h| 2 +- libavcodec/webp.c | 758 ++-- libavcodec/webp.h | 38 + libavcodec/webp_parser.c| 130 ++-- libavformat/Makefile| 1 + libavformat/allformats.c| 1 + libavformat/version.h | 2 +- libavformat/webpdec.c | 733 +++ tests/fate/image.mak| 3 + tests/ref/fate/exif-image-webp | 12 +- tests/ref/fate/webp-anim| 22 + tests/ref/fate/webp-rgb-lena-lossless | 2 +- tests/ref/fate/webp-rgb-lena-lossless-rgb24 | 2 +- tests/ref/fate/webp-rgb-lossless| 2 +- tests/ref/fate/webp-rgb-lossy-q80 | 2 +- tests/ref/fate/webp-rgba-lossless | 2 +- tests/ref/fate/webp-rgba-lossy-q80 | 2 +- 20 files changed, 1625 insertions(+), 122 deletions(-) create mode 100644 libavcodec/webp.h create mode 100644 libavformat/webpdec.c create mode 100644 tests/ref/fate/webp-anim -- 2.37.1 (Apple Git-137.1) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 6/7] libavformat/webp: add WebP demuxer
From: Josef Zlomek Adds the demuxer of animated WebP files. It supports non-animated, animated, truncated, and concatenated files. Reading from a pipe (and other non-seekable inputs) is also supported. The WebP demuxer splits the input stream into packets containing one frame. It also marks the key frames properly. The loop count is ignored by default (same behaviour as animated PNG and GIF), it may be enabled by the option '-ignore_loop 0'. The frame rate is set according to the frame delay in the ANMF chunk. If the delay is too low, or the image is not animated, the default frame rate is set to 10 fps, similarly to other WebP libraries and browsers. The fate suite was updated accordingly. Signed-off-by: Josef Zlomek --- Changelog | 1 + doc/demuxers.texi | 28 + libavformat/Makefile| 1 + libavformat/allformats.c| 1 + libavformat/version.h | 2 +- libavformat/webpdec.c | 733 tests/ref/fate/exif-image-webp | 12 +- tests/ref/fate/webp-rgb-lena-lossless | 2 +- tests/ref/fate/webp-rgb-lena-lossless-rgb24 | 2 +- tests/ref/fate/webp-rgb-lossless| 2 +- tests/ref/fate/webp-rgb-lossy-q80 | 2 +- tests/ref/fate/webp-rgba-lossless | 2 +- tests/ref/fate/webp-rgba-lossy-q80 | 2 +- 13 files changed, 777 insertions(+), 13 deletions(-) create mode 100644 libavformat/webpdec.c diff --git a/Changelog b/Changelog index 8f34660767..fce4cda7ba 100644 --- a/Changelog +++ b/Changelog @@ -44,6 +44,7 @@ version 6.1: variable-fields elements within the same parent element - ffprobe -output_format option added as an alias of -of - animated WebP parser/decoder +- animated WebP demuxer version 6.0: diff --git a/doc/demuxers.texi b/doc/demuxers.texi index e4c5b560a6..fcb9f9ee3c 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -943,4 +943,32 @@ which in turn, acts as a ceiling for the size of scripts that can be read. Default is 1 MiB. @end table +@section webp + +Animated WebP demuxer. + +It accepts the following options: + +@table @option +@item -min_delay @var{int} +Set the minimum valid delay between frames in milliseconds. +Range is 0 to 6. Default value is 10. + +@item -max_webp_delay @var{int} +Set the maximum valid delay between frames in milliseconds. +Range is 0 to 16777215. Default value is 16777215 (over four hours), +the maximum value allowed by the specification. + +@item -default_delay @var{int} +Set the default delay between frames in milliseconds. +Range is 0 to 6. Default value is 100. + +@item -ignore_loop @var{bool} +WebP files can contain information to loop a certain number of times +(or infinitely). If @option{ignore_loop} is set to true, then the loop +setting from the input will be ignored and looping will not occur. +If set to false, then looping will occur and will cycle the number +of times according to the WebP. Default value is true. +@end table + @c man end DEMUXERS diff --git a/libavformat/Makefile b/libavformat/Makefile index 329055ccfd..4f0379f13b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -618,6 +618,7 @@ OBJS-$(CONFIG_WEBM_MUXER)+= matroskaenc.o matroska.o \ av1.o avlanguage.o OBJS-$(CONFIG_WEBM_DASH_MANIFEST_MUXER) += webmdashenc.o OBJS-$(CONFIG_WEBM_CHUNK_MUXER) += webm_chunk.o +OBJS-$(CONFIG_WEBP_DEMUXER) += webpdec.o OBJS-$(CONFIG_WEBP_MUXER)+= webpenc.o OBJS-$(CONFIG_WEBVTT_DEMUXER)+= webvttdec.o subtitles.o OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index d4b505a5a3..d80c2f73a5 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -502,6 +502,7 @@ extern const AVInputFormat ff_webm_dash_manifest_demuxer; extern const FFOutputFormat ff_webm_dash_manifest_muxer; extern const FFOutputFormat ff_webm_chunk_muxer; extern const FFOutputFormat ff_webp_muxer; +extern const AVInputFormat ff_webp_demuxer; extern const AVInputFormat ff_webvtt_demuxer; extern const FFOutputFormat ff_webvtt_muxer; extern const AVInputFormat ff_wsaud_demuxer; diff --git a/libavformat/version.h b/libavformat/version.h index 2a28a3bf40..3d85862bc1 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 17 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/libavformat/webpdec.c b/libavformat/webpdec.c new file mode 100644 index 00..b4024809f7 --- /dev/null +++ b/libavformat/webpdec.c @@ -0,0 +1,733 @@ +
[FFmpeg-devel] [PATCH v6 4/7] libavcodec/webp: add support for animated WebP decoding
From: Josef Zlomek Fixes: 4907 Adds support for decoding of animated WebP. The WebP decoder adds the animation related features according to the specs: https://developers.google.com/speed/webp/docs/riff_container#animation The frames of the animation may be smaller than the image canvas. Therefore, the frame is decoded to a temporary frame, then it is blended into the canvas, the canvas is copied to the output frame, and finally the frame is disposed from the canvas. The output to AV_PIX_FMT_YUVA420P/AV_PIX_FMT_YUV420P is still supported. The background color is specified only as BGRA in the WebP file so it is converted to YUVA if YUV formats are output. Signed-off-by: Josef Zlomek --- Changelog | 1 + libavcodec/codec_desc.c | 3 +- libavcodec/version.h| 2 +- libavcodec/webp.c | 763 4 files changed, 700 insertions(+), 69 deletions(-) diff --git a/Changelog b/Changelog index 7d79be1c3e..8f34660767 100644 --- a/Changelog +++ b/Changelog @@ -43,6 +43,7 @@ version 6.1: - ffprobe XML output schema changed to account for multiple variable-fields elements within the same parent element - ffprobe -output_format option added as an alias of -of +- animated WebP parser/decoder version 6.0: diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 432a9c9ea6..2ab975f8d7 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1259,8 +1259,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_VIDEO, .name = "webp", .long_name = NULL_IF_CONFIG_SMALL("WebP"), -.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | - AV_CODEC_PROP_LOSSLESS, +.props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, .mime_types= MT("image/webp"), }, { diff --git a/libavcodec/version.h b/libavcodec/version.h index 0ef6c991f3..0a91c6b916 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #include "version_major.h" #define LIBAVCODEC_VERSION_MINOR 34 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 286e7c8b73..5e77902128 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -35,12 +35,16 @@ * Exif metadata * ICC profile * + * @author Josef Zlomek, Pexeso Inc. + * Animation + * * Unimplemented: - * - Animation * - XMP metadata */ +#include "libavcodec/packet.h" #include "libavutil/imgutils.h" +#include "libavutil/colorspace.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -192,9 +196,12 @@ typedef struct ImageContext { typedef struct WebPContext { VP8Context v; /* VP8 Context used for lossy decoding */ GetBitContext gb; /* bitstream reader for main image chunk */ +ThreadFrame canvas_frame; /* ThreadFrame for canvas */ +AVFrame *frame; /* AVFrame for decoded frame */ AVFrame *alpha_frame; /* AVFrame for alpha data decompressed from VP8L */ AVPacket *pkt; /* AVPacket to be passed to the underlying VP8 decoder */ AVCodecContext *avctx; /* parent AVCodecContext */ +AVCodecContext *avctx_vp8; /* wrapper context for VP8 decoder */ int initialized;/* set once the VP8 context is initialized */ int has_alpha; /* has a separate alpha chunk */ enum AlphaCompression alpha_compression; /* compression type for alpha chunk */ @@ -203,9 +210,24 @@ typedef struct WebPContext { int alpha_data_size;/* alpha chunk data size */ int has_exif; /* set after an EXIF chunk has been processed */ int has_iccp; /* set after an ICCP chunk has been processed */ -int width; /* image width */ -int height; /* image height */ -int lossless; /* indicates lossless or lossy */ +int vp8x_flags; /* global flags from VP8X chunk */ +int canvas_width; /* canvas width */ +int canvas_height; /* canvas height */ +int anmf_flags; /* frame flags from ANMF chunk */ +int width; /* frame width */ +int height; /* frame height */ +int pos_x; /* frame position X */ +int pos_y; /* frame position Y */ +int prev_anmf_flags;/* previous frame flags from ANMF chunk */ +int prev_width; /* previous frame width */ +int prev_height;
[FFmpeg-devel] [PATCH v6 7/7] fate: add test for animated WebP
--- tests/fate/image.mak | 3 +++ tests/ref/fate/webp-anim | 22 ++ 2 files changed, 25 insertions(+) create mode 100644 tests/ref/fate/webp-anim diff --git a/tests/fate/image.mak b/tests/fate/image.mak index 400199c28a..2e0d1e8e3f 100644 --- a/tests/fate/image.mak +++ b/tests/fate/image.mak @@ -567,6 +567,9 @@ fate-webp-rgb-lossy-q80: CMD = framecrc -i $(TARGET_SAMPLES)/webp/rgb_q80.webp FATE_WEBP += fate-webp-rgba-lossy-q80 fate-webp-rgba-lossy-q80: CMD = framecrc -i $(TARGET_SAMPLES)/webp/rgba_q80.webp +FATE_WEBP += fate-webp-anim +fate-webp-anim: CMD = framecrc -i $(TARGET_SAMPLES)/webp/130227-100431-6817p.webp + FATE_WEBP-$(call DEMDEC, IMAGE2, WEBP) += $(FATE_WEBP) FATE_IMAGE_FRAMECRC += $(FATE_WEBP-yes) fate-webp: $(FATE_WEBP-yes) diff --git a/tests/ref/fate/webp-anim b/tests/ref/fate/webp-anim new file mode 100644 index 00..1baef9f7fb --- /dev/null +++ b/tests/ref/fate/webp-anim @@ -0,0 +1,22 @@ +#tb 0: 2/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 100x70 +#sar 0: 0/1 +0, 0, 0,1,28000, 0x2023ba6e +0, 1, 1,1,28000, 0x4292b778 +0, 2, 2,1,28000, 0x9772a187 +0, 3, 3,1,28000, 0xa98d8d04 +0, 4, 4,1,28000, 0xd323b6af +0, 5, 5,1,28000, 0x508aba99 +0, 6, 6,1,28000, 0x5c672dda +0, 7, 7,1,28000, 0xcc992d59 +0, 8, 8, 12,28000, 0x82460e1b +0, 21, 21,1,28000, 0x3debbfc9 +0, 22, 22,1,28000, 0x427ab31f +0, 23, 23,1,28000, 0x6bbdec2e +0, 24, 24,1,28000, 0x5690b56b +0, 25, 25,1,28000, 0xb62963f3 +0, 26, 26,1,28000, 0x68dd37b2 +0, 27, 27,1,28000, 0x465c47d2 +0, 28, 28, 125,28000, 0x465c47d2 -- 2.37.1 (Apple Git-137.1) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 5/7] avcodec/webp: make init_canvas_frame static
--- libavcodec/webp.c | 142 +++--- 1 file changed, 70 insertions(+), 72 deletions(-) diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 5e77902128..7e79bd3212 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -1367,7 +1367,76 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, return ret; } -int init_canvas_frame(WebPContext *s, int format, int key_frame); +static int init_canvas_frame(WebPContext *s, int format, int key_frame) +{ +AVFrame *canvas = s->canvas_frame.f; +int height; +int ret; + +// canvas is needed only for animation +if (!(s->vp8x_flags & VP8X_FLAG_ANIMATION)) +return 0; + +// avoid init for non-key frames whose format and size did not change +if (!key_frame && +canvas->data[0] && +canvas->format == format && +canvas->width == s->canvas_width && +canvas->height == s->canvas_height) +return 0; + +// canvas changes within IPPP sequences will lose thread sync +// because of the ThreadFrame reallocation and will wait forever +// so if frame-threading is used, forbid canvas changes and unlock +// previous frames +if (!key_frame && canvas->data[0]) { +if (s->avctx->thread_count > 1) { +av_log(s->avctx, AV_LOG_WARNING, "Canvas change detected. The output will be damaged. Use -threads 1 to try decoding with best effort.\n"); +// unlock previous frames that have sent an _await() call +ff_thread_report_progress(&s->canvas_frame, INT_MAX, 0); +return AVERROR_PATCHWELCOME; +} else { +// warn for damaged frames +av_log(s->avctx, AV_LOG_WARNING, "Canvas change detected. The output will be damaged.\n"); +} +} + +s->avctx->pix_fmt = format; +canvas->format= format; +canvas->width = s->canvas_width; +canvas->height= s->canvas_height; + +// VP8 decoder changed the width and height in AVCodecContext. +// Change it back to the canvas size. +ret = ff_set_dimensions(s->avctx, s->canvas_width, s->canvas_height); +if (ret < 0) +return ret; + +ff_thread_release_ext_buffer(&s->canvas_frame); +ret = ff_thread_get_ext_buffer(s->avctx, &s->canvas_frame, AV_GET_BUFFER_FLAG_REF); +if (ret < 0) +return ret; + +if (canvas->format == AV_PIX_FMT_ARGB) { +height = canvas->height; +memset(canvas->data[0], 0, height * canvas->linesize[0]); +} else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ { +const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(canvas->format); +for (int comp = 0; comp < desc->nb_components; comp++) { +int plane = desc->comp[comp].plane; + +if (comp == 1 || comp == 2) +height = AV_CEIL_RSHIFT(canvas->height, desc->log2_chroma_h); +else +height = FFALIGN(canvas->height, 1 << desc->log2_chroma_h); + +memset(canvas->data[plane], s->transparent_yuva[plane], + height * canvas->linesize[plane]); +} +} + +return 0; +} static int webp_decode_frame_common(AVCodecContext *avctx, uint8_t *data, int size, int *got_frame, int key_frame) @@ -1606,77 +1675,6 @@ exif_end: return size; } -int init_canvas_frame(WebPContext *s, int format, int key_frame) -{ -AVFrame *canvas = s->canvas_frame.f; -int height; -int ret; - -// canvas is needed only for animation -if (!(s->vp8x_flags & VP8X_FLAG_ANIMATION)) -return 0; - -// avoid init for non-key frames whose format and size did not change -if (!key_frame && -canvas->data[0] && -canvas->format == format && -canvas->width == s->canvas_width && -canvas->height == s->canvas_height) -return 0; - -// canvas changes within IPPP sequences will loose thread sync -// because of the ThreadFrame reallocation and will wait forever -// so if frame-threading is used, forbid canvas changes and unlock -// previous frames -if (!key_frame && canvas->data[0]) { -if (s->avctx->thread_count > 1) { -av_log(s->avctx, AV_LOG_WARNING, "Canvas change detected. The output will be damaged. Use -threads 1 to try decoding with best effort.\n"); -// unlock previous frames that have sent an _await() call -ff_thread_report_progress(&s->canvas_frame, INT_MAX, 0); -return AVERROR_PATCHWELCOME; -} else { -// warn for damaged frames -av_log(s->avctx, AV_LOG_WARNING, "Canvas change detected. The output will be damaged.\n"); -} -} - -s->avctx->pix_fmt = format; -canvas->format= format; -canvas->width = s->canvas_width; -canvas->height= s->canvas_height; - -// VP8 decoder changed the width and height in AVCodecContext. -// Change it back
Re: [FFmpeg-devel] [PATCH 2/3] x86/ac3dsp: add ff_float_to_fixed24_avx2()
On 11/23/2023 3:56 AM, Kieran Kunhya wrote: On Wed, 22 Nov 2023, 19:49 James Almer, wrote: Signed-off-by: James Almer --- libavcodec/ac3dsp.h | 4 ++-- libavcodec/ac3enc_template.c | 2 +- libavcodec/x86/ac3dsp.asm| 28 ++-- libavcodec/x86/ac3dsp_init.c | 4 4 files changed, 33 insertions(+), 5 deletions(-) I think this is AVX, I might be wrong but I don't see any AVX2. Kieran movdqa wiht ymm is avx2. I could change it to movaps, but technically the registers contain floats and i don't know if any old AVX cpu has penalties for changing domains. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] fftools/ffplay_renderer: declare function argument as const
Declaring the function argument as const fixes a warning down the line that the const parameter is stripped. We don't modify this argument. Signed-off-by: Leo Izen --- fftools/ffplay_renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fftools/ffplay_renderer.c b/fftools/ffplay_renderer.c index a57e4980eb..45ca84fa95 100644 --- a/fftools/ffplay_renderer.c +++ b/fftools/ffplay_renderer.c @@ -133,7 +133,7 @@ static const char *optional_device_exts[] = { "VK_MESA_video_decode_av1", }; -static inline int enable_debug(AVDictionary *opt) +static inline int enable_debug(const AVDictionary *opt) { AVDictionaryEntry *entry = av_dict_get(opt, "debug", NULL, 0); int debug = entry && strtol(entry->value, NULL, 10); -- 2.42.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/3] x86/ac3dsp: add ff_float_to_fixed24_avx2()
On Thu, Nov 23, 2023 at 12:51 PM James Almer wrote: > movdqa wiht ymm is avx2. I could change it to movaps, but technically > the registers contain floats and i don't know if any old AVX cpu has > penalties for changing domains. Fwiw I believe what domain the result of fp <-> int conversion instructions belongs to actually differs between µarchs. Realistically whether movaps or movdqa is used to store the result to memory is unlikely to matter in practice though. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3] avformat/hls: use av_strlcopy instead of strncpy
Avoids a -Wstringop-truncation warning by using av_strlcopy instead of strncpy. Additionally, prints a warning to the log context if this truncation occurred. Signed-off-by: Leo Izen --- libavformat/hls.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index f5f549b24d..61e2d67588 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -540,11 +540,16 @@ static struct rendition *new_rendition(HLSContext *c, struct rendition_info *inf } if (info->assoc_language[0]) { -int langlen = strlen(rend->language); +size_t langlen = strlen(rend->language); if (langlen < sizeof(rend->language) - 3) { +size_t assoc_len; rend->language[langlen] = ','; -strncpy(rend->language + langlen + 1, info->assoc_language, -sizeof(rend->language) - langlen - 2); +assoc_len = av_strlcpy(rend->language + langlen + 1, + info->assoc_language, + sizeof(rend->language) - langlen - 1); +if (langlen + assoc_len + 2 > sizeof(rend->language)) // truncation occurred +av_log(c->ctx, AV_LOG_WARNING, "Truncated rendition language: %s\n", + info->assoc_language); } } -- 2.42.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] checkasm/ac3dsp: add float_to_fixed24 test
Le torstaina 23. marraskuuta 2023, 9.08.16 EET flow gg a écrit : > You should probably add the test case to tests/fate/checkasm.mak -- レミ・デニ-クールモン http://www.remlab.net/ ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] ac3dsp: RISC-V V float_to_fixed24
Le torstaina 23. marraskuuta 2023, 1.17.03 EET flow gg a écrit : > Hello, I saw the new commit "avcodec/ac3dsp: make len a size_t in > float_to_fixed24." > > So I removed the part #if (__riscv_xlen == 64) and restored the patch. You're not checking for Zba. Also 'bnez' would be more logical than 'bgtz' for an unsigned counter. -- レミ・デニ-クールモン http://www.remlab.net/ ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] checkasm/ac3dsp: add float_to_fixed24 test
On 11/23/2023 4:08 AM, flow gg wrote: +static void check_float_to_fixed24(AC3DSPContext *c) { +#define BUF_SIZE 1024 +LOCAL_ALIGNED_32(int32_t, v1, [BUF_SIZE]); This one is not necessary. You can reuse dst or dst2 for the bench() as it's write only. +LOCAL_ALIGNED_32(float, v2, [BUF_SIZE]); + +declare_func(void, int32_t *, const float *, unsigned int); + +randomize_float(v2, BUF_SIZE); + +if (check_func(c->float_to_fixed24, "float_to_fixed24")) { +LOCAL_ALIGNED_32(int32_t, dst, [BUF_SIZE]); +LOCAL_ALIGNED_32(int32_t, dst2, [BUF_SIZE]); + +call_ref(dst, v2, BUF_SIZE); +call_new(dst2, v2, BUF_SIZE); + +if (memcmp(dst, dst2, sizeof(*dst) * 10) != 0) BUF_SIZE instead of 10. +fail(); + +bench_new(v1, v2, BUF_SIZE); +} + + +report("float_to_fixed24"); +} ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 01/13] lavfi/buffersink: avoid leaking peeked_frame on uninit
--- libavfilter/buffersink.c | 9 + 1 file changed, 9 insertions(+) diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index ca2af1bc07..3da3331159 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -164,6 +164,13 @@ static av_cold int common_init(AVFilterContext *ctx) return 0; } +static void uninit(AVFilterContext *ctx) +{ +BufferSinkContext *buf = ctx->priv; + +av_frame_free(&buf->peeked_frame); +} + static int activate(AVFilterContext *ctx) { BufferSinkContext *buf = ctx->priv; @@ -385,6 +392,7 @@ const AVFilter ff_vsink_buffer = { .priv_size = sizeof(BufferSinkContext), .priv_class= &buffersink_class, .init = common_init, +.uninit= uninit, .activate = activate, FILTER_INPUTS(ff_video_default_filterpad), .outputs = NULL, @@ -397,6 +405,7 @@ const AVFilter ff_asink_abuffer = { .priv_class= &abuffersink_class, .priv_size = sizeof(BufferSinkContext), .init = common_init, +.uninit= uninit, .activate = activate, FILTER_INPUTS(ff_audio_default_filterpad), .outputs = NULL, -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 04/13] fftools/ffmpeg: make sure FrameData is writable when we modify it
Also, add a function that returns const FrameData* for cases that only read from it. --- fftools/ffmpeg.c| 21 + fftools/ffmpeg.h| 2 ++ fftools/ffmpeg_filter.c | 4 ++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index cdb16ef90b..61fcda2526 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -427,21 +427,34 @@ InputStream *ist_iter(InputStream *prev) return NULL; } -FrameData *frame_data(AVFrame *frame) +static int frame_data_ensure(AVFrame *frame, int writable) { if (!frame->opaque_ref) { FrameData *fd; frame->opaque_ref = av_buffer_allocz(sizeof(*fd)); if (!frame->opaque_ref) -return NULL; +return AVERROR(ENOMEM); fd = (FrameData*)frame->opaque_ref->data; fd->dec.frame_num = UINT64_MAX; fd->dec.pts = AV_NOPTS_VALUE; -} +} else if (writable) +return av_buffer_make_writable(&frame->opaque_ref); -return (FrameData*)frame->opaque_ref->data; +return 0; +} + +FrameData *frame_data(AVFrame *frame) +{ +int ret = frame_data_ensure(frame, 1); +return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data; +} + +const FrameData *frame_data_c(AVFrame *frame) +{ +int ret = frame_data_ensure(frame, 0); +return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data; } void remove_avoptions(AVDictionary **a, AVDictionary *b) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 41935d39d5..1f11a2f002 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -726,6 +726,8 @@ int subtitle_wrap_frame(AVFrame *frame, AVSubtitle *subtitle, int copy); */ FrameData *frame_data(AVFrame *frame); +const FrameData *frame_data_c(AVFrame *frame); + int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference); int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb); int ifilter_sub2video(InputFilter *ifilter, const AVFrame *frame); diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index f942c97c40..69c28a6b2b 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1859,9 +1859,9 @@ static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame) FPSConvContext *fps = &ofp->fps; AVRationaltb = (AVRational){ 0, 0 }; AVRational fr; -FrameData *fd; +const FrameData *fd; -fd = frame_data(frame); +fd = frame_data_c(frame); // apply -enc_time_base if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX && -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 03/13] fftools/ffmpeg_filter: track input/output index in {Input, Output}FilterPriv
Will be useful in following commits. --- fftools/ffmpeg_filter.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index b6fbc5b195..f942c97c40 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -74,6 +74,8 @@ static const FilterGraphPriv *cfgp_from_cfg(const FilterGraph *fg) typedef struct InputFilterPriv { InputFilter ifilter; +int index; + AVFilterContext *filter; InputStream *ist; @@ -162,6 +164,8 @@ typedef struct FPSConvContext { typedef struct OutputFilterPriv { OutputFilterofilter; +int index; + AVFilterContext*filter; /* desired output stream properties */ @@ -594,6 +598,7 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg) ofilter = &ofp->ofilter; ofilter->graph= fg; ofp->format = -1; +ofp->index= fg->nb_outputs - 1; ofilter->last_pts = AV_NOPTS_VALUE; return ofilter; @@ -787,6 +792,7 @@ static InputFilter *ifilter_alloc(FilterGraph *fg) if (!ifp->frame) return NULL; +ifp->index = fg->nb_inputs - 1; ifp->format = -1; ifp->fallback.format = -1; -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 05/13] fftools/ffmpeg_filter: move filtering to a separate thread
As previously for decoding, this is merely "scaffolding" for moving to a fully threaded architecture and does not yet make filtering truly parallel - the main thread will currently wait for the filtering thread to finish its work before continuing. That will change in future commits after encoders are also moved to threads and a thread-aware scheduler is added. --- fftools/ffmpeg.h| 9 +- fftools/ffmpeg_dec.c| 39 +- fftools/ffmpeg_filter.c | 825 ++-- 3 files changed, 730 insertions(+), 143 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 1f11a2f002..f50222472c 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -80,6 +80,14 @@ enum HWAccelID { HWACCEL_GENERIC, }; +enum FrameOpaque { +FRAME_OPAQUE_REAP_FILTERS = 1, +FRAME_OPAQUE_CHOOSE_INPUT, +FRAME_OPAQUE_SUB_HEARTBEAT, +FRAME_OPAQUE_EOF, +FRAME_OPAQUE_SEND_COMMAND, +}; + typedef struct HWDevice { const char *name; enum AVHWDeviceType type; @@ -730,7 +738,6 @@ const FrameData *frame_data_c(AVFrame *frame); int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference); int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb); -int ifilter_sub2video(InputFilter *ifilter, const AVFrame *frame); void ifilter_sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb); /** diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 517d6b3ced..b60bad1220 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -147,11 +147,12 @@ fail: static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame) { -int i, ret; +int i, ret = 0; -av_assert1(ist->nb_filters > 0); /* ensure ret is initialized */ for (i = 0; i < ist->nb_filters; i++) { -ret = ifilter_send_frame(ist->filters[i], decoded_frame, i < ist->nb_filters - 1); +ret = ifilter_send_frame(ist->filters[i], decoded_frame, + i < ist->nb_filters - 1 || + ist->dec->type == AVMEDIA_TYPE_SUBTITLE); if (ret == AVERROR_EOF) ret = 0; /* ignore */ if (ret < 0) { @@ -380,15 +381,6 @@ static int video_frame_process(InputStream *ist, AVFrame *frame) return 0; } -static void sub2video_flush(InputStream *ist) -{ -for (int i = 0; i < ist->nb_filters; i++) { -int ret = ifilter_sub2video(ist->filters[i], NULL); -if (ret != AVERROR_EOF && ret < 0) -av_log(NULL, AV_LOG_WARNING, "Flush the frame error.\n"); -} -} - static int process_subtitle(InputStream *ist, AVFrame *frame) { Decoder *d = ist->decoder; @@ -426,14 +418,9 @@ static int process_subtitle(InputStream *ist, AVFrame *frame) if (!subtitle) return 0; -for (int i = 0; i < ist->nb_filters; i++) { -ret = ifilter_sub2video(ist->filters[i], frame); -if (ret < 0) { -av_log(ist, AV_LOG_ERROR, "Error sending a subtitle for filtering: %s\n", - av_err2str(ret)); -return ret; -} -} +ret = send_frame_to_filters(ist, frame); +if (ret < 0) +return ret; subtitle = (AVSubtitle*)frame->buf[0]->data; if (!subtitle->num_rects) @@ -824,14 +811,10 @@ finish: return ret; // signal EOF to our downstreams -if (ist->dec->type == AVMEDIA_TYPE_SUBTITLE) -sub2video_flush(ist); -else { -ret = send_filter_eof(ist); -if (ret < 0) { -av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n"); -return ret; -} +ret = send_filter_eof(ist); +if (ret < 0) { +av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n"); +return ret; } return AVERROR_EOF; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 69c28a6b2b..1b964fc53f 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -21,6 +21,8 @@ #include #include "ffmpeg.h" +#include "ffmpeg_utils.h" +#include "thread_queue.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersink.h" @@ -53,12 +55,50 @@ typedef struct FilterGraphPriv { int is_meta; int disable_conversions; +int nb_inputs_bound; +int nb_outputs_bound; + const char *graph_desc; // frame for temporarily holding output from the filtergraph AVFrame *frame; // frame for sending output to the encoder AVFrame *frame_enc; + +pthread_tthread; +/** + * Queue for sending frames from the main thread to the filtergraph. Has + * nb_inputs+1 streams - the first nb_inputs stream correspond to + * filtergraph inputs. Frames on those streams may have their opaque set to + * - FRAME_OPAQUE_EOF: frame contains no data, but pts+timebase of the + * EOF event for the correspondint stream. Will be immediately followed by + * this stream being send-closed. +
[FFmpeg-devel] [PATCH 02/13] fftools/ffmpeg_filter: make sub2video heartbeat more robust
Avoid making decisions based on current graph input state, which makes the output dependent on the order in which the frames from different inputs are interleaved. Makes the output of fate-filter-overlay-dvdsub-2397 more correct - the subtitle appears two frames later, which is closer to its PTS as stored in the file. --- fftools/ffmpeg_filter.c | 3 +-- tests/ref/fate/filter-overlay-dvdsub-2397 | 4 ++-- tests/ref/fate/sub2video | 8 +--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index b7da105141..b6fbc5b195 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -2274,8 +2274,7 @@ void ifilter_sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational t or if we need to initialize the system, update the overlayed subpicture and its start/end times */ sub2video_update(ifp, pts2 + 1, NULL); - -if (av_buffersrc_get_nb_failed_requests(ifp->filter)) +else sub2video_push_ref(ifp, pts2); } diff --git a/tests/ref/fate/filter-overlay-dvdsub-2397 b/tests/ref/fate/filter-overlay-dvdsub-2397 index 7df4f50776..45c026f540 100644 --- a/tests/ref/fate/filter-overlay-dvdsub-2397 +++ b/tests/ref/fate/filter-overlay-dvdsub-2397 @@ -489,12 +489,12 @@ 1, 3877, 3877, 10, 2013, 0x95a39f9c 1, 3887, 3887, 10, 2013, 0x4f7ea123 1, 3897, 3897, 10, 2013, 0x9efb9ba1 -0,117,117,1, 518400, 0xbf8523da +0,117,117,1, 518400, 0x61e0f688 1, 3907, 3907, 10, 2013, 0xf395b2cd 1, 3917, 3917, 10, 2013, 0x261a881e 1, 3927, 3927, 10, 2013, 0x7f2d9f72 1, 3937, 3937, 10, 2013, 0x0105b38d -0,118,118,1, 518400, 0x41890ed6 +0,118,118,1, 518400, 0xa47de755 1, 3952, 3952, 10, 2013, 0x0e5db67e 1, 3962, 3962, 10, 2013, 0xfc9baf97 0,119,119,1, 518400, 0x588534fc diff --git a/tests/ref/fate/sub2video b/tests/ref/fate/sub2video index 80abe9c905..76347322f3 100644 --- a/tests/ref/fate/sub2video +++ b/tests/ref/fate/sub2video @@ -68,7 +68,8 @@ 0,258,258,1, 518400, 0x34cdddee 0,269,269,1, 518400, 0xbab197ea 1, 5391, 5391, 2696000, 2095, 0x61bb15ed -0,270,270,1, 518400, 0x4db4ce51 +0,270,270,1, 518400, 0xbab197ea +0,271,271,1, 518400, 0x4db4ce51 0,283,283,1, 518400, 0xbab197ea 1, 56663000, 56663000, 1262000, 1013, 0xc9ae89b7 0,284,284,1, 518400, 0xe6bc0ea9 @@ -137,7 +138,7 @@ 1, 168049000, 168049000, 190, 1312, 0x0bf20e8d 0,850,850,1, 518400, 0xbab197ea 1, 170035000, 170035000, 1524000, 1279, 0xb6c2dafe -0,851,851,1, 518400, 0x8780239e +0,851,851,1, 518400, 0xbab197ea 0,858,858,1, 518400, 0xbab197ea 0,861,861,1, 518400, 0x6eb72347 1, 172203000, 172203000, 1695000, 1826, 0x9a1ac769 @@ -161,7 +162,8 @@ 0,976,976,1, 518400, 0x923d1ce7 0,981,981,1, 518400, 0xbab197ea 1, 196361000, 196361000, 1524000, 1715, 0x695ca41e -0,982,982,1, 518400, 0x6e652cd2 +0,982,982,1, 518400, 0xbab197ea +0,983,983,1, 518400, 0x6e652cd2 0,989,989,1, 518400, 0xbab197ea 1, 197946000, 197946000, 116, 789, 0xc63a189e 0,990,990,1, 518400, 0x25113966 -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2] ffmpeg CLI multithreading
Hi, this is the updated version of the CLI multithreading set. All issues reported in the previous version should be fixed. The -fix_sub_duration_heartbeat option is enabled again, thanks to JEEB for testing. I've now merged the actual conversion patches into the last one, so every patch of the set should work in isolation. If you want to review conversions of individual components, see branch 'ffmpeg_threading' in git://git.khirnov.net/libav Cheers, -- Anton Khirnov ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 07/13] fftools/ffmpeg_filter: reindent
--- fftools/ffmpeg_filter.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 3bafef9717..cd4b55dd40 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -2526,17 +2526,17 @@ static int sub2video_frame(InputFilter *ifilter, AVFrame *frame) return 0; } -if (!frame) { -if (ifp->sub2video.end_pts < INT64_MAX) -sub2video_update(ifp, INT64_MAX, NULL); +if (!frame) { +if (ifp->sub2video.end_pts < INT64_MAX) +sub2video_update(ifp, INT64_MAX, NULL); -return av_buffersrc_add_frame(ifp->filter, NULL); -} +return av_buffersrc_add_frame(ifp->filter, NULL); +} -ifp->width = frame->width ? frame->width : ifp->width; -ifp->height = frame->height ? frame->height : ifp->height; +ifp->width = frame->width ? frame->width : ifp->width; +ifp->height = frame->height ? frame->height : ifp->height; -sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data); +sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data); return 0; } -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 08/13] fftools/ffmpeg_mux: add muxing thread private data
To be used for data that never needs to be visible outside of the muxer thread. Start by moving the muxed AVPacket in there. --- fftools/ffmpeg_mux.c | 44 +++- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 30c033036d..82352b7981 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -39,6 +39,10 @@ #include "libavformat/avformat.h" #include "libavformat/avio.h" +typedef struct MuxThreadContext { +AVPacket *pkt; +} MuxThreadContext; + int want_sdp = 1; static Muxer *mux_from_of(OutputFile *of) @@ -210,18 +214,40 @@ static void thread_set_name(OutputFile *of) ff_thread_setname(name); } +static void mux_thread_uninit(MuxThreadContext *mt) +{ +av_packet_free(&mt->pkt); + +memset(mt, 0, sizeof(*mt)); +} + +static int mux_thread_init(MuxThreadContext *mt) +{ +memset(mt, 0, sizeof(*mt)); + +mt->pkt = av_packet_alloc(); +if (!mt->pkt) +goto fail; + +return 0; + +fail: +mux_thread_uninit(mt); +return AVERROR(ENOMEM); +} + static void *muxer_thread(void *arg) { Muxer *mux = arg; OutputFile *of = &mux->of; -AVPacket *pkt = NULL; + +MuxThreadContext mt; + intret = 0; -pkt = av_packet_alloc(); -if (!pkt) { -ret = AVERROR(ENOMEM); +ret = mux_thread_init(&mt); +if (ret < 0) goto finish; -} thread_set_name(of); @@ -229,7 +255,7 @@ static void *muxer_thread(void *arg) OutputStream *ost; int stream_idx, stream_eof = 0; -ret = tq_receive(mux->tq, &stream_idx, pkt); +ret = tq_receive(mux->tq, &stream_idx, mt.pkt); if (stream_idx < 0) { av_log(mux, AV_LOG_VERBOSE, "All streams finished\n"); ret = 0; @@ -237,8 +263,8 @@ static void *muxer_thread(void *arg) } ost = of->streams[stream_idx]; -ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt, &stream_eof); -av_packet_unref(pkt); +ret = sync_queue_process(mux, ost, ret < 0 ? NULL : mt.pkt, &stream_eof); +av_packet_unref(mt.pkt); if (ret == AVERROR_EOF) { if (stream_eof) { tq_receive_finish(mux->tq, stream_idx); @@ -254,7 +280,7 @@ static void *muxer_thread(void *arg) } finish: -av_packet_free(&pkt); +mux_thread_uninit(&mt); for (unsigned int i = 0; i < mux->fc->nb_streams; i++) tq_receive_finish(mux->tq, i); -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 06/13] fftools/ffmpeg_filter: buffer sub2video heartbeat frames like other frames
Otherwise they'd be silently ignored if received by the filtering thread before the filtergraph can be initialized, which would make the output dependent on the order in which frames from different inputs arrive. --- fftools/ffmpeg_filter.c | 43 - 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 1b964fc53f..3bafef9717 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -1769,6 +1769,8 @@ static int graph_is_meta(AVFilterGraph *graph) return 1; } +static int sub2video_frame(InputFilter *ifilter, AVFrame *frame); + static int configure_filtergraph(FilterGraph *fg, const FilterGraphThread *fgt) { FilterGraphPriv *fgp = fgp_from_fg(fg); @@ -1880,7 +1882,7 @@ static int configure_filtergraph(FilterGraph *fg, const FilterGraphThread *fgt) AVFrame *tmp; while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) { if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) { -sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)tmp->buf[0]->data); +sub2video_frame(&ifp->ifilter, tmp); } else { ret = av_buffersrc_add_frame(ifp->filter, tmp); } @@ -2475,9 +2477,6 @@ static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb InputFilterPriv *ifp = ifp_from_ifilter(ifilter); int64_t pts2; -if (!ifilter->graph->graph) -return; - /* subtitles seem to be usually muxed ahead of other streams; if not, subtracting a larger time here is necessary */ pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1; @@ -2495,18 +2494,38 @@ static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb sub2video_push_ref(ifp, pts2); } -static int sub2video_frame(InputFilter *ifilter, const AVFrame *frame) +static int sub2video_frame(InputFilter *ifilter, AVFrame *frame) { InputFilterPriv *ifp = ifp_from_ifilter(ifilter); int ret; +if (!ifilter->graph->graph) { +AVFrame *tmp; + +if (!frame) +return 0; + +tmp = av_frame_alloc(); +if (!tmp) +return AVERROR(ENOMEM); + +av_frame_move_ref(tmp, frame); + +ret = av_fifo_write(ifp->frame_queue, &tmp, 1); +if (ret < 0) { +av_frame_free(&tmp); +return ret; +} + +return 0; +} + // heartbeat frame if (frame && !frame->buf[0]) { sub2video_heartbeat(ifilter, frame->pts, frame->time_base); return 0; } -if (ifilter->graph->graph) { if (!frame) { if (ifp->sub2video.end_pts < INT64_MAX) sub2video_update(ifp, INT64_MAX, NULL); @@ -2518,18 +2537,6 @@ static int sub2video_frame(InputFilter *ifilter, const AVFrame *frame) ifp->height = frame->height ? frame->height : ifp->height; sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data); -} else if (frame) { -AVFrame *tmp = av_frame_clone(frame); - -if (!tmp) -return AVERROR(ENOMEM); - -ret = av_fifo_write(ifp->frame_queue, &tmp, 1); -if (ret < 0) { -av_frame_free(&tmp); -return ret; -} -} return 0; } -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 10/13] fftools/ffmpeg_demux: switch from AVThreadMessageQueue to ThreadQueue
* the code is made shorter and simpler * avoids constantly allocating and freeing AVPackets, thanks to ThreadQueue integration with ObjPool * is consistent with decoding/filtering/muxing * reduces the diff in the future switch to thread-aware scheduling This makes ifile_get_packet() always block. Any potential issues caused by this will be resolved by the switch to thread-aware scheduling in future commits. --- fftools/ffmpeg.c| 32 ++-- fftools/ffmpeg.h| 3 +- fftools/ffmpeg_demux.c | 108 ++-- fftools/ffmpeg_filter.c | 5 +- 4 files changed, 58 insertions(+), 90 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 61fcda2526..cf8a50bffc 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1043,9 +1043,6 @@ static int check_keyboard_interaction(int64_t cur_time) static void reset_eagain(void) { -int i; -for (i = 0; i < nb_input_files; i++) -input_files[i]->eagain = 0; for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) ost->unavailable = 0; } @@ -1069,19 +1066,14 @@ static void decode_flush(InputFile *ifile) * this function should be called again * - AVERROR_EOF -- this function should not be called again */ -static int process_input(int file_index) +static int process_input(int file_index, AVPacket *pkt) { InputFile *ifile = input_files[file_index]; InputStream *ist; -AVPacket *pkt; int ret, i; -ret = ifile_get_packet(ifile, &pkt); +ret = ifile_get_packet(ifile, pkt); -if (ret == AVERROR(EAGAIN)) { -ifile->eagain = 1; -return ret; -} if (ret == 1) { /* the input file is looped: flush the decoders */ decode_flush(ifile); @@ -1128,7 +1120,7 @@ static int process_input(int file_index) ret = process_input_packet(ist, pkt, 0); -av_packet_free(&pkt); +av_packet_unref(pkt); return ret < 0 ? ret : 0; } @@ -1138,7 +1130,7 @@ static int process_input(int file_index) * * @return 0 for success, <0 for error */ -static int transcode_step(OutputStream *ost) +static int transcode_step(OutputStream *ost, AVPacket *demux_pkt) { InputStream *ist = NULL; int ret; @@ -1153,10 +1145,8 @@ static int transcode_step(OutputStream *ost) av_assert0(ist); } -ret = process_input(ist->file_index); +ret = process_input(ist->file_index, demux_pkt); if (ret == AVERROR(EAGAIN)) { -if (input_files[ist->file_index]->eagain) -ost->unavailable = 1; return 0; } @@ -1182,12 +1172,19 @@ static int transcode(int *err_rate_exceeded) int ret = 0, i; InputStream *ist; int64_t timer_start; +AVPacket *demux_pkt = NULL; print_stream_maps(); *err_rate_exceeded = 0; atomic_store(&transcode_init_done, 1); +demux_pkt = av_packet_alloc(); +if (!demux_pkt) { +ret = AVERROR(ENOMEM); +goto fail; +} + if (stdin_interaction) { av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n"); } @@ -1215,7 +1212,7 @@ static int transcode(int *err_rate_exceeded) break; } -ret = transcode_step(ost); +ret = transcode_step(ost, demux_pkt); if (ret < 0 && ret != AVERROR_EOF) { av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret)); break; @@ -1256,6 +1253,9 @@ static int transcode(int *err_rate_exceeded) /* dump report by using the first video and audio streams */ print_report(1, timer_start, av_gettime_relative()); +fail: +av_packet_free(&demux_pkt); + return ret; } diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index f50222472c..3c153021f8 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -407,7 +407,6 @@ typedef struct InputFile { AVFormatContext *ctx; int eof_reached; /* true if eof reached */ -int eagain; /* true if last read attempt returned EAGAIN */ int64_t input_ts_offset; int input_sync_ref; /** @@ -859,7 +858,7 @@ void ifile_close(InputFile **f); * caller should flush decoders and read from this demuxer again * - a negative error code on failure */ -int ifile_get_packet(InputFile *f, AVPacket **pkt); +int ifile_get_packet(InputFile *f, AVPacket *pkt); int ist_output_add(InputStream *ist, OutputStream *ost); int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple); diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 791952f120..65a5e08ca5 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -21,6 +21,8 @@ #include "ffmpeg.h" #include "ffmpeg_utils.h" +#include "objpool.h" +#include "thread_queue.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" @@ -33,7 +35,6 @@ #include "libavutil/time.h" #include "libavutil/timestamp.h" #include "libavutil/thread.h" -#include "libavutil/threadmessage.h
[FFmpeg-devel] [PATCH 11/13] fftools/ffmpeg_enc: move encoding to a separate thread
As for the analogous decoding change, this is only a preparatory step to a fully threaded architecture and does not yet make encoding truly parallel. The main thread will currently submit a frame and wait until it has been fully processed by the encoder before moving on. That will change in future commits after filters are moved to threads and a thread-aware scheduler is added. This code suffers from a known issue - if an encoder with a sync queue receives EOF it will terminate after processing everything it currently has, even though the sync queue might still be triggered by other threads. That will be fixed in following commits. --- fftools/ffmpeg_enc.c | 360 ++- 1 file changed, 320 insertions(+), 40 deletions(-) diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index fa4539664f..46c21fc0e4 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -20,6 +20,8 @@ #include #include "ffmpeg.h" +#include "ffmpeg_utils.h" +#include "thread_queue.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" @@ -43,6 +45,7 @@ struct Encoder { // packet for receiving encoded output AVPacket *pkt; +AVFrame *sub_frame; // combined size of all the packets received from the encoder uint64_t data_size; @@ -51,8 +54,48 @@ struct Encoder { uint64_t packets_encoded; int opened; +int finished; + +pthread_t thread; +/** + * Queue for sending frames from the main thread to + * the encoder thread. + */ +ThreadQueue*queue_in; +/** + * Queue for sending encoded packets from the encoder thread + * to the main thread. + * + * An empty packet is sent to signal that a previously sent + * frame has been fully processed. + */ +ThreadQueue*queue_out; }; +// data that is local to the decoder thread and not visible outside of it +typedef struct EncoderThread { +AVFrame *frame; +AVPacket *pkt; +} EncoderThread; + +static int enc_thread_stop(Encoder *e) +{ +void *ret; + +if (!e->queue_in) +return 0; + +tq_send_finish(e->queue_in, 0); +tq_receive_finish(e->queue_out, 0); + +pthread_join(e->thread, &ret); + +tq_free(&e->queue_in); +tq_free(&e->queue_out); + +return (int)(intptr_t)ret; +} + void enc_free(Encoder **penc) { Encoder *enc = *penc; @@ -60,7 +103,10 @@ void enc_free(Encoder **penc) if (!enc) return; +enc_thread_stop(enc); + av_frame_free(&enc->sq_frame); +av_frame_free(&enc->sub_frame); av_packet_free(&enc->pkt); @@ -77,6 +123,12 @@ int enc_alloc(Encoder **penc, const AVCodec *codec) if (!enc) return AVERROR(ENOMEM); +if (codec->type == AVMEDIA_TYPE_SUBTITLE) { +enc->sub_frame = av_frame_alloc(); +if (!enc->sub_frame) +goto fail; +} + enc->pkt = av_packet_alloc(); if (!enc->pkt) goto fail; @@ -165,6 +217,52 @@ static int set_encoder_id(OutputFile *of, OutputStream *ost) return 0; } +static void *encoder_thread(void *arg); + +static int enc_thread_start(OutputStream *ost) +{ +Encoder *e = ost->enc; +ObjPool *op; +int ret = 0; + +op = objpool_alloc_frames(); +if (!op) +return AVERROR(ENOMEM); + +e->queue_in = tq_alloc(1, 1, op, frame_move); +if (!e->queue_in) { +objpool_free(&op); +return AVERROR(ENOMEM); +} + +op = objpool_alloc_packets(); +if (!op) +goto fail; + +e->queue_out = tq_alloc(1, 4, op, pkt_move); +if (!e->queue_out) { +objpool_free(&op); +goto fail; +} + +ret = pthread_create(&e->thread, NULL, encoder_thread, ost); +if (ret) { +ret = AVERROR(ret); +av_log(ost, AV_LOG_ERROR, "pthread_create() failed: %s\n", + av_err2str(ret)); +goto fail; +} + +return 0; +fail: +if (ret >= 0) +ret = AVERROR(ENOMEM); + +tq_free(&e->queue_in); +tq_free(&e->queue_out); +return ret; +} + int enc_open(OutputStream *ost, const AVFrame *frame) { InputStream *ist = ost->ist; @@ -373,6 +471,13 @@ int enc_open(OutputStream *ost, const AVFrame *frame) if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); +ret = enc_thread_start(ost); +if (ret < 0) { +av_log(ost, AV_LOG_ERROR, "Error starting encoder thread: %s\n", + av_err2str(ret)); +return ret; +} + ret = of_stream_init(of, ost); if (ret < 0) return ret; @@ -386,19 +491,18 @@ static int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) if (of->recording_time != INT64_MAX && av_compare_ts(ts, tb, of->recording_time, AV_TIME_BASE_Q) >= 0) { -close_output_stream(ost); return 0; } return 1; } -int enc_subtitle(OutputFile *of, OutputStr
[FFmpeg-devel] [PATCH 09/13] fftools/ffmpeg_mux: move bitstream filtering to the muxer thread
This will be the appropriate place for it after the rest of transcoding is switched to a threaded architecture. --- fftools/ffmpeg_mux.c | 112 ++- 1 file changed, 67 insertions(+), 45 deletions(-) diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 82352b7981..57fb8a8413 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -207,6 +207,67 @@ static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt, int return 0; } +/* apply the output bitstream filters */ +static int mux_packet_filter(Muxer *mux, OutputStream *ost, + AVPacket *pkt, int *stream_eof) +{ +MuxStream *ms = ms_from_ost(ost); +const char *err_msg; +int ret = 0; + +if (ms->bsf_ctx) { +int bsf_eof = 0; + +if (pkt) +av_packet_rescale_ts(pkt, pkt->time_base, ms->bsf_ctx->time_base_in); + +ret = av_bsf_send_packet(ms->bsf_ctx, pkt); +if (ret < 0) { +err_msg = "submitting a packet for bitstream filtering"; +goto fail; +} + +while (!bsf_eof) { +ret = av_bsf_receive_packet(ms->bsf_ctx, ms->bsf_pkt); +if (ret == AVERROR(EAGAIN)) +return 0; +else if (ret == AVERROR_EOF) +bsf_eof = 1; +else if (ret < 0) { +av_log(ost, AV_LOG_ERROR, + "Error applying bitstream filters to a packet: %s", + av_err2str(ret)); +if (exit_on_error) +return ret; +continue; +} + +if (!bsf_eof) +ms->bsf_pkt->time_base = ms->bsf_ctx->time_base_out; + +ret = sync_queue_process(mux, ost, bsf_eof ? NULL : ms->bsf_pkt, stream_eof); +if (ret < 0) +goto mux_fail; +} +*stream_eof = 1; +return AVERROR_EOF; +} else { +ret = sync_queue_process(mux, ost, pkt, stream_eof); +if (ret < 0) +goto mux_fail; +} + +return 0; + +mux_fail: +err_msg = "submitting a packet to the muxer"; + +fail: +if (ret != AVERROR_EOF) +av_log(ost, AV_LOG_ERROR, "Error %s: %s\n", err_msg, av_err2str(ret)); +return ret; +} + static void thread_set_name(OutputFile *of) { char name[16]; @@ -263,7 +324,7 @@ static void *muxer_thread(void *arg) } ost = of->streams[stream_idx]; -ret = sync_queue_process(mux, ost, ret < 0 ? NULL : mt.pkt, &stream_eof); +ret = mux_packet_filter(mux, ost, ret < 0 ? NULL : mt.pkt, &stream_eof); av_packet_unref(mt.pkt); if (ret == AVERROR_EOF) { if (stream_eof) { @@ -376,58 +437,19 @@ static int submit_packet(Muxer *mux, AVPacket *pkt, OutputStream *ost) int of_output_packet(OutputFile *of, OutputStream *ost, AVPacket *pkt) { Muxer *mux = mux_from_of(of); -MuxStream *ms = ms_from_ost(ost); -const char *err_msg; int ret = 0; if (pkt && pkt->dts != AV_NOPTS_VALUE) ost->last_mux_dts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q); -/* apply the output bitstream filters */ -if (ms->bsf_ctx) { -int bsf_eof = 0; - -if (pkt) -av_packet_rescale_ts(pkt, pkt->time_base, ms->bsf_ctx->time_base_in); - -ret = av_bsf_send_packet(ms->bsf_ctx, pkt); -if (ret < 0) { -err_msg = "submitting a packet for bitstream filtering"; -goto fail; -} - -while (!bsf_eof) { -ret = av_bsf_receive_packet(ms->bsf_ctx, ms->bsf_pkt); -if (ret == AVERROR(EAGAIN)) -return 0; -else if (ret == AVERROR_EOF) -bsf_eof = 1; -else if (ret < 0) { -err_msg = "applying bitstream filters to a packet"; -goto fail; -} - -if (!bsf_eof) -ms->bsf_pkt->time_base = ms->bsf_ctx->time_base_out; - -ret = submit_packet(mux, bsf_eof ? NULL : ms->bsf_pkt, ost); -if (ret < 0) -goto mux_fail; -} -} else { -ret = submit_packet(mux, pkt, ost); -if (ret < 0) -goto mux_fail; +ret = submit_packet(mux, pkt, ost); +if (ret < 0) { +av_log(ost, AV_LOG_ERROR, "Error submitting a packet to the muxer: %s", + av_err2str(ret)); +return ret; } return 0; - -mux_fail: -err_msg = "submitting a packet to the muxer"; - -fail: -av_log(ost, AV_LOG_ERROR, "Error %s\n", err_msg); -return exit_on_error ? ret : 0; } int of_streamcopy(OutputStream *ost, const AVPacket *pkt, int64_t dts) -- 2.42.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org w
[FFmpeg-devel] [PATCH 12/13] fftools/ffmpeg: add thread-aware transcode scheduling infrastructure
See the comment block at the top of fftools/ffmpeg_sched.h for more details on what this scheduler is for. This commit adds the scheduling code itself, along with minimal integration with the rest of the program: * allocating and freeing the scheduler * passing it throughout the call stack in order to register the individual components (demuxers/decoders/filtergraphs/encoders/muxers) with the scheduler The scheduler is not actually used as of this commit, so it should not result in any change in behavior. That will change in future commits. --- fftools/Makefile |1 + fftools/ffmpeg.c | 18 +- fftools/ffmpeg.h | 24 +- fftools/ffmpeg_dec.c | 10 +- fftools/ffmpeg_demux.c| 46 +- fftools/ffmpeg_enc.c | 13 +- fftools/ffmpeg_filter.c | 37 +- fftools/ffmpeg_mux.c | 17 +- fftools/ffmpeg_mux.h | 12 + fftools/ffmpeg_mux_init.c | 106 +- fftools/ffmpeg_opt.c | 22 +- fftools/ffmpeg_sched.c| 2174 + fftools/ffmpeg_sched.h| 468 13 files changed, 2892 insertions(+), 56 deletions(-) create mode 100644 fftools/ffmpeg_sched.c create mode 100644 fftools/ffmpeg_sched.h diff --git a/fftools/Makefile b/fftools/Makefile index 3c763e3db9..083a1368ce 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -18,6 +18,7 @@ OBJS-ffmpeg += \ fftools/ffmpeg_mux.o\ fftools/ffmpeg_mux_init.o \ fftools/ffmpeg_opt.o\ +fftools/ffmpeg_sched.o \ fftools/objpool.o \ fftools/sync_queue.o\ fftools/thread_queue.o \ diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index cf8a50bffc..b8a97258a0 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -99,6 +99,7 @@ #include "cmdutils.h" #include "ffmpeg.h" +#include "ffmpeg_sched.h" #include "ffmpeg_utils.h" #include "sync_queue.h" @@ -1167,7 +1168,7 @@ static int transcode_step(OutputStream *ost, AVPacket *demux_pkt) /* * The following code is the main loop of the file converter */ -static int transcode(int *err_rate_exceeded) +static int transcode(Scheduler *sch, int *err_rate_exceeded) { int ret = 0, i; InputStream *ist; @@ -1305,6 +1306,8 @@ static int64_t getmaxrss(void) int main(int argc, char **argv) { +Scheduler *sch = NULL; + int ret, err_rate_exceeded; BenchmarkTimeStamps ti; @@ -1322,8 +1325,14 @@ int main(int argc, char **argv) show_banner(argc, argv, options); +sch = sch_alloc(); +if (!sch) { +ret = AVERROR(ENOMEM); +goto finish; +} + /* parse options and open all input/output files */ -ret = ffmpeg_parse_options(argc, argv); +ret = ffmpeg_parse_options(argc, argv, sch); if (ret < 0) goto finish; @@ -1341,7 +1350,7 @@ int main(int argc, char **argv) } current_time = ti = get_benchmark_time_stamps(); -ret = transcode(&err_rate_exceeded); +ret = transcode(sch, &err_rate_exceeded); if (ret >= 0 && do_benchmark) { int64_t utime, stime, rtime; current_time = get_benchmark_time_stamps(); @@ -1361,5 +1370,8 @@ finish: ret = 0; ffmpeg_cleanup(ret); + +sch_free(&sch); + return ret; } diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 3c153021f8..a89038b765 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -27,6 +27,7 @@ #include #include "cmdutils.h" +#include "ffmpeg_sched.h" #include "sync_queue.h" #include "libavformat/avformat.h" @@ -721,7 +722,8 @@ int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_id int check_filter_outputs(void); int filtergraph_is_simple(const FilterGraph *fg); int init_simple_filtergraph(InputStream *ist, OutputStream *ost, -char *graph_desc); +char *graph_desc, +Scheduler *sch, unsigned sch_idx_enc); int init_complex_filtergraph(FilterGraph *fg); int copy_av_subtitle(AVSubtitle *dst, const AVSubtitle *src); @@ -746,7 +748,8 @@ void ifilter_sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational t */ int ifilter_parameters_from_dec(InputFilter *ifilter, const AVCodecContext *dec); -int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost); +int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost, + unsigned sched_idx_enc); /** * Create a new filtergraph in the global filtergraph list. @@ -754,7 +757,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost); * @param graph_desc Graph description; an av_malloc()ed string, filtergraph * takes ownership of it. */ -int fg_create(FilterGraph **pfg, char *graph_desc); +int fg_create(FilterGraph **pfg, char *graph_desc, Scheduler *sch); void fg_free(FilterGraph **pfg); @@ -778,7 +781,7 @@ void fg_send_command(FilterGraph *fg, double time, const char *target, */ int reap_filter
[FFmpeg-devel] [PATCH 13/13] fftools/ffmpeg: convert to a threaded architecture
Change the main loop and every component (demuxers, decoders, filters, encoders, muxers) to use the previously added transcode scheduler. Every instance of every such component was already running in a separate thread, but now they can actually run in parallel. Changes the results of ffmpeg-fix_sub_duration_heartbeat - tested by JEEB to be more correct and deterministic. --- fftools/ffmpeg.c | 374 + fftools/ffmpeg.h | 97 +-- fftools/ffmpeg_dec.c | 321 ++-- fftools/ffmpeg_demux.c| 268 --- fftools/ffmpeg_enc.c | 368 ++--- fftools/ffmpeg_filter.c | 720 +- fftools/ffmpeg_mux.c | 324 ++-- fftools/ffmpeg_mux.h | 24 +- fftools/ffmpeg_mux_init.c | 88 +-- fftools/ffmpeg_opt.c | 6 +- .../fate/ffmpeg-fix_sub_duration_heartbeat| 36 +- 11 files changed, 598 insertions(+), 2028 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index b8a97258a0..30b594fd97 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -117,7 +117,7 @@ typedef struct BenchmarkTimeStamps { static BenchmarkTimeStamps get_benchmark_time_stamps(void); static int64_t getmaxrss(void); -unsigned nb_output_dumped = 0; +atomic_uint nb_output_dumped = 0; static BenchmarkTimeStamps current_time; AVIOContext *progress_avio = NULL; @@ -138,30 +138,6 @@ static struct termios oldtty; static int restore_tty; #endif -/* sub2video hack: - Convert subtitles to video with alpha to insert them in filter graphs. - This is a temporary solution until libavfilter gets real subtitles support. - */ - -static void sub2video_heartbeat(InputFile *infile, int64_t pts, AVRational tb) -{ -/* When a frame is read from a file, examine all sub2video streams in - the same file and send the sub2video frame again. Otherwise, decoded - video frames could be accumulating in the filter graph while a filter - (possibly overlay) is desperately waiting for a subtitle frame. */ -for (int i = 0; i < infile->nb_streams; i++) { -InputStream *ist = infile->streams[i]; - -if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) -continue; - -for (int j = 0; j < ist->nb_filters; j++) -ifilter_sub2video_heartbeat(ist->filters[j], pts, tb); -} -} - -/* end of sub2video hack */ - static void term_exit_sigsafe(void) { #if HAVE_TERMIOS_H @@ -499,23 +475,13 @@ void update_benchmark(const char *fmt, ...) } } -void close_output_stream(OutputStream *ost) -{ -OutputFile *of = output_files[ost->file_index]; -ost->finished |= ENCODER_FINISHED; - -if (ost->sq_idx_encode >= 0) -sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); -} - -static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time) +static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time, int64_t pts) { AVBPrint buf, buf_script; int64_t total_size = of_filesize(output_files[0]); int vid; double bitrate; double speed; -int64_t pts = AV_NOPTS_VALUE; static int64_t last_time = -1; static int first_report = 1; uint64_t nb_frames_dup = 0, nb_frames_drop = 0; @@ -533,7 +499,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti last_time = cur_time; } if (((cur_time - last_time) < stats_period && !first_report) || -(first_report && nb_output_dumped < nb_output_files)) +(first_report && atomic_load(&nb_output_dumped) < nb_output_files)) return; last_time = cur_time; } @@ -544,7 +510,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC); for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { -const float q = ost->enc ? ost->quality / (float) FF_QP2LAMBDA : -1; +const float q = ost->enc ? atomic_load(&ost->quality) / (float) FF_QP2LAMBDA : -1; if (vid && ost->type == AVMEDIA_TYPE_VIDEO) { av_bprintf(&buf, "q=%2.1f ", q); @@ -565,22 +531,18 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti if (is_last_report) av_bprintf(&buf, "L"); -nb_frames_dup = ost->filter->nb_frames_dup; -nb_frames_drop = ost->filter->nb_frames_drop; +nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup); +nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop); vid = 1; } -/* compute min output value */ -if (ost->last_mux_dts != AV_NOPTS_VALUE) { -if (p
Re: [FFmpeg-devel] [PATCH 01/13] lavfi/buffersink: avoid leaking peeked_frame on uninit
LGTM ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] ac3dsp: RISC-V V float_to_fixed24
Okay, changed Rémi Denis-Courmont 于2023年11月24日周五 01:09写道: > Le torstaina 23. marraskuuta 2023, 1.17.03 EET flow gg a écrit : > > Hello, I saw the new commit "avcodec/ac3dsp: make len a size_t in > > float_to_fixed24." > > > > So I removed the part #if (__riscv_xlen == 64) and restored the patch. > > You're not checking for Zba. Also 'bnez' would be more logical than > 'bgtz' > for an unsigned counter. > > -- > レミ・デニ-クールモン > http://www.remlab.net/ > > > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > From af221d659ebc1e97b6d274681061fa8331d0b147 Mon Sep 17 00:00:00 2001 From: sunyuechi Date: Wed, 22 Nov 2023 14:57:29 +0800 Subject: [PATCH] lavc/ac3dsp: R-V V float_to_fixed24 c910 float_to_fixed24_c: 2207.2 float_to_fixed24_rvv_f32: 696.2 --- libavcodec/riscv/Makefile | 3 ++- libavcodec/riscv/ac3dsp_init.c | 3 +++ libavcodec/riscv/ac3dsp_rvv.S | 39 ++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 libavcodec/riscv/ac3dsp_rvv.S diff --git a/libavcodec/riscv/Makefile b/libavcodec/riscv/Makefile index 8f2a519827..ac7b7c2929 100644 --- a/libavcodec/riscv/Makefile +++ b/libavcodec/riscv/Makefile @@ -1,7 +1,8 @@ OBJS-$(CONFIG_AAC_DECODER) += riscv/aacpsdsp_init.o riscv/sbrdsp_init.o RVV-OBJS-$(CONFIG_AAC_DECODER) += riscv/aacpsdsp_rvv.o riscv/sbrdsp_rvv.o OBJS-$(CONFIG_AC3DSP) += riscv/ac3dsp_init.o \ - riscv/ac3dsp_rvb.o + riscv/ac3dsp_rvb.o \ + riscv/ac3dsp_rvv.o OBJS-$(CONFIG_ALAC_DECODER) += riscv/alacdsp_init.o RVV-OBJS-$(CONFIG_ALAC_DECODER) += riscv/alacdsp_rvv.o OBJS-$(CONFIG_AUDIODSP) += riscv/audiodsp_init.o \ diff --git a/libavcodec/riscv/ac3dsp_init.c b/libavcodec/riscv/ac3dsp_init.c index 20f294f1de..25244943cb 100644 --- a/libavcodec/riscv/ac3dsp_init.c +++ b/libavcodec/riscv/ac3dsp_init.c @@ -26,6 +26,7 @@ #include "libavcodec/ac3dsp.h" void ff_extract_exponents_rvb(uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_float_to_fixed24_rvv(int32_t *dst, const float *src, unsigned int len); av_cold void ff_ac3dsp_init_riscv(AC3DSPContext *c) { @@ -34,5 +35,7 @@ av_cold void ff_ac3dsp_init_riscv(AC3DSPContext *c) if (flags & AV_CPU_FLAG_RVB_ADDR) { if (flags & AV_CPU_FLAG_RVB_BASIC) c->extract_exponents = ff_extract_exponents_rvb; +if (flags & AV_CPU_FLAG_RVV_F32) +c->float_to_fixed24 = ff_float_to_fixed24_rvv; } } diff --git a/libavcodec/riscv/ac3dsp_rvv.S b/libavcodec/riscv/ac3dsp_rvv.S new file mode 100644 index 00..82c14ea275 --- /dev/null +++ b/libavcodec/riscv/ac3dsp_rvv.S @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Institue of Software Chinese Academy of Sciences (ISCAS). + * + * 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 + */ + +#include "config.h" +#include "libavutil/riscv/asm.S" + +func ff_float_to_fixed24_rvv, zve32f +lit1, 1 << 24 +fcvt.s.w f0, t1 +1: +vsetvli t0, a2, e32, m4, ta, ma +sub a2, a2, t0 +vle32.v v0, (a1) +vfmul.vf v0, v0, f0 +vfcvt.x.f.v v0, v0 +sh2adda1, t0, a1 +vse32.v v0, (a0) +sh2adda0, t0, a0 +bnez a2, 1b + +ret +endfunc -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] checkasm/ac3dsp: add float_to_fixed24 test
> You should probably add the test case to tests/fate/checkasm.mak > This one is not necessary. You can reuse dst or dst2 for the bench() as it's write only. > Changed BUF_SIZE instead of 10. Okay, changed. James Almer 于2023年11月24日周五 01:11写道: > On 11/23/2023 4:08 AM, flow gg wrote: > > +static void check_float_to_fixed24(AC3DSPContext *c) { > > +#define BUF_SIZE 1024 > > +LOCAL_ALIGNED_32(int32_t, v1, [BUF_SIZE]); > > This one is not necessary. You can reuse dst or dst2 for the bench() as > it's write only. > > > +LOCAL_ALIGNED_32(float, v2, [BUF_SIZE]); > > + > > +declare_func(void, int32_t *, const float *, unsigned int); > > + > > +randomize_float(v2, BUF_SIZE); > > + > > +if (check_func(c->float_to_fixed24, "float_to_fixed24")) { > > +LOCAL_ALIGNED_32(int32_t, dst, [BUF_SIZE]); > > +LOCAL_ALIGNED_32(int32_t, dst2, [BUF_SIZE]); > > + > > +call_ref(dst, v2, BUF_SIZE); > > +call_new(dst2, v2, BUF_SIZE); > > + > > +if (memcmp(dst, dst2, sizeof(*dst) * 10) != 0) > > BUF_SIZE instead of 10. > > > +fail(); > > + > > +bench_new(v1, v2, BUF_SIZE); > > +} > > + > > + > > +report("float_to_fixed24"); > > +} > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > From d5bfbecdd32dda0839387d470fee72b6155f084d Mon Sep 17 00:00:00 2001 From: sunyuechi Date: Wed, 22 Nov 2023 14:57:29 +0800 Subject: [PATCH] checkasm/ac3dsp: add float_to_fixed24 test --- tests/checkasm/Makefile | 1 + tests/checkasm/ac3dsp.c | 70 +++ tests/checkasm/checkasm.c | 3 ++ tests/checkasm/checkasm.h | 1 + tests/fate/checkasm.mak | 1 + 5 files changed, 76 insertions(+) create mode 100644 tests/checkasm/ac3dsp.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 8bc241d29b..53742c93ae 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -1,5 +1,6 @@ # libavcodec tests # subsystems +AVCODECOBJS-$(CONFIG_AC3DSP)+= ac3dsp.o AVCODECOBJS-$(CONFIG_AUDIODSP) += audiodsp.o AVCODECOBJS-$(CONFIG_BLOCKDSP) += blockdsp.o AVCODECOBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o diff --git a/tests/checkasm/ac3dsp.c b/tests/checkasm/ac3dsp.c new file mode 100644 index 00..8f36f1736c --- /dev/null +++ b/tests/checkasm/ac3dsp.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Institue of Software Chinese Academy of Sciences (ISCAS). + * + * 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/mem.h" +#include "libavutil/mem_internal.h" + +#include "libavcodec/ac3dsp.h" + +#include "checkasm.h" + +#define randomize_float(buf, len) \ +do {\ +int i; \ +for (i = 0; i < len; i++) { \ +float f = (float)rnd() / (UINT_MAX >> 5) - 16.0f; \ +buf[i] = f; \ +} \ +} while (0) + +static void check_float_to_fixed24(AC3DSPContext *c) { +#define BUF_SIZE 1024 +LOCAL_ALIGNED_32(float, src, [BUF_SIZE]); + +declare_func(void, int32_t *, const float *, unsigned int); + +randomize_float(src, BUF_SIZE); + +if (check_func(c->float_to_fixed24, "float_to_fixed24")) { +LOCAL_ALIGNED_32(int32_t, dst, [BUF_SIZE]); +LOCAL_ALIGNED_32(int32_t, dst2, [BUF_SIZE]); + +call_ref(dst, src, BUF_SIZE); +call_new(dst2, src, BUF_SIZE); + +if (memcmp(dst, dst2, BUF_SIZE) != 0) +fail(); + +bench_new(dst, src, BUF_SIZE); +} + + +report("float_to_fixed24"); +} + +void checkasm_check_ac3dsp(void) +{ +AC3DSPContext c; +ff_ac3dsp_init(&c); + +check_float_to_fixed24(&c); +} diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 708119e7c6..f37c7fad3a 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -78,6 +78,9 @@ static const
[FFmpeg-devel] [PATCH 1/2] avcodec/jpegxl_parse{, r}: use correct ISOBMFF extended size location
According to ISO/IEC 14996-12, size == 1 means a 64-bit extended-size field occurs *after* the 32-bit box type, not before. This fix should allow correct parsing of JXL files with extended-size boxes. Signed-off-by: Leo Izen --- libavcodec/jpegxl_parse.c | 6 +++--- libavcodec/jpegxl_parser.c | 9 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libavcodec/jpegxl_parse.c b/libavcodec/jpegxl_parse.c index eb28e80867..7cfdd3e7d5 100644 --- a/libavcodec/jpegxl_parse.c +++ b/libavcodec/jpegxl_parse.c @@ -462,8 +462,10 @@ int ff_jpegxl_collect_codestream_header(const uint8_t *input_buffer, int input_l return AVERROR_BUFFER_TOO_SMALL; size = bytestream2_get_be32(&gb); +tag = bytestream2_get_le32(&gb); + if (size == 1) { -if (bytestream2_get_bytes_left(&gb) < 12) +if (bytestream2_get_bytes_left(&gb) < 8) return AVERROR_BUFFER_TOO_SMALL; size = bytestream2_get_be64(&gb); head_size = 16; @@ -474,8 +476,6 @@ int ff_jpegxl_collect_codestream_header(const uint8_t *input_buffer, int input_l if (size) size -= head_size; -tag = bytestream2_get_le32(&gb); - if (tag == MKTAG('j','x','l','p')) { uint32_t idx; if (bytestream2_get_bytes_left(&gb) < 4) diff --git a/libavcodec/jpegxl_parser.c b/libavcodec/jpegxl_parser.c index 630fc8a60b..750872f17f 100644 --- a/libavcodec/jpegxl_parser.c +++ b/libavcodec/jpegxl_parser.c @@ -1342,7 +1342,7 @@ static int skip_boxes(JXLParseContext *ctx, const uint8_t *buf, int buf_size) while (1) { uint64_t size; -int head_size = 4; +int head_size = 8; if (bytestream2_peek_le16(&gb) == FF_JPEGXL_CODESTREAM_SIGNATURE_LE) break; @@ -1353,16 +1353,17 @@ static int skip_boxes(JXLParseContext *ctx, const uint8_t *buf, int buf_size) return AVERROR_BUFFER_TOO_SMALL; size = bytestream2_get_be32(&gb); +bytestream2_skip(&gb, 4); // tag if (size == 1) { -if (bytestream2_get_bytes_left(&gb) < 12) +if (bytestream2_get_bytes_left(&gb) < 8) return AVERROR_BUFFER_TOO_SMALL; size = bytestream2_get_be64(&gb); -head_size = 12; +head_size = 16; } if (!size) return AVERROR_INVALIDDATA; /* invalid ISOBMFF size */ -if (size <= head_size + 4 || size > INT_MAX - ctx->skip) +if (size <= head_size || size > INT_MAX - ctx->skip) return AVERROR_INVALIDDATA; ctx->skip += size; -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 0/2] JPEG XL parser bug fixes
Two bug fixes related to the JPEG XL parser. They're not exactly related and don't need to be applied in sequence. Leo Izen (2): avcodec/jpegxl_parse{,r}: use correct ISOBMFF extended size location avcodec/jpegxl_parser: fix parsing sequences of extremely small files libavcodec/jpegxl_parse.c | 6 +++--- libavcodec/jpegxl_parser.c | 23 +++ 2 files changed, 18 insertions(+), 11 deletions(-) -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] avcodec/jpegxl_parser: fix parsing sequences of extremely small files
This patch allows the JXL parser to parse sequences of extremely small files concatenated together. (e.g. smaller than the parser buffer) Signed-off-by: Leo Izen --- libavcodec/jpegxl_parser.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavcodec/jpegxl_parser.c b/libavcodec/jpegxl_parser.c index 750872f17f..006eb6b295 100644 --- a/libavcodec/jpegxl_parser.c +++ b/libavcodec/jpegxl_parser.c @@ -1454,15 +1454,21 @@ static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx, { JXLParseContext *ctx = s->priv_data; int next = END_NOT_FOUND, ret; +const uint8_t *pbuf = ctx->pc.buffer; +int pindex = ctx->pc.index; *poutbuf_size = 0; *poutbuf = NULL; -if (!ctx->pc.index) -goto flush; +if (!ctx->pc.index) { +if (ctx->pc.overread) +goto flush; +pbuf = buf; +pindex = buf_size; +} if ((!ctx->container || !ctx->codestream_length) && !ctx->next) { -ret = try_parse(s, avctx, ctx, ctx->pc.buffer, ctx->pc.index); +ret = try_parse(s, avctx, ctx, pbuf, pindex); if (ret < 0) goto flush; ctx->next = ret; @@ -1471,7 +1477,7 @@ static int jpegxl_parse(AVCodecParserContext *s, AVCodecContext *avctx, } if (ctx->container && ctx->next >= 0) { -ret = skip_boxes(ctx, ctx->pc.buffer, ctx->pc.index); +ret = skip_boxes(ctx, pbuf, pindex); if (ret < 0) { if (ret == AVERROR_INVALIDDATA) ctx->next = -1; -- 2.43.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] lavu/hwcontext_d3d11va: Add option vendor_id
From: Artem Galin User may choose the hardware via option vendor_id when multiple hardware are available. Signed-off-by: Artem Galin Signed-off-by: Haihao Xiang --- libavutil/hwcontext_d3d11va.c | 67 ++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index cc8c97d2b6..a6777b70a1 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -552,6 +552,55 @@ static void d3d11va_device_uninit(AVHWDeviceContext *hwdev) } } +static int d3d11va_device_find_adapter_by_vendor_id(AVHWDeviceContext *ctx, uint32_t flags, const char *vendor_id) +{ +HRESULT hr; +IDXGIAdapter *adapter = NULL; +IDXGIFactory2 *factory; +int adapter_id = 0; +long int id = strtol(vendor_id, NULL, 0); + +hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&factory); +if (FAILED(hr)) { +av_log(ctx, AV_LOG_ERROR, "CreateDXGIFactory returned error\n"); +return -1; +} + +while (IDXGIFactory2_EnumAdapters(factory, adapter_id++, &adapter) != DXGI_ERROR_NOT_FOUND) { +ID3D11Device* device = NULL; +DXGI_ADAPTER_DESC adapter_desc; + +hr = mD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL); +if (FAILED(hr)) { +av_log(ctx, AV_LOG_ERROR, "D3D11CreateDevice returned error\n"); + +if (adapter) +IDXGIAdapter_Release(adapter); + +continue; +} + +hr = IDXGIAdapter2_GetDesc(adapter, &adapter_desc); + +if (device) +ID3D11Device_Release(device); + +if (adapter) +IDXGIAdapter_Release(adapter); + +if (FAILED(hr)) { +av_log(ctx, AV_LOG_ERROR, "IDXGIAdapter2_GetDesc returned error\n"); +continue; +} else if (adapter_desc.VendorId == id) { +IDXGIFactory2_Release(factory); +return adapter_id - 1; +} +} + +IDXGIFactory2_Release(factory); +return -1; +} + static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags) { @@ -563,6 +612,7 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; int is_debug = !!av_dict_get(opts, "debug", NULL, 0); int ret; +int adapter = -1; // (On UWP we can't check this.) #if !HAVE_UWP @@ -581,10 +631,25 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, } if (device) { +adapter = atoi(device); +} else { +AVDictionaryEntry *e = av_dict_get(opts, "vendor_id", NULL, 0); +if (e && e->value) { +adapter = d3d11va_device_find_adapter_by_vendor_id(ctx, creationFlags, e->value); +if (adapter < 0) { +av_log(ctx, AV_LOG_ERROR, "Failed to find d3d11va adapter by " + "vendor id %s\n", e->value); +return AVERROR_UNKNOWN; +} +} +} + +if (adapter >= 0) { IDXGIFactory2 *pDXGIFactory; + +av_log(ctx, AV_LOG_VERBOSE, "Selecting d3d11va adapter %d\n", adapter); hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory); if (SUCCEEDED(hr)) { -int adapter = atoi(device); if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter))) pAdapter = NULL; IDXGIFactory2_Release(pDXGIFactory); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] doc/ffmpeg: Update the description about d3d11va
From: Haihao Xiang Signed-off-by: Haihao Xiang --- doc/ffmpeg.texi | 15 +++ 1 file changed, 15 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 68363ae045..5296b75a4e 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1165,6 +1165,21 @@ Choose the first device and use the primary device context. @item d3d11va @var{device} is the number of the Direct3D 11 display adapter. +If not specified, it will attempt to use the default Direct3D 11 display adapter +or the first Direct3D 11 display adapter whose Harware VendorId is specified +by @samp{vendor_id}. + +Examples: +@table @emph +@item -init_hw_device d3d11va +Create a d3d11va device on the default Direct3D 11 display adapter. + +@item -init_hw_device d3d11va:1 +Create a d3d11va device on the Direct3D 11 display adapter specified by index 1. + +@item -init_hw_device d3d11va:,vendor_id=0x8086 +Create a d3d11va device on the first Direct3D 11 display adapter whose Harware VendorId is 0x8086. +@end table @item vaapi @var{device} is either an X11 display name, a DRM render node or a DirectX adapter index. -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] lavu/hwcontext_qsv: Make sure hardware vendor is Intel for qsv on d3d11va
From: Haihao Xiang When multiple hardware are available, the default one might not be Intel Hareware. We can use option vendor_id to choose the required vendor. Tested-by: Artem Galin Signed-off-by: Haihao Xiang --- libavutil/hwcontext_qsv.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 1bfda9e69b..7a9cd0cc37 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -2200,6 +2200,12 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, #endif #if CONFIG_D3D11VA case AV_HWDEVICE_TYPE_D3D11VA: +{ +// Make sure the hardware vendor is Intel when multiple devices are +// available, it will be ignored if user specifies the child device +// explicitly +av_dict_set(&child_device_opts, "vendor_id","0x8086", 0); +} break; #endif #if CONFIG_DXVA2 -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/3] doc/ffmpeg: Update the description about d3d11va
On 2023-11-24 11:13 am, Xiang, Haihao wrote: From: Haihao Xiang Signed-off-by: Haihao Xiang --- doc/ffmpeg.texi | 15 +++ 1 file changed, 15 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 68363ae045..5296b75a4e 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1165,6 +1165,21 @@ Choose the first device and use the primary device context. @item d3d11va @var{device} is the number of the Direct3D 11 display adapter. +If not specified, it will attempt to use the default Direct3D 11 display adapter +or the first Direct3D 11 display adapter whose Harware VendorId is specified s/Harware/Hardware here and elsewhere. Regards, Gyan +by @samp{vendor_id}. + +Examples: +@table @emph +@item -init_hw_device d3d11va +Create a d3d11va device on the default Direct3D 11 display adapter. + +@item -init_hw_device d3d11va:1 +Create a d3d11va device on the Direct3D 11 display adapter specified by index 1. + +@item -init_hw_device d3d11va:,vendor_id=0x8086 +Create a d3d11va device on the first Direct3D 11 display adapter whose Harware VendorId is 0x8086. +@end table @item vaapi @var{device} is either an X11 display name, a DRM render node or a DirectX adapter index. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavu/hwcontext_vaapi: ignore nonexistent device in default DRM device selection
From: Haihao Xiang It is possible that renderD128 doesn't exist but renderD129 is available in a system (see [1]). This change can make sure the default DRM device selection works even if renderD128 doesn't exist. [1] https://github.com/intel/intel-device-plugins-for-kubernetes/blob/main/cmd/gpu_plugin/README.md#issues-with-media-workloads-on-multi-gpu-setups Signed-off-by: Haihao Xiang --- libavutil/hwcontext_vaapi.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 12bc95119a..6d542a9bc9 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -1733,8 +1733,18 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, "/dev/dri/renderD%d", 128 + n); priv->drm_fd = open(path, O_RDWR); if (priv->drm_fd < 0) { -av_log(ctx, AV_LOG_VERBOSE, "Cannot open " - "DRM render node for device %d.\n", n); +if (errno == ENOENT) { +if (n != max_devices - 1) { +av_log(ctx, AV_LOG_VERBOSE, + "No render device %s, try next device for " + "DRM render node.\n", path); +continue; +} else +av_log(ctx, AV_LOG_VERBOSE, "No avaialbe render device " + "for DRM render node.\n"); +} else +av_log(ctx, AV_LOG_VERBOSE, "Cannot open " + "DRM render node for device %d.\n", n); break; } #if CONFIG_LIBDRM -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/3] doc/ffmpeg: Update the description about d3d11va
On Vr, 2023-11-24 at 11:25 +0530, Gyan Doshi wrote: > > > On 2023-11-24 11:13 am, Xiang, Haihao wrote: > > From: Haihao Xiang > > > > Signed-off-by: Haihao Xiang > > --- > > doc/ffmpeg.texi | 15 +++ > > 1 file changed, 15 insertions(+) > > > > diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi > > index 68363ae045..5296b75a4e 100644 > > --- a/doc/ffmpeg.texi > > +++ b/doc/ffmpeg.texi > > @@ -1165,6 +1165,21 @@ Choose the first device and use the primary device > > context. > > > > @item d3d11va > > @var{device} is the number of the Direct3D 11 display adapter. > > +If not specified, it will attempt to use the default Direct3D 11 display > > adapter > > +or the first Direct3D 11 display adapter whose Harware VendorId is > > specified > > s/Harware/Hardware here and elsewhere. Thanks for catching this typo, I'll fix it in the new version. BRs Haihao > > Regards, > Gyan > > > > +by @samp{vendor_id}. > > + > > +Examples: > > +@table @emph > > +@item -init_hw_device d3d11va > > +Create a d3d11va device on the default Direct3D 11 display adapter. > > + > > +@item -init_hw_device d3d11va:1 > > +Create a d3d11va device on the Direct3D 11 display adapter specified by > > index 1. > > + > > +@item -init_hw_device d3d11va:,vendor_id=0x8086 > > +Create a d3d11va device on the first Direct3D 11 display adapter whose > > Harware VendorId is 0x8086. > > +@end table > > > > @item vaapi > > @var{device} is either an X11 display name, a DRM render node or a DirectX > > adapter index. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavfi/vf_vpp_qsv: set the default value of async_depth to 4
From: Haihao Xiang Both qsv encoders and decoders use 4 as the default value of async_depth, let's use 4 as the default value for vpp_qsv filter too. Signed-off-by: Haihao Xiang --- libavfilter/vf_vpp_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index c07b45fedb..5356103e00 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -879,7 +879,7 @@ static const AVOption vpp_options[] = { { "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, -{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, +{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, INT_MAX, .flags = FLAGS }, #if QSV_ONEVPL { "scale_mode", "scaling & format conversion mode (mode compute(3), vd(4) and ve(5) are only available on some platforms)", OFFSET(scale_mode), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 5, .flags = FLAGS, "scale mode" }, #else -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] Fixed nvenc release dump
Signed-off-by: GOOR, Jean-Noël --- libavcodec/nvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 3c68ed3930..1f8c7e8c0e 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -1860,7 +1860,7 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_fifo_freep2(&ctx->unused_surface_queue); if (ctx->frame_data_array) { -for (i = 0; i < ctx->nb_surfaces; i++) + for (i = 0; i < ctx->frame_data_array_nb; i++) av_buffer_unref(&ctx->frame_data_array[i].frame_opaque_ref); av_freep(&ctx->frame_data_array); } -- 2.37.3.windows.1 Jean-Noël GOOR - Senior Software Architect T. +32 4 361.58.70 jn.g...@evs.com EVS Broadcast Equipment - Rue Bois Saint Jean, 13 - 4102 Seraing - BELGIUM EVS Broadcast Equipment is a commercial name which is used for all legal entities of our group. At EVS we give utmost importance to your data's privacy. If you wish to know more on how we manage your data and on your rights, please consult our Privacy Statement. This message may contain confidential information and is intended solely for the use of the addressee. Please do not use or publish the contained information without the agreement of the sender. If you are not the intended recipient of this message, please notify the sender and do not disclose, use, disseminate or copy this message. Please consider the environment before printing this email. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v4] lavu/hwcontext_vaapi: Use vaMapBuffer2 for mapping image buffers
On Vr, 2023-10-27 at 22:25 +0200, David Rosca wrote: > This allows some optimizations in driver, such as not having to read > back the data if write-only mapping is requested. > --- > v4: overwrite + note about vaMapBuffer libva fallback > > libavutil/hwcontext_vaapi.c | 12 > 1 file changed, 12 insertions(+) > > diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c > index 558fed94c6..435f10a7f3 100644 > --- a/libavutil/hwcontext_vaapi.c > +++ b/libavutil/hwcontext_vaapi.c > @@ -799,6 +799,9 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, > VAStatus vas; > void *address = NULL; > int err, i; > +#if VA_CHECK_VERSION(1, 21, 0) > + uint32_t vaflags = 0; > +#endif > > surface_id = (VASurfaceID)(uintptr_t)src->data[3]; > av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id); > @@ -882,7 +885,16 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc, > } > } > > +#if VA_CHECK_VERSION(1, 21, 0) > + if (flags & AV_HWFRAME_MAP_READ) > + vaflags |= VA_MAPBUFFER_FLAG_READ; > + if (flags & AV_HWFRAME_MAP_WRITE) > + vaflags |= VA_MAPBUFFER_FLAG_WRITE; > + // On drivers not implementing vaMapBuffer2 libva calls vaMapBuffer > instead. > + vas = vaMapBuffer2(hwctx->display, map->image.buf, &address, vaflags); > +#else > vas = vaMapBuffer(hwctx->display, map->image.buf, &address); > +#endif > if (vas != VA_STATUS_SUCCESS) { > av_log(hwfc, AV_LOG_ERROR, "Failed to map image from surface " > "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); LGTM, and will apply it when the official libva 2.21 is released. Thanks Haihao ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavu/hwcontext_qsv: use mfxImplDescription instead of mfxExtendedDeviceId on Linux
From: Haihao Xiang This fixed the issue mentioned in [1] [1] http://ffmpeg.org/pipermail/ffmpeg-user/2023-October/056983.html Signed-off-by: Haihao Xiang --- libavutil/hwcontext_qsv.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 1bfda9e69b..7f4a0fda0f 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -821,7 +821,7 @@ static int qsv_va_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) impl_value.Type = MFX_VARIANT_TYPE_U16; impl_value.Data.U16 = (attr.value & 0x); sts = MFXSetConfigFilterProperty(cfg, - (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value); + (const mfxU8 *)"mfxImplDescription.mfxDeviceDescription.DeviceID", impl_value); if (sts != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" "DeviceID property: %d.\n", sts); @@ -893,10 +893,10 @@ static int qsv_new_mfx_loader(void *ctx, goto fail; } -impl_value.Type = MFX_VARIANT_TYPE_U16; -impl_value.Data.U16 = 0x8086; // Intel device only +impl_value.Type = MFX_VARIANT_TYPE_U32; +impl_value.Data.U32 = 0x8086; // Intel device only sts = MFXSetConfigFilterProperty(cfg, - (const mfxU8 *)"mfxExtendedDeviceId.VendorID", impl_value); + (const mfxU8 *)"mfxImplDescription.VendorID", impl_value); if (sts != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" "VendorID property: %d.\n", sts); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".